From be8749e472552994aa376cf1f66f6036a4a9814d Mon Sep 17 00:00:00 2001 From: Ruud Date: Mon, 9 Apr 2012 20:28:07 +0200 Subject: [PATCH] Proper subtitle support --- couchpotato/core/plugins/renamer/main.py | 15 +++++++- couchpotato/core/plugins/scanner/main.py | 45 ++++++++++++++++++++-- couchpotato/core/plugins/subtitle/main.py | 27 +++++++------ couchpotato/core/providers/subtitle/__init__.py | 0 couchpotato/core/providers/subtitle/base.py | 13 ------- .../core/providers/subtitle/subliminal/__init__.py | 6 --- .../core/providers/subtitle/subliminal/main.py | 22 ----------- 7 files changed, 72 insertions(+), 56 deletions(-) delete mode 100644 couchpotato/core/providers/subtitle/__init__.py delete mode 100644 couchpotato/core/providers/subtitle/base.py delete mode 100644 couchpotato/core/providers/subtitle/subliminal/__init__.py delete mode 100644 couchpotato/core/providers/subtitle/subliminal/main.py diff --git a/couchpotato/core/plugins/renamer/main.py b/couchpotato/core/plugins/renamer/main.py index e8d7018..563604c 100644 --- a/couchpotato/core/plugins/renamer/main.py +++ b/couchpotato/core/plugins/renamer/main.py @@ -192,11 +192,16 @@ class Renamer(Plugin): if file_type is 'leftover': if self.conf('move_leftover'): rename_files[current_file] = os.path.join(destination, final_folder_name, os.path.basename(current_file)) - else: + elif file_type not in ['subtitle']: rename_files[current_file] = os.path.join(destination, final_folder_name, final_file_name) # Check for extra subtitle files if file_type is 'subtitle': + + # rename subtitles with or without language + #rename_files[current_file] = os.path.join(destination, final_folder_name, final_file_name) + sub_langs = group['subtitle_language'].get(current_file) + rename_extras = self.getRenameExtras( extra_type = 'subtitle_extra', replacements = replacements, @@ -206,6 +211,14 @@ class Renamer(Plugin): group = group, current_file = current_file ) + + # Don't add language if multiple languages in 1 file + if len(sub_langs) > 1: + rename_files[current_file] = os.path.join(destination, final_folder_name, final_file_name) + elif len(sub_langs) == 1: + sub_name = final_file_name.replace(replacements['ext'], '%s.%s' % (sub_langs[0], replacements['ext'])) + rename_files[current_file] = os.path.join(destination, final_folder_name, sub_name) + rename_files = mergeDicts(rename_files, rename_extras) # Filename without cd etc diff --git a/couchpotato/core/plugins/scanner/main.py b/couchpotato/core/plugins/scanner/main.py index 2d9607c..927fb12 100644 --- a/couchpotato/core/plugins/scanner/main.py +++ b/couchpotato/core/plugins/scanner/main.py @@ -7,6 +7,7 @@ from couchpotato.core.plugins.base import Plugin from couchpotato.core.settings.model import File from couchpotato.environment import Env from enzyme.exceptions import NoParserError, ParseError +from subliminal.videos import scan import enzyme import logging import os @@ -208,7 +209,7 @@ class Scanner(Plugin): for identifier, group in movie_files.iteritems(): if identifier not in group['identifiers'] and len(identifier) > 0: group['identifiers'].append(identifier) - log.debug('Grouping files for: %s' % identifier) + log.debug('Grouping files: %s' % identifier) for file_path in group['unsorted_files']: wo_ext = file_path[:-(len(getExt(file_path)) + 1)] @@ -233,7 +234,7 @@ class Scanner(Plugin): # Group the files based on the identifier for identifier, group in movie_files.iteritems(): - log.debug('Grouping files for: %s' % identifier) + log.debug('Grouping files on identifier: %s' % identifier) found_files = set(self.path_identifiers.get(identifier, [])) group['unsorted_files'].extend(found_files) @@ -262,7 +263,7 @@ class Scanner(Plugin): file_too_new = tryInt(time.time() - file_time) break - if file_too_new: + if file_too_new and not Env.get('dev'): log.info('Files seem to be still unpacking or just unpacked (created on %s), ignoring for now: %s' % (time.ctime(file_time), identifier)) continue @@ -291,6 +292,9 @@ class Scanner(Plugin): log.debug('Getting metadata for %s' % identifier) group['meta_data'] = self.getMetaData(group) + # Subtitle meta + group['subtitle_language'] = self.getSubtitleLanguage(group) + # Get parent dir from movie files for movie_file in group['files']['movie']: group['parentdir'] = os.path.dirname(movie_file) @@ -381,6 +385,41 @@ class Scanner(Plugin): return {} + def getSubtitleLanguage(self, group): + detected_languages = {} + + # Subliminal scanner + try: + paths = group['files']['movie'] + scan_result = [] + for p in paths: + scan_result.extend(scan(p)) + + for video, detected_subtitles in scan_result: + for s in detected_subtitles: + if s.language and s.path not in paths: + detected_languages[s.path] = [s.language] + except: + log.error('Failed parsing subtitle languages for %s: %s' % (paths, traceback.format_exc())) + + # IDX + for extra in group['files']['subtitle_extra']: + try: + if os.path.isfile(extra): + output = open(extra, 'r') + txt = output.read() + output.close() + + idx_langs = re.findall('\nid: (\w+)', txt) + + sub_file = '%s.sub' % os.path.splitext(extra)[0] + if len(idx_langs) > 0 and os.path.isfile(sub_file): + detected_languages[sub_file] = idx_langs + except: + log.error('Failed parsing subtitle idx for %s: %s' % (extra, traceback.format_exc())) + + return detected_languages + def determineMovie(self, group): imdb_id = None diff --git a/couchpotato/core/plugins/subtitle/main.py b/couchpotato/core/plugins/subtitle/main.py index 45f87db..da86d49 100644 --- a/couchpotato/core/plugins/subtitle/main.py +++ b/couchpotato/core/plugins/subtitle/main.py @@ -3,15 +3,18 @@ from couchpotato.core.event import addEvent, fireEvent from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin from couchpotato.core.settings.model import Library, FileType +from couchpotato.environment import Env +import subliminal log = CPLog(__name__) class Subtitle(Plugin): + services = ['opensubtitles', 'thesubdb', 'subswiki'] + def __init__(self): - pass - #addEvent('renamer.before', self.searchSingle) + addEvent('renamer.before', self.searchSingle) def searchLibrary(self): @@ -33,20 +36,22 @@ class Subtitle(Plugin): files.append(file.path); # get subtitles for those files - subtitles = fireEvent('subtitle.search', files = files, languages = self.getLanguages(), merge = True) - - # do something with the returned subtitles - print subtitles - + subliminal.list_subtitles(files, cache_dir = Env.get('cache_dir'), multi = True, languages = self.getLanguages(), services = self.services) def searchSingle(self, group): if self.isDisabled(): return - subtitles = fireEvent('subtitle.search', files = group['files']['movie'], languages = self.getLanguages(), merge = True) + available_languages = sum(group['subtitle_language'].itervalues(), []) + downloaded = [] + for lang in self.getLanguages(): + if lang not in available_languages: + download = subliminal.download_subtitles(group['files']['movie'], multi = True, force = False, languages = [lang], services = self.services, cache_dir = Env.get('cache_dir')) + downloaded.extend(download) - # do something with the returned subtitles - print subtitles + for d_sub in downloaded: + group['files']['subtitle'].add(d_sub.path) + group['subtitle_language'][d_sub.path] = [d_sub.language] def getLanguages(self): - return self.conf('languages').split(',') + return [x.strip() for x in self.conf('languages').split(',')] diff --git a/couchpotato/core/providers/subtitle/__init__.py b/couchpotato/core/providers/subtitle/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/couchpotato/core/providers/subtitle/base.py b/couchpotato/core/providers/subtitle/base.py deleted file mode 100644 index d26a6d1..0000000 --- a/couchpotato/core/providers/subtitle/base.py +++ /dev/null @@ -1,13 +0,0 @@ -from couchpotato.core.event import addEvent -from couchpotato.core.providers.base import Provider - - -class SubtitleProvider(Provider): - - type = 'subtitle' - - def __init__(self): - addEvent('subtitle.search', self.search) - - def search(self, group): - pass diff --git a/couchpotato/core/providers/subtitle/subliminal/__init__.py b/couchpotato/core/providers/subtitle/subliminal/__init__.py deleted file mode 100644 index bc3cb85..0000000 --- a/couchpotato/core/providers/subtitle/subliminal/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from .main import SubliminalProvider - -def start(): - return SubliminalProvider() - -config = [] diff --git a/couchpotato/core/providers/subtitle/subliminal/main.py b/couchpotato/core/providers/subtitle/subliminal/main.py deleted file mode 100644 index 9616aea..0000000 --- a/couchpotato/core/providers/subtitle/subliminal/main.py +++ /dev/null @@ -1,22 +0,0 @@ -from couchpotato.core.logger import CPLog -from couchpotato.core.providers.subtitle.base import SubtitleProvider -from couchpotato.environment import Env -from libs import subliminal - -log = CPLog(__name__) - - -class SubliminalProvider(SubtitleProvider): - - plugins = ['OpenSubtitles', 'TheSubDB', 'SubsWiki'] - - def search(self, files = [], languages = []): - - # download subtitles - with subliminal.Subliminal(cache_dir = Env.get('cache_dir'), multi = True, - languages = self.getLanguages(), plugins = self.plugins) as subli: - subtitles = subli.downloadSubtitles(files) - - print subtitles - - return subtitles