280 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			280 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python3.6
 | 
						|
# -*- coding: utf-8 -*-
 | 
						|
# @Author: KevinMidboe
 | 
						|
# @Date:   2017-08-25 23:22:27
 | 
						|
# @Last Modified by:   KevinMidboe
 | 
						|
# @Last Modified time: 2017-10-12 22:44:27
 | 
						|
 | 
						|
from guessit import guessit
 | 
						|
import os, errno
 | 
						|
import logging
 | 
						|
import tvdb_api
 | 
						|
from pprint import pprint
 | 
						|
 | 
						|
import env_variables as env
 | 
						|
 | 
						|
from video import VIDEO_EXTENSIONS, Episode, Movie, Video
 | 
						|
from subtitle import SUBTITLE_EXTENSIONS, Subtitle, get_subtitle_path
 | 
						|
from utils import sanitize
 | 
						|
 | 
						|
logging.basicConfig(filename=os.path.dirname(__file__) + '/' + env.logfile, level=logging.INFO)
 | 
						|
 | 
						|
from datetime import datetime
 | 
						|
 | 
						|
#: Supported archive extensions
 | 
						|
ARCHIVE_EXTENSIONS = ('.rar',)
 | 
						|
 | 
						|
def scan_video(path):
 | 
						|
    """Scan a video from a `path`.
 | 
						|
 | 
						|
    :param str path: existing path to the video.
 | 
						|
    :return: the scanned video.
 | 
						|
    :rtype: :class:`~subliminal.video.Video`
 | 
						|
 | 
						|
    """
 | 
						|
    # check for non-existing path
 | 
						|
    if not os.path.exists(path):
 | 
						|
        raise ValueError('Path does not exist')
 | 
						|
 | 
						|
    # check video extension
 | 
						|
    # if not path.endswith(VIDEO_EXTENSIONS):
 | 
						|
    #     raise ValueError('%r is not a valid video extension' % os.path.splitext(path)[1])
 | 
						|
 | 
						|
    dirpath, filename = os.path.split(path)
 | 
						|
    logging.info('Scanning video %r in %r', filename, dirpath)
 | 
						|
 | 
						|
    # guess
 | 
						|
    parent_path = path.strip(filename)
 | 
						|
    # video = Video.fromguess(filename, parent_path, guessit(path))
 | 
						|
    video = Video(filename)
 | 
						|
    # guessit(path)
 | 
						|
 | 
						|
    return video
 | 
						|
 | 
						|
 | 
						|
def scan_subtitle(path):
 | 
						|
   if not os.path.exists(path):
 | 
						|
      raise ValueError('Path does not exist')
 | 
						|
 | 
						|
   dirpath, filename = os.path.split(path)
 | 
						|
   logging.info('Scanning subtitle %r in %r', filename, dirpath)
 | 
						|
 | 
						|
   # guess
 | 
						|
   parent_path = path.strip(filename)
 | 
						|
   subtitle = Subtitle.fromguess(filename, parent_path, guessit(path))
 | 
						|
 | 
						|
 | 
						|
   return subtitle
 | 
						|
 | 
						|
 | 
						|
