Cli implimintation #3
46
src/core.py
46
src/core.py
@@ -19,6 +19,7 @@ from titlecase import titlecase
|
|||||||
import langdetect
|
import langdetect
|
||||||
|
|
||||||
import env_variables as env
|
import env_variables as env
|
||||||
|
from exceptions import InsufficientInfoError
|
||||||
|
|
||||||
from video import VIDEO_EXTENSIONS, Episode, Movie, Video
|
from video import VIDEO_EXTENSIONS, Episode, Movie, Video
|
||||||
from subtitle import SUBTITLE_EXTENSIONS, Subtitle, get_subtitle_path
|
from subtitle import SUBTITLE_EXTENSIONS, Subtitle, get_subtitle_path
|
||||||
@@ -95,8 +96,8 @@ def scan_video(path):
|
|||||||
# guess
|
# guess
|
||||||
video = Video.fromguess(path, guessit(path))
|
video = Video.fromguess(path, guessit(path))
|
||||||
|
|
||||||
if video.sufficientInfo():
|
video.subtitles |= set(search_external_subtitles(video.name))
|
||||||
video.setMoveLocation()
|
refine(video)
|
||||||
|
|
||||||
# hash of name
|
# hash of name
|
||||||
# if isinstance(video, Movie):
|
# if isinstance(video, Movie):
|
||||||
@@ -260,7 +261,7 @@ def save_subtitles(files, single=False, directory=None, encoding=None):
|
|||||||
|
|
||||||
def scan_folder(path):
|
def scan_folder(path):
|
||||||
videos = []
|
videos = []
|
||||||
ignored_videos = []
|
insufficient_info = []
|
||||||
errored_paths = []
|
errored_paths = []
|
||||||
logger.debug('Collecting path %s', path)
|
logger.debug('Collecting path %s', path)
|
||||||
|
|
||||||
@@ -274,41 +275,39 @@ def scan_folder(path):
|
|||||||
# if path is a file
|
# if path is a file
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
logger.info('Path is a file')
|
logger.info('Path is a file')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
video = scan_video(path)
|
video = scan_video(path)
|
||||||
except:
|
videos.append(video)
|
||||||
logger.exception('Unexpected error while collection file with path {}'.format(path))
|
|
||||||
|
|
||||||
video.subtitles |= set(search_external_subtitles(video.name))
|
except InsufficientInfoError as e:
|
||||||
|
logger.error(e)
|
||||||
refine(video)
|
insufficient_info.append(path)
|
||||||
videos.append(video)
|
|
||||||
|
|
||||||
# directories
|
# directories
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
logger.info('Path is a directory')
|
logger.info('Path is a directory')
|
||||||
|
|
||||||
|
scanned_videos = []
|
||||||
try:
|
try:
|
||||||
scanned_videos = scan_videos(path)
|
scanned_videos = scan_videos(path)
|
||||||
|
except InsufficientInfoError as e:
|
||||||
|
logger.error(e)
|
||||||
|
insufficient_info.append(path)
|
||||||
except:
|
except:
|
||||||
logger.exception('Unexpected error while collecting directory path %s', path)
|
logger.exception('Unexpected error while collecting directory path %s', path)
|
||||||
errored_paths.append(path)
|
errored_paths.append(path)
|
||||||
|
|
||||||
# Iterates over our scanned videos
|
click.echo('%s video%s collected / %s file%s with insufficient info / %s error%s' % (
|
||||||
with click.progressbar(scanned_videos, label='Parsing videos') as bar:
|
|
||||||
for v in bar:
|
|
||||||
v.subtitles |= set(search_external_subtitles(v.name))
|
|
||||||
refine(v)
|
|
||||||
videos.append(v)
|
|
||||||
video.size = find_file_size()
|
|
||||||
|
|
||||||
click.echo('%s video%s collected / %s error%s' % (
|
|
||||||
click.style(str(len(videos)), bold=True, fg='green' if videos else None),
|
click.style(str(len(videos)), bold=True, fg='green' if videos else None),
|
||||||
's' if len(videos) > 1 else '',
|
's' if len(videos) > 1 else '',
|
||||||
|
click.style(str(len(insufficient_info)), bold=True, fg='yellow' if insufficient_info else None),
|
||||||
|
's' if len(insufficient_info) > 1 else '',
|
||||||
click.style(str(len(errored_paths)), bold=True, fg='red' if errored_paths else None),
|
click.style(str(len(errored_paths)), bold=True, fg='red' if errored_paths else None),
|
||||||
's' if len(errored_paths) > 1 else '',
|
's' if len(errored_paths) > 1 else '',
|
||||||
))
|
))
|
||||||
|
|
||||||
return videos
|
return videos, insufficient_info
|
||||||
|
|
||||||
def pickforgirlscouts(video):
|
def pickforgirlscouts(video):
|
||||||
if video.sufficientInfo():
|
if video.sufficientInfo():
|
||||||
@@ -318,19 +317,20 @@ def pickforgirlscouts(video):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def moveHome(video):
|
def moveHome(video):
|
||||||
dir = os.path.dirname(video.home)
|
wantedFilePath = video.wantedFilePath()
|
||||||
|
dir = os.path.dirname(wantedFilePath)
|
||||||
|
|
||||||
if not os.path.exists(dir):
|
if not os.path.exists(dir):
|
||||||
logger.info('Creating directory {}'.format(dir))
|
logger.info('Creating directory {}'.format(dir))
|
||||||
os.makedirs(dir)
|
os.makedirs(dir)
|
||||||
|
|
||||||
logger.info("Moving video file from: '{}' to: '{}'".format(video.name, video.home))
|
logger.info("Moving video file from: '{}' to: '{}'".format(video.name, wantedFilePath))
|
||||||
shutil.move(video.name, video.home)
|
shutil.move(video.name, wantedFilePath)
|
||||||
for sub in video.subtitles:
|
for sub in video.subtitles:
|
||||||
if not os.path.isfile(sub):
|
if not os.path.isfile(sub):
|
||||||
continue
|
continue
|
||||||
oldpath = sub
|
oldpath = sub
|
||||||
newpath = subtitle_path(video.home, sub)
|
newpath = subtitle_path(wantedFilePath, sub)
|
||||||
logger.info("Moving subtitle file from: '{}' to: '{}'".format(oldpath, newpath))
|
logger.info("Moving subtitle file from: '{}' to: '{}'".format(oldpath, newpath))
|
||||||
shutil.move(oldpath, newpath)
|
shutil.move(oldpath, newpath)
|
||||||
|
|
||||||
|
|||||||
28
src/video.py
28
src/video.py
@@ -12,6 +12,7 @@ from titlecase import titlecase
|
|||||||
import hashlib, tvdb_api
|
import hashlib, tvdb_api
|
||||||
|
|
||||||
import env_variables as env
|
import env_variables as env
|
||||||
|
from exceptions import InsufficientInfoError
|
||||||
|
|
||||||
logger = logging.getLogger('seasonedParser')
|
logger = logging.getLogger('seasonedParser')
|
||||||
|
|
||||||
@@ -160,7 +161,7 @@ class Episode(Video):
|
|||||||
raise ValueError('The guess must be an episode guess')
|
raise ValueError('The guess must be an episode guess')
|
||||||
|
|
||||||
if 'title' not in guess or 'season' not in guess or 'episode' not in guess:
|
if 'title' not in guess or 'season' not in guess or 'episode' not in guess:
|
||||||
raise ValueError('Insufficient data to process the guess')
|
raise InsufficientInfoError('Insufficient data to process the guess')
|
||||||
|
|
||||||
return cls(name, guess['title'], guess.get('season', 1), guess['episode'], title=guess.get('episode_title'),
|
return cls(name, guess['title'], guess.get('season', 1), guess['episode'], title=guess.get('episode_title'),
|
||||||
year=guess.get('year'), format=guess.get('format'), original_series='year' not in guess,
|
year=guess.get('year'), format=guess.get('format'), original_series='year' not in guess,
|
||||||
@@ -171,26 +172,11 @@ class Episode(Video):
|
|||||||
def fromname(cls, name):
|
def fromname(cls, name):
|
||||||
return cls.fromguess(name, guessit(name, {'type': 'episode'}))
|
return cls.fromguess(name, guessit(name, {'type': 'episode'}))
|
||||||
|
|
||||||
def sufficientInfo(self):
|
def wantedFilePath(self):
|
||||||
ser = hasattr(self, 'series')
|
|
||||||
sea = hasattr(self, 'season')
|
|
||||||
ep = hasattr(self, 'episode')
|
|
||||||
|
|
||||||
if False in [ser, sea, ep]:
|
|
||||||
logger.error('{}, {} or {} found to have none value, manual correction required'.format(self.series, self.season, self.episode))
|
|
||||||
return False
|
|
||||||
|
|
||||||
if list in [type(self.series), type(self.season), type(self.episode)]:
|
|
||||||
logger.error('{}, {} or {} found to have list values, manual correction required'.format(self.series, self.season, self.episode))
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def setMoveLocation(self):
|
|
||||||
series = titlecase(self.series)
|
series = titlecase(self.series)
|
||||||
grandParent = '{}/{} Season {:02d}'.format(series, series, self.season)
|
grandParent = '{}/{} Season {:02d}'.format(series, series, self.season)
|
||||||
parent = '{} S{:02d}E{:02d}'.format(series, self.season, self.episode)
|
parent = '{} S{:02d}E{:02d}'.format(series, self.season, self.episode)
|
||||||
self.move_location = os.path.join(env.SHOWBASE, grandParent, parent, os.path.basename(self.name))
|
return os.path.join(env.SHOWBASE, grandParent, parent, os.path.basename(self.name))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.year is None:
|
if self.year is None:
|
||||||
@@ -221,7 +207,7 @@ class Movie(Video):
|
|||||||
raise ValueError('The guess must be a movie guess')
|
raise ValueError('The guess must be a movie guess')
|
||||||
|
|
||||||
if 'title' not in guess or 'year' not in guess:
|
if 'title' not in guess or 'year' not in guess:
|
||||||
raise ValueError('Insufficient data to process the guess')
|
raise InsufficientInfoError('Insufficient data to process the guess')
|
||||||
|
|
||||||
return cls(name, guess['title'], format=guess.get('format'), release_group=guess.get('release_group'),
|
return cls(name, guess['title'], format=guess.get('format'), release_group=guess.get('release_group'),
|
||||||
resolution=guess.get('screen_size'), video_codec=guess.get('video_codec'),
|
resolution=guess.get('screen_size'), video_codec=guess.get('video_codec'),
|
||||||
@@ -244,10 +230,10 @@ class Movie(Video):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def setMoveLocation(self):
|
def wantedFilePath(self):
|
||||||
title = titlecase(self.title)
|
title = titlecase(self.title)
|
||||||
parent = '{} ({})'.format(title, self.year)
|
parent = '{} ({})'.format(title, self.year)
|
||||||
self.move_location = os.path.join(env.MOVIEBASE, parent, os.path.basename(self.name))
|
return os.path.join(env.MOVIEBASE, parent, os.path.basename(self.name))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.year is None:
|
if self.year is None:
|
||||||
|
|||||||
Reference in New Issue
Block a user