Browse Source

Searcher and scanner fixes

pull/62/head
Ruud 14 years ago
parent
commit
5f23a16fae
  1. 2
      couchpotato/core/plugins/quality/main.py
  2. 17
      couchpotato/core/plugins/renamer/__init__.py
  3. 69
      couchpotato/core/plugins/renamer/main.py
  4. 40
      couchpotato/core/plugins/scanner/main.py
  5. 8
      couchpotato/core/plugins/searcher/main.py
  6. 4
      couchpotato/core/providers/movie/imdbapi/__init__.py

2
couchpotato/core/plugins/quality/main.py

@ -136,7 +136,7 @@ class QualityPlugin(Plugin):
def guess(self, files, extra = {}, loose = False): def guess(self, files, extra = {}, loose = False):
for file in files: for file in files:
size = (os.path.getsize(file) / 1024 / 1024) size = (os.path.getsize(file) / 1024 / 1024) if os.path.isfile(file) else 0
words = re.split('\W+', file.lower()) words = re.split('\W+', file.lower())
for quality in self.all(): for quality in self.all():

17
couchpotato/core/plugins/renamer/__init__.py

@ -30,7 +30,7 @@ config = [{
{ {
'name': 'folder_name', 'name': 'folder_name',
'label': 'Folder naming', 'label': 'Folder naming',
'description': 'Name of the folder', 'description': 'Name of the folder. Keep empty for no folder.',
'default': '<namethe> (<year>)', 'default': '<namethe> (<year>)',
}, },
{ {
@ -40,6 +40,19 @@ config = [{
'default': '<thename><cd>.<ext>', 'default': '<thename><cd>.<ext>',
}, },
{ {
'name': 'cleanup',
'type': 'bool',
'description': 'Cleanup leftover files after successful rename.',
'default': False,
},
{
'name': 'move_leftover',
'type': 'bool',
'description': 'Move all leftover file after renaming, to the movie folder.',
'default': False,
'advanced': True,
},
{
'advanced': True, 'advanced': True,
'name': 'separator', 'name': 'separator',
'label': 'Separator', 'label': 'Separator',
@ -72,7 +85,7 @@ config = [{
{ {
'name': 'nfo_name', 'name': 'nfo_name',
'label': 'NFO naming', 'label': 'NFO naming',
'default': '<filename>.<ext>-orig', 'default': '<filename>.orig.<ext>',
}, },
{ {
'name': 'trailer_name', 'name': 'trailer_name',

69
couchpotato/core/plugins/renamer/main.py

@ -4,7 +4,7 @@ from couchpotato.core.helpers.encoding import toUnicode
from couchpotato.core.helpers.variable import getExt from couchpotato.core.helpers.variable import getExt
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.plugins.base import Plugin from couchpotato.core.plugins.base import Plugin
from couchpotato.core.settings.model import Library, Movie from couchpotato.core.settings.model import Library
import os.path import os.path
import re import re
import shutil import shutil
@ -15,6 +15,8 @@ log = CPLog(__name__)
class Renamer(Plugin): class Renamer(Plugin):
renaming_started = False
def __init__(self): def __init__(self):
addEvent('renamer.scan', self.scan) addEvent('renamer.scan', self.scan)
@ -27,6 +29,10 @@ class Renamer(Plugin):
if self.isDisabled(): if self.isDisabled():
return return
if self.renaming_started is True:
log.error('Renamer is disabled to avoid infinite looping of the same error.')
return
# Check to see if the "to" folder is inside the "from" folder. # Check to see if the "to" folder is inside the "from" folder.
if self.conf('from') in self.conf('to'): if self.conf('from') in self.conf('to'):
log.error('The "to" can\'t be inside of the "from" folder. You\'ll get an infinite loop.') log.error('The "to" can\'t be inside of the "from" folder. You\'ll get an infinite loop.')
@ -35,11 +41,12 @@ class Renamer(Plugin):
groups = fireEvent('scanner.scan', folder = self.conf('from'), single = True) groups = fireEvent('scanner.scan', folder = self.conf('from'), single = True)
if groups is None: return if groups is None: return
self.renaming_started = True
destination = self.conf('to') destination = self.conf('to')
folder_name = self.conf('folder_name') folder_name = self.conf('folder_name')
file_name = self.conf('file_name') file_name = self.conf('file_name')
trailer_name = self.conf('trailer_name') trailer_name = self.conf('trailer_name')
backdrop_name = self.conf('fanart_name')
nfo_name = self.conf('nfo_name') nfo_name = self.conf('nfo_name')
separator = self.conf('separator') separator = self.conf('separator')
@ -47,6 +54,8 @@ class Renamer(Plugin):
group = groups[group_identifier] group = groups[group_identifier]
rename_files = {} rename_files = {}
remove_files = []
remove_releases = []
# Add _UNKNOWN_ if no library item is connected # Add _UNKNOWN_ if no library item is connected
if not group['library']: if not group['library']:
@ -159,6 +168,9 @@ class Renamer(Plugin):
# Do rename others # Do rename others
else: else:
if self.conf('move_leftover') and file_type is 'leftover':
rename_files[file] = os.path.join(destination, final_folder_name, os.path.basename(file))
else:
rename_files[file] = os.path.join(destination, final_folder_name, final_file_name) rename_files[file] = os.path.join(destination, final_folder_name, final_file_name)
# Check for extra subtitle files # Check for extra subtitle files
@ -203,19 +215,21 @@ class Renamer(Plugin):
# Go over current movie releases # Go over current movie releases
for release in movie.releases: for release in movie.releases:
# When a release already exists
if release.status_id is done_status.get('id'):
# This is where CP removes older, lesser quality releases # This is where CP removes older, lesser quality releases
if release.quality.order > group['meta_data']['quality']['order']: if release.quality.order > group['meta_data']['quality']['order']:
log.info('Removing older release for %s, with quality %s' % (movie.library.titles[0].title, release.quality.label)) log.info('Removing lesser quality %s for %s.' % (movie.library.titles[0].title, release.quality.label))
for file in release.files: for file in release.files:
log.info('Removing (not really) "%s"' % file.path) remove_files.append(file)
remove_releases.append(release)
# When a release already exists
elif release.status_id is done_status.get('id'):
# Same quality, but still downloaded, so maybe repack/proper/unrated/directors cut etc # Same quality, but still downloaded, so maybe repack/proper/unrated/directors cut etc
if release.quality.order is group['meta_data']['quality']['order']: elif release.quality.order is group['meta_data']['quality']['order']:
log.info('Same quality release already exists for %s, with quality %s. Assuming repack.' % (movie.library.titles[0].title, release.quality.label)) log.info('Same quality release already exists for %s, with quality %s. Assuming repack.' % (movie.library.titles[0].title, release.quality.label))
for file in release.files:
remove_files.append(file)
remove_releases.append(release)
# Downloaded a lower quality, rename the newly downloaded files/folder to exclude them from scan # Downloaded a lower quality, rename the newly downloaded files/folder to exclude them from scan
else: else:
@ -237,26 +251,39 @@ class Renamer(Plugin):
break break
# Remove leftover files
if self.conf('cleanup') and not self.conf('move_leftover'):
log.debug('Removing leftover files')
for file in group['files']['leftover']:
remove_files.append(file)
# Rename all files marked # Rename all files marked
for src in rename_files: for src in rename_files:
if rename_files[src]: if rename_files[src]:
dst = rename_files[src] dst = rename_files[src]
log.info('Renaming "%s" to "%s"' % (src, dst)) log.info('Renaming "%s" to "%s"' % (src, dst))
path = os.path.dirname(dst)
# Create dir # Create dir
self.makeDir(path) self.makeDir(os.path.dirname(dst))
try: try:
pass self.moveFile(src, dst)
#shutil.move(src, dst)
except: except:
log.error('Failed moving the file "%s" : %s' % (os.path.basename(src), traceback.format_exc())) log.error('Failed moving the file "%s" : %s' % (os.path.basename(src), traceback.format_exc()))
#print rename_me, rename_files[rename_me] # Remove files
for src in remove_files:
log.info('Removing "%s"' % src)
# Remove matching releases
for release in remove_releases:
log.info('Removing release %s' % release)
# Add this release to the library
if not group['destination_dir'] is destination:
fireEventAsync('scanner.to_library', folder = group['destination_dir'])
else:
log.error('Single destination folder not fully supported yet.')
# Search for trailers etc # Search for trailers etc
fireEventAsync('renamer.after', group) fireEventAsync('renamer.after', group)
@ -269,12 +296,14 @@ class Renamer(Plugin):
if self.shuttingDown(): if self.shuttingDown():
break break
def moveFile(self, old, dest, suppress = True): self.renaming_started = False
def moveFile(self, old, dest):
try: try:
shutil.move(old, dest) shutil.move(old, dest)
except: except:
log.error("Couldn't move file '%s' to '%s': %s" % (old, dest, traceback.format_exc())) log.error("Couldn't move file '%s' to '%s': %s" % (old, dest, traceback.format_exc()))
return False raise Exception
return True return True

40
couchpotato/core/plugins/scanner/main.py

@ -69,14 +69,16 @@ class Scanner(Plugin):
def __init__(self): def __init__(self):
#addEvent('app.load', self.scanLibrary)
addEvent('scanner.create_file_identifier', self.createStringIdentifier) addEvent('scanner.create_file_identifier', self.createStringIdentifier)
addEvent('scanner.scan', self.scan) addEvent('scanner.scan', self.scan)
addEvent('scanner.to_library', self.scanToLibrary)
addEvent('scanner.name_year', self.getReleaseNameYear)
def scanLibrary(self): def scanToLibrary(self, folder = None, files = []):
folder = '/Volumes/Media/Test/' if not os.path.isdir(folder):
return
groups = self.scan(folder = folder) groups = self.scan(folder = folder)
@ -223,6 +225,7 @@ class Scanner(Plugin):
# Leftover "sorted" files # Leftover "sorted" files
for type in group['files']: for type in group['files']:
if not type is 'leftover':
group['files']['leftover'] -= set(group['files'][type]) group['files']['leftover'] -= set(group['files'][type])
# Delete the unsorted list # Delete the unsorted list
@ -463,12 +466,17 @@ class Scanner(Plugin):
# groups, release tags, scenename cleaner, regex isn't correct # groups, release tags, scenename cleaner, regex isn't correct
identifier = re.sub(self.clean, '::', simplifyString(identifier)) identifier = re.sub(self.clean, '::', simplifyString(identifier))
# Year
year = self.findYear(identifier) year = self.findYear(identifier)
if year: if year:
identifier = '%s %s' % (identifier.split(year)[0].strip(), year) identifier = '%s %s' % (identifier.split(year)[0].strip(), year)
else: else:
identifier = identifier.split('::')[0] identifier = identifier.split('::')[0]
# Quality
quality = fireEvent('quality.guess', [file_path], single = True)
identifier += ' %s' % quality.get('identifier', '')
# Remove duplicates # Remove duplicates
out = [] out = []
for word in identifier.split(): for word in identifier.split():
@ -530,3 +538,29 @@ class Scanner(Plugin):
return matches.group('year') return matches.group('year')
return '' return ''
def getReleaseNameYear(self, release_name):
cleaned = ' '.join(re.split('\W+', simplifyString(release_name)))
cleaned = re.sub(self.clean, ' ', cleaned)
year = self.findYear(cleaned)
if year: # Split name on year
try:
movie_name = cleaned.split(year).pop(0).strip()
return {
'name': movie_name,
'year': year,
}
except:
pass
else: # Split name on multiple spaces
try:
movie_name = cleaned.split(' ').pop(0).strip()
return {
'name': movie_name,
'year': year,
}
except:
pass
return {}

8
couchpotato/core/plugins/searcher/main.py

@ -194,7 +194,7 @@ class Searcher(Plugin):
return True return True
# if no IMDB link, at least check year # if no IMDB link, at least check year
if len(movie_words) == 2 and self.correctYear([nzb['name']], movie['library']['year'], 0): if len(movie_words) <= 2 and self.correctYear([nzb['name']], movie['library']['year'], 0):
return True return True
log.info("Wrong: %s, undetermined naming. Looking for '%s (%s)'" % (nzb['name'], movie['library']['titles'][0]['title'], movie['library']['year'])) log.info("Wrong: %s, undetermined naming. Looking for '%s (%s)'" % (nzb['name'], movie['library']['titles'][0]['title'], movie['library']['year']))
@ -244,7 +244,9 @@ class Searcher(Plugin):
def correctName(self, check_name, movie_name): def correctName(self, check_name, movie_name):
check_words = re.split('\W+', simplifyString(check_name)) check_movie = fireEvent('scanner.name_year', check_name, single = True)
check_words = re.split('\W+', check_movie.get('name', ''))
movie_words = re.split('\W+', simplifyString(movie_name)) movie_words = re.split('\W+', simplifyString(movie_name))
return len(list(set(check_words) & set(movie_words))) == len(movie_words) return len(list(set(check_words) - set(movie_words))) == 0

4
couchpotato/core/providers/movie/imdbapi/__init__.py

@ -1,6 +1,6 @@
from .main import IMDB from .main import IMDBAPI
def start(): def start():
return IMDB() return IMDBAPI()
config = [] config = []

Loading…
Cancel
Save