def scan_files(path, age=None, archives=True):
 | 
						|
    """Scan `path` for videos and their subtitles.
 | 
						|
 | 
						|
    See :func:`refine` to find additional information for the video.
 | 
						|
 | 
						|
    :param str path: existing directory path to scan.
 | 
						|
    :param datetime.timedelta age: maximum age of the video or archive.
 | 
						|
    :param bool archives: scan videos in archives.
 | 
						|
    :return: the scanned videos.
 | 
						|
    :rtype: list of :class:`~subliminal.video.Video`
 | 
						|
 | 
						|
    """
 | 
						|
    # check for non-existing path
 | 
						|
    if not os.path.exists(path):
 | 
						|
        raise ValueError('Path does not exist')
 | 
						|
 | 
						|
    # check for non-directory path
 | 
						|
    if not os.path.isdir(path):
 | 
						|
        raise ValueError('Path is not a directory')
 | 
						|
 | 
						|
    name_dict = {}
 | 
						|
 | 
						|
    # walk the path
 | 
						|
    mediafiles = []
 | 
						|
    for dirpath, dirnames, filenames in os.walk(path):
 | 
						|
        logging.debug('Walking directory %r', dirpath)
 | 
						|
 | 
						|
        # remove badly encoded and hidden dirnames
 | 
						|
        for dirname in list(dirnames):
 | 
						|
            if dirname.startswith('.'):
 | 
						|
                logging.debug('Skipping hidden dirname %r in %r', dirname, dirpath)
 | 
						|
                dirnames.remove(dirname)
 | 
						|
 | 
						|
        # scan for videos
 | 
						|
        for filename in filenames:
 | 
						|
            # filter on videos and archives
 | 
						|
            if not (filename.endswith(VIDEO_EXTENSIONS) or filename.endswith(SUBTITLE_EXTENSIONS) or archives and filename.endswith(ARCHIVE_EXTENSIONS)):
 | 
						|
                continue
 | 
						|
 | 
						|
            # skip hidden files
 | 
						|
            if filename.startswith('.'):
 | 
						|
                logging.debug('Skipping hidden filename %r in %r', filename, dirpath)
 | 
						|
                continue
 | 
						|
 | 
						|
            # reconstruct the file path
 | 
						|
            filepath = os.path.join(dirpath, filename)
 | 
						|
 | 
						|
            # skip links
 | 
						|
            if os.path.islink(filepath):
 | 
						|
                logging.debug('Skipping link %r in %r', filename, dirpath)
 | 
						|
                continue
 | 
						|
 | 
						|
            # skip old files 
 | 
						|
            if age and datetime.utcnow() - datetime.utcfromtimestamp(os.path.getmtime(filepath)) > age:
 | 
						|
                logging.debug('Skipping old file %r in %r', filename, dirpath)
 | 
						|
                continue
 | 
						|
 | 
						|
            # scan
 | 
						|
            if filename.endswith(VIDEO_EXTENSIONS):  # video
 | 
						|
                try:
 | 
						|
                    video = scan_video(filepath)
 | 
						|
                    try:
 | 
						|
                        name_dict[video.series] += 1
 | 
						|
                    except KeyError:
 | 
						|
                        name_dict[video.series] = 0
 | 
						|
                    mediafiles.append(video)
 | 
						|
 | 
						|
                except ValueError:  # pragma: no cover
 | 
						|
                    logging.exception('Error scanning video')
 | 
						|
                    continue
 | 
						|
            elif archives and filename.endswith(ARCHIVE_EXTENSIONS):  # archive
 | 
						|
                print('archive')
 | 
						|
                pass
 | 
						|
            #    try:
 | 
						|
            #        video = scan_archive(filepath)
 | 
						|
            #        mediafiles.append(video)
 | 
						|
            #    except (NotRarFile, RarCannotExec, ValueError):  # pragma: no cover
 | 
						|
            #        logging.exception('Error scanning archive')
 | 
						|
            #        continue
 | 
						|
            elif filename.endswith(SUBTITLE_EXTENSIONS): # subtitle
 | 
						|
                try:
 | 
						|
                    subtitle = scan_subtitle(filepath)
 | 
						|
                    mediafiles.append(subtitle)
 | 
						|
                except ValueError: 
 | 
						|
                    logging.exception('Error scanning subtitle')
 | 
						|
                    continue
 | 
						|
            else:  # pragma: no cover
 | 
						|
                raise ValueError('Unsupported file %r' % filename)
 | 
						|
 | 
						|
 | 
						|
    pprint(name_dict)
 | 
						|
    return mediafiles
 | 
						|
 | 
						|
 | 
						|
def organize_files(path):
 | 
						|
   hashList = {}
 | 
						|
   mediafiles = scan_files(path)
 | 
						|
   # print(mediafiles)
 | 
						|
 | 
						|
   for file in mediafiles:
 | 
						|
        hashList.setdefault(file.__hash__(),[]).append(file)
 | 
						|
         # hashList[file.__hash__()] = file
 | 
						|
 | 
						|
   return hashList
 | 
						|
 | 
						|
 | 
						|
def save_subtitles(files, single=False, directory=None, encoding=None):
 | 
						|
    t = tvdb_api.Tvdb()
 | 
						|
 | 
						|
    if not isinstance(files, list):
 | 
						|
        files = [files]
 | 
						|
 | 
						|
    for file in files:
 | 
						|
        # TODO this should not be done in the loop
 | 
						|
        dirname = "%s S%sE%s" % (file.series, "%02d" % (file.season), "%02d" % (file.episode))
 | 
						|
 | 
						|
        createParentfolder = not dirname in file.parent_path
 | 
						|
        if createParentfolder:
 | 
						|
            dirname = os.path.join(file.parent_path, dirname)
 | 
						|
            print('Created: %s' % dirname)
 | 
						|
            try:
 | 
						|
                os.makedirs(dirname)
 | 
						|
            except OSError as e:
 | 
						|
                if e.errno != errno.EEXIST:
 | 
						|
                    raise
 | 
						|
 | 
						|
        # TODO Clean this !
 | 
						|
        try:
 | 
						|
            tvdb_episode = t[file.series][file.season][file.episode]
 | 
						|
            episode_title = tvdb_episode['episodename']
 | 
						|
        except:
 | 
						|
            episode_title = ''
 | 
						|
 | 
						|
        old = os.path.join(file.parent_path, file.name)
 | 
						|
 | 
						|
        if file.name.endswith(SUBTITLE_EXTENSIONS):
 | 
						|
            lang = file.getLanguage()
 | 
						|
            sdh = '.sdh' if file.sdh else ''
 | 
						|
            filename = "%s S%sE%s %s%s.%s.%s" % (file.series, "%02d" % (file.season), "%02d" % (file.episode), episode_title, sdh, lang, file.container)
 | 
						|
        else:
 | 
						|
            filename = "%s S%sE%s %s.%s" % (file.series, "%02d" % (file.season), "%02d" % (file.episode), episode_title, file.container)
 | 
						|
 | 
						|
        if createParentfolder:
 | 
						|
            newname = os.path.join(dirname, filename)
 | 
						|
        else:
 | 
						|
            newname = os.path.join(file.parent_path, filename)
 | 
						|
 | 
						|
        
 | 
						|
        print('Moved: %s ---> %s' % (old, newname))
 | 
						|
        os.rename(old, newname)
 | 
						|
 | 
						|
        print()
 | 
						|
 | 
						|
 | 
						|
    # for hash in files:
 | 
						|
    #   hashIndex = [files[hash]]
 | 
						|
    #   for hashItems in hashIndex:
 | 
						|
    #      for file in hashItems:
 | 
						|
    #         print(file.series)
 | 
						|
 | 
						|
    # saved_subtitles = []
 | 
						|
    # for subtitle in files:
 | 
						|
    #     # check content
 | 
						|
    #     if subtitle.name is None:
 | 
						|
    #         logging.error('Skipping subtitle %r: no content', subtitle)
 | 
						|
    #         continue
 | 
						|
 | 
						|
    #     # check language
 | 
						|
    #     if subtitle.language in set(s.language for s in saved_subtitles):
 | 
						|
    #         logging.debug('Skipping subtitle %r: language already saved', subtitle)
 | 
						|
    #         continue
 | 
						|
 | 
						|
    #     # create subtitle path
 | 
						|
    #     subtitle_path = get_subtitle_path(video.name, None if single else subtitle.language)
 | 
						|
    #     if directory is not None:
 | 
						|
    #         subtitle_path = os.path.join(directory, os.path.split(subtitle_path)[1])
 | 
						|
 | 
						|
    #     # save content as is or in the specified encoding
 | 
						|
    #     logging.info('Saving %r to %r', subtitle, subtitle_path)
 | 
						|
    #     if encoding is None:
 | 
						|
    #         with io.open(subtitle_path, 'wb') as f:
 | 
						|
    #             f.write(subtitle.content)
 | 
						|
    #     else:
 | 
						|
    #         with io.open(subtitle_path, 'w', encoding=encoding) as f:
 | 
						|
    #             f.write(subtitle.text)
 | 
						|
    #     saved_subtitles.append(subtitle)
 | 
						|
 | 
						|
    #     # check single
 | 
						|
    #     if single:
 | 
						|
    #         break
 | 
						|
 | 
						|
    # return saved_subtitles
 | 
						|
 | 
						|
def stringTime():
 | 
						|
    return str(datetime.now().strftime("%Y-%m-%d %H:%M:%S:%f"))
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    # episodePath = '/Volumes/media/tv/Black Mirror/Black Mirror Season 01/'
 | 
						|
    episodePath = '/Volumes/mainframe/shows/Black Mirror/Black Mirror Season 01/'
 | 
						|
 | 
						|
    t = tvdb_api.Tvdb()
 | 
						|
 | 
						|
    hashList = organize_files(episodePath)
 | 
						|
    pprint(hashList)
 | 
						|
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    main()
 |