Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI: Added optional range param to 'play' command for easier continuous play of show #484

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 31 additions & 9 deletions trackma/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ def _add_show_to_library(self, library, library_cache, rescan, fullpath, filenam

return library, library_cache

def get_episode_path(self, show, episode):
def get_episode_path(self, show, episode, error_on_fail=True):
"""
This function returns the full path of the requested episode from the requested show.
"""
Expand All @@ -828,7 +828,9 @@ def get_episode_path(self, show, episode):
if showid not in library:
raise utils.EngineError('Show not in library.')
if episode not in library[showid]:
raise utils.EngineError('Episode not in library.')
if error_on_fail:
raise utils.EngineError('Episode not in library.')
return

return library[showid][episode]

Expand All @@ -854,7 +856,7 @@ def play_random(self):
ep = self.play_episode(show)
return (show, ep)

def play_episode(self, show, playep=0):
def play_episode(self, show, playep=0, playto=0):
"""
Does a local search in the hard disk (in the folder specified by the config file)
for the specified episode (**playep**) for the specified **show**.
Expand All @@ -865,28 +867,48 @@ def play_episode(self, show, playep=0):
if not self.mediainfo.get('can_play'):
raise utils.EngineError('Operation not supported by current site or mediatype.')

eps = re.split('-', str(playep))
if len(eps) > 1:
if eps[0] != '':
playep = eps[0]
else:
playep = 0
if eps[1] != '':
playto = eps[1]
else:
playto = show['total']
try:
playep = int(playep)
playto = int(playto)
except ValueError:
raise utils.EngineError('Episode must be numeric.')
raise utils.EngineError('Episode[s] must be numeric or with optional range (eg: 1-3, -3, or - to play all unseen episodes)')

if show:
playing_next = False
if not playep:
playep = show['my_progress'] + 1
playing_next = True

if show['total'] and playep > show['total']:
raise utils.EngineError('Episode beyond limits.')
if not playto or playto < playep:
playto = playep

if show['total']:
if playep > show['total']:
raise utils.EngineError('Episode beyond limits.')
if playto > show['total']:
self.msg.info(self.name, "Play to %i is beyond limits of show %s. Defaulting to total episodes of %s" % (playto, show['title'], show['total']))
playto = show['total']

self.msg.info(self.name, "Getting %s %s from library..." % (show['title'], playep))
filename = self.get_episode_path(show, playep)
endep = playep

if filename:
if self.get_episode_path(show, playep):
self.msg.info(self.name, 'Found. Starting player...')
arg_list = shlex.split(self.config['player'])
arg_list.append(filename)
for episode in range(playep, playto+1):
ep = self.get_episode_path(show, episode, error_on_fail=False)
if ep:
arg_list.append(ep)
Comment on lines +908 to +911
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be safer to stop appending episodes after the first unfound episode because this suggested behavior is equivalent to silent failure. If episode 4 was missing but 5+ were not, that episode would not be added to the player's playlist and a user wanting hands-off playback would be likely to miss that this episode was never there. If instead we stopped adding episodes alltogether, the user is implicitly prompted to start investigating once he reaches the end of the playlist.

An alternative would be to abort on any error and request an episode range that can be found. For that, the default playto value needs to be the last available episode, not the show's total according to metadata.

try:
with open(os.devnull, 'wb') as DEVNULL:
subprocess.Popen(arg_list, stdout=DEVNULL, stderr=DEVNULL)
Expand Down
8 changes: 6 additions & 2 deletions trackma/ui/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class Trackma_cmd(cmd.Cmd):
'add': 1,
'del': 1,
'delete': 1,
'play': (1, 2),
'play': (1, 3),
'openfolder': 1,
'update': (1, 2),
'score': 2,
Expand Down Expand Up @@ -498,6 +498,7 @@ def do_play(self, args):
:param show Episode index or title.
:optparam ep Episode number. Assume next if not specified.
:optparam playto Episode number to play to in range.
:usage play <show index or title> [episode number]
"""
try:
Expand All @@ -508,8 +509,11 @@ def do_play(self, args):
# otherwise play the next episode not watched yet
if len(args) > 1:
episode = args[1]
playto = episode
if len(args) > 2:
playto = args[2]

self.engine.play_episode(show, episode)
self.engine.play_episode(show, episode, playto)
except utils.TrackmaError as e:
self.display_error(e)

Expand Down
2 changes: 1 addition & 1 deletion trackma/ui/curses.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ def do_play(self):
item = self._get_selected_item()
if item:
show = self.engine.get_show_info(item.showid)
self.ask('[Play] Episode # to play: ', self.play_request, show['my_progress']+1)
self.ask('[Play] Episodes to play (eg: 1, 1-3 or - to play all unseen): ', self.play_request, show['my_progress']+1)

def do_openfolder(self):
item = self._get_selected_item()
Expand Down