From 67f2eec4ebb93d54afe580cf29c2a493544e662b Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 8 Jan 2019 11:56:10 -0600 Subject: [PATCH] Audio display features have been moved to work in MVP --- src/controller/buffers.py | 9 +-- src/interactors/postDisplayer.py | 61 +++++++++++++++++++- src/presenters/postDisplayer.py | 96 ++++++++++++++++++++++++++++++-- 3 files changed, 153 insertions(+), 13 deletions(-) diff --git a/src/controller/buffers.py b/src/controller/buffers.py index bb013eb..0b6aa6c 100644 --- a/src/controller/buffers.py +++ b/src/controller/buffers.py @@ -24,6 +24,7 @@ from sessionmanager import session, renderers, utils from mysc.thread_utils import call_threaded from wxUI import commonMessages, menus from sessionmanager.renderers import add_attachment +from wxUI.dialogs import postDialogs log = logging.getLogger("controller.buffers") @@ -341,9 +342,7 @@ class baseBuffer(object): if post == None: return if "type" in post and post["type"] == "audio": - a = posts.audio(self.session, post["audio"]["items"]) - a.dialog.get_response() - a.dialog.Destroy() + a = presenters.displayAudioPresenter(session=self.session, postObject=post["audio"]["items"], interactor=interactors.displayAudioInteractor(), view=postDialogs.audio()) elif "type" in post and post["type"] == "friend": pub.sendMessage("open-post", post_object=post, controller_="friendship") else: @@ -514,9 +513,7 @@ class audioBuffer(feedBuffer): if selected == -1: return audios = [self.session.db[self.name]["items"][selected]] - a = posts.audio(self.session, audios) - a.dialog.get_response() - a.dialog.Destroy() + a = presenters.displayAudioPresenter(session=self.session, postObject=audios, interactor=interactors.displayAudioInteractor(), view=postDialogs.audio()) def play_all(self, *args, **kwargs): selected = self.tab.list.get_selected() diff --git a/src/interactors/postDisplayer.py b/src/interactors/postDisplayer.py index 73e054e..a573622 100644 --- a/src/interactors/postDisplayer.py +++ b/src/interactors/postDisplayer.py @@ -43,6 +43,7 @@ class displayPostInteractor(base.baseInteractor): def install(self, *args, **kwargs): super(displayPostInteractor, self).install(*args, **kwargs) self.view.comments.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_show_comment) + self.view.attachments.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_open_attachment) widgetUtils.connect_event(self.view.like, widgetUtils.BUTTON_PRESSED, self.on_like) widgetUtils.connect_event(self.view.comment, widgetUtils.BUTTON_PRESSED, self.on_add_comment) widgetUtils.connect_event(self.view.tools, widgetUtils.BUTTON_PRESSED, self.on_show_tools_menu) @@ -81,18 +82,72 @@ class displayPostInteractor(base.baseInteractor): def on_open_url(self, *args, **kwargs): pass + def on_open_attachment(self, *args, **kwargs): + attachment = self.view.attachments.get_selected() + self.presenter.open_attachment(attachment) + def on_translate(self, *args, **kwargs): dlg = translator.gui.translateDialog() if dlg.get_response() == widgetUtils.OK: - text_to_translate = self.view.get_text() + text_to_translate = self.view.get("post_view") dest = [x[0] for x in translator.translator.available_languages()][dlg.get("dest_lang")] self.presenter.translate(text_to_translate, dest) dlg.Destroy() def on_spellcheck(self, event=None): - text = self.view.get_text() + text = self.view.get("post_view") self.presenter.spellcheck(text) def on_show_comment(self, *args, **kwargs): comment = self.view.comments.get_selected() - self.presenter.show_comment(comment) \ No newline at end of file + self.presenter.show_comment(comment) + +class displayAudioInteractor(base.baseInteractor): + + def set(self, control, value): + if not hasattr(self.view, control): + raise AttributeError("The control is not present in the view.") + getattr(self.view, control).SetValue(value) + + def add_items(self, control, items): + if not hasattr(self.view, control): + raise AttributeError("The control is not present in the view.") + for i in items: + getattr(self.view, control).Append(i) + getattr(self.view, control).SetSelection(0) + + def install(self, *args, **kwargs): + super(displayAudioInteractor, self).install(*args, **kwargs) + widgetUtils.connect_event(self.view.list, widgetUtils.LISTBOX_CHANGED, self.on_change) + widgetUtils.connect_event(self.view.download, widgetUtils.BUTTON_PRESSED, self.on_download) + widgetUtils.connect_event(self.view.play, widgetUtils.BUTTON_PRESSED, self.on_play) + widgetUtils.connect_event(self.view.add, widgetUtils.BUTTON_PRESSED, self.on_add_to_library) + widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.on_remove_from_library) + pub.subscribe(self.set, self.modulename+"_set") + pub.subscribe(self.add_items, self.modulename+"_add_items") + + def uninstall(self): + pub.unsubscribe(self.set, self.modulename+"_set") + pub.unsubscribe(self.add_items, self.modulename+"_add_items") + + def on_change(self, *args, **kwargs): + post = self.view.get_audio() + self.presenter.handle_changes(post) + + def on_download(self, *args, **kwargs): + post = self.view.get_audio() + suggested_filename = self.presenter.get_suggested_filename(post) + path = self.view.get_destination_path(suggested_filename) + self.presenter.download(post, path) + + def on_play(self, *args, **kwargs): + post = self.view.get_audio() + self.presenter.play(post) + + def on_add_to_library(self, *args, **kwargs): + post = self.view.get_audio() + self.presenter.add_to_library(post) + + def on_remove_from_library(self, *args, **kwargs): + post = self.view.get_audio() + self.presenter.remove_from_library(post) \ No newline at end of file diff --git a/src/presenters/postDisplayer.py b/src/presenters/postDisplayer.py index 58fe30c..750a774 100644 --- a/src/presenters/postDisplayer.py +++ b/src/presenters/postDisplayer.py @@ -12,10 +12,10 @@ import interactors import output import webbrowser import logging +from wxUI.dialogs import postDialogs from sessionmanager import session, renderers, utils # We'll use some functions from there from pubsub import pub from extra import SpellChecker, translator -from controller.posts import comment, audio from mysc.thread_utils import call_threaded from .import base from .postCreation import createPostPresenter @@ -283,9 +283,7 @@ class displayPostPresenter(base.basePresenter): def open_attachment(self, index): attachment = self.attachments[index] if attachment["type"] == "audio": - a = audio(session=self.session, postObject=[attachment["audio"]]) - a.dialog.get_response() - a.dialog.Destroy() + a = displayAudioPresenter(session=self.session, postObject=[attachment["audio"]], interactor=interactors.displayAudioInteractor(), view=postDialogs.audio()) if attachment["type"] == "link": output.speak(_("Opening URL..."), True) webbrowser.open_new_tab(attachment["link"]["url"]) @@ -321,3 +319,93 @@ class displayPostPresenter(base.basePresenter): def __del__(self): if hasattr(self, "worker"): self.worker.finished.set() + +class displayAudioPresenter(base.basePresenter): + def __init__(self, session, postObject, view, interactor): + super(displayAudioPresenter, self).__init__(view=view, interactor=interactor, modulename="display_audio") + self.added_audios = {} + self.session = session + self.post = postObject + self.load_audios() + self.fill_information(0) + self.run() + + def add_to_library(self, audio_index): + post = self.post[audio_index] + args = {} + args["audio_id"] = post["id"] + if "album_id" in post: + args["album_id"] = post["album_id"] + args["owner_id"] = post["owner_id"] + audio = self.session.vk.client.audio.add(**args) + if audio != None and int(audio) > 21: + self.added_audios[post["id"]] = audio + self.send_message("disable_control", control="add") + self.send_message("enable_control", control="remove") + + def remove_from_library(self, audio_index): + post = self.post[audio_index] + args = {} + if post["id"] in self.added_audios: + args["audio_id"] = self.added_audios[post["id"]] + args["owner_id"] = self.session.user_id + else: + args["audio_id"] = post["id"] + args["owner_id"] = post["owner_id"] + result = self.session.vk.client.audio.delete(**args) + if int(result) == 1: + self.send_message("enable_control", control="add") + self.send_message("disable_control", control="remove") + if post["id"] in self.added_audios: + self.added_audios.pop(post["id"]) + + def fill_information(self, index): + post = self.post[index] + if "artist" in post: + self.send_message("set", control="artist", value=post["artist"]) + if "title" in post: + self.send_message("set", control="title", value=post["title"]) + if "duration" in post: + self.send_message("set", control="duration", value=utils.seconds_to_string(post["duration"])) + self.send_message("set_title", value="{0} - {1}".format(post["title"], post["artist"])) + call_threaded(self.get_lyrics, index) + if post["owner_id"] == self.session.user_id or (post["id"] in self.added_audios) == True: + self.send_message("enable_control", control="remove") + self.send_message("disable_control", control="add") + else: + self.send_message("enable_control", control="add") + self.send_message("disable_control", control="remove") + + def get_lyrics(self, audio_index): + post = self.post[audio_index] + if "lyrics_id" in post: + l = self.session.vk.client.audio.getLyrics(lyrics_id=int(post["lyrics_id"])) + self.send_message("set", control="lyric", value=l["text"]) + else: + self.send_message("disable_control", control="lyric") + + def get_suggested_filename(self, audio_index): + post = self.post[audio_index] + return "{0} - {1}.mp3".format(post["title"], post["artist"]) + + def download(self, audio_index, path): + post = self.post[audio_index] + if path != None: + pub.sendMessage("download-file", url=post["url"], filename=path) + + def play(self, audio_index): + post = self.post[audio_index] + pub.sendMessage("play-audio", audio_object=post) + + def load_audios(self): + audios = [] + for i in self.post: + s = "{0} - {1}. {2}".format(i["title"], i["artist"], utils.seconds_to_string(i["duration"])) + audios.append(s) + self.send_message("add_items", control="list", items=audios) + if len(self.post) == 1: + self.send_message("disable_control", control="list") + self.send_message("focus_control", control="title") + + def handle_changes(self, audio_index): + self.fill_information(audio_index)