Cleanup & refactoring.

This commit is contained in:
Andrew Dunai 2018-01-08 21:54:25 +02:00
parent b2141b02c1
commit 13ad75cfce
13 changed files with 153 additions and 58 deletions

View file

@ -300,7 +300,7 @@ ignore-comments=yes
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
ignore-imports=yes
# Minimum lines number of a similarity.
min-similarity-lines=4

View file

@ -13,12 +13,12 @@ import urwid
from clay.player import Player
from clay.playbar import PlayBar
from clay.pages import StartUp
from clay.mylibrary import MyLibrary
from clay.myplaylists import MyPlaylists
from clay.playerqueue import Queue
from clay.search import Search
from clay.settings import Settings
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
PALETTE = [
@ -35,6 +35,8 @@ PALETTE = [
('panel', '', '', '', '#FFF', '#222'),
('panel_focus', '', '', '', '#FFF', '#F54'),
('panel_divider', '', '', '', '#444', '#222'),
('panel_divider_focus', '', '', '', '#444', '#F54'),
('line1', '', '', '', '#FFF', ''),
('line1_focus', '', '', '', '#FFF', '#444'),
@ -68,38 +70,42 @@ class AppWidget(urwid.Frame):
super(AppWidget.Tab, self).__init__(
self.get_title()
)
self.set_active(False)
def set_active(self, active):
"""
Mark tab visually as active.
"""
self.set_text(
[('panel_focus' if active else 'panel', self.get_title())]
[
('panel_divider_focus' if active else 'panel_divider', '\u23b8 '),
('panel_focus' if active else 'panel', self.get_title() + ' ')
]
)
def get_title(self):
"""
Render tab title.
"""
return ' {} {} '.format(
return '{} {}'.format(
self.page.key,
self.page.name
)
def __init__(self):
self.pages = [
StartUp(self),
MyLibrary(self),
MyPlaylists(self),
Queue(self),
Search(self),
Settings(self)
StartUpPage(self),
MyLibraryPage(self),
MyPlaylistsPage(self),
QueuePage(self),
SearchPage(self),
SettingsPage(self)
]
self.tabs = [
AppWidget.Tab(page)
for page
in self.pages
if hasattr(page, 'key')
if page.key is not None
]
NotificationArea.set_app(self)
self.header = urwid.Pile([
@ -108,7 +114,7 @@ class AppWidget(urwid.Frame):
('pack', tab)
for tab
in self.tabs
], dividechars=1), 'panel'),
], dividechars=0), 'panel'),
NotificationArea.get()
# urwid.Divider('\u2500')
])
@ -135,6 +141,7 @@ class AppWidget(urwid.Frame):
footer=self.panel,
body=self.current_page
)
self.current_page.activate()
self.loop = None
@ -206,8 +213,7 @@ class AppWidget(urwid.Frame):
self.redraw()
if hasattr(page, 'start'):
page.start()
page.activate()
def redraw(self):
"""

View file

@ -21,7 +21,7 @@ except Exception as error:
else:
IS_INIT = True
from clay.settings import Settings
from clay.settings import SettingsPage
from clay.eventhook import EventHook
from clay.notifications import NotificationArea
@ -74,7 +74,7 @@ class HotkeyManager(object):
"""
Load hotkey config from settings.
"""
config = Settings.get_config()
config = SettingsPage.get_config()
hotkeys = config.get('hotkeys', {})
for operation, default_key in HotkeyManager.DEFAULT_HOTKEYS.items():
if operation not in hotkeys or not hotkeys[operation]:

View file

@ -2,19 +2,26 @@
Library page.
"""
import urwid
from clay.gp import GP
from clay.songlist import SongListBox
from clay.notifications import NotificationArea
from clay.page import Page
class MyLibrary(urwid.Columns):
class MyLibraryPage(urwid.Columns, Page):
"""
My library page.
Displays :class:`clay.songlist.SongListBox` with all songs in library.
"""
name = 'Library'
key = 1
@property
def name(self):
return 'Library'
@property
def key(self):
return 1
def __init__(self, app):
self.app = app
@ -23,7 +30,7 @@ class MyLibrary(urwid.Columns):
GP.get().auth_state_changed += self.auth_state_changed
super(MyLibrary, self).__init__([
super(MyLibraryPage, self).__init__([
self.songlist
])
@ -49,3 +56,6 @@ class MyLibrary(urwid.Columns):
GP.get().get_all_tracks_async(callback=self.on_get_all_songs)
# self.notification = NotificationArea.notify('Loading library...')
def activate(self):
pass

View file

@ -6,6 +6,7 @@ import urwid
from clay.gp import GP
from clay.songlist import SongListBox
from clay.notifications import NotificationArea
from clay.page import Page
class MyPlaylistListItem(urwid.Columns):
@ -106,7 +107,7 @@ class MyPlaylistListBox(urwid.ListBox):
urwid.emit_signal(self, 'activate', myplaylistlistitem)
class MyPlaylists(urwid.Columns):
class MyPlaylistsPage(urwid.Columns, Page):
"""
Playlists page.
@ -115,8 +116,13 @@ class MyPlaylists(urwid.Columns):
- List of playlists (:class:`.MyPlaylistListBox`)
- List of songs in selected playlist (:class:`clay:songlist:SongListBox`)
"""
name = 'Playlists'
key = 2
@property
def name(self):
return 'Playlists'
@property
def key(self):
return 2
def __init__(self, app):
self.app = app
@ -129,7 +135,7 @@ class MyPlaylists(urwid.Columns):
self.myplaylistlist, 'activate', self.myplaylistlistitem_activated
)
super(MyPlaylists, self).__init__([
super(MyPlaylistsPage, self).__init__([
self.myplaylistlist,
self.songlist
])
@ -142,3 +148,6 @@ class MyPlaylists(urwid.Columns):
self.songlist.populate(
myplaylistlistitem.get_tracks()
)
def activate(self):
pass

27
clay/page.py Normal file
View file

@ -0,0 +1,27 @@
"""
Generic page classes.
"""
# pylint: disable=too-few-public-methods
class Page(object):
"""
Represents app page.
"""
def name(self):
"""
Return page name.
"""
raise NotImplementedError()
def key(self):
"""
Return page key (``int``), used for hotkeys.
"""
raise NotImplementedError()
def activate(self):
"""
Notify page that it is activated.
"""
raise NotImplementedError()

View file

@ -5,14 +5,20 @@ import urwid
from clay.songlist import SongListBox
from clay.player import Player
from clay.page import Page
class Queue(urwid.Columns):
class QueuePage(urwid.Columns, Page):
"""
Queue page.
"""
name = 'Queue'
key = 3
@property
def name(self):
return 'Queue'
@property
def key(self):
return 3
def __init__(self, app):
self.app = app
@ -24,7 +30,7 @@ class Queue(urwid.Columns):
player.track_appended += self.track_appended
player.track_removed += self.track_removed
super(Queue, self).__init__([
super(QueuePage, self).__init__([
self.songlist
])
@ -48,3 +54,6 @@ class Queue(urwid.Columns):
Removes track from this queue widget.
"""
self.songlist.remove_track(track)
def activate(self):
pass

View file

@ -2,9 +2,11 @@
Components for search page.
"""
import urwid
from clay.gp import GP
from clay.songlist import SongListBox
from clay.notifications import NotificationArea
from clay.page import Page
class ArtistListBox(urwid.ListBox):
@ -39,14 +41,19 @@ class SearchBox(urwid.Columns):
return super(SearchBox, self).keypress(size, key)
class Search(urwid.Columns):
class SearchPage(urwid.Columns, Page):
"""
Search page.
Allows to perform searches & displays search results.
"""
name = 'Search'
key = 4
@property
def name(self):
return 'Search'
@property
def key(self):
return 4
def __init__(self, app):
self.app = app
@ -56,7 +63,7 @@ class Search(urwid.Columns):
urwid.connect_signal(self.search_box, 'search-requested', self.perform_search)
super(Search, self).__init__([
super(SearchPage, self).__init__([
urwid.Pile([
('pack', self.search_box),
('pack', urwid.Divider(u'\u2500')),
@ -79,3 +86,6 @@ class Search(urwid.Columns):
return
self.songlist.populate(results.get_tracks())
def activate(self):
pass

View file

@ -6,16 +6,22 @@ import errno
import yaml
import appdirs
import urwid
from clay.page import Page
class Settings(urwid.Columns):
class SettingsPage(urwid.Columns, Page):
"""
Settings page.
"""
name = 'Settings'
key = 9
@property
def name(self):
return 'Settings'
@property
def key(self):
return 9
def __init__(self, app):
self.app = app
@ -29,7 +35,7 @@ class Settings(urwid.Columns):
self.device_id = urwid.Edit(
edit_text=config.get('device_id', '')
)
super(Settings, self).__init__([urwid.ListBox(urwid.SimpleListWalker([
super(SettingsPage, self).__init__([urwid.ListBox(urwid.SimpleListWalker([
urwid.Text('Settings'),
urwid.Divider(' '),
urwid.Text('Username'),
@ -106,3 +112,6 @@ class Settings(urwid.Columns):
for x
in ('username', 'password', 'device_id')
])
def activate(self):
pass

View file

@ -1,15 +1,17 @@
"""
Generic pages.
Initial startup page.
"""
# pylint: disable=too-many-ancestors
import urwid
from clay.settings import Settings
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 StartUp(urwid.Filler):
class StartUpPage(urwid.Filler, Page):
"""
Initial page.
@ -18,7 +20,7 @@ class StartUp(urwid.Filler):
def __init__(self, app):
self.app = app
super(StartUp, self).__init__(
super(StartUpPage, self).__init__(
urwid.Pile([
urwid.Padding(
urwid.AttrWrap(urwid.BigText(
@ -31,16 +33,20 @@ class StartUp(urwid.Filler):
urwid.AttrWrap(urwid.Text('Version {}'.format(VERSION), align='center'), 'line1'),
urwid.AttrWrap(urwid.Text('Authorizing...', align='center'), 'line2')
])
# urwid.Text('Loading...'),
# valign='top'
)
self.start()
@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``, switches app to "My library" page.'
If *error* is ``None``, switch app to "My library" page.'
"""
if error:
NotificationArea.notify('Failed to log in: {}'.format(str(error)))
@ -53,16 +59,16 @@ class StartUp(urwid.Filler):
)
return
self.app.set_page('MyLibrary')
self.app.set_page('MyLibraryPage')
def start(self):
def activate(self):
"""
Called when this page is show.
Called when this page is shown.
Requests user authorization.
Request user authorization.
"""
if Settings.is_config_valid():
config = Settings.get_config()
if SettingsPage.is_config_valid():
config = SettingsPage.get_config()
GP.get().login_async(
config['username'],
config['password'],

View file

@ -15,11 +15,12 @@ Welcome to Clay's documentation!
ref/player
ref/songlist
ref/playbar
ref/startup
ref/mylibrary
ref/myplaylists
ref/playerqueue
ref/settings
ref/pages
ref/page
ref/notifications
ref/hotkeys
ref/eventhook

View file

@ -1,7 +1,7 @@
pages.py
########
.. automodule:: clay.pages
.. automodule:: clay.page
:members:
:private-members:
:special-members:

View file

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