XBMC Metadata .nfo generation
This commit is contained in:
@@ -42,17 +42,11 @@ class FileManager(Plugin):
|
||||
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.exists(dest):
|
||||
log.debug('Writing file to: %s' % dest)
|
||||
output = open(dest, 'wb')
|
||||
output.write(file)
|
||||
output.close()
|
||||
else:
|
||||
log.debug('File already exists: %s' % dest)
|
||||
if overwrite or not os.path.isfile(dest):
|
||||
self.createFile(dest, file)
|
||||
|
||||
return dest
|
||||
|
||||
|
||||
def add(self, path = '', part = 1, type = (), available = 1, properties = {}):
|
||||
db = get_session()
|
||||
|
||||
|
||||
@@ -2,14 +2,15 @@ from couchpotato import get_session
|
||||
from couchpotato.core.event import addEvent, fireEventAsync, fireEvent
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
from couchpotato.core.settings.model import Library, LibraryTitle, File
|
||||
from couchpotato.core.settings.model import Library, LibraryTitle, File, \
|
||||
LibraryGenre
|
||||
import traceback
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
class LibraryPlugin(Plugin):
|
||||
|
||||
default_dict = {'titles': {}, 'files':{}, 'info':{}}
|
||||
default_dict = {'titles': {}, 'files':{}, 'info':{}, 'genres':{}}
|
||||
|
||||
def __init__(self):
|
||||
addEvent('library.add', self.add)
|
||||
@@ -77,7 +78,6 @@ class LibraryPlugin(Plugin):
|
||||
db.commit()
|
||||
|
||||
titles = info.get('titles', [])
|
||||
|
||||
log.debug('Adding titles: %s' % titles)
|
||||
for title in titles:
|
||||
t = LibraryTitle(
|
||||
@@ -88,6 +88,20 @@ 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 = genre
|
||||
)
|
||||
library.genres.append(g)
|
||||
|
||||
db.commit()
|
||||
|
||||
# Files
|
||||
images = info.get('images', [])
|
||||
for type in images:
|
||||
|
||||
@@ -8,9 +8,7 @@ log = CPLog(__name__)
|
||||
class MetaData(Plugin):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('renaming.after', self.add)
|
||||
|
||||
addEvent('app.load', self.add)
|
||||
addEvent('renamer.after', self.add)
|
||||
|
||||
def add(self, data = {}):
|
||||
log.info('Getting meta data')
|
||||
|
||||
@@ -77,11 +77,6 @@ config = [{
|
||||
'label': 'Trailer naming',
|
||||
'default': '<filename>-trailer.<ext>',
|
||||
},
|
||||
{
|
||||
'name': 'backdrop_name',
|
||||
'label': 'Backdrop naming',
|
||||
'default': '<filename>-backdrop.<ext>',
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -119,14 +119,13 @@ class Renamer(Plugin):
|
||||
final_folder_name = self.doReplace(folder_name, replacements)
|
||||
final_file_name = self.doReplace(file_name, replacements)
|
||||
replacements['filename'] = final_file_name[:-(len(getExt(final_file_name)) + 1)]
|
||||
group['filename'] = replacements['filename']
|
||||
|
||||
# Meta naming
|
||||
if file_type is 'trailer':
|
||||
final_file_name = self.doReplace(trailer_name, replacements)
|
||||
elif file_type is 'nfo':
|
||||
final_file_name = self.doReplace(nfo_name, replacements)
|
||||
elif file_type is 'backdrop':
|
||||
final_file_name = self.doReplace(backdrop_name, replacements)
|
||||
|
||||
# Seperator replace
|
||||
if separator:
|
||||
|
||||
@@ -194,7 +194,7 @@ class Scanner(Plugin):
|
||||
'subtitle_extra': self.getSubtitlesExtras(group['unsorted_files']),
|
||||
'nfo': self.getNfo(group['unsorted_files']),
|
||||
'trailer': self.getTrailers(group['unsorted_files']),
|
||||
'backdrop': images['backdrop'],
|
||||
#'backdrop': images['backdrop'],
|
||||
'leftover': set(group['unsorted_files']),
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.event import addEvent, fireEvent
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
|
||||
@@ -17,7 +17,7 @@ class MetaDataBase(Plugin):
|
||||
|
||||
log.info('Creating %s metadata.' % self.getName())
|
||||
|
||||
root = self.getRootName()
|
||||
root = self.getRootName(release)
|
||||
|
||||
for type in ['nfo', 'thumbnail', 'fanart']:
|
||||
try:
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
from couchpotato.core.helpers.encoding import toUnicode
|
||||
from couchpotato.core.providers.metadata.base import MetaDataBase
|
||||
from xml.etree.ElementTree import Element, SubElement, tostring
|
||||
import os
|
||||
import re
|
||||
import xml.dom.minidom
|
||||
|
||||
class XBMC(MetaDataBase):
|
||||
|
||||
def getRootName(self, data = {}):
|
||||
|
||||
|
||||
|
||||
return '/Users/ruud/Downloads/Test/Transformers'
|
||||
return os.path.join(data['destination_dir'], data['filename'])
|
||||
|
||||
def getFanartName(self, root):
|
||||
return '%s-fanart.jpg' % root
|
||||
@@ -23,8 +22,30 @@ class XBMC(MetaDataBase):
|
||||
def getNfo(self, data):
|
||||
nfoxml = Element('movie')
|
||||
|
||||
types = ['title', 'rating', 'year', 'votes', 'rating', 'mpaa', 'originaltitle:original_title', 'outline:overview', 'premiered:released', 'id:imdb_id']
|
||||
types = ['rating', 'year', 'votes', 'rating', 'mpaa', 'originaltitle:original_title', 'outline:plot', 'premiered:released']
|
||||
|
||||
# Title
|
||||
try:
|
||||
el = SubElement(nfoxml, 'title')
|
||||
el.text = toUnicode(data['library']['titles'][0]['title'])
|
||||
except:
|
||||
pass
|
||||
|
||||
# IMDB id
|
||||
try:
|
||||
el = SubElement(nfoxml, 'id')
|
||||
el.text = toUnicode(data['library']['identifier'])
|
||||
except:
|
||||
pass
|
||||
|
||||
# Runtime
|
||||
try:
|
||||
runtime = SubElement(nfoxml, 'runtime')
|
||||
runtime.text = '%s min' % data['library']['runtime']
|
||||
except:
|
||||
pass
|
||||
|
||||
# Other values
|
||||
for type in types:
|
||||
|
||||
if ':' in type:
|
||||
@@ -33,20 +54,17 @@ class XBMC(MetaDataBase):
|
||||
name = type
|
||||
|
||||
try:
|
||||
el = SubElement(nfoxml, name)
|
||||
el.text = data.get(type, '')
|
||||
if data['library'].get(type):
|
||||
el = SubElement(nfoxml, name)
|
||||
el.text = toUnicode(data['library'].get(type, ''))
|
||||
except:
|
||||
pass
|
||||
|
||||
#for genre in self.get('genres'):
|
||||
# genres = SubElement(nfoxml, 'genre')
|
||||
# genres.text = genre
|
||||
# Genre
|
||||
for genre in data['library'].get('genres', []):
|
||||
genres = SubElement(nfoxml, 'genre')
|
||||
genres.text = genre.get('name')
|
||||
|
||||
try:
|
||||
runtime = SubElement(nfoxml, 'runtime')
|
||||
runtime.text = data.get('runtime') + " min"
|
||||
except:
|
||||
pass
|
||||
|
||||
# Clean up the xml and return it
|
||||
nfoxml = xml.dom.minidom.parseString(tostring(nfoxml))
|
||||
@@ -55,130 +73,3 @@ class XBMC(MetaDataBase):
|
||||
xml_string = text_re.sub('>\g<1></', xml_string)
|
||||
|
||||
return xml_string.encode('utf-8')
|
||||
"""
|
||||
def _get_fanart(self, min_height, min_width):
|
||||
''' Fetches the fanart for the specified imdb_id and saves it to dir.
|
||||
Arguments
|
||||
|
||||
min_height/width: Sets lowest acceptable resolution fanart. 0 means
|
||||
disregard. If no fanart available at specified resolution or greater, then
|
||||
we disregard.
|
||||
'''
|
||||
images = [image['image'] for image in self.tmdb_data['backdrops'] if image['image'].get('size') == 'original']
|
||||
if len(images) == 0:
|
||||
return
|
||||
|
||||
return self._get_image(images, min_height, min_width)
|
||||
|
||||
def get_fanart_url(self, min_height, min_width):
|
||||
return self._get_fanart(min_height, min_width)['url']
|
||||
|
||||
def write_fanart(self, filename_root, path, min_height, min_width):
|
||||
fanart_url = self.get_fanart_url(min_height, min_width)
|
||||
#fetch and write to disk
|
||||
dest = os.path.join(path, filename_root)
|
||||
try:
|
||||
f = open(dest, 'wb')
|
||||
except:
|
||||
raise IOError("Can't open for writing: %s" % dest)
|
||||
|
||||
response = urllib2.urlopen(fanart_url)
|
||||
f.write(response.read())
|
||||
f.close()
|
||||
|
||||
return True
|
||||
|
||||
def _get_poster(self, min_height, min_width):
|
||||
''' Fetches the poster for the specified imdb_id and saves it to dir.
|
||||
Arguments
|
||||
|
||||
min_height/width: Sets lowest acceptable resolution poster. 0 means
|
||||
disregard. If no poster available at specified resolution or greater, then
|
||||
we disregard.
|
||||
'''
|
||||
images = [image['image'] for image in self.tmdb_data['posters'] if image['image'].get('size') == 'original']
|
||||
if len(images) == 0:
|
||||
return
|
||||
|
||||
return self._get_image(images, min_height, min_width)
|
||||
|
||||
def get_poster_url(self, min_height, min_width):
|
||||
return self._get_poster(min_height, min_width)['url']
|
||||
|
||||
def write_poster(self, filename_root, path, min_height, min_width):
|
||||
poster_url = self.get_poster_url(min_height, min_width)
|
||||
dest = os.path.join(path, filename_root)
|
||||
|
||||
try:
|
||||
f = open(dest, 'wb')
|
||||
except:
|
||||
raise IOError("Can't open for writing: %s" % dest)
|
||||
|
||||
response = urllib2.urlopen(poster_url)
|
||||
f.write(response.read())
|
||||
f.close()
|
||||
|
||||
return True
|
||||
|
||||
def _get_tmdb_imdb(self):
|
||||
url = "http://api.themoviedb.org/2.1/Movie.imdbLookup/en/json/%s/%s" % (__tmdb_apikey__, self.imdbid)
|
||||
|
||||
count = 0
|
||||
while 1:
|
||||
count += 1
|
||||
response = urllib2.urlopen(url)
|
||||
json_string = response.read()
|
||||
try:
|
||||
tmdb_data = json.loads(json_string)[0]
|
||||
return tmdb_data
|
||||
except ValueError, e:
|
||||
if count < 3:
|
||||
continue
|
||||
else:
|
||||
raise ApiError("Invalid JSON: %s: %s" % (e, json_string))
|
||||
except:
|
||||
ApiError("JSON error with: %s" % json_string)
|
||||
|
||||
|
||||
def _get_image(self, image_list, min_height, min_width):
|
||||
#Select image
|
||||
images = []
|
||||
for image in image_list:
|
||||
if not min_height or min_width:
|
||||
images.append(image)
|
||||
break
|
||||
elif min_height and not min_width:
|
||||
if image['height'] >= min_height:
|
||||
images.append(image)
|
||||
break
|
||||
elif min_width and not min_height:
|
||||
if image['width'] >= min_width:
|
||||
images.append(image)
|
||||
break
|
||||
elif min_width and min_height:
|
||||
if image['width'] >= min_width and image['height'] >= min_height:
|
||||
images.append(image)
|
||||
break
|
||||
|
||||
#No image meets our resolution requirements, so disregard those requirements
|
||||
if len(images) == 0 and min_height or min_width:
|
||||
images.append(image_list[0])
|
||||
|
||||
return images[0]
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
try:
|
||||
id = sys.argv[1]
|
||||
except:
|
||||
id = 'tt0111161'
|
||||
|
||||
x = MetaGen(id)
|
||||
x.write_nfo("movie.nfo")
|
||||
try:
|
||||
x.write_fanart("fanart.jpg", ".", 0, 0)
|
||||
except: pass
|
||||
try:
|
||||
x.write_poster("movie.tbn", ".", 0, 0)
|
||||
except: pass
|
||||
"""
|
||||
|
||||
@@ -92,7 +92,7 @@ class TheMovieDb(MovieProvider):
|
||||
def getInfo(self, identifier = None):
|
||||
|
||||
cache_key = 'tmdb.cache.%s' % identifier
|
||||
result = self.getCache(cache_key)
|
||||
result = None #self.getCache(cache_key)
|
||||
|
||||
if not result:
|
||||
result = {}
|
||||
@@ -112,27 +112,33 @@ class TheMovieDb(MovieProvider):
|
||||
|
||||
def parseMovie(self, movie):
|
||||
|
||||
year = str(movie.get('released', 'none'))[:4]
|
||||
|
||||
# Poster url
|
||||
poster = self.getImage(movie, type = 'poster')
|
||||
backdrop = self.getImage(movie, type = 'backdrop')
|
||||
|
||||
# Genres
|
||||
genres = self.getCategory(movie, 'genre')
|
||||
|
||||
# 1900 is the same as None
|
||||
year = str(movie.get('released', 'none'))[:4]
|
||||
if year == '1900' or year.lower() == 'none':
|
||||
year = None
|
||||
|
||||
movie_data = {
|
||||
'id': int(movie.get('id', 0)),
|
||||
'titles': [toUnicode(movie.get('name'))],
|
||||
'original_title': movie.get('original_name'),
|
||||
'images': {
|
||||
'posters': [poster],
|
||||
'backdrops': [backdrop],
|
||||
},
|
||||
'imdb': movie.get('imdb_id'),
|
||||
'runtime': movie.get('runtime'),
|
||||
'released': movie.get('released'),
|
||||
'year': year,
|
||||
'plot': movie.get('overview', ''),
|
||||
'tagline': '',
|
||||
'genres': genres,
|
||||
}
|
||||
|
||||
# Add alternative names
|
||||
@@ -153,6 +159,19 @@ class TheMovieDb(MovieProvider):
|
||||
|
||||
return image
|
||||
|
||||
def getCategory(self, movie, type = 'genre'):
|
||||
|
||||
cats = movie.get('categories', {}).get(type)
|
||||
|
||||
categories = []
|
||||
for category in cats:
|
||||
try:
|
||||
categories.append(category)
|
||||
except:
|
||||
pass
|
||||
|
||||
return categories
|
||||
|
||||
def isDisabled(self):
|
||||
if self.conf('api_key') == '':
|
||||
log.error('No API key provided.')
|
||||
|
||||
@@ -44,12 +44,10 @@ class Library(Entity):
|
||||
status = ManyToOne('Status')
|
||||
movies = OneToMany('Movie')
|
||||
titles = OneToMany('LibraryTitle')
|
||||
genres = ManyToMany('LibraryGenre')
|
||||
files = ManyToMany('File')
|
||||
info = OneToMany('LibraryInfo')
|
||||
|
||||
def title(self):
|
||||
return self.titles[0]['title']
|
||||
|
||||
|
||||
class LibraryInfo(Entity):
|
||||
""""""
|
||||
@@ -71,6 +69,14 @@ class LibraryTitle(Entity):
|
||||
libraries = ManyToOne('Library')
|
||||
|
||||
|
||||
class LibraryGenre(Entity):
|
||||
""""""
|
||||
|
||||
name = Field(Unicode)
|
||||
|
||||
libraries = ManyToMany('Library')
|
||||
|
||||
|
||||
class Language(Entity):
|
||||
""""""
|
||||
|
||||
|
||||
@@ -350,7 +350,7 @@ class MovieDb:
|
||||
etree = XmlHandler(url).getEt()
|
||||
lookup_results = SearchResults()
|
||||
for cur_lookup in etree.find("movies").findall("movie"):
|
||||
cur_movie = self._parseSearchResults(cur_lookup)
|
||||
cur_movie = self._parseMovie(cur_lookup)
|
||||
lookup_results.append(cur_movie)
|
||||
return lookup_results
|
||||
|
||||
|
||||
Reference in New Issue
Block a user