whatever
commit
95d3c196ad
|
|
@ -0,0 +1,86 @@
|
|||
alabaster==0.7.11
|
||||
apipkg==1.5
|
||||
appdirs==1.4.3
|
||||
arandr==0.1.9
|
||||
atomicwrites==1.2.1
|
||||
attrs==18.2.0
|
||||
Babel==2.6.0
|
||||
babelfish==0.5.5
|
||||
beautifulsoup4==4.6.3
|
||||
cache==1.0.3
|
||||
certifi==2018.8.24
|
||||
chardet==3.0.4
|
||||
click==6.7
|
||||
contextlib2==0.5.5
|
||||
coverage==4.5.1
|
||||
cwiid==0.6.0
|
||||
docutils==0.14
|
||||
dogpile==0.2.2
|
||||
dogpile.cache==0.6.7
|
||||
enzyme==0.4.1
|
||||
execnet==1.5.0
|
||||
funcsigs==1.0.2
|
||||
futures==3.2.0
|
||||
guessit==3.0.0
|
||||
idna==2.7
|
||||
imagesize==1.1.0
|
||||
Jinja2==2.10
|
||||
louis==3.4.0
|
||||
MarkupSafe==1.0
|
||||
mock==2.0.0
|
||||
more-itertools==4.3.0
|
||||
mpmath==1.0.0
|
||||
mutagen==1.40.0
|
||||
netsnmp-python==1.0a1
|
||||
olefile==0.45.1
|
||||
packaging==17.1
|
||||
pathlib2==2.3.2
|
||||
pbr==4.2.0
|
||||
pep8==1.7.1
|
||||
Pillow==5.0.0
|
||||
pluggy==0.7.1
|
||||
psutil==5.4.3
|
||||
pwquality==1.4.0
|
||||
py==1.6.0
|
||||
PyBluez==0.22
|
||||
pycairo==1.16.3
|
||||
pyflakes==2.0.0
|
||||
Pygments==2.2.0
|
||||
pygobject==3.26.1
|
||||
pyparsing==2.2.0
|
||||
pysrt==1.1.1
|
||||
pytest==3.8.0
|
||||
pytest-cache==1.0
|
||||
pytest-cov==2.6.0
|
||||
pytest-flakes==4.0.0
|
||||
pytest-pep8==1.0.6
|
||||
python-dateutil==2.7.3
|
||||
pytz==2018.5
|
||||
PyYAML==3.13
|
||||
rarfile==3.0
|
||||
rebulk==0.9.0
|
||||
requests==2.19.1
|
||||
scandir==1.9.0
|
||||
simplejson==3.13.2
|
||||
six==1.11.0
|
||||
snowballstemmer==1.2.1
|
||||
Sphinx==1.8.0
|
||||
sphinx-rtd-theme==0.4.1
|
||||
sphinxcontrib-programoutput==0.11
|
||||
sphinxcontrib-websupport==1.1.0
|
||||
stevedore==1.29.0
|
||||
subliminal==2.0.5
|
||||
sympy==1.3
|
||||
team==1.0
|
||||
terminator==1.91
|
||||
toml==0.9.6
|
||||
tox==3.3.0
|
||||
twodict==1.2
|
||||
typing==3.6.6
|
||||
urllib3==1.23
|
||||
vcrpy==1.13.0
|
||||
virtualenv==16.0.0
|
||||
wrapt==1.10.11
|
||||
wxPython==3.0.2.0
|
||||
wxPython-common==3.0.2.0
|
||||
Youtube-DLG==0.4
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
#! /usr/bin/python2.7
|
||||
|
||||
def get_save_subtitles(fpath) :
|
||||
import subliminal
|
||||
from babelfish import Language
|
||||
from datetime import timedelta
|
||||
from os import system
|
||||
print("Finding and saving subtitles for "+str(fpath))
|
||||
vids = subliminal.scan_video(fpath)
|
||||
subs = subliminal.download_best_subtitles([vids], {Language("eng")})
|
||||
for v in [vids] :
|
||||
subliminal.save_subtitles(v, subs[v])
|
||||
system("chmod -R 777 {}".format(v.name[:v.name.rindex("/")]))
|
||||
|
||||
import threading
|
||||
class Downloader(threading.Thread) :
|
||||
def __init__(self, in_q, rate) :
|
||||
threading.Thread.__init__(self)
|
||||
self.q = in_q
|
||||
self.rate = rate
|
||||
def run(self) :
|
||||
@RateLimited(self.rate)
|
||||
def doit(arg) :
|
||||
try :
|
||||
get_save_subtitles(arg)
|
||||
except Exception as e :
|
||||
print("Could not save subtitles for "+arg+", "+str(e))
|
||||
while True :
|
||||
job = self.q.get()
|
||||
if job is None :
|
||||
return
|
||||
doit(job)
|
||||
|
||||
class FileWatcher(threading.Thread) :
|
||||
def __init__(self, root, out_q) :
|
||||
threading.Thread.__init__(self)
|
||||
self.q = out_q
|
||||
self.root = root
|
||||
def run(self) :
|
||||
import os
|
||||
for dirpath, _, fnames in os.walk(self.root) :
|
||||
fnames = sorted(fnames)
|
||||
if len(fnames) > 150 :
|
||||
continue
|
||||
for fname in fnames :
|
||||
fname = os.path.join(dirpath, fname)
|
||||
if not self.isVideoExt(fname.split(".")[-1]) :
|
||||
continue
|
||||
if not self.noSubYet(".".join(fname.split(".")[:-1])) :
|
||||
continue
|
||||
if self.isLink(fname) :
|
||||
continue
|
||||
self.q.put(fname)
|
||||
|
||||
self.q.put(None)
|
||||
def isVideoExt(self, ext) :
|
||||
return ext in ["mp4", "avi", "mkv"]
|
||||
|
||||
def noSubYet(self, basename) :
|
||||
from os import path
|
||||
return not (
|
||||
path.isfile(basename+".srt") or
|
||||
path.isfile(basename+".en.srt") or
|
||||
path.isfile(basename+".en.ttml") or
|
||||
path.isfile(basename+".ttml")
|
||||
)
|
||||
|
||||
def isLink(self, fpath) :
|
||||
from os import path
|
||||
return path.islink(fpath)
|
||||
|
||||
job_queue = None
|
||||
def get_job_queue() :
|
||||
global job_queue
|
||||
if job_queue is None :
|
||||
import Queue as queue
|
||||
job_queue = queue.Queue()
|
||||
return job_queue
|
||||
|
||||
last = 0.0
|
||||
def RateLimited(opsPerSec) :
|
||||
import time
|
||||
minInterval = 1.0 / float(opsPerSec)
|
||||
def dec(func) :
|
||||
def limitedFunc(*args, **kwargs) :
|
||||
global last
|
||||
elapsed = time.clock() - last
|
||||
left = minInterval - elapsed
|
||||
if left > 0 :
|
||||
time.sleep(left)
|
||||
ret = func(*args, **kwargs)
|
||||
last = time.clock()
|
||||
return ret
|
||||
return limitedFunc
|
||||
return dec
|
||||
|
||||
def get_args() :
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--root", type=str, default="/volume1/video/TV") #required=True)
|
||||
parser.add_argument("--rate", type=float, default=1)
|
||||
return parser.parse_args()
|
||||
|
||||
def main() :
|
||||
args = get_args()
|
||||
|
||||
FileWatcher(args.root, get_job_queue()).run()
|
||||
Downloader(get_job_queue(), args.rate).run()
|
||||
|
||||
return
|
||||
|
||||
threads = []
|
||||
threads.append(FileWatcher(args.root, get_job_queue()))
|
||||
threads.append(Downloader(get_job_queue(), args.rate))
|
||||
|
||||
for t in threads :
|
||||
t.start()
|
||||
|
||||
for t in threads :
|
||||
t.join()
|
||||
|
||||
if __name__ == "__main__" :
|
||||
main()
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
babelfish==0.5.5
|
||||
beautifulsoup4==4.6.3
|
||||
cache==1.0.3
|
||||
dogpile==0.2.2
|
||||
dogpile.cache==0.6.7
|
||||
futures==3.2.0
|
||||
guessit==3.0.0
|
||||
pysrt==1.1.1
|
||||
rarfile==3.0
|
||||
requests==2.19.1
|
||||
subliminal==2.0.5
|
||||
Loading…
Reference in New Issue