def DownloadSubtitles(key, type): data = [] oc = ObjectContainer(no_cache=True, title2='Subtitles') video = XML.ElementFromURL(HOST + key).xpath('//Video')[0] if video: subs = OpenSubtitles(SETTINGS) token = subs.login(SETTINGS['username'], SETTINGS['password']) full_path = video.xpath('./Media/Part')[0].get('file') root, filename = os.path.split(full_path) filename = filename.split('.')[0] if type == 'show': title = video.get('grandparentTitle') season = video.get('parentIndex') episode = video.get('index') if title and season and episode: data = subs.search_subtitles([{'sublanguageid': SETTINGS['language'], 'query': title, 'season': season, 'episode': episode}]) else: title = video.get('title') if title: data = subs.search_subtitles([{'sublanguageid': SETTINGS['language'], 'query': title}]) subs.logout() for item in data: oc.add(DirectoryObject(key = Callback(WriteSubtitle, url=item['SubDownloadLink'], root=root, filename=filename), title = item['MovieReleaseName'] + ' (' + item['SubDownloadsCnt'] + ' downloads)')) return oc
def get_sentence(word, imdb_id): """ Получить предложение для слова Args: word (:obj:`str`): слово imdb_id (:obj:`int`): id фильма на сайте *imdb.com* Returns: sentence (:obj:`str`): предложение для слова """ OP = OpenSubtitles() logger.info("Getting sentence, OpenSubtitles token %s" % OP.login()) postgre = DataBase() sentence = postgre.GetSentence(word, imdb_id) if sentence: return sentence subtitle_id = postgre.GetSubtitleID(imdb_id) logger.info("subtitle id - %s" % subtitle_id) FileData = (OP.download_subtitles([subtitle_id])) sentence = search_sentence(FileData['data'][0]['data'], word) OP.logout() if sentence: postgre.AddSentence(word, imdb_id, sentence) return sentence else: return None
def SearchSubtitles(subtitles, auto=False): try: sortedList = [] update = False subs = OpenSubtitles(SETTINGS) token = subs.login(SETTINGS['username'], SETTINGS['password']) for item in subtitles: data = cleanedList = sortedList = [] if item['type'] == 'episode': data = subs.search_subtitles([{ 'sublanguageid': SETTINGS['language'], 'imdbid': item['id'], 'season': item['season'], 'episode': item['episode'] }]) else: data = subs.search_subtitles([{ 'sublanguageid': SETTINGS['language'], 'imdbid': item['id'] }]) if data != False: for video in data: if video['SubFormat'] == 'srt': cleanedList.append(video) sortedList = sorted(cleanedList, key=lambda k: int(k['SubDownloadsCnt']), reverse=True) if auto == True: update = True response = WriteSubtitle(sortedList[0]['SubDownloadLink'], item['root'], item['filename']) else: Log.Info('There are no subtites for ' + item['filename'] + ' at this time') subs.logout() if update: UpdateLibrary() except: Log.Exception('Error connecting to Opensubtitles.org') return sortedList
def SearchSubtitles(subtitles, auto=False): try: sortedList = [] update = False subs = OpenSubtitles({ 'opensubtitles_server' : 'http://api.opensubtitles.org/xml-rpc', 'user_agent' : 'plexapp.com v9.0', 'language' : Prefs['language'], 'username' : Prefs['username'], 'password' : Prefs['password'] }) token = subs.login(Prefs['username'], Prefs['password']) for item in subtitles: data = cleanedList = sortedList = [] if item['type'] == 'episode': data = subs.search_subtitles([{'sublanguageid': Prefs['language'], 'imdbid': item['id'], 'season': item['season'], 'episode': item['episode']}]) else: data = subs.search_subtitles([{'sublanguageid': Prefs['language'], 'imdbid': item['id']}]) if data != None and data != False: for video in data: if video['SubFormat'] == 'srt': cleanedList.append(video) sortedList = sorted(cleanedList, key=lambda k: int(k['SubDownloadsCnt']), reverse=True) if auto == True: update = True response = WriteSubtitle(sortedList[0]['SubDownloadLink'], item['root'], item['filename']) else: Log.Info('There are no subtites for ' + item['filename'] + ' at this time') subs.logout() if update: UpdateLibrary() except: Log.Exception('Error connecting to Opensubtitles.org') return sortedList
def __init__(self, subtitle_languages, choose_subtitle): self.opensubtitles = OpenSubtitles() self.vid_sub_dict = {} self.subtitle_languages = subtitle_languages self.choose_subtitle = choose_subtitle
class SubtitleProcessor: _vid_match_pattern = '(.*)\.(avi|mkv|mp4)$' _sub_match_pattern = '(.*)\.(srt|ass)$' _season_episode_patterns = [ '\s|-|_|\.|\[|\(|\{(\d{1,2})\s|-|_|\.|\]|\)|\}', '\s|-|_|\.|\[|\(|\{(\d{1,2})(\d{2})\s|-|_|\.|\]|\)|\}', '\s|-|_|\.|\[|\(|\{(\d{1,2})x(\d{2})\s|-|_|\.|\]|\)|\}', 's(\d{1,2})e(\d{1,2})' ] _supported_encodings = ['UTF-8', 'ISO-8859-1', 'ISO-8859-2', 'ASCII'] def __init__(self, subtitle_languages, choose_subtitle): self.opensubtitles = OpenSubtitles() self.vid_sub_dict = {} self.subtitle_languages = subtitle_languages self.choose_subtitle = choose_subtitle def process(self): videos = [] subtitles = [] if len(sys.argv) > 1: for arg in sys.argv[1:]: self.init_path_args(arg, videos, subtitles) else: print("Usage: {:s} [video|directory]...".format(os.path.basename(sys.argv[0]))) sys.exit(1) self.pair_videos_subs(videos, subtitles) del videos del subtitles self.process_videos_subs() print("Done!") sys.exit(0) def init_path_args(self, base_path, videos, subtitles): if os.path.exists(base_path): if os.path.isdir(base_path): for filename in os.listdir(base_path): absolute_path = os.path.join(base_path, filename) self.init_path_args(absolute_path, videos, subtitles) elif os.path.isfile(base_path): self.detect_file_type(base_path, videos, subtitles) else: print("No such file or directory: {:s}".format(base_path)) def detect_file_type(self, file, videos, subtitles): vid_match = re.search(self._vid_match_pattern, file, re.IGNORECASE) sub_match = re.search(self._sub_match_pattern, file, re.IGNORECASE) if vid_match: videos.append(file) elif sub_match: subtitles.append(file) def pair_videos_subs(self, videos, subtitles): for video in videos: self.vid_sub_dict[video] = [] video_season_episode = self.get_episode(video) for subtitle in subtitles: sub_season_episode = self.get_episode(subtitle) if video_season_episode[0] == sub_season_episode[0] and video_season_episode[1] == sub_season_episode[1]: self.vid_sub_dict[video].append(subtitle) def get_episode(self, filename): season = 0 episode = 0 for pattern in self._season_episode_patterns: input_match = re.search(pattern, filename, re.IGNORECASE) if input_match: groups = input_match.groups() if len(groups) == 1: episode = groups[0] elif len(groups) == 2: season = groups[0] episode = groups[1] return [str(season), str(episode)] def process_videos_subs(self): for video, subtitles in self.vid_sub_dict.items(): if len(subtitles) > 0: processed_subtitles = [] for idx, subtitle in enumerate(subtitles): self.encode_sub(subtitle) renamed_subtitle = self.rename_sub(video, subtitle, idx) processed_subtitles.append(renamed_subtitle) self.vid_sub_dict[video] = processed_subtitles else: self.download_missing_subs(video) def encode_sub(self, subtitle): for encoding in self._supported_encodings: try: with open(subtitle, encoding=encoding) as input_sub: data = input_sub.read() if encoding == 'UTF-8': print("Encoding of subtitle {:s} is already UTF-8, skipping".format(subtitle)) pass print("Encoding subtitle {:s} from {:s} to UTF-8".format(subtitle, encoding)) temp = os.path.dirname(subtitle) + '/' + str(time.time()) + '.tmp' with open(temp, 'w+', encoding='UTF-8') as output: output.write(data) input_sub.close() output.close() shutil.move(temp, subtitle) break except UnicodeDecodeError: pass def rename_sub(self, video, subtitle, index): vid_match = re.search(self._vid_match_pattern, video, re.IGNORECASE) sub_match = re.search(self._sub_match_pattern, subtitle, re.IGNORECASE) if vid_match and sub_match: vid_name = vid_match.group(1) sub_name = sub_match.group(1) sub_ext = sub_match.group(2) new_sub_name = vid_name + '.' + sub_ext if os.path.exists(new_sub_name): new_sub_name = vid_name + '.' + index + '.' + sub_ext print("Renaming subtitle: {:s} --> {:s}".format(sub_name + sub_ext, new_sub_name)) shutil.move(subtitle, new_sub_name) return new_sub_name def download_missing_subs(self, video): print("Searching subtitles for video: {:s}".format(video)) vid_hash = self.opensubtitles.hash(video) for lang in self.subtitle_languages: sub_infos = self.opensubtitles.search_subtitles([{'sublanguageid': lang, 'moviehash': vid_hash, 'moviebytesize': str(os.path.getsize(video))}]) if sub_infos: sub_index = self.choose_subtitle_to_download(sub_infos, lang) fetched_subtitle = self.fetch_subtitle(sub_index, sub_infos) vid_match = re.search(self._vid_match_pattern, video, re.IGNORECASE) if vid_match and fetched_subtitle is not None: vid_name = vid_match.group(1) sub_file_name = vid_name + '.' + lang + '.srt' print("Writing subtitle to file: {:s}".format(sub_file_name)) self.write_subtitle_file(fetched_subtitle, sub_file_name) self.encode_sub(sub_file_name) self.vid_sub_dict[video].append(sub_file_name) else: print("Couldn't download subtitle for video {:s} with language {:s}".format(video, lang)) else: print("No subtitles found for video {:s} with language {:s}".format(video, lang)) def choose_subtitle_to_download(self, sub_infos, lang): sub_index = 0 if self.choose_subtitle and len(sub_infos) > 1: print("Language: {:s}".format(lang)) for idx, sub_info in enumerate(sub_infos): print("[{:d}] {:s}".format(idx, sub_info.get('SubFileName'))) valid_input = False while not valid_input: try: sub_index_input = input("Select a subtitle: ") sub_index = int(sub_index_input) if (sub_index < len(sub_infos)) and (sub_index >= 0): valid_input = True except ValueError: pass return sub_index def fetch_subtitle(self, sub_index, sub_infos): print("Downloading subtitle: {:s}".format(sub_infos[sub_index].get('SubFileName'))) fetched_subtitles = self.opensubtitles.download_subtitle([sub_infos[sub_index].get('IDSubtitleFile')]) if fetched_subtitles: fetched_subtitle = fetched_subtitles[0].get('data') return fetched_subtitle else: return None @staticmethod def write_subtitle_file(data, file): file_data = base64.b64decode(data) uncompressed_sub = gzip.decompress(file_data) try: with open(file, 'bw+') as subtitle: subtitle.write(uncompressed_sub) except IOError: print("Couldn't write subtitle file")
class SubtitleProcessor: _vid_match_pattern = '(.*)\.(avi|mkv|mp4)$' _sub_match_pattern = '(.*)\.(srt|ass)$' _season_episode_patterns = [ '\s|-|_|\.|\[|\(|\{(\d{1,2})\s|-|_|\.|\]|\)|\}', '\s|-|_|\.|\[|\(|\{(\d{1,2})(\d{2})\s|-|_|\.|\]|\)|\}', '\s|-|_|\.|\[|\(|\{(\d{1,2})x(\d{2})\s|-|_|\.|\]|\)|\}', 's(\d{1,2})e(\d{1,2})' ] _supported_encodings = ['UTF-8', 'ISO-8859-1', 'ISO-8859-2', 'ASCII'] def __init__(self, subtitle_languages, choose_subtitle): self.opensubtitles = OpenSubtitles() self.vid_sub_dict = {} self.subtitle_languages = subtitle_languages self.choose_subtitle = choose_subtitle def process(self): videos = [] subtitles = [] if len(sys.argv) > 1: for arg in sys.argv[1:]: self.init_path_args(arg, videos, subtitles) else: print("Usage: {:s} [video|directory]...".format( os.path.basename(sys.argv[0]))) sys.exit(1) self.pair_videos_subs(videos, subtitles) del videos del subtitles self.process_videos_subs() print("Done!") sys.exit(0) def init_path_args(self, base_path, videos, subtitles): if os.path.exists(base_path): if os.path.isdir(base_path): for filename in os.listdir(base_path): absolute_path = os.path.join(base_path, filename) self.init_path_args(absolute_path, videos, subtitles) elif os.path.isfile(base_path): self.detect_file_type(base_path, videos, subtitles) else: print("No such file or directory: {:s}".format(base_path)) def detect_file_type(self, file, videos, subtitles): vid_match = re.search(self._vid_match_pattern, file, re.IGNORECASE) sub_match = re.search(self._sub_match_pattern, file, re.IGNORECASE) if vid_match: videos.append(file) elif sub_match: subtitles.append(file) def pair_videos_subs(self, videos, subtitles): for video in videos: self.vid_sub_dict[video] = [] video_season_episode = self.get_episode(video) for subtitle in subtitles: sub_season_episode = self.get_episode(subtitle) if video_season_episode[0] == sub_season_episode[ 0] and video_season_episode[1] == sub_season_episode[1]: self.vid_sub_dict[video].append(subtitle) def get_episode(self, filename): season = 0 episode = 0 for pattern in self._season_episode_patterns: input_match = re.search(pattern, filename, re.IGNORECASE) if input_match: groups = input_match.groups() if len(groups) == 1: episode = groups[0] elif len(groups) == 2: season = groups[0] episode = groups[1] return [str(season), str(episode)] def process_videos_subs(self): for video, subtitles in self.vid_sub_dict.items(): if len(subtitles) > 0: processed_subtitles = [] for idx, subtitle in enumerate(subtitles): self.encode_sub(subtitle) renamed_subtitle = self.rename_sub(video, subtitle, idx) processed_subtitles.append(renamed_subtitle) self.vid_sub_dict[video] = processed_subtitles else: self.download_missing_subs(video) def encode_sub(self, subtitle): for encoding in self._supported_encodings: try: with open(subtitle, encoding=encoding) as input_sub: data = input_sub.read() if encoding == 'UTF-8': print( "Encoding of subtitle {:s} is already UTF-8, skipping" .format(subtitle)) pass print("Encoding subtitle {:s} from {:s} to UTF-8".format( subtitle, encoding)) temp = os.path.dirname(subtitle) + '/' + str( time.time()) + '.tmp' with open(temp, 'w+', encoding='UTF-8') as output: output.write(data) input_sub.close() output.close() shutil.move(temp, subtitle) break except UnicodeDecodeError: pass def rename_sub(self, video, subtitle, index): vid_match = re.search(self._vid_match_pattern, video, re.IGNORECASE) sub_match = re.search(self._sub_match_pattern, subtitle, re.IGNORECASE) if vid_match and sub_match: vid_name = vid_match.group(1) sub_name = sub_match.group(1) sub_ext = sub_match.group(2) new_sub_name = vid_name + '.' + sub_ext if os.path.exists(new_sub_name): new_sub_name = vid_name + '.' + index + '.' + sub_ext print("Renaming subtitle: {:s} --> {:s}".format( sub_name + sub_ext, new_sub_name)) shutil.move(subtitle, new_sub_name) return new_sub_name def download_missing_subs(self, video): print("Searching subtitles for video: {:s}".format(video)) vid_hash = self.opensubtitles.hash(video) for lang in self.subtitle_languages: sub_infos = self.opensubtitles.search_subtitles([{ 'sublanguageid': lang, 'moviehash': vid_hash, 'moviebytesize': str(os.path.getsize(video)) }]) if sub_infos: sub_index = self.choose_subtitle_to_download(sub_infos, lang) fetched_subtitle = self.fetch_subtitle(sub_index, sub_infos) vid_match = re.search(self._vid_match_pattern, video, re.IGNORECASE) if vid_match and fetched_subtitle is not None: vid_name = vid_match.group(1) sub_file_name = vid_name + '.' + lang + '.srt' print( "Writing subtitle to file: {:s}".format(sub_file_name)) self.write_subtitle_file(fetched_subtitle, sub_file_name) self.encode_sub(sub_file_name) self.vid_sub_dict[video].append(sub_file_name) else: print( "Couldn't download subtitle for video {:s} with language {:s}" .format(video, lang)) else: print("No subtitles found for video {:s} with language {:s}". format(video, lang)) def choose_subtitle_to_download(self, sub_infos, lang): sub_index = 0 if self.choose_subtitle and len(sub_infos) > 1: print("Language: {:s}".format(lang)) for idx, sub_info in enumerate(sub_infos): print("[{:d}] {:s}".format(idx, sub_info.get('SubFileName'))) valid_input = False while not valid_input: try: sub_index_input = input("Select a subtitle: ") sub_index = int(sub_index_input) if (sub_index < len(sub_infos)) and (sub_index >= 0): valid_input = True except ValueError: pass return sub_index def fetch_subtitle(self, sub_index, sub_infos): print("Downloading subtitle: {:s}".format( sub_infos[sub_index].get('SubFileName'))) fetched_subtitles = self.opensubtitles.download_subtitle( [sub_infos[sub_index].get('IDSubtitleFile')]) if fetched_subtitles: fetched_subtitle = fetched_subtitles[0].get('data') return fetched_subtitle else: return None @staticmethod def write_subtitle_file(data, file): file_data = base64.b64decode(data) uncompressed_sub = gzip.decompress(file_data) try: with open(file, 'bw+') as subtitle: subtitle.write(uncompressed_sub) except IOError: print("Couldn't write subtitle file")
def main(): args = process_arguments() movies_list = [] os.path.dirname(os.path.realpath(__file__)) # Single file should be checked if args.path[0] == "single": movies_list = get_list_of_files(args.path[1], "single") # Folder should be scanned recusrivly elif args.path[0] == "folder" and args.recursive: movies_list = get_list_of_files(args.path[1], "recursive") # Folder else: movies_list = get_list_of_files(args.path[1], "folder") print "Working..." # Obtain imdb id for each movie file movie_dict = {} movie_dict = OpenSubtitles.get_movie_data(movies_list) del movies_list # Create movies database which contains movie objects movies_database = [] for element in movie_dict.items(): movie_obj = Movie() movie_obj.imdb_id = element[1] movie_obj.path = element[0] movies_database.append(movie_obj) del movie_dict # For movies which has not imdb id detected try to obtain title # from the file name # File name must be in such format: mobie_title_year(4 digits)_extension for movie in movies_database: if movie.imdb_id == None: obtain_title_and_year(movie) print "obtained! %s" % (movie.title) # Obtain movie details from imdb. unique_movies_dict = {} for movie in movies_database: # imdb id detected - take movie data from imdb.com if movie.imdb_id != None: movie.imdb_object = ImdbCom.get_movie_data_from_imdbcom(movie.imdb_id) movie.prepare_data_from_imdb() if movie.imdb_id not in unique_movies_dict.keys(): print '"%s" processed.' % movie.title unique_movies_dict[movie.imdb_id] = movie # imdb id is not known but title has been obtained from file name elif movie.title != None: movie.imdb_object, movie.imdb_id = ImdbCom.search_movie_by_title(movie) if movie.imdb_object: movie.prepare_data_from_imdb() if movie.imdb_id not in unique_movies_dict.keys(): print '"%s" processed.' % movie.title unique_movies_dict[movie.imdb_id] = movie else: print '"%s" not processed.' % movie.path # Preapre list of not duplicated movies # Each movie objact on this list contains data from imdb.com unique_movies_list = unique_movies_dict.values() # Finally render index.html file # Prepare environment for jinja2 execution_path = os.path.dirname(os.path.realpath(__file__)) templates_path = os.path.join(execution_path, "templates") static_path = os.path.join(execution_path, "static") # Prepare path for copying static files to cwd templates_cwd_path = os.path.join(os.getcwd(), "moview/templates") static_cwd_path = os.path.join(os.getcwd(), "moview/static") # Remove moview tmp files if already exists in cwd try: shutil.rmtree(os.path.join(os.getcwd(), "moview")) except: pass # Copy static files to cwd under moview direcotry shutil.copytree(templates_path, templates_cwd_path) shutil.copytree(static_path, static_cwd_path) # Prepare environment for jinja2 env = Environment(loader=FileSystemLoader(templates_path)) # Select template template = env.get_template("index.html") # Render results to index.html file rendered_file = open("index.html", "w") rendered_file.write(template.render(movielist=unique_movies_list).encode("utf-8")) rendered_file.close() # That's it! print "index.html with movie list has been " + "generated in the current directory." print "Thanks for using MoView!" return sys.exit(0)