add command 'videoob playlist download'
This commit is contained in:
parent
69d392e0c0
commit
dc4984a811
1 changed files with 65 additions and 50 deletions
|
|
@ -75,30 +75,23 @@ class Videoob(ReplApplication):
|
||||||
self.load_config()
|
self.load_config()
|
||||||
return ReplApplication.main(self, argv)
|
return ReplApplication.main(self, argv)
|
||||||
|
|
||||||
def complete_download(self, text, line, *ignored):
|
def obj_to_filename(self, obj, dest, default=None):
|
||||||
args = line.split(' ')
|
if default is None:
|
||||||
if len(args) == 2:
|
default = '{id}-{title}.{ext}'
|
||||||
return self._complete_object()
|
if dest is None:
|
||||||
elif len(args) >= 3:
|
dest = '.'
|
||||||
return self.path_completer(args[2])
|
if os.path.isdir(dest):
|
||||||
|
dest = os.path.join(dest, default)
|
||||||
|
|
||||||
def do_download(self, line):
|
def repl(m):
|
||||||
"""
|
field = m.group(1)
|
||||||
download ID [FILENAME]
|
if hasattr(obj, field):
|
||||||
|
return re.sub('[?:/]', '-', '%s' % getattr(obj, field))
|
||||||
Download a video
|
else:
|
||||||
|
return m.group(0)
|
||||||
Braces-enclosed tags are replaced with data fields. Use the 'info'
|
return re.sub(r'\{(.+?)\}', repl, dest)
|
||||||
command to see what fields are available on a given video.
|
|
||||||
|
|
||||||
Example: download KdRRge4XYIo@youtube '{title}.{ext}'
|
|
||||||
"""
|
|
||||||
_id, dest = self.parse_command_args(line, 2, 1)
|
|
||||||
video = self.get_object(_id, 'get_video', ['url'])
|
|
||||||
if not video:
|
|
||||||
print >>sys.stderr, 'Video not found: %s' % _id
|
|
||||||
return 3
|
|
||||||
|
|
||||||
|
def download(self, video, dest, default=None):
|
||||||
if not video.url:
|
if not video.url:
|
||||||
print >>sys.stderr, 'Error: the direct URL is not available.'
|
print >>sys.stderr, 'Error: the direct URL is not available.'
|
||||||
return 4
|
return 4
|
||||||
|
|
@ -111,27 +104,7 @@ class Videoob(ReplApplication):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def video_to_file(_video):
|
dest = self.obj_to_filename(video, dest, default)
|
||||||
ext = _video.ext
|
|
||||||
if not ext:
|
|
||||||
ext = 'avi'
|
|
||||||
return '%s.%s' % (re.sub('[?:/]', '-', _video.id), ext)
|
|
||||||
|
|
||||||
if dest is not None and os.path.isdir(dest):
|
|
||||||
dest += '/%s' % video_to_file(video)
|
|
||||||
|
|
||||||
if dest is None:
|
|
||||||
dest = video_to_file(video)
|
|
||||||
else:
|
|
||||||
fields = video.to_dict()
|
|
||||||
def repl(m):
|
|
||||||
field = m.group(1)
|
|
||||||
if field in fields:
|
|
||||||
return fields[field]
|
|
||||||
else:
|
|
||||||
return m.group(0)
|
|
||||||
|
|
||||||
dest = re.sub(r'\{(.+?)\}', repl, dest)
|
|
||||||
|
|
||||||
if video.url.startswith('rtmp'):
|
if video.url.startswith('rtmp'):
|
||||||
if not check_exec('rtmpdump'):
|
if not check_exec('rtmpdump'):
|
||||||
|
|
@ -151,6 +124,34 @@ class Videoob(ReplApplication):
|
||||||
|
|
||||||
os.spawnlp(os.P_WAIT, args[0], *args)
|
os.spawnlp(os.P_WAIT, args[0], *args)
|
||||||
|
|
||||||
|
|
||||||
|
def complete_download(self, text, line, *ignored):
|
||||||
|
args = line.split(' ')
|
||||||
|
if len(args) == 2:
|
||||||
|
return self._complete_object()
|
||||||
|
elif len(args) >= 3:
|
||||||
|
return self.path_completer(args[2])
|
||||||
|
|
||||||
|
|
||||||
|
def do_download(self, line):
|
||||||
|
"""
|
||||||
|
download ID [FILENAME]
|
||||||
|
|
||||||
|
Download a video
|
||||||
|
|
||||||
|
Braces-enclosed tags are replaced with data fields. Use the 'info'
|
||||||
|
command to see what fields are available on a given video.
|
||||||
|
|
||||||
|
Example: download KdRRge4XYIo@youtube '{title}.{ext}'
|
||||||
|
"""
|
||||||
|
_id, dest = self.parse_command_args(line, 2, 1)
|
||||||
|
video = self.get_object(_id, 'get_video', ['url'])
|
||||||
|
if not video:
|
||||||
|
print >>sys.stderr, 'Video not found: %s' % _id
|
||||||
|
return 3
|
||||||
|
|
||||||
|
return self.download(video, dest)
|
||||||
|
|
||||||
def complete_play(self, text, line, *ignored):
|
def complete_play(self, text, line, *ignored):
|
||||||
args = line.split(' ')
|
args = line.split(' ')
|
||||||
if len(args) >= 2:
|
if len(args) >= 2:
|
||||||
|
|
@ -213,15 +214,31 @@ class Videoob(ReplApplication):
|
||||||
|
|
||||||
self.format(video)
|
self.format(video)
|
||||||
|
|
||||||
|
def complete_playlist(self, text, line, *ignored):
|
||||||
|
args = line.split(' ')
|
||||||
|
if len(args) == 2:
|
||||||
|
return ['cmd', 'add', 'remove', 'export', 'display', 'download']
|
||||||
|
if len(args) >= 3:
|
||||||
|
if args[1] in ('export', 'download'):
|
||||||
|
return self.path_completer(args[2])
|
||||||
|
if args[1] in ('add', 'remove'):
|
||||||
|
return self._complete_object()
|
||||||
|
|
||||||
def do_playlist(self, line):
|
def do_playlist(self, line):
|
||||||
"""
|
"""
|
||||||
playlist cmd [args]
|
playlist cmd [args]
|
||||||
|
|
||||||
playlist add ID [ID2 ID3 ...]
|
playlist add ID [ID2 ID3 ...]
|
||||||
playlist remove ID [ID2 ID3 ...]
|
playlist remove ID [ID2 ID3 ...]
|
||||||
playlist export [FILENAME]
|
playlist export [FILENAME]
|
||||||
playlist display
|
playlist display
|
||||||
|
playlist download [PATH]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not self.interactive:
|
||||||
|
print >>sys.stderr, 'This command can be used only in interactive mode.'
|
||||||
|
return 1
|
||||||
|
|
||||||
if not line:
|
if not line:
|
||||||
print >>sys.stderr, 'This command takes an argument: %s' % self.get_command_help('playlist')
|
print >>sys.stderr, 'This command takes an argument: %s' % self.get_command_help('playlist')
|
||||||
return 2
|
return 2
|
||||||
|
|
@ -241,11 +258,9 @@ class Videoob(ReplApplication):
|
||||||
return 4
|
return 4
|
||||||
|
|
||||||
self.PLAYLIST.append(video)
|
self.PLAYLIST.append(video)
|
||||||
|
|
||||||
elif cmd == "remove":
|
elif cmd == "remove":
|
||||||
_ids = args.strip().split(' ')
|
_ids = args.strip().split(' ')
|
||||||
for _id in _ids:
|
for _id in _ids:
|
||||||
|
|
||||||
video_to_remove = self.get_object(_id, 'get_video')
|
video_to_remove = self.get_object(_id, 'get_video')
|
||||||
|
|
||||||
if not video_to_remove:
|
if not video_to_remove:
|
||||||
|
|
@ -260,7 +275,6 @@ class Videoob(ReplApplication):
|
||||||
if video.id == video_to_remove.id:
|
if video.id == video_to_remove.id:
|
||||||
self.PLAYLIST.remove(video)
|
self.PLAYLIST.remove(video)
|
||||||
break
|
break
|
||||||
|
|
||||||
elif cmd == "export":
|
elif cmd == "export":
|
||||||
filename = "playlist.m3u"
|
filename = "playlist.m3u"
|
||||||
if args:
|
if args:
|
||||||
|
|
@ -270,13 +284,14 @@ class Videoob(ReplApplication):
|
||||||
for video in self.PLAYLIST:
|
for video in self.PLAYLIST:
|
||||||
file.write('%s\r\n' % video.url)
|
file.write('%s\r\n' % video.url)
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
elif cmd == "display":
|
elif cmd == "display":
|
||||||
for video in self.PLAYLIST:
|
for video in self.PLAYLIST:
|
||||||
self.cached_format(video)
|
self.cached_format(video)
|
||||||
|
elif cmd == "download":
|
||||||
|
for i, video in enumerate(self.PLAYLIST):
|
||||||
|
self.download(video, args, '%02d-{id}-{title}.{ext}' % (i+1))
|
||||||
else:
|
else:
|
||||||
print >>sys.stderr, 'Playlist command only support "add", "remove", "display" and "export" arguments.'
|
print >>sys.stderr, 'Playlist command only support "add", "remove", "display", "download" and "export" arguments.'
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
def complete_nsfw(self, text, line, begidx, endidx):
|
def complete_nsfw(self, text, line, begidx, endidx):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue