Skip to content

Instantly share code, notes, and snippets.

@aykut
Created November 24, 2014 08:49
Show Gist options
  • Save aykut/c52f124a7db87cb9cd7f to your computer and use it in GitHub Desktop.
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 script finds and uploads subtitles which matches all(or under given parent folder) video files in your putio account.
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
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