Skip to content

Commit

Permalink
Completion of Playlist Player
Browse files Browse the repository at this point in the history
  • Loading branch information
johejo committed Mar 5, 2018
1 parent 6c771f2 commit d5025d8
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 97 deletions.
9 changes: 6 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,23 @@ Install
Usage
-----

station player
~~~~~~~~~~~~~~

.. code:: bash
$ gpm-station
Future help
playlist player
~~~~~~~~~~~~~~~

.. code:: bash
$ gpm-station --help
$ gpm-playlist
Tasks
-----

- playlist player
- equalizer
- seek and set time

Expand Down
107 changes: 81 additions & 26 deletions gpm_player/common.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,61 @@
import platform
import argparse
import subprocess
import tempfile
import warnings
import getpass
import urllib.request

import vlc
from gmusicapi import Mobileclient, CallFailure
from inputimeout import inputimeout, TimeoutOccurred

from .exceptions import LoginFailure, PlayerExitException
from .exceptions import LoginFailure, PlayerExitException, StoredTrackError
from .__version__ import __version__

if platform.system() == 'Windows':
CLEAR_SCREEN = 'cls'
else:
CLEAR_SCREEN = 'clear'


def input_login_info():
email = input('Email: ')
password = getpass.getpass()
return email, password


def set_args():
p = argparse.ArgumentParser()
p.add_argument('-v', '--version', action='version', version=__version__,
help='show version and exit')
p.add_argument('-i', '--interval', nargs='?', default=3, type=float,
help='screen display update interval')
p.add_argument('-w', '--width', nargs='?', default=50, type=int,
help='progress bar width')
a = p.parse_args()
return a


def run(player):
arg = set_args()

while True:
try:
email, password = input_login_info()
except KeyboardInterrupt:
return

try:
p = player(email=email, password=password,
interval=arg.interval, width=arg.width)
p.start()
except LoginFailure:
continue
else:
return


def clear_screen():
subprocess.run(CLEAR_SCREEN, shell=True)
print()
Expand All @@ -35,18 +75,18 @@ def print_track_info(info):
def print_command_list():
print('Command List\n'
'\'q\': stop and quit\n'
'\'p\': pause or play\n'
'\'p\': pause or run\n'
'\'f\': go to next track\n'
'\'b\': back to previous track\n'
'\'r\': restart current track\n'
'\'s\': back to station menu\n')
'\'s\': back to selection menu\n')


def print_bar(current, duration, remain, width=50):
per = current / duration * 100
bar = '█' * int(width * per / 100)

print('Remaining play time: {} [s]'.format(remain))
print('Remaining run time: {} [s]'.format(remain))
print(' {}% |{}| {}/{} {}\n'
.format(round(per, 2), bar.ljust(width),
round(current / 1000, 2), duration / 1000, '[s]'))
Expand Down Expand Up @@ -75,12 +115,18 @@ def is_digit(cmd, length):

def choose_track_id(track):
try:
track_id = track['trackId']
track_id = track['storeId']
except KeyError:
try:
track_id = track['storeId']
except KeyError:
track_id = track['nid']
except KeyError:
try:
track_id = track['trackId']
except KeyError:
raise KeyError

if not track_id.startswith('T'):
raise StoredTrackError

return track_id

Expand Down Expand Up @@ -111,12 +157,10 @@ def close(self):
self.api.logout()

def prepare(self):
if not self._logged_in:
msg = 'Login is not completed.'
warnings.warn(msg)

if not self.api.is_authenticated():
if (not self._logged_in) or (not self.api.is_authenticated()):
raise LoginFailure
else:
return True

def start(self):
try:
Expand All @@ -137,34 +181,45 @@ def _run_player(self):
while True:
tracks = self.get_tracks()
i = 0
ns = 0
while True:
try:
track_id = choose_track_id(tracks[i])
except KeyError:
i += 1
if i >= len(tracks):
i = 0
continue

cmd = self._play_track(track_id)

if cmd == 'f':
except StoredTrackError:
ns += 1
i += 1
if i >= len(tracks):
i = 0
elif cmd == 'b':
i -= 1
if i < 0:
i = len(tracks) - 1
elif cmd == 's':
break

warnings.warn('Track is not in the store.\n')
if ns >= len(tracks):
warnings.warn('All tracks are not in the store.\n')
break
else:
continue
else:
cmd = self._play_track(track_id)
if cmd == 'f':
i += 1
if i >= len(tracks):
i = 0
elif cmd == 'b':
i -= 1
if i < 0:
i = len(tracks) - 1
elif cmd == 's':
break

def _play_track(self, track_id):
self.prepare()
try:
info = self.api.get_track_info(track_id)
except CallFailure:
info = None

try:
info = self.api.get_track_info(track_id)
url = self.api.get_stream_url(track_id)
except CallFailure as e:
warnings.warn(str(e))
Expand Down
11 changes: 6 additions & 5 deletions gpm_player/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ class BasePlayerException(Exception):
pass


class StationPlayerError(BasePlayerException):
pass


class LoginFailure(StationPlayerError):
class LoginFailure(BasePlayerException):
def __str__(self):
return 'Credentials weren\'t accepted.'


class PlayerExitException(BasePlayerException):
pass


class StoredTrackError(BasePlayerException):
def __str__(self):
return 'Track does not exist in store.'
36 changes: 5 additions & 31 deletions gpm_player/playlist.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import argparse
import getpass

from .__version__ import __version__
from .exceptions import PlayerExitException
from .common import BasePlayer, is_digit, is_quit
from .common import BasePlayer, is_digit, is_quit, run


class PlayListPlayer(BasePlayer):
def __init__(self, *, email=None, password=None, interval=3, width=50):
super().__init__(email=email, password=password, interval=interval,
width=width)
def __init__(self, **kwargs):
super().__init__(**kwargs)

def get_tracks(self):
self.prepare()
playlists = self.api.get_all_user_playlist_contents()
print()

for i, playlist in enumerate(playlists):
print('{}: {}'.format(i, playlist['name']))
Expand All @@ -30,27 +26,5 @@ def get_tracks(self):
return tracks


def set_args():
p = argparse.ArgumentParser()
p.add_argument('-v', '--version', action='version', version=__version__,
help='show version and exit')
p.add_argument('-i', '--interval', nargs='?', default=3, type=float,
help='screen display update interval')
p.add_argument('-w', '--width', nargs='?', default=50, type=int,
help='progress bar width')
a = p.parse_args()
return a


def main():
arg = set_args()

try:
email = input('Email: ')
password = getpass.getpass()
except KeyboardInterrupt:
return

player = PlayListPlayer(email=email, password=password,
interval=arg.interval, width=arg.width)
player.start()
run(PlayListPlayer)
36 changes: 5 additions & 31 deletions gpm_player/station.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import argparse
import getpass

from .__version__ import __version__
from .exceptions import PlayerExitException
from .common import BasePlayer, is_digit, is_quit
from .common import BasePlayer, is_digit, is_quit, run


class StationPlayer(BasePlayer):
def __init__(self, *, email=None, password=None, interval=3, width=50):
super().__init__(email=email, password=password, interval=interval,
width=width)
def __init__(self, **kwargs):
super().__init__(**kwargs)

def get_tracks(self):
self.prepare()
stations = self.api.get_all_stations()
print()

for i, station in enumerate(stations):
print('{}: {}'.format(i, station['name']))
Expand All @@ -36,27 +32,5 @@ def get_tracks(self):
return tracks


def set_args():
p = argparse.ArgumentParser()
p.add_argument('-v', '--version', action='version', version=__version__,
help='show version and exit')
p.add_argument('-i', '--interval', nargs='?', default=3, type=float,
help='screen display update interval')
p.add_argument('-w', '--width', nargs='?', default=50, type=int,
help='progress bar width')
a = p.parse_args()
return a


def main():
arg = set_args()

try:
email = input('Email: ')
password = getpass.getpass()
except KeyboardInterrupt:
return

player = StationPlayer(email=email, password=password,
interval=arg.interval, width=arg.width)
player.start()
run(StationPlayer)
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
url=about['__url__'],
py_modules=['gpm_player'],
entry_points={
'console_scripts': 'gpm-station = gpm_player.station:main'
'console_scripts': [
'gpm-station = gpm_player.station:main',
'gpm-playlist = gpm_player.playlist:main',
]
},
keyword=['gmusicapi', 'music', 'music-player'],
install_requires=install_requires,
Expand Down

0 comments on commit d5025d8

Please sign in to comment.