From 2895d02cdc02fa5309ab0a9b1b21cac7cd61b5ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Cort=C3=A9z?= Date: Mon, 29 Dec 2014 20:58:30 -0600 Subject: [PATCH] Next-gen: Audio uploader is now MVC, so tweets can include audios. Sounds tutorial is MVC and has been improved. --- src/controller/mainController.py | 4 + src/controller/messages.py | 19 +- src/extra/AudioUploader/__init__.py | 3 - src/extra/AudioUploader/audioUploader.py | 186 +++++++++++++++++ src/extra/AudioUploader/dropbox_transfer.py | 25 +-- src/extra/AudioUploader/gui.py | 190 ------------------ src/extra/AudioUploader/transfer.py | 14 +- ...sfer_dialogs.py => wx_transfer_dialogs.py} | 21 +- src/extra/AudioUploader/wx_ui.py | 64 ++++++ src/extra/SoundsTutorial/__init__.py | 2 +- src/extra/SoundsTutorial/gui.py | 59 ------ src/extra/SoundsTutorial/soundsTutorial.py | 22 ++ .../soundsTutorial_constants.py | 23 +++ src/extra/SoundsTutorial/wx_ui.py | 25 +++ src/widgetUtils/baseDialog.py | 13 +- src/wxUI/view.py | 2 +- 16 files changed, 380 insertions(+), 292 deletions(-) create mode 100644 src/extra/AudioUploader/audioUploader.py delete mode 100644 src/extra/AudioUploader/gui.py rename src/extra/AudioUploader/{transfer_dialogs.py => wx_transfer_dialogs.py} (88%) create mode 100644 src/extra/AudioUploader/wx_ui.py delete mode 100644 src/extra/SoundsTutorial/gui.py create mode 100644 src/extra/SoundsTutorial/soundsTutorial.py create mode 100644 src/extra/SoundsTutorial/soundsTutorial_constants.py create mode 100644 src/extra/SoundsTutorial/wx_ui.py diff --git a/src/controller/mainController.py b/src/controller/mainController.py index 04bf1e02..bfb90a2e 100644 --- a/src/controller/mainController.py +++ b/src/controller/mainController.py @@ -11,6 +11,7 @@ from mysc.repeating_timer import RepeatingTimer import config import widgetUtils import platform +from extra import SoundsTutorial if platform.system() == "Windows": import keystrokeEditor @@ -174,6 +175,9 @@ class Controller(object): dlg.ShowModal() dlg.Destroy() + def learn_sounds(self, *args, **kwargs): + SoundsTutorial.soundsTutorial() + def view_user_lists(self, users): pass diff --git a/src/controller/messages.py b/src/controller/messages.py index 9a085f91..dfef1aef 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -3,16 +3,19 @@ import widgetUtils import output import url_shortener import sound +from pubsub import pub from wxUI.dialogs import message, urlList from extra import translator, SpellChecker +from extra.AudioUploader import audioUploader from twitter import utils class tweet(object): def __init__(self, session): super(tweet, self).__init__() + self.session = session self.message = message.tweet(_(u"Write the tweet here"), _(u"tweet - 0 characters"), "") widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck) -# widgetUtils.connect_event(self.message.attach, widgetUtils.BUTTON_PRESSED, self.attach) + widgetUtils.connect_event(self.message.attach, widgetUtils.BUTTON_PRESSED, self.attach) widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor) widgetUtils.connect_event(self.message.shortenButton, widgetUtils.BUTTON_PRESSED, self.shorten) widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten) @@ -76,4 +79,16 @@ class tweet(object): text = self.message.get_text() checker = SpellChecker.spellchecker.spellChecker(text, "") if hasattr(checker, "fixed_text"): - self.message.set_text(checker.fixed_text) \ No newline at end of file + self.message.set_text(checker.fixed_text) + + def attach(self, *args, **kwargs): + def completed_callback(): + url = dlg.uploaderFunction.get_url() + pub.unsubscribe(dlg.uploaderDialog.update, "uploading") + dlg.uploaderDialog.destroy() + if url != 0: + self.message.set_text(self.message.get_text()+url+" #audio") + else: + output.speak(_(u"Unable to upload the audio")) + dlg.cleanup() + dlg = audioUploader.audioUploader(self.session.settings, completed_callback) diff --git a/src/extra/AudioUploader/__init__.py b/src/extra/AudioUploader/__init__.py index 8c0cd2e8..e69de29b 100644 --- a/src/extra/AudioUploader/__init__.py +++ b/src/extra/AudioUploader/__init__.py @@ -1,3 +0,0 @@ -import gui, transfer, transfer_dialogs, platform -if platform.system() != "Darwin": - import dropbox \ No newline at end of file diff --git a/src/extra/AudioUploader/audioUploader.py b/src/extra/AudioUploader/audioUploader.py new file mode 100644 index 00000000..58548f0f --- /dev/null +++ b/src/extra/AudioUploader/audioUploader.py @@ -0,0 +1,186 @@ +# -*- coding: utf-8 -*- +############################################################ +# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################ +import widgetUtils +import wx_ui +import wx_transfer_dialogs +import dropbox_transfer, transfer +import output +import tempfile +import sound +import os +import config +from pubsub import pub +from mysc.thread_utils import call_threaded +import sound_lib + +class audioUploader(object): + def __init__(self, configFile, completed_callback): + self.config = configFile + super(audioUploader, self).__init__() + self.dialog = wx_ui.audioDialog(services=self.get_available_services()) + self.file = None + self.recorded = False + self.recording = None + self.playing = None + widgetUtils.connect_event(self.dialog.play, widgetUtils.BUTTON_PRESSED, self.on_play) + widgetUtils.connect_event(self.dialog.pause, widgetUtils.BUTTON_PRESSED, self.on_pause) + widgetUtils.connect_event(self.dialog.record, widgetUtils.BUTTON_PRESSED, self.on_record) + widgetUtils.connect_event(self.dialog.attach_exists, widgetUtils.BUTTON_PRESSED, self.on_attach_exists) + widgetUtils.connect_event(self.dialog.discard, widgetUtils.BUTTON_PRESSED, self.on_discard) + if self.dialog.get_response() == widgetUtils.OK: + self.postprocess() + self.uploaderDialog = wx_transfer_dialogs.UploadDialog(self.file) + output.speak(_(u"Attaching...")) + if self.dialog.get("services") == "Dropbox": + self.uploaderFunction = dropbox_transfer.dropboxUploader(filename=self.file, completed_callback=completed_callback, config=self.config) + elif self.dialog.get("services") == "SNDUp": + base_url = "http://sndup.net/post.php" + if len(self.config["sound"]["sndup_api_key"]) > 0: + url = base_url + '?apikey=' + self.config['sound']['sndup_api_key'] + else: + url = base_url + self.uploaderFunction = transfer.Upload(field='file', url=url, filename=self.file, completed_callback=completed_callback) + elif self.dialog.get("services") == "TwUp": + url = "http://api.twup.me/post.json" + self.uploaderFunction = transfer.Upload(field='file', url=url, filename=self.file, completed_callback=completed_callback) + pub.subscribe(self.uploaderDialog.update, "uploading") + self.uploaderDialog.get_response() + self.uploaderFunction.perform_threaded() + + def get_available_services(self): + services = [] + services.append("TwUp") + if self.config["services"]["dropbox_token"] != "": + services.append("Dropbox") + services.append("SNDUp") + return services + + def on_pause(self, *args, **kwargs): + if self.dialog.get("pause") == _(u"Pause"): + self.recording.pause() + self.dialog.set("pause", _(u"Resume")) + elif self.dialog.get("pause") == _(u"Resume"): + self.recording.play() + self.dialog.set("pause", _(U"Pause")) + + def on_record(self, *args, **kwargs): + if self.recording != None: + self.stop_recording() + self.dialog.disable_control("pause") + else: + self.start_recording() + self.dialog.enable_control("pause") + + def start_recording(self): + self.dialog.disable_control("attach_exists") + self.file = tempfile.mktemp(suffix='.wav') + self.recording = sound.recording(self.file) + self.recording.play() + self.dialog.set("record", _(u"Stop recording")) + output.speak(_(u"Recording")) + + def stop_recording(self): + self.recording.stop() + self.recording.free() + output.speak(_(u"Stopped")) + self.recorded = True + self.dialog.set("record", _(u"Record")) + self.file_attached() + + def file_attached(self): + self.dialog.set("pause", _(u"Pause")) + self.dialog.disable_control("record") + self.dialog.enable_control("play") + self.dialog.enable_control("discard") + self.dialog.disable_control("attach_exists") + self.dialog.enable_control("attach") + self.dialog.play.SetFocus() + + def on_discard(self, *args, **kwargs): + if self.playing: + self._stop() + if self.recording != None: + self.dialog.disable_control("attach") + self.dialog.disable_control("play") + self.file = None + self.dialog.enable_control("record") + self.dialog.enable_control("attach_exists") + self.dialog.record.SetFocus() + self.dialog.disable_control("discard") + self.recording = None + output.speak(_(u"Discarded")) + + def on_play(self, *args, **kwargs): + if not self.playing: + call_threaded(self._play) + else: + self._stop() + + def _play(self): + output.speak(_(u"Playing...")) +# try: + self.playing = sound_lib.stream.FileStream(file=unicode(self.file), flags=sound_lib.stream.BASS_UNICODE) + self.playing.play() + self.dialog.set("play", _(u"Stop")) + try: + while self.playing.is_playing: + pass + self.dialog.set("play", _(u"Play")) + self.playing.free() + self.playing = None + except: + pass + + def _stop(self): + output.speak(_(u"Stopped")) + self.playing.stop() + self.playing.free() + self.dialog.set("play", _(u"Play")) + self.playing = None + + def postprocess(self): + if self.file.lower().endswith('.wav'): + output.speak(_(u"Recoding audio...")) + sound.recode_audio(self.file) + self.wav_file = self.file + self.file = '%s.ogg' % self.file[:-4] + + def cleanup(self): + if self.playing and self.playing.is_playing: + self.playing.stop() + if self.recording != None: + if self.recording.is_playing: + self.recording.stop() + try: + self.recording.free() + except: + pass + os.remove(self.file) + if hasattr(self, 'wav_file'): + os.remove(self.wav_file) + del(self.wav_file) + if hasattr(self, 'wav_file') and os.path.exists(self.file): + os.remove(self.file) + + + def on_attach_exists(self, *args, **kwargs): + self.file = self.dialog.get_file() + if self.file != False: + self.file_attached() + diff --git a/src/extra/AudioUploader/dropbox_transfer.py b/src/extra/AudioUploader/dropbox_transfer.py index e693fef4..a68d3e70 100644 --- a/src/extra/AudioUploader/dropbox_transfer.py +++ b/src/extra/AudioUploader/dropbox_transfer.py @@ -3,13 +3,11 @@ import threading import time import os import exceptions -import wx import dropbox -import config -from mysc import event from utils import * from dropbox.rest import ErrorResponse from StringIO import StringIO +from pubsub import pub class UnauthorisedError(exceptions.Exception): def __init__(self, *args, **kwargs): @@ -39,10 +37,11 @@ class newChunkedUploader(dropbox.client.ChunkedUploader): self.offset = reply['offset'] class dropboxLogin(object): - def __init__(self): + def __init__(self, config): self.logged = False self.app_key = "c8ikm0gexqvovol" self.app_secret = "gvvi6fzfecooast" + self.config = config def get_url(self): self.flow = dropbox.client.DropboxOAuth2FlowNoRedirect(self.app_key, self.app_secret) @@ -50,18 +49,17 @@ class dropboxLogin(object): def authorise(self, code): access_token, user_id = self.flow.finish(code) - config.main["services"]["dropbox_token"] = access_token + config["services"]["dropbox_token"] = access_token self.logged = True class dropboxUploader(object): - def __init__(self, filename, completed_callback, wxDialog, short_url=False): - if config.main["services"]["dropbox_token"] != "": - self.client = dropbox.client.DropboxClient(config.main["services"]["dropbox_token"]) + def __init__(self, config, filename, completed_callback, short_url=False): + if config["services"]["dropbox_token"] != "": + self.client = dropbox.client.DropboxClient(config["services"]["dropbox_token"]) else: raise UnauthorisedError("You need authorise TWBlue") self.filename = filename self.short_url = short_url - self.wxDialog = wxDialog self.file = open(self.filename, "rb") self.file_size = os.path.getsize(self.filename) self.uploader = newChunkedUploader(client=self.client, file_obj=self.file, length=self.file_size, callback=self.process) @@ -94,9 +92,7 @@ class dropboxUploader(object): progress["eta"] = (progress["total"] - progress["current"]) / self.transfer_rate else: progress["eta"] = 0 - info = event.event(event.EVT_OBJECT, 1) - info.SetItem(progress) - wx.PostEvent(self.wxDialog, info) + pub.sendMessage("uploading", data=progress) def perform_threaded(self): self.background_thread = threading.Thread(target=self.perform_transfer) @@ -109,5 +105,6 @@ class dropboxUploader(object): self.completed_callback() def get_url(self): - original = "%s" % (self.client.share(os.path.basename(self.filename), False)["url"]) - return original.replace("dl=0", "dl=1") \ No newline at end of file + original = "%s" % (self.client.media(os.path.basename(self.filename))["url"]) + return original +# .replace("dl=0", "dl=1") \ No newline at end of file diff --git a/src/extra/AudioUploader/gui.py b/src/extra/AudioUploader/gui.py deleted file mode 100644 index 0388fa65..00000000 --- a/src/extra/AudioUploader/gui.py +++ /dev/null @@ -1,190 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################ -# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -############################################################ -import wx -import output -import tempfile -import sound -import os -import config -from mysc.thread_utils import call_threaded -import sound_lib - -class audioDialog(wx.Dialog): - def __init__(self, parent): - self.parent = parent - wx.Dialog.__init__(self, None, -1, _(u"Attach audio")) - self.file = None - self.recorded = False - self.recording = None - self.playing = None - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - self.play = wx.Button(panel, -1, _(u"Play")) - self.play.Bind(wx.EVT_BUTTON, self.onPlay) - self.play.Disable() - self.pause = wx.Button(panel, -1, _(u"Pause")) - self.pause.Bind(wx.EVT_BUTTON, self.onPause) - self.pause.Disable() - self.record = wx.Button(panel, -1, _(u"Record")) - self.record.Bind(wx.EVT_BUTTON, self.onRecord) - self.record.SetFocus() - self.attach_exists = wx.Button(panel, -1, _(u"Add an existing file")) - self.attach_exists.Bind(wx.EVT_BUTTON, self.onAttach) - self.discard = wx.Button(panel, -1, _(u"Discard")) - self.discard.Bind(wx.EVT_BUTTON, self.onDiscard) - self.discard.Disable() - label = wx.StaticText(panel, -1, _(u"Upload to")) - self.services = wx.ComboBox(panel, -1, choices=self.get_available_services(), value=self.get_available_services()[0], style=wx.CB_READONLY) - servicesBox = wx.BoxSizer(wx.HORIZONTAL) - servicesBox.Add(label) - servicesBox.Add(self.services) - self.attach = wx.Button(panel, wx.ID_OK, _(u"Attach")) - self.attach.Disable() - cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel")) - sizer.Add(self.play) - sizer.Add(self.pause) - sizer.Add(self.record) - sizer.Add(self.attach_exists) - sizer.Add(self.discard) - sizer.Add(self.attach) - - def get_available_services(self): - services = [] - if config.main["services"]["dropbox_token"] != "": - services.append("Dropbox") - services.append("SNDUp") - return services - - def onPause(self, ev): - if self.pause.GetLabel() == _(u"Pause"): - self.recording.pause() - self.pause.SetLabel(_(u"Resume")) - elif self.pause.GetLabel() == _(u"Resume"): - self.recording.play() - self.pause.SetLabel(_(U"Pause")) - - def onRecord(self, ev): - if self.recording != None: - self.stop_recording() - self.pause.Disable() - else: - self.start_recording() - self.pause.Enable() - - def start_recording(self): - self.attach_exists.Disable() - self.file = tempfile.mktemp(suffix='.wav') - self.recording = sound.recording(self.file) - self.recording.play() - self.record.SetLabel(_(u"Stop recording")) - output.speak(_(u"Recording")) - - def stop_recording(self): - self.recording.stop() - self.recording.free() - output.speak(_(u"Stopped")) - self.recorded = True - self.record.SetLabel(_(u"Record")) - self.file_attached() - - def file_attached(self): - self.pause.SetLabel(_(u"Pause")) - self.record.Disable() - self.play.Enable() - self.discard.Enable() - self.attach_exists.Disable() - self.attach.Enable() - self.play.SetFocus() - - def onDiscard(self, evt): - evt.Skip() - if self.playing: - self._stop() - if self.recording != None: - self.attach.Disable() - self.play.Disable() - self.file = None - self.record.Enable() - self.attach_exists.Enable() - self.record.SetFocus() - self.discard.Disable() - self.recording = None - output.speak(_(u"Discarded")) - - def onPlay(self, evt): - evt.Skip() - if not self.playing: - call_threaded(self._play) - else: - self._stop() - - def _play(self): - output.speak(_(u"Playing...")) -# try: - self.playing = sound_lib.stream.FileStream(file=unicode(self.file), flags=sound_lib.stream.BASS_UNICODE) - self.playing.play() - self.play.SetLabel(_(u"Stop")) - try: - while self.playing.is_playing: - pass - self.play.SetLabel(_(u"Play")) - self.playing.free() - self.playing = None - except: - pass - - def _stop(self): - output.speak(_(u"Stopped")) - self.playing.stop() - self.playing.free() - self.play.SetLabel(_(u"Play")) - self.playing = None - - def postprocess(self): - if self.file.lower().endswith('.wav'): - output.speak(_(u"Recoding audio...")) - sound.recode_audio(self.file) - self.wav_file = self.file - self.file = '%s.ogg' % self.file[:-4] - - def cleanup(self): - if self.playing and self.playing.is_playing: - self.playing.stop() - if self.recording != None: - if self.recording.is_playing: - self.recording.stop() - try: - self.recording.free() - except: - pass - os.remove(self.file) - if hasattr(self, 'wav_file'): - os.remove(self.wav_file) - del(self.wav_file) - if hasattr(self, 'wav_file') and os.path.exists(self.file): - os.remove(self.file) - - - def onAttach(self, ev): - openFileDialog = wx.FileDialog(self, _(u"Select the audio file to be uploaded"), "", "", _("Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return - self.file = openFileDialog.GetPath() - self.file_attached() - ev.Skip() diff --git a/src/extra/AudioUploader/transfer.py b/src/extra/AudioUploader/transfer.py index 506b1cd5..fdbbc160 100644 --- a/src/extra/AudioUploader/transfer.py +++ b/src/extra/AudioUploader/transfer.py @@ -4,15 +4,12 @@ import sys import threading import time import json -import wx -from mysc import event from utils import * - -#__all__ = ['TransferDialog', 'DownloadDialog', 'UploadDialog'] +from pubsub import pub class Transfer(object): - def __init__(self, url=None, filename=None, follow_location=True, completed_callback=None, verbose=False, wxDialog=None, *args, **kwargs): + def __init__(self, url=None, filename=None, follow_location=True, completed_callback=None, verbose=False, *args, **kwargs): self.url = url self.filename = filename self.curl = pycurl.Curl() @@ -26,7 +23,6 @@ class Transfer(object): self.curl.setopt(self.curl.HTTP_VERSION, self.curl.CURL_HTTP_VERSION_1_0) self.curl.setopt(self.curl.FOLLOWLOCATION, int(follow_location)) self.curl.setopt(self.curl.VERBOSE, int(verbose)) - self.wxDialog = wxDialog super(Transfer, self).__init__(*args, **kwargs) def elapsed_time(self): @@ -52,15 +48,13 @@ class Transfer(object): progress["eta"] = (progress["total"] - progress["current"]) / self.transfer_rate else: progress["eta"] = 0 - info = event.event(event.EVT_OBJECT, 1) - info.SetItem(progress) - wx.PostEvent(self.wxDialog, info) + pub.sendMessage("uploading", data=progress) def perform_transfer(self): self.start_time = time.time() self.curl.perform() self.curl.close() - wx.CallAfter(self.complete_transfer) + self.complete_transfer() def perform_threaded(self): self.background_thread = threading.Thread(target=self.perform_transfer) diff --git a/src/extra/AudioUploader/transfer_dialogs.py b/src/extra/AudioUploader/wx_transfer_dialogs.py similarity index 88% rename from src/extra/AudioUploader/transfer_dialogs.py rename to src/extra/AudioUploader/wx_transfer_dialogs.py index 46e48a40..18ecbd1c 100644 --- a/src/extra/AudioUploader/transfer_dialogs.py +++ b/src/extra/AudioUploader/wx_transfer_dialogs.py @@ -1,14 +1,12 @@ # -*- coding: utf-8 -*- import wx -from mysc import event from utils import * +import widgetUtils -__all__ = ['TransferDialog', 'DownloadDialog', 'UploadDialog'] - -class TransferDialog(wx.Dialog): +class TransferDialog(widgetUtils.BaseDialog): def __init__(self, filename, *args, **kwargs): - super(TransferDialog, self).__init__(*args, **kwargs) + super(TransferDialog, self).__init__(parent=None, id=wx.NewId(), *args, **kwargs) self.pane = wx.Panel(self) self.progress_bar = wx.Gauge(parent=self.pane) fileBox = wx.BoxSizer(wx.HORIZONTAL) @@ -37,7 +35,7 @@ class TransferDialog(wx.Dialog): self.eta = wx.TextCtrl(self.pane, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, value="Unknown", size=(200, 100)) etaBox.Add(etaLabel) etaBox.Add(self.eta) -# self.create_buttons() + self.create_buttons() sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(fileBox) sizer.Add(currentAmountBox) @@ -46,10 +44,8 @@ class TransferDialog(wx.Dialog): sizer.Add(etaBox) sizer.Add(self.progress_bar) self.pane.SetSizerAndFit(sizer) - self.Bind(event.MyEVT_OBJECT, self.update) - def update(self, ev): - data = ev.GetItem() + def update(self, data): wx.CallAfter(self.progress_bar.SetValue, data["percent"]) wx.CallAfter(self.current_amount.SetValue, '%s (%d%%)' % (convert_bytes(data["current"]), data["percent"])) wx.CallAfter(self.total_size.SetValue, convert_bytes(data["total"])) @@ -59,7 +55,12 @@ class TransferDialog(wx.Dialog): def create_buttons(self): self.cancel_button = wx.Button(parent=self.pane, id=wx.ID_CANCEL) - self.cancel_button.Bind(wx.EVT_BUTTON, self.on_cancel) + + def get_response(self): + self.Show() + + def destroy(self): + self.Destroy() class UploadDialog(TransferDialog): diff --git a/src/extra/AudioUploader/wx_ui.py b/src/extra/AudioUploader/wx_ui.py new file mode 100644 index 00000000..7c3d5abc --- /dev/null +++ b/src/extra/AudioUploader/wx_ui.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +############################################################ +# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################ +import wx +import widgetUtils +import output + +class audioDialog(widgetUtils.BaseDialog): + def __init__(self, services): + super(audioDialog, self).__init__(None, -1, _(u"Attach audio")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + self.play = wx.Button(panel, -1, _(u"Play")) + self.play.Disable() + self.pause = wx.Button(panel, -1, _(u"Pause")) + self.pause.Disable() + self.record = wx.Button(panel, -1, _(u"Record")) + self.record.SetFocus() + self.attach_exists = wx.Button(panel, -1, _(u"Add an existing file")) + self.discard = wx.Button(panel, -1, _(u"Discard")) + self.discard.Disable() + label = wx.StaticText(panel, -1, _(u"Upload to")) + self.services = wx.ComboBox(panel, -1, choices=services, value=services[0], style=wx.CB_READONLY) + servicesBox = wx.BoxSizer(wx.HORIZONTAL) + servicesBox.Add(label) + servicesBox.Add(self.services) + self.attach = wx.Button(panel, wx.ID_OK, _(u"Attach")) + self.attach.Disable() + cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel")) + sizer.Add(self.play) + sizer.Add(self.pause) + sizer.Add(self.record) + sizer.Add(self.attach_exists) + sizer.Add(self.discard) + sizer.Add(self.attach) + + def enable_control(self, control): + if hasattr(self, control): + getattr(self, control).Enable() + + def disable_control(self, control): + if hasattr(self, control): + getattr(self, control).Disable() + + def get_file(self): + openFileDialog = wx.FileDialog(self, _(u"Select the audio file to be uploaded"), "", "", _("Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return False + return openFileDialog.GetPath() diff --git a/src/extra/SoundsTutorial/__init__.py b/src/extra/SoundsTutorial/__init__.py index ea9d0162..9c245eb4 100644 --- a/src/extra/SoundsTutorial/__init__.py +++ b/src/extra/SoundsTutorial/__init__.py @@ -1 +1 @@ -import gui \ No newline at end of file +from soundsTutorial import * \ No newline at end of file diff --git a/src/extra/SoundsTutorial/gui.py b/src/extra/SoundsTutorial/gui.py deleted file mode 100644 index ebb8c2eb..00000000 --- a/src/extra/SoundsTutorial/gui.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -import wx -import config -import os -import paths -import sound - -class soundsTutorial(wx.Dialog): - def __init__(self): - self.actions = [ - _(u"The tweet may contain a playable audio"), - _(u"A timeline has been created"), - _(u"A timeline has been deleted"), - _(u"You've received a direct message"), - _(u"You've sent a direct message"), - _(u"A bug has happened"), - _(u"You've added a tweet to your favourites"), - _(u"Someone's favourites have been updated"), - _(u"There are no more tweets to read"), - _(u"A list has a new tweet"), - _(u"You can't add any more characters on the tweet"), - _(u"You've been mentioned "), - _(u"A new event has happened"), - _(u"TW Blue is ready "), - _(u"You've replied"), - _(u"You've retweeted"), - _(u"A search has been updated"), - _(u"There's a new tweet in the main buffer"), - _(u"You've sent a tweet"), - _(u"There's a new tweet in a timeline"), - _(u"You have a new follower"), - _(u"You've turned the volume up or down")] - self.files = os.listdir(paths.sound_path("default")) - super(soundsTutorial, self).__init__(None, -1) - if len(self.actions) > len(self.files): - wx.MessageDialog(None, _(u"It seems as though the currently used sound pack needs an update. %i fails are still be required to use this function. Make sure to obtain the needed lacking sounds or to contact with the sound pack developer.") % (len(self.actions) - len(self.files)), _(u"Error"), wx.ICON_ERROR).ShowModal() - self.Destroy() - self.SetTitle(_(u"Sounds tutorial")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - label = wx.StaticText(panel, -1, _(u"Press enter to listen to the sound for the selected event")) - self.items = wx.ListBox(panel, 1, choices=self.actions, style=wx.LB_SINGLE) - self.items.SetSelection(0) - listBox = wx.BoxSizer(wx.HORIZONTAL) - listBox.Add(label) - listBox.Add(self.items) - play = wx.Button(panel, 1, (u"Play")) - play.SetDefault() - self.Bind(wx.EVT_BUTTON, self.onPlay, play) - close = wx.Button(panel, wx.ID_CANCEL) - btnBox = wx.BoxSizer(wx.HORIZONTAL) - btnBox.Add(play) - btnBox.Add(close) - sizer.Add(listBox) - sizer.Add(btnBox) - panel.SetSizer(sizer) - - def onPlay(self, ev): - sound.player.play(self.files[self.items.GetSelection()]) \ No newline at end of file diff --git a/src/extra/SoundsTutorial/soundsTutorial.py b/src/extra/SoundsTutorial/soundsTutorial.py new file mode 100644 index 00000000..896f0445 --- /dev/null +++ b/src/extra/SoundsTutorial/soundsTutorial.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +import widgetUtils +import config +import os +import paths +import sound +import wx_ui +import soundsTutorial_constants + +class soundsTutorial(object): + def __init__(self): + super(soundsTutorial, self).__init__() + self.actions = [] + [self.actions.append(i[1]) for i in soundsTutorial_constants.actions] + self.files = [] + [self.files.append(i[0]) for i in soundsTutorial_constants.actions] + self.dialog = wx_ui.soundsTutorialDialog(self.actions) + widgetUtils.connect_event(self.dialog.play, widgetUtils.BUTTON_PRESSED, self.on_play) + self.dialog.get_response() + + def on_play(self, *args, **kwargs): + sound.player.play(self.files[self.dialog.items.GetSelection()]+".ogg") \ No newline at end of file diff --git a/src/extra/SoundsTutorial/soundsTutorial_constants.py b/src/extra/SoundsTutorial/soundsTutorial_constants.py new file mode 100644 index 00000000..0972dea2 --- /dev/null +++ b/src/extra/SoundsTutorial/soundsTutorial_constants.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +actions = [ ("audio", _(u"The tweet may contain a playable audio")), + ("create_timeline", _(u"A timeline has been created")), + ("delete_timeline", _(u"A timeline has been deleted")), + ("dm_received", _(u"You've received a direct message")), + ("dm_sent", _(u"You've sent a direct message")), + ("error", _(u"A bug has happened")), + ("favourite", _(u"You've added a tweet to your favourites")), + ("favourites_timeline_updated", _(u"Someone's favourites have been updated")), + ("limit", _(u"There are no more tweets to read")), + ("list_tweet", _(u"A list has a new tweet")), + ("max_length", _(u"You can't add any more characters on the tweet")), + ("mention_received", _(u"You've been mentioned ")), + ("new_event", _(u"A new event has happened")), + ("ready", _(u"TW Blue is ready ")), + ("reply_send", _(u"You've replied")), + ("retweet_send", _(u"You've retweeted")), + ("search_updated", _(u"A search has been updated")), + ("tweet_received", _(u"There's a new tweet in the main buffer")), + ("tweet_send", _(u"You've sent a tweet")), + ("tweet_timeline", _(u"There's a new tweet in a timeline")), + ("update_followers", _(u"You have a new follower")), + ("volume_changed", _(u"You've turned the volume up or down"))] \ No newline at end of file diff --git a/src/extra/SoundsTutorial/wx_ui.py b/src/extra/SoundsTutorial/wx_ui.py new file mode 100644 index 00000000..5c647a0b --- /dev/null +++ b/src/extra/SoundsTutorial/wx_ui.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +import wx +import widgetUtils + +class soundsTutorialDialog(widgetUtils.BaseDialog): + def __init__(self, actions): + super(soundsTutorialDialog, self).__init__(None, -1) + self.SetTitle(_(u"Sounds tutorial")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + label = wx.StaticText(panel, -1, _(u"Press enter to listen to the sound for the selected event")) + self.items = wx.ListBox(panel, 1, choices=actions, style=wx.LB_SINGLE) + self.items.SetSelection(0) + listBox = wx.BoxSizer(wx.HORIZONTAL) + listBox.Add(label) + listBox.Add(self.items) + self.play = wx.Button(panel, 1, (u"Play")) + self.play.SetDefault() + close = wx.Button(panel, wx.ID_CANCEL) + btnBox = wx.BoxSizer(wx.HORIZONTAL) + btnBox.Add(self.play) + btnBox.Add(close) + sizer.Add(listBox) + sizer.Add(btnBox) + panel.SetSizer(sizer) \ No newline at end of file diff --git a/src/widgetUtils/baseDialog.py b/src/widgetUtils/baseDialog.py index e20b805b..9d1faa44 100644 --- a/src/widgetUtils/baseDialog.py +++ b/src/widgetUtils/baseDialog.py @@ -1,8 +1,8 @@ import wx -class BaseWXDialog(wx.Dialog): +class BaseDialog(wx.Dialog): def __init__(self, *args, **kwargs): - super(BaseWXDialog, self).__init__(*args, **kwargs) + super(BaseDialog, self).__init__(*args, **kwargs) def get_response(self): return self.ShowModal() @@ -13,4 +13,13 @@ class BaseWXDialog(wx.Dialog): if hasattr(control, "GetValue"): return getattr(control, "GetValue")() elif hasattr(control, "GetLabel"): return getattr(control, "GetLabel")() else: return -1 + else: return 0 + + def set(self, control, text): + if hasattr(self, control): + control = getattr(self, control) + if hasattr(control, "SetValue"): return getattr(control, "SetValue")(text) + elif hasattr(control, "SetLabel"): return getattr(control, "SetLabel")(text) + elif hasattr(control, "ChangeValue"): return getattr(control, "ChangeValue")(text) + else: return -1 else: return 0 \ No newline at end of file diff --git a/src/wxUI/view.py b/src/wxUI/view.py index e2d90cf8..b3275d4e 100644 --- a/src/wxUI/view.py +++ b/src/wxUI/view.py @@ -20,7 +20,7 @@ class mainFrame(wx.Frame): lists = app.Append(wx.NewId(), _(u"&Lists manager")) # self.view.Bind(wx.EVT_MENU, self.list_manager, lists) sounds_tutorial = app.Append(wx.NewId(), _(u"Sounds &tutorial")) -# self.view.Bind(wx.EVT_MENU, self.learn_sounds, sounds_tutorial) + self.Bind(wx.EVT_MENU, self.controller.learn_sounds, sounds_tutorial) keystroke_editor = app.Append(wx.NewId(), _(u"&Edit keystrokes")) self.Bind(wx.EVT_MENU, self.controller.edit_keystrokes, keystroke_editor) prefs = app.Append(wx.ID_PREFERENCES, _(u"&Preferences"))