Refactoring.

This commit is contained in:
Andrew Dunai 2018-01-09 11:54:01 +02:00
parent 44f9a6a94a
commit 423b85afb4
7 changed files with 87 additions and 100 deletions

View file

@ -13,13 +13,13 @@ import urwid
from clay.player import Player
from clay.playbar import PlayBar
from clay.startup import StartUpPage
from clay.mylibrary import MyLibraryPage
from clay.myplaylists import MyPlaylistsPage
from clay.playerqueue import QueuePage
from clay.search import SearchPage
from clay.settings import SettingsPage
from clay.notifications import NotificationArea
from clay.gp import GP
PALETTE = [
('logo', '', '', '', '#F54', ''),
@ -94,7 +94,6 @@ class AppWidget(urwid.Frame):
def __init__(self):
self.pages = [
StartUpPage(self),
MyLibraryPage(self),
MyPlaylistsPage(self),
QueuePage(self),
@ -105,9 +104,12 @@ class AppWidget(urwid.Frame):
AppWidget.Tab(page)
for page
in self.pages
if page.key is not None
]
self.current_page = None
NotificationArea.set_app(self)
self._login_notification = None
self.header = urwid.Pile([
# urwid.Divider('\u2500'),
urwid.AttrWrap(urwid.Columns([
@ -135,13 +137,13 @@ class AppWidget(urwid.Frame):
]),
self.playbar
])
self.current_page = self.pages[0]
# self.current_page = self.pages[0]
super(AppWidget, self).__init__(
header=self.header,
footer=self.panel,
body=self.current_page
body=urwid.Filler(urwid.Text('Loading...', align='center'))
)
self.current_page.activate()
# self.current_page.activate()
self.loop = None
@ -151,6 +153,46 @@ class AppWidget(urwid.Frame):
player.track_changed += self.track_changed
player.playback_flags_changed += self.playback_flags_changed
self.set_page('MyLibraryPage')
self.log_in()
def on_login(self, success, error):
"""
Called once user authorization finishes.
If *error* is ``None``, switch app to "My library" page.'
"""
if error:
self._login_notification.update('Failed to log in: {}'.format(str(error)))
return
if not success:
self._login_notification.update(
'Google Play Music login failed (API returned false)'
)
return
self._login_notification.close()
def log_in(self):
"""
Called when this page is shown.
Request user authorization.
"""
if SettingsPage.is_config_valid():
config = SettingsPage.get_config()
self._login_notification = NotificationArea.notify('Logging in...')
GP.get().login_async(
config['username'],
config['password'],
config['device_id'],
callback=self.on_login
)
else:
NotificationArea.notify(
'Please set your credentials on the settings page.'
)
def set_loop(self, loop):
"""
Assign a MainLoop to this app.
@ -226,7 +268,7 @@ class AppWidget(urwid.Frame):
def keypress(self, size, key):
"""
Handle keypress.
Can switch tabs, control playbackm, flags, notifications and app state.
Can switch tabs, control playback, flags, notifications and app state.
"""
for tab in self.tabs:
if 'meta {}'.format(tab.page.key) == key:

View file

@ -55,6 +55,7 @@ class MyLibraryPage(urwid.Columns, Page):
self.songlist.set_placeholder(u'\n \uf01e Loading song list...')
GP.get().get_all_tracks_async(callback=self.on_get_all_songs)
self.app.redraw()
# self.notification = NotificationArea.notify('Loading library...')
def activate(self):

View file

@ -16,7 +16,7 @@ class Notification(urwid.Columns):
self.area = area
self._id = notification_id
self.text = urwid.Text('')
self.update(message)
self._set_text(message)
super(Notification, self).__init__([
urwid.AttrWrap(
urwid.Columns([
@ -34,17 +34,35 @@ class Notification(urwid.Columns):
"""
return self._id
def update(self, message):
def _set_text(self, message):
"""
Update notification message.
Set contents for this notification.
"""
message = message.split('\n')
message = '\n'.join([
message[0]
] + [' {}'.format(line) for line in message[1:]])
self.text.set_text(Notification.TEMPLATE.format(message))
def update(self, message):
"""
Update notification message.
"""
self._set_text(message)
if not self.is_alive:
self.area.append_notification(self)
self.area.__class__.app.redraw()
@property
def is_alive(self):
"""
Return True if notification is currently visible.
"""
for notification, _ in self.area.contents:
if notification is self:
return True
return False
def close(self):
"""
Close notification.
@ -53,6 +71,9 @@ class Notification(urwid.Columns):
if notification is self:
self.area.contents.remove((notification, props))
if self.area.__class__.app is not None:
self.area.__class__.app.redraw()
class NotificationArea(urwid.Pile):
"""
@ -117,6 +138,13 @@ class NotificationArea(urwid.Pile):
"""
self.last_id += 1
notification = Notification(self, self.last_id, message)
self.append_notification(notification)
return notification
def append_notification(self, notification):
"""
Append an existing notification (that was probably closed).
"""
self.contents.append(
(
notification,
@ -125,7 +153,6 @@ class NotificationArea(urwid.Pile):
)
if self.__class__.app is not None:
self.__class__.app.redraw()
return notification
def do_close_all(self):
"""

View file

@ -75,6 +75,9 @@ class SearchPage(urwid.Columns, Page):
"""
Search tracks by query.
"""
self.songlist.set_placeholder(u' \U0001F50D Searching for "{}"...'.format(
query
))
GP.get().search_async(query, callback=self.search_finished)
def search_finished(self, results, error):
@ -86,6 +89,7 @@ class SearchPage(urwid.Columns, Page):
return
self.songlist.populate(results.get_tracks())
self.app.redraw()
def activate(self):
pass

View file

@ -272,6 +272,8 @@ class SongListBox(urwid.ListBox):
self.update_indexes()
if current_index is not None:
self.walker.set_focus(current_index)
elif len(self.walker) >= 1:
self.walker.set_focus(0)
def append_track(self, track):
"""

View file

@ -1,81 +0,0 @@
"""
Initial startup page.
"""
# pylint: disable=too-many-ancestors
import urwid
from clay.page import Page
from clay.settings import SettingsPage
from clay.gp import GP
from clay.meta import VERSION
from clay.notifications import NotificationArea
class StartUpPage(urwid.Filler, Page):
"""
Initial page.
Shown when app is started or login credentials are changed.
"""
def __init__(self, app):
self.app = app
super(StartUpPage, self).__init__(
urwid.Pile([
urwid.Padding(
urwid.AttrWrap(urwid.BigText(
'Clay',
urwid.font.HalfBlock5x4Font()
), 'logo'),
'center',
None
),
urwid.AttrWrap(urwid.Text('Version {}'.format(VERSION), align='center'), 'line1'),
urwid.AttrWrap(urwid.Text('Authorizing...', align='center'), 'line2')
])
)
@property
def name(self):
pass
@property
def key(self):
pass
def on_login(self, success, error):
"""
Called once user authorization finishes.
If *error* is ``None``, switch app to "My library" page.'
"""
if error:
NotificationArea.notify('Failed to log in: {}'.format(str(error)))
return
if not success:
NotificationArea.notify(
'Google Play Music login failed '
'(API returned false)'
)
return
self.app.set_page('MyLibraryPage')
def activate(self):
"""
Called when this page is shown.
Request user authorization.
"""
if SettingsPage.is_config_valid():
config = SettingsPage.get_config()
GP.get().login_async(
config['username'],
config['password'],
config['device_id'],
callback=self.on_login
)
else:
NotificationArea.notify(
'Please set your credentials on the settings page.'
)

View file

@ -1,8 +0,0 @@
startup.py
##########
.. automodule:: clay.startup
:members:
:private-members:
:special-members: