Added context menu for tracks and file downloads

This commit is contained in:
Manuel Cortez 2018-01-26 12:56:50 -06:00
parent 834b1d2dd7
commit d307ca1784
4 changed files with 63 additions and 3 deletions

View File

@ -5,7 +5,7 @@ import logging
import widgetUtils import widgetUtils
import utils import utils
from pubsub import pub from pubsub import pub
from wxUI import mainWindow from wxUI import mainWindow, menus
from extractors import zaycev from extractors import zaycev
from . import player from . import player
@ -56,6 +56,9 @@ class Controller(object):
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.on_volume_up, menuitem=self.window.player_volume_up) widgetUtils.connect_event(self.window, widgetUtils.MENU, self.on_volume_up, menuitem=self.window.player_volume_up)
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.on_mute, menuitem=self.window.player_mute) widgetUtils.connect_event(self.window, widgetUtils.MENU, self.on_mute, menuitem=self.window.player_mute)
widgetUtils.connect_event(self.window, widgetUtils.MENU, self.on_shuffle, menuitem=self.window.player_shuffle) widgetUtils.connect_event(self.window, widgetUtils.MENU, self.on_shuffle, menuitem=self.window.player_shuffle)
self.window.list.Bind(wx.EVT_LISTBOX_DCLICK, self.on_play)
self.window.list.Bind(wx.EVT_CONTEXT_MENU, self.on_context)
pub.subscribe(self.change_status, "change_status") pub.subscribe(self.change_status, "change_status")
# Event functions. These functions will call other functions in a thread and are bound to widget events. # Event functions. These functions will call other functions in a thread and are bound to widget events.
@ -114,6 +117,26 @@ class Controller(object):
def on_shuffle(self, *args, **kwargs): def on_shuffle(self, *args, **kwargs):
player.player.shuffle = self.window.player_shuffle.IsChecked() player.player.shuffle = self.window.player_shuffle.IsChecked()
def on_context(self, *args, **kwargs):
item = self.window.get_item()
if item == -1:
return wx.Bell()
menu = menus.contextMenu()
widgetUtils.connect_event(menu, widgetUtils.MENU, self.on_play, menuitem=menu.play)
widgetUtils.connect_event(menu, widgetUtils.MENU, self.on_download, menuitem=menu.download)
self.window.PopupMenu(menu, wx.GetMousePosition())
menu.Destroy()
def on_download(self, *args, **kwargs):
item = self.results[self.window.get_item()]
f = "{0}.mp3".format(item.title)
if item.download_url == "":
item.get_download_url()
path = self.window.get_destination_path(f)
if path != None:
log.debug("downloading %s URL to %s filename" % (item.download_url, path,))
utils.call_threaded(utils.download_file, item.download_url, path)
def change_status(self, status): def change_status(self, status):
""" Function used for changing the status bar from outside the main controller module.""" """ Function used for changing the status bar from outside the main controller module."""
self.window.change_status("{0} {1}".format(status, self.get_status_info())) self.window.change_status("{0} {1}".format(status, self.get_status_info()))
@ -129,4 +152,5 @@ class Controller(object):
self.results = self.extractor.results self.results = self.extractor.results
for i in self.results: for i in self.results:
self.window.list.Append(i.format_track()) self.window.list.Append(i.format_track())
self.change_status("") self.change_status("")

View File

@ -1,6 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
import requests
import threading import threading
import logging import logging
from pubsub import pub
log = logging.getLogger("utils") log = logging.getLogger("utils")
@ -44,3 +47,20 @@ class RepeatingTimer(threading.Thread):
self.function(*self.args, **self.kwargs) self.function(*self.args, **self.kwargs)
except: except:
log.exception("Execution failed. Function: %r args: %r and kwargs: %r" % (self.function, self.args, self.kwargs)) log.exception("Execution failed. Function: %r args: %r and kwargs: %r" % (self.function, self.args, self.kwargs))
def download_file(url, local_filename):
r = requests.get(url, stream=True)
pub.sendMessage("change_status", status=_(u"Downloading {0}.").format(local_filename,))
total_length = r.headers.get("content-length")
dl = 0
total_length = int(total_length)
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=64):
if chunk: # filter out keep-alive new chunks
dl += len(chunk)
f.write(chunk)
done = int(100 * dl / total_length)
msg = _(u"Downloading {0} ({1}%).").format(os.path.basename(local_filename), done)
pub.sendMessage("change_status", status=msg)
pub.sendMessage("change_status", status="")
return local_filename

View File

@ -69,4 +69,10 @@ class mainWindow(wx.Frame):
return t return t
def get_item(self): def get_item(self):
return self.list.GetSelection() return self.list.GetSelection()
def get_destination_path(self, filename):
saveFileDialog = wx.FileDialog(self, _(u"Save this file"), "", filename, _(u"Audio Files(*.mp3)|*.mp3"), wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if saveFileDialog.ShowModal() == wx.ID_OK:
return saveFileDialog.GetPath()
saveFileDialog.Destroy()

10
src/wxUI/menus.py Normal file
View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
import wx
class contextMenu(wx.Menu):
def __init__(self, *args, **kwargs):
super(contextMenu, self).__init__(*args, **kwargs)
self.play = wx.MenuItem(self, wx.NewId(), _("Play"))
self.AppendItem(self.play)
self.download = wx.MenuItem(self, wx.NewId(), _("Download"))
self.AppendItem(self.download)