Created
November 24, 2014 08:49
-
-
Save aykut/c52f124a7db87cb9cd7f to your computer and use it in GitHub Desktop.
# this script finds and uploads subtitles which matches all(or under given parent folder) video files in your putio account.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# this script finds and uploads subtitles which matches all(or under given parent folder) video files in your putio account. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from contextlib import closing | |
import gzip | |
import os | |
import shutil | |
import tempfile | |
import sys | |
import guessit | |
__version__ = '1.5.2' | |
# Taken from https://github.com/nicoddemus/ss and updated to work with putio. | |
if sys.version_info[0] == 3: # pragma: no cover | |
from urllib.request import urlopen | |
from xmlrpc.client import ServerProxy | |
else: # pragma: no cover | |
from urllib import urlopen | |
from xmlrpclib import Server as ServerProxy | |
def obtain_guessit_query(movie_filename, language): | |
guess = guessit.guess_file_info( | |
os.path.basename(movie_filename), info=['filename']) | |
def extract_query(guess, parts): | |
result = ['"%s"' % guess.get(k) for k in parts if guess.get(k)] | |
return ' '.join(result) | |
result = {} | |
if guess.get('type') == 'episode': | |
result['query'] = extract_query( | |
guess, ['series', 'title', 'releaseGroup']) | |
if 'season' in guess: | |
result['season'] = guess['season'] | |
if 'episodeNumber' in guess: | |
result['episode'] = guess['episodeNumber'] | |
elif guess.get('type') == 'movie': | |
result['query'] = extract_query(guess, ['title', 'year']) | |
else: # pragma: no cover | |
assert False, 'internal error: guessit guess: {0}'.format(guess) | |
result['sublanguageid'] = language | |
return result | |
def obtain_movie_hash_query(moviehash, movie_filesize, language): | |
return { | |
'moviehash': moviehash, | |
'moviebytesize': movie_filesize, | |
'sublanguageid': language, | |
} | |
def filter_bad_results(search_results, guessit_query): | |
""" | |
filter out search results with bad season and episode number (if | |
applicable); sometimes OpenSubtitles will report search results subtitles | |
that belong to a different episode or season from a tv show; no reason | |
why, but it seems to work well just filtering those out | |
""" | |
if 'season' in guessit_query and 'episode' in guessit_query: | |
guessit_season_episode = (guessit_query['season'], | |
guessit_query['episode']) | |
search_results = [x for x in search_results | |
if (int(x['SeriesSeason']), int(x['SeriesEpisode'])) == guessit_season_episode] | |
return search_results | |
def query_open_subtitles(movie_filename, moviehash, movie_filesize, language): | |
uri = 'http://api.opensubtitles.org/xml-rpc' | |
server = ServerProxy(uri, verbose=0, allow_none=True, use_datetime=True) | |
login_info = server.LogIn('', '', 'en', 'ss v' + __version__) | |
token = login_info['token'] | |
try: | |
guessit_query = obtain_guessit_query(movie_filename, language) | |
search_queries = [ | |
guessit_query, | |
obtain_movie_hash_query(moviehash, movie_filesize, language), | |
] | |
response = server.SearchSubtitles(token, search_queries) | |
try: | |
search_results = response['data'] | |
except KeyError: | |
raise KeyError('"data" key not found in response: %r' % response) | |
if search_results: | |
search_results = filter_bad_results(search_results, guessit_query) | |
return search_results | |
finally: | |
server.LogOut(token) | |
def find_subtitle(movie_filename, moviehash, movie_filesize, language): | |
search_results = query_open_subtitles(movie_filename, moviehash, | |
movie_filesize, language) | |
if search_results: | |
search_result = search_results[0] | |
return search_result['SubDownloadLink'], ( | |
'.' + search_result['SubFormat']) | |
else: | |
return None, None | |
def download_subtitle(subtitle_url): | |
# first download it and save to a temp dir | |
with closing(urlopen(subtitle_url)) as urlfile: | |
gzip_subtitle_contents = urlfile.read() | |
tempdir = tempfile.mkdtemp() | |
try: | |
basename = subtitle_url.split('/')[-1] | |
tempfilename = os.path.join(tempdir, basename) | |
with open(tempfilename, 'wb') as f: | |
f.write(gzip_subtitle_contents) | |
with closing(gzip.GzipFile(tempfilename, 'rb')) as f: | |
subtitle_contents = f.read() | |
return subtitle_contents | |
finally: | |
shutil.rmtree(tempdir) | |
def search_and_download(movie_filename, moviehash, movie_filesize, language): | |
subtitle_url, subtitle_ext = find_subtitle(movie_filename, moviehash, | |
movie_filesize, language) | |
if subtitle_url: | |
return download_subtitle(subtitle_url) | |
else: | |
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import putio | |
import os | |
from ss import search_and_download | |
OAUTH_TOKEN = '' | |
client = putio.Client(OAUTH_TOKEN) | |
def subtitle_finder(parent_id, language, recursive=True): | |
""" | |
Finds subtitles and uploads them to your putio account. | |
""" | |
files = client.File.list(parent_id=parent_id) | |
for f in files: | |
if f.content_type == 'application/x-directory' and recursive: | |
subtitle_finder(f.id, language, recursive=recursive) | |
elif f.content_type.split('/')[0] == 'video': | |
subtitle_content = search_and_download( | |
f.name, f.opensubtitles_hash, f.size, language) | |
if subtitle_content: | |
name, ext = os.path.splitext(f.name) | |
client.request( | |
'/files/upload', method='POST', | |
data={'parent_id': f.parent_id}, | |
files={'file': (name + '.srt', subtitle_content)}) | |
print f.name + ' [OK]' | |
else: | |
print f.name + ' [NotFound]' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment