diff --git a/couchpotato/core/plugins/file/main.py b/couchpotato/core/plugins/file/main.py index cf2481e..099246f 100644 --- a/couchpotato/core/plugins/file/main.py +++ b/couchpotato/core/plugins/file/main.py @@ -31,17 +31,18 @@ class FileManager(Plugin): def download(self, url = '', dest = None, overwrite = False): + if not dest: # to Cache + dest = os.path.join(Env.get('cache_dir'), '%s.%s' % (md5(url), getExt(url))) + + if not overwrite and os.path.isfile(dest): + return dest + try: filedata = self.urlopen(url) except: return False - if not dest: # to Cache - dest = os.path.join(Env.get('cache_dir'), '%s.%s' % (md5(url), getExt(url))) - - if overwrite or not os.path.isfile(dest): - self.createFile(dest, filedata, binary = True) - + self.createFile(dest, filedata, binary = True) return dest def add(self, path = '', part = 1, type = (), available = 1, properties = {}): diff --git a/couchpotato/core/plugins/library/main.py b/couchpotato/core/plugins/library/main.py index dd29ba5..b5d38d9 100644 --- a/couchpotato/core/plugins/library/main.py +++ b/couchpotato/core/plugins/library/main.py @@ -3,16 +3,16 @@ from couchpotato.core.event import addEvent, fireEventAsync, fireEvent from couchpotato.core.helpers.encoding import toUnicode, simplifyString from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin -from couchpotato.core.settings.model import Library, LibraryTitle, File, \ - LibraryGenre +from couchpotato.core.settings.model import Library, LibraryTitle, File from string import ascii_letters +import json import traceback log = CPLog(__name__) class LibraryPlugin(Plugin): - default_dict = {'titles': {}, 'files':{}, 'info':{}, 'genres':{}} + default_dict = {'titles': {}, 'files':{}} def __init__(self): addEvent('library.add', self.add) @@ -75,6 +75,7 @@ class LibraryPlugin(Plugin): library.tagline = toUnicode(info.get('tagline', '')) library.year = info.get('year', 0) library.status_id = done_status.get('id') + library.info = toUnicode(json.dumps(info)) db.commit() # Titles @@ -93,20 +94,6 @@ class LibraryPlugin(Plugin): db.commit() - # Genres - [db.delete(genre) for genre in library.genres] - db.commit() - - genres = info.get('genres', []) - log.debug('Adding genres: %s' % genres) - for genre in genres: - g = LibraryGenre( - name = toUnicode(genre) - ) - library.genres.append(g) - - db.commit() - # Files images = info.get('images', []) for type in images: diff --git a/couchpotato/core/plugins/movie/main.py b/couchpotato/core/plugins/movie/main.py index ccf3d66..44045ba 100644 --- a/couchpotato/core/plugins/movie/main.py +++ b/couchpotato/core/plugins/movie/main.py @@ -8,7 +8,7 @@ from couchpotato.core.plugins.base import Plugin from couchpotato.core.settings.model import Movie, Library, LibraryTitle from couchpotato.environment import Env from sqlalchemy.orm import joinedload_all -from sqlalchemy.sql.expression import func, or_, asc, not_ +from sqlalchemy.sql.expression import or_, asc, not_ from string import ascii_lowercase from urllib import urlencode @@ -43,7 +43,7 @@ class MoviePlugin(Plugin): def get(self, movie_id): db = get_session() - m = db.query(Movie).filter_by(movie_id = movie_id).first() + m = db.query(Movie).filter_by(id = movie_id).first() return m.to_dict(self.default_dict) diff --git a/couchpotato/core/plugins/movie/static/search.js b/couchpotato/core/plugins/movie/static/search.js index fc26d19..4dedb4c 100644 --- a/couchpotato/core/plugins/movie/static/search.js +++ b/couchpotato/core/plugins/movie/static/search.js @@ -211,7 +211,7 @@ Block.Search.Item = new Class({ if(info.actors){ Object.each(info.actors, function(actor){ new Element('span', { - 'text': actor.name + 'text': actor }).inject(self.starring) }) } diff --git a/couchpotato/core/plugins/scanner/main.py b/couchpotato/core/plugins/scanner/main.py index 5b77dbb..2ddb94c 100644 --- a/couchpotato/core/plugins/scanner/main.py +++ b/couchpotato/core/plugins/scanner/main.py @@ -100,7 +100,7 @@ class Scanner(Plugin): if group['library']: fireEvent('release.add', group = group) - def scanFolderToLibrary(self, folder = None): + def scanFolderToLibrary(self, folder = None, newer_as = None): if not os.path.isdir(folder): return @@ -322,6 +322,7 @@ class Scanner(Plugin): data['audio'] = meta.get('audio', self.getCodec(cur_file, self.codecs['audio'])) data['resolution_width'] = meta.get('resolution_width', 720) data['resolution_height'] = meta.get('resolution_height', 480) + data['aspect'] = meta.get('resolution_width', 720) / meta.get('resolution_height', 480) except: log.debug('Error parsing metadata: %s %s' % (cur_file, traceback.format_exc())) pass @@ -348,8 +349,8 @@ class Scanner(Plugin): return { 'video': p.video[0].codec, 'audio': p.audio[0].codec, - 'resolution_width': p.video[0].width, - 'resolution_height': p.video[0].height, + 'resolution_width': tryInt(p.video[0].width), + 'resolution_height': tryInt(p.video[0].height), } except ParseError: log.debug('Failed to parse meta for %s' % filename) diff --git a/couchpotato/core/providers/metadata/base.py b/couchpotato/core/providers/metadata/base.py index 70338e9..c054026 100644 --- a/couchpotato/core/providers/metadata/base.py +++ b/couchpotato/core/providers/metadata/base.py @@ -1,6 +1,8 @@ from couchpotato.core.event import addEvent, fireEvent +from couchpotato.core.helpers.variable import mergeDicts from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin +import json import os.path import shutil import traceback @@ -20,8 +22,21 @@ class MetaDataBase(Plugin): log.info('Creating %s metadata.' % self.getName()) + # Update library to get latest info + try: + updated_library = fireEvent('library.update', release['library']['identifier'], force = True, single = True) + release['library'] = mergeDicts(release['library'], updated_library) + except: + log.error('Failed to update movie, before creating metadata: %s' % traceback.format_exc()) + root = self.getRootName(release) + try: + movie_info = json.loads(release['library'].get('info')) + except: + log.error('Failed to parse movie info: %s' % traceback.format_exc()) + movie_info = {} + for file_type in ['nfo', 'thumbnail', 'fanart']: try: # Get file path @@ -30,7 +45,7 @@ class MetaDataBase(Plugin): if name and self.conf('meta_' + file_type): # Get file content - content = getattr(self, 'get' + file_type.capitalize())(release) + content = getattr(self, 'get' + file_type.capitalize())(movie_info = movie_info, data = release) if content: log.debug('Creating %s file: %s' % (file_type, name)) if os.path.isfile(content): @@ -38,7 +53,7 @@ class MetaDataBase(Plugin): else: self.createFile(name, content) - except Exception, e: + except: log.error('Unable to create %s file: %s' % (file_type, traceback.format_exc())) def getRootName(self, data): @@ -53,18 +68,18 @@ class MetaDataBase(Plugin): def getNfoName(self, root): return - def getNfo(self, data): + def getNfo(self, movie_info = {}, data = {}): return - def getThumbnail(self, data, file_type = 'poster_original'): + def getThumbnail(self, movie_info = {}, data = {}, wanted_file_type = 'poster_original'): file_types = fireEvent('file.types', single = True) - for type in file_types: - if type.get('identifier') == file_type: + for file_type in file_types: + if file_type.get('identifier') == wanted_file_type: break - for cur_file in data['library'].get('files'): - if cur_file.get('type_id') is type.get('id'): + for cur_file in data['library'].get('files', []): + if cur_file.get('type_id') is file_type.get('id'): return cur_file.get('path') - def getFanart(self, data): - return self.getThumbnail(data, file_type = 'backdrop_original') + def getFanart(self, movie_info = {}, data = {}): + return self.getThumbnail(movie_info = movie_info, data = data, wanted_file_type = 'backdrop_original') diff --git a/couchpotato/core/providers/metadata/xbmc/main.py b/couchpotato/core/providers/metadata/xbmc/main.py index 0f83e7b..5763ea2 100644 --- a/couchpotato/core/providers/metadata/xbmc/main.py +++ b/couchpotato/core/providers/metadata/xbmc/main.py @@ -1,10 +1,14 @@ from couchpotato.core.helpers.encoding import toUnicode +from couchpotato.core.logger import CPLog from couchpotato.core.providers.metadata.base import MetaDataBase from xml.etree.ElementTree import Element, SubElement, tostring import os import re +import traceback import xml.dom.minidom +log = CPLog(__name__) + class XBMC(MetaDataBase): def getRootName(self, data = {}): @@ -19,11 +23,9 @@ class XBMC(MetaDataBase): def getNfoName(self, root): return '%s.nfo' % root - def getNfo(self, data): + def getNfo(self, movie_info = {}, data = {}): nfoxml = Element('movie') - types = ['rating', 'year', 'votes', 'rating', 'mpaa', 'originaltitle:original_title', 'outline:plot', 'premiered:released'] - # Title try: el = SubElement(nfoxml, 'title') @@ -41,11 +43,12 @@ class XBMC(MetaDataBase): # Runtime try: runtime = SubElement(nfoxml, 'runtime') - runtime.text = '%s min' % data['library']['runtime'] + runtime.text = '%s min' % movie_info.get('runtime') except: pass # Other values + types = ['rating', 'year', 'mpaa', 'originaltitle:original_title', 'outline', 'plot', 'tagline', 'premiered:released'] for type in types: if ':' in type: @@ -56,14 +59,32 @@ class XBMC(MetaDataBase): try: if data['library'].get(type): el = SubElement(nfoxml, name) - el.text = toUnicode(data['library'].get(type, '')) + el.text = toUnicode(movie_info.get(type, '')) except: pass + # Rating + for rating_type in ['imdb', 'rotten', 'tmdb']: + try: + r, v = movie_info['rating'][rating_type] + rating = SubElement(nfoxml, 'rating') + rating.text = str(r) + votes = SubElement(nfoxml, 'votes') + votes.text = str(v) + break + except: + log.error('Failed adding rating info from %s: %s' % (rating_type, traceback.format_exc())) + # Genre - for genre in data['library'].get('genres', []): + for genre in movie_info.get('genres', []): genres = SubElement(nfoxml, 'genre') - genres.text = genre.get('name') + genres.text = toUnicode(genre) + + # Actors + for actor in movie_info.get('actors', []): + actors = SubElement(nfoxml, 'actor') + name = SubElement(actors, 'name') + name.text = toUnicode(actor) # Clean up the xml and return it diff --git a/couchpotato/core/providers/movie/imdbapi/main.py b/couchpotato/core/providers/movie/imdbapi/main.py index 5bb8e6a..2b0647a 100644 --- a/couchpotato/core/providers/movie/imdbapi/main.py +++ b/couchpotato/core/providers/movie/imdbapi/main.py @@ -4,6 +4,7 @@ from couchpotato.core.logger import CPLog from couchpotato.core.providers.movie.base import MovieProvider from urllib import urlencode import json +import re import traceback log = CPLog(__name__) @@ -63,7 +64,7 @@ class IMDBAPI(MovieProvider): 'rotten': (tryFloat(movie.get('tomatoRating', 0)), tryInt(movie.get('tomatoReviews', 0))), }, 'imdb': str(movie.get('ID', '')), - 'runtime': movie.get('Runtime', ''), + 'runtime': self.runtimeToMinutes(movie.get('Runtime', '')), 'released': movie.get('Released', ''), 'year': movie.get('Year', ''), 'plot': movie.get('Plot', ''), @@ -75,3 +76,14 @@ class IMDBAPI(MovieProvider): log.error('Failed parsing IMDB API json: %s' % traceback.format_exc()) return movie_data + + def runtimeToMinutes(self, runtime_str): + runtime = 0 + + regex = '(\d*.?\d+).(hr|hrs|mins|min)+' + matches = re.findall(regex, runtime_str) + for match in matches: + nr, size = match + runtime += tryInt(nr) * (60 if 'hr' in str(size) else 1) + + return runtime diff --git a/couchpotato/core/providers/movie/themoviedb/main.py b/couchpotato/core/providers/movie/themoviedb/main.py index 15f0d9c..8229841 100644 --- a/couchpotato/core/providers/movie/themoviedb/main.py +++ b/couchpotato/core/providers/movie/themoviedb/main.py @@ -131,9 +131,9 @@ class TheMovieDb(MovieProvider): # Images poster = self.getImage(movie, type = 'poster') - backdrop = None #self.getImage(movie, type = 'backdrop') - poster_original = None #self.getImage(movie, type = 'poster', size = 'mid') - backdrop_original = None #self.getImage(movie, type = 'backdrop', size = 'w1280') + backdrop = self.getImage(movie, type = 'backdrop') + poster_original = self.getImage(movie, type = 'poster', size = 'mid') + backdrop_original = self.getImage(movie, type = 'backdrop', size = 'w1280') # Genres try: diff --git a/couchpotato/core/settings/model.py b/couchpotato/core/settings/model.py index 64b1309..69aa3f1 100644 --- a/couchpotato/core/settings/model.py +++ b/couchpotato/core/settings/model.py @@ -1,9 +1,8 @@ from elixir.entity import Entity from elixir.fields import Field -from elixir.options import options_defaults -from elixir.relationships import OneToMany, ManyToOne -from elixir.options import using_options -from elixir.relationships import ManyToMany +from elixir.options import options_defaults, using_options +from elixir.relationships import ManyToMany, OneToMany, ManyToOne +from libs.elixir.relationships import OneToOne from sqlalchemy.types import Integer, Unicode, UnicodeText, Boolean, Float, \ String @@ -40,22 +39,12 @@ class Library(Entity): plot = Field(UnicodeText) tagline = Field(UnicodeText(255)) + info = Field(UnicodeText) status = ManyToOne('Status') movies = OneToMany('Movie') titles = OneToMany('LibraryTitle') - genres = ManyToMany('LibraryGenre') files = ManyToMany('File') - info = OneToMany('LibraryInfo') - - -class LibraryInfo(Entity): - """""" - - identifier = Field(String(50)) - value = Field(Unicode(255), nullable = False) - - library = ManyToOne('Library') class LibraryTitle(Entity): @@ -70,14 +59,6 @@ class LibraryTitle(Entity): libraries = ManyToOne('Library') -class LibraryGenre(Entity): - """""" - - name = Field(Unicode) - - libraries = ManyToMany('Library') - - class Language(Entity): """"""