class BaseController: globals = {'url': url, 'Qualities': Qualities(), 'Minify': Minify()} def __init__(self): self.cron = cherrypy.config.get('cron') self.searchers = cherrypy.config.get('searchers') self.flash = self.globals['flash'] = cherrypy.config.get('flash') self.globals['debug'] = cherrypy.config.get('debug') self.globals['updater'] = cherrypy.config.get('updater') self.globals['searchers'] = self.searchers self.globals['cherrypy'] = cherrypy self.globals['config'] = cherrypy.config.get('config') def updateGlobals(self): self.globals['baseUrl'] = base() + '/' self.globals['yarr'] = self.cron.get('yarr') def render(self, list): self.updateGlobals() list.update(self.globals) return list
def find(self, movie, queue): ''' Find movie by name ''' log.debug('Searching for movie: %s' % movie.name) qualities = Qualities() for source in self.sources: results = [] # find by main name type = queue.qualityType results.extend(source.find(movie, type, type)) # Search for alternative naming for alt in qualities.getAlternatives(type): results.extend(source.find(movie, alt, type)) #search for highest score highest = None highestScore = -1000 if results: for result in results: if result.score > highestScore: if not result.checkNZB or self.validNZB(result.url): highest = result highestScore = result.score if highest: return highest return None
def initDb(): log.info('Initializing Database.') # DB exists, do upgrade if os.path.isfile(path): doUpgrade = True else: doUpgrade = False metadata.create_all() # set default qualities from app.lib.qualities import Qualities qu = Qualities() qu.initDefaults() if doUpgrade: upgradeDb() else: for nr in range(1, latestDatabaseVersion + 1): Session.add(DbVersion(nr)) Session.flush()
def save(self, **data): ''' Save all config settings ''' config = cherrypy.config.get('config') # catch checkboxes bools = filter(lambda s: not data.get(s), [ 'global.launchbrowser', 'global.updater', 'XBMC.enabled', 'XBMC.onSnatch', 'NMJ.enabled', 'PLEX.enabled', 'PROWL.enabled', 'PROWL.onSnatch', 'GROWL.enabled', 'GROWL.onSnatch', 'Notifo.enabled', 'Notifo.onSnatch', 'Boxcar.enabled', 'Boxcar.onSnatch', 'NMA.enable', 'NMA.onSnatch', 'Twitter.enabled', 'Twitter.onSnatch', 'Trakt.notification_enabled', 'Trakt.watchlist_remove', 'Trakt.watchlist_enabled', 'Trakt.dontaddcollection', 'Meta.enabled', 'MovieETA.enabled', 'Renamer.enabled', 'Renamer.trailerQuality', 'Renamer.cleanup', 'Torrents.enabled', 'NZB.enabled', 'NZBMatrix.enabled', 'NZBMatrix.english', 'NZBMatrix.ssl', 'NZBsRUS.enabled', 'newzbin.enabled', 'NZBsorg.enabled', 'newznab.enabled', 'x264.enabled', 'Subtitles.enabled', 'Subtitles.addLanguage', 'MovieRSS.enabled', 'KinepolisRSS.enabled', ]) data.update(data.fromkeys(bools, False)) # Do quality order order = data.get('Quality.order').split(',') for id in order: qo = Db.query(QualityTemplate).filter_by(id=int(id)).one() qo.order = order.index(id) Db.flush() del data['Quality.order'] # Save templates if data.get('Quality.templates'): templates = json.loads(data.get('Quality.templates')) Qualities().saveTemplates(templates) del data['Quality.templates'] # Save post data for name in data: section = name.split('.')[0] var = name.split('.')[1] config.set(section, var, data[name]) # Change cron interval self.cron.get('yarr').setInterval(config.get('Intervals', 'search')) config.save() self.flash.add('config', 'Settings successfully saved.') return redirect(cherrypy.request.headers.get('referer'))
def getMovies(self, folder=None, withMeta=True): log.debug('getMoviesStart') movies = [] qualities = Qualities() movieFolder = unicode(folder) if folder else self.config.get( 'Renamer', 'destination') if not os.path.isdir(movieFolder): log.error('Can\'t find directory: %s' % movieFolder) return movies log.debug('os.walk(movieFolder) %s' % movieFolder) # Walk the tree once to catch any UnicodeDecodeErrors that might arise # from malformed file and directory names. Use the non-unicode version # of movieFolder if so. try: for x in os.walk(movieFolder): pass walker = os.walk(movieFolder) except UnicodeDecodeError: walker = os.walk(str(movieFolder)) for root, subfiles, filenames in walker: if self.abort: log.debug('Aborting moviescan') return movies movie = { 'movie': None, 'queue': 0, 'match': False, 'meta': {}, 'info': { 'name': None, 'cpnfoImdb': None, 'ppScriptName': None, 'imdb': None, 'year': None, 'quality': '', 'resolution': None, 'sourcemedia': '', 'size': 0, 'codec': { 'video': '', 'audio': '' }, 'group': '' }, 'history': None, 'path': root, 'folder': root.split(os.path.sep)[-1:].pop(), 'nfo': [], 'files': [], 'trailer': [], 'cpnfo': None, 'subtitles': { 'files': [], 'extras': [] } } if movie['folder'] == 'VIDEO_TS': movie['folder'] = movie['path'].split(os.path.sep)[-2:-1].pop() patterns = [] for extType in self.extensions.itervalues(): patterns.extend(extType) for pattern in patterns: for filename in fnmatch.filter(sorted(filenames), pattern): fullFilePath = os.path.join(root, filename) log.debug('Processing file: %s' % fullFilePath) new = { 'filename': filename, 'ext': os.path.splitext(filename)[1].lower() [1:], #[1:]to remove . from extension } #cpnfo if new.get('filename') in self.extensions['cpnfo']: movie['cpnfo'] = new.get('filename') #nfo file if ('*.' + new.get('ext') in self.extensions['nfo']): movie['nfo'].append(filename) #subtitle file elif ('*.' + new.get('ext') in self.extensions['subtitle']): movie['subtitles']['files'].append(new) #idx files elif ('*.' + new.get('ext') in self.extensions['subtitleExtras']): movie['subtitles']['extras'].append(new) #trailer file elif re.search('(^|[\W_])trailer\d*[\W_]', filename.lower()) and self.filesizeBetween( fullFilePath, 2, 250): movie['trailer'].append(new) else: #ignore movies files / or not if self.keepFile(fullFilePath): log.debug('self.keepFile(fullFilePath)') new['hash'] = hashFile( fullFilePath) # Add movie hash new['size'] = os.path.getsize( fullFilePath) # File size movie['files'].append(new) if movie['files']: log.debug('Files found') #Find movie by cpnfo if movie['cpnfo']: log.debug('Scanning cpnfo') cpnfoFile = open( os.path.join(movie['path'], movie['cpnfo']), 'r').readlines() cpnfoFile = [x.strip() for x in cpnfoFile] movie['info']['ppScriptName'] = cpnfoFile[0] movie['info']['cpnfoImdb'] = cpnfoFile[1] # Find movie by nfo if movie['nfo']: log.debug('Scanning nfo') for nfo in movie['nfo']: nfoFile = open(os.path.join(movie['path'], nfo), 'r').read() movie['info']['imdb'] = self.getImdb(nfoFile) # Find movie via files log.debug('self.determineMovie(movie)') movie['movie'] = self.determineMovie(movie) if movie['movie']: movie['match'] = True log.debug('self.getHistory(movie[movie])') movie['history'] = self.getHistory(movie['movie']) movie['queue'] = self.getQueue(movie['movie']) movie['info']['name'] = movie['movie'].name movie['info']['year'] = movie['movie'].year try: movie['info']['quality'] = qualities.types.get( movie['queue'].qualityType).get('label') except: movie['info']['quality'] = qualities.guess([ os.path.join(movie['path'], file['filename']) for file in movie['files'] ]) for file in movie['files']: movie['info']['size'] += file['size'] movie['info']['size'] = str(movie['info']['size']) movie['info']['group'] = self.getGroup(movie['folder']) movie['info']['codec']['video'] = self.getCodec( movie['folder'], self.codecs['video']) movie['info']['codec']['audio'] = self.getCodec( movie['folder'], self.codecs['audio']) #get metainfo about file if withMeta: log.debug('self.getHistory(movie[movie])') testFile = os.path.join(movie['path'], movie['files'][0]['filename']) try: movie['meta'].update(self.getMeta(testFile)) except: pass #check the video file for its resolution if movie['meta'].has_key('video stream'): width = movie['meta']['video stream'][0][ 'image width'] height = movie['meta']['video stream'][0][ 'image height'] if width and height: if width > 1900 and width < 2000 and height <= 1080: namedResolution = '1080p' elif width > 1200 and width < 1300 and height <= 720: namedResolution = '720p' else: namedResolution = None else: log.info( "Unable to fetch audio/video details for %s" % testFile) namedResolution = None movie['info']['resolution'] = namedResolution movie['info']['sourcemedia'] = self.getSourceMedia( testFile) # Create filename without cd1/cd2 etc log.debug('removeMultipart') movie['filename'] = self.removeMultipart( os.path.splitext(movie['files'][0]['filename'])[0]) # Give back ids, not table rows if self.noTables: log.debug('self.noTables') movie['history'] = [ h.id for h in movie['history'] ] if movie['history'] else movie['history'] movie['movie'] = movie['movie'].id if movie[ 'movie'] else movie['movie'] log.debug('movies.append(movie)') movies.append(movie) log.debug('getMoviesEnd') return movies
def isCorrectMovie(self, item, movie, qualityType, imdbResults=False, singleCategory=False): # Ignore already added. #if self.alreadyTried(item, movie.id): # log.info('Already tried this one, ignored: %s' % item.name) # return False def get_words(text): return filter(None, re.split('\W+', text.lower())) nzbWords = get_words(item.name) requiredWords = self.config.get('global', 'requiredWords').split(',') # missing = set(requiredWords) - set(nzbWords) missing = True for word in requiredWords: if word.strip() and word.strip().lower() in nzbWords: missing = False if missing: log.info("NZB '%s' misses the required words" % (item.name)) return False ignoredWords = get_words(self.config.get('global', 'ignoreWords')) blacklisted = set(ignoredWords).intersection(set(nzbWords)) if blacklisted: log.info("NZB '%s' contains the following blacklisted words: %s" % (item.name, ", ".join(blacklisted))) return False q = Qualities() type = q.types.get(qualityType) # Contains lower quality string if self.containsOtherQuality(item.name, type, singleCategory): log.info('Wrong: %s, contains other quality, looking for %s' % (item.name, type['label'])) return False # Outsize retention if item.type is 'nzb': if item.date < time.time() - ( int(self.config.get('NZB', 'retention')) * 24 * 60 * 60): log.info('Found but outside %s retention: %s' % (self.config.get('NZB', 'retention'), item.name)) return False # File to small minSize = q.minimumSize(qualityType) if minSize > item.size: log.info( '"%s" is too small to be %s. %sMB instead of the minimal of %sMB.' % (item.name, type['label'], item.size, minSize)) return False # File to large maxSize = q.maximumSize(qualityType) if maxSize < item.size: log.info( '"%s" is too large to be %s. %sMB instead of the maximum of %sMB.' % (item.name, type['label'], item.size, maxSize)) return False if imdbResults: return True # Check if nzb contains imdb link if self.checkIMDB([item.content], movie.imdb): return True # if no IMDB link, at least check year range 1 if len(movie.name.split(' ')) > 2 and self.correctYear( [item.name], movie.year, 1) and self.correctName( item.name, movie.name): return True # if no IMDB link, at least check year if len(movie.name.split(' ')) == 2 and self.correctYear( [item.name], movie.year, 0) and self.correctName( item.name, movie.name): return True log.info("Wrong: %s, undetermined naming. Looking for '%s (%s)'" % (item.name, movie.name, movie.year)) return False