import zipfile
import subprocess
+
+def output(fo, fmt, *args, **kargs):
+ if not args:
+ args = kargs
+ fo.write((fmt % args) + '\n')
+
+def echo(fmt, *args, **kargs):
+ output(sys.stdout, fmt, *args, **kargs)
+
+def error(fmt, *args, **kargs):
+ output(sys.stderr, fmt, *args, **kargs)
+
+
class SubDivXQuery:
def __init__(self, to_search, page_number):
self.host = "www.subdivx.com"
return subs
-def get_subs(query_str, filters):
+def unzip_subs(fname):
sub_exts = ('.srt', '.sub')
+ z = zipfile.ZipFile(fname, 'r')
+ z.printdir()
+ for fn in z.namelist():
+ if fn.endswith(sub_exts):
+ if '..' in fn or fn.startswith('/'):
+ error('Ignoring file with dangerous name: %s',
+ fn)
+ continue
+ echo('Extracting %s...', fn)
+ z.extract(fn)
+
+
+def get_subs(query_str, filters):
+ global opts
zip_exts = ('application/zip',)
rar_exts = ('application/rar', 'application/x-rar-compressed')
subs.sort(key=lambda s: int(s['downloads']), reverse=True)
for sub in subs:
- print('''\
+ echo('''\
- %(titulo)s (%(autor)s - %(fecha)s - %(downloads)s - %(comentarios)s)
%(desc)s
DOWNLOADING ...
-''' % sub)
- continue
+''', **sub)
+ if opts.list_only:
+ continue
fname, headers = urlretrieve(sub['url'])
if 'Content-Type' in headers:
if headers['Content-Type'] in zip_exts:
- z = zipfile.ZipFile(fname, 'r')
- z.printdir()
- for fn in z.namelist():
- if fn.endswith(sub_exts):
- if '..' in fn or fn.startswith('/'):
- print('Dangerous file name:', fn)
- continue
- print('Extracting', fn, '...')
- z.extract(fn)
+ unzip_subs(fname)
elif headers['Content-Type'] in rar_exts:
if subprocess.call(['rar', 'x', fname]) != 0:
- print('Error unraring file %s' % fname)
+ error('Error unraring file %s', fname)
else:
- print('Unrecognized file type:', headers['Content-Type'])
+ error('Unrecognized file type:',
+ headers['Content-Type'])
else:
- print('No Content-Type!')
+ error('No Content-Type!')
+
+
+def parse_args(argv):
+ from optparse import OptionParser
+ parser = OptionParser(usage="%prog [OPTIONS] QUERY [FILTER ...]",
+ description="""
+Download subtitles from subdivx.com searching the string QUERY. If FILTERs are
+specified, only subtitles that matches all those filters are downloaded.
+Filters have the format "X:fitler", where X is a field specification: t=titulo,
+d=desc, a=autor, f=formato, c=comentarios, C=cds, F=fecha and D=downloads.
+filter is a string that should be found on that field (case insensitive). If
+the format specifier is not known (or there isn't one) the filter string is
+looked in all the fields.
+ """.strip())
+ parser.add_option("-l", "--list-only",
+ default=False, action='store_true',
+ help="Don't download the subtitles, just list them")
+
+ (opts, args) = parser.parse_args()
+ if not args:
+ parser.error("Missing query string")
+
+ return (args[0], args[1:], opts)
+
+(query_str, filters, opts) = parse_args(sys.argv)
+get_subs(query_str, filters)
-get_subs(sys.argv[1], sys.argv[2:])