Movie search

Profile Settings
This commit is contained in:
Ruud
2011-03-20 22:12:33 +01:00
parent cc260d3a07
commit 288aa8c0a1
34 changed files with 1408 additions and 178 deletions
+8
View File
@@ -24,3 +24,11 @@ def toUnicode(original, *args):
except UnicodeDecodeError:
ascii_text = str(original).encode('string_escape')
return unicode(ascii_text)
def is_int(value):
try:
int(value)
return True
except ValueError:
return False
+56 -5
View File
@@ -1,17 +1,67 @@
from flask.globals import current_app
from flask.helpers import json, jsonify
from flask.helpers import json
from libs.werkzeug.urls import url_decode
import flask
import re
def getParams():
return getattr(flask.request, 'args')
params = url_decode(getattr(flask.request, 'environ').get('QUERY_STRING', ''))
reg = re.compile('^[a-z0-9_\.]+$')
current = temp = {}
for param, value in sorted(params.iteritems()):
nest = re.split("([\[\]]+)", param)
if len(nest) > 1:
nested = []
for key in nest:
if reg.match(key):
nested.append(key)
current = temp
for item in nested:
if item is nested[-1]:
current[item] = value
else:
try:
current[item]
except:
current[item] = {}
current = current[item]
else:
temp[param] = value
return dictToList(temp)
def dictToList(params):
if type(params) is dict:
new = {}
for x, value in params.iteritems():
try:
new_value = [dictToList(value2) for value2 in value.itervalues()]
except:
new_value = value
new[x] = new_value
else:
new = params
return new
def getParam(attr, default = None):
return getattr(flask.request, 'args').get(attr, default)
def padded_jsonify(callback, *args, **kwargs):
content = str(callback) + '(' + json.dumps(dict(*args, **kwargs)) + ')'
return current_app.response_class(content, mimetype = 'text/javascript')
return getattr(current_app, 'response_class')(content, mimetype = 'text/javascript')
def jsonify(mimetype, *args, **kwargs):
content = json.dumps(dict(*args, **kwargs))
return getattr(current_app, 'response_class')(content, mimetype = mimetype)
def jsonified(*args, **kwargs):
from couchpotato.environment import Env
@@ -19,4 +69,5 @@ def jsonified(*args, **kwargs):
if callback:
return padded_jsonify(callback, *args, **kwargs)
else:
return jsonify(*args, **kwargs)
return jsonify('text/javascript' if Env.doDebug() else 'application/json', *args, **kwargs)
@@ -0,0 +1,6 @@
from couchpotato.core.plugins.library.main import LibraryPlugin
def start():
return LibraryPlugin()
config = []
+32
View File
@@ -0,0 +1,32 @@
from couchpotato import get_session
from couchpotato.core.event import addEvent
from couchpotato.core.plugins.base import Plugin
from couchpotato.core.settings.model import Library
class LibraryPlugin(Plugin):
def __init__(self):
addEvent('library.add', self.add)
def add(self, attrs = {}):
db = get_session();
l = db.query(Library).filter_by(identifier = attrs.get('identifier')).first()
if not l:
l = Library(
name = attrs.get('name'),
year = attrs.get('year'),
identifier = attrs.get('identifier'),
description = attrs.get('description')
)
db.add(l)
db.commit()
return l
def update(self, item):
pass
@@ -0,0 +1,6 @@
from couchpotato.core.plugins.movie.main import MoviePlugin
def start():
return MoviePlugin()
config = []
+94
View File
@@ -0,0 +1,94 @@
from couchpotato import get_session
from couchpotato.api import addApiView
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.request import getParams, jsonified
from couchpotato.core.plugins.base import Plugin
from couchpotato.core.settings.model import Movie, Release, Profile
from couchpotato.environment import Env
from urllib import urlencode
class MoviePlugin(Plugin):
def __init__(self):
addApiView('movie.search', self.search)
addApiView('movie.list', self.list)
addApiView('movie.add', self.add)
def list(self):
a = getParams()
results = get_session().query(Movie).filter(
Movie.releases.any(
Release.status.has(identifier = 'wanted')
)
).all()
movies = []
for movie in results:
temp = {
'id': movie.id,
'name': movie.id,
'releases': [],
}
for release in movie.releases:
temp['releases'].append({
'status': release.status.label,
'quality': release.quality.label
})
movies.append(temp)
return jsonified({
'success': True,
'empty': len(movies) == 0,
'movies': movies,
})
def search(self):
a = getParams()
cache_key = '%s/%s' % (__name__, urlencode(a))
movies = Env.get('cache').get(cache_key)
if not movies:
results = fireEvent('provider.movie.search', q = a.get('q'))
# Combine movie results
movies = []
for r in results:
movies += r
Env.get('cache').set(cache_key, movies, timeout = 10)
return jsonified({
'success': True,
'empty': len(movies) == 0,
'movies': movies,
})
def add(self):
a = getParams()
db = get_session();
library = fireEvent('library.add', attrs = a)
profile = db.query(Profile).filter_by(identifier = a.get('profile_identifier'))
m = db.query(Movie).filter_by(library = library).first()
if not m:
m = Movie(
library = library,
profile = profile,
)
db.add(m)
db.commit()
return jsonified({
'success': True,
'added': True,
'params': a,
})
@@ -1,6 +0,0 @@
from couchpotato.core.plugins.movie_add.main import MovieAdd
def start():
return MovieAdd()
config = []
@@ -1,36 +0,0 @@
from couchpotato.api import addApiView
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.request import getParams, jsonified
from couchpotato.core.plugins.base import Plugin
class MovieAdd(Plugin):
def __init__(self):
addApiView('movie.add.search', self.search)
addApiView('movie.add.select', self.select)
def search(self):
a = getParams()
results = fireEvent('provider.movie.search', q = a.get('q'))
# Combine movie results
movies = []
for r in results:
movies += r
return jsonified({
'success': True,
'empty': len(movies) == 0,
'movies': movies,
})
def select(self):
a = getParams()
return jsonified({
'success': True,
'added': True,
})
@@ -1,6 +0,0 @@
from couchpotato.core.plugins.movie_list.main import MovieList
def start():
return MovieList()
config = []
@@ -1,41 +0,0 @@
from couchpotato import get_session
from couchpotato.api import addApiView
from couchpotato.core.helpers.request import getParams, jsonified
from couchpotato.core.plugins.base import Plugin
from couchpotato.core.settings.model import Movie, Release
class MovieList(Plugin):
def __init__(self):
addApiView('movie.list', self.list)
def list(self):
a = getParams()
results = get_session().query(Movie).filter(
Movie.releases.any(
Release.status.has(identifier = 'wanted')
)
).all()
movies = []
for movie in results:
temp = {
'id': movie.id,
'name': movie.id,
'releases': [],
}
for release in movie.releases:
temp['releases'].append({
'status': release.status.label,
'quality': release.quality.label
})
movies.append(temp)
return jsonified({
'success': True,
'empty': len(movies) == 0,
'movies': movies,
})
@@ -0,0 +1,6 @@
from couchpotato.core.plugins.profile.main import ProfilePlugin
def start():
return ProfilePlugin()
config = []
+28
View File
@@ -0,0 +1,28 @@
from couchpotato.api import addApiView
from couchpotato.core.event import addEvent
from couchpotato.core.helpers.request import jsonified, getParams
from couchpotato.core.plugins.base import Plugin
class ProfilePlugin(Plugin):
def __init__(self):
addEvent('profile.get', self.get)
addApiView('profile.save', self.save)
addApiView('profile.delete', self.delete)
def get(self, key = ''):
pass
def save(self):
a = getParams()
return jsonified({
'success': True,
'a': a
})
def delete(self):
pass
+2 -2
View File
@@ -1,7 +1,7 @@
from couchpotato.core.providers.tmdb.main import TMDB
from couchpotato.core.providers.tmdb.main import TMDBWrapper
def start():
return TMDB()
return TMDBWrapper()
config = [{
'name': 'themoviedb',
+28 -18
View File
@@ -4,6 +4,7 @@ from couchpotato.core.helpers.encoding import simplifyString, toUnicode
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import Provider
from couchpotato.environment import Env
from libs.themoviedb import tmdb
from urllib import quote_plus
import copy
import simplejson as json
@@ -11,7 +12,7 @@ import urllib2
log = CPLog(__name__)
class TMDB(Provider):
class TMDBWrapper(Provider):
"""Api for theMovieDb"""
type = 'movie'
@@ -20,6 +21,10 @@ class TMDB(Provider):
def __init__(self):
addEvent('provider.movie.search', self.search)
addEvent('provider.movie.info', self.getInfo)
# Use base wrapper
tmdb.Config.api_key = self.conf('api_key')
def conf(self, attr):
return Env.setting(attr, 'themoviedb')
@@ -32,31 +37,32 @@ class TMDB(Provider):
log.debug('TheMovieDB - Searching for movie: %s' % q)
url = "%s/%s/%s/json/%s/%s" % (self.apiUrl, 'Movie.search', 'en', self.conf('api_key'), quote_plus(simplifyString(q)))
raw = tmdb.search(simplifyString(q))
log.info('Searching: %s' % url)
#url = "%s/%s/%s/json/%s/%s" % (self.apiUrl, 'Movie.search', 'en', self.conf('api_key'), quote_plus(simplifyString(q)))
data = urllib2.urlopen(url)
jsn = json.load(data)
return self.parse(jsn, limit, alternative = alternative)
# data = urllib2.urlopen(url)
# jsn = json.load(data)
def parse(self, data, limit, alternative = True):
if data:
if raw:
log.debug('TheMovieDB - Parsing RSS')
try:
results = []
nr = 0
for movie in data:
for movie in raw:
year = str(movie['released'])[:4]
for k, x in movie.iteritems():
print k
print x
year = str(movie.get('released', 'none'))[:4]
# Poster url
poster = ''
for p in movie['posters']:
p = p['image']
if(p['size'] == 'thumb'):
poster = p['url']
for p in movie.get('images'):
if(p.get('type') == 'poster'):
poster = p.get('thumb')
break
# 1900 is the same as None
@@ -64,16 +70,16 @@ class TMDB(Provider):
year = None
movie_data = {
'id': int(movie['id']),
'name': toUnicode(movie['name']),
'id': int(movie.get('id', 0)),
'name': toUnicode(movie.get('name')),
'poster': poster,
'imdb': movie['imdb_id'],
'imdb': movie.get('imdb_id'),
'year': year,
'tagline': 'This is the tagline of the movie',
}
results.append(copy.deepcopy(movie_data))
alternativeName = movie['alternative_name']
alternativeName = movie.get('alternative_name')
if alternativeName and alternative:
if alternativeName.lower() != movie['name'].lower() and alternativeName.lower() != 'none' and alternativeName != None:
movie_data['name'] = toUnicode(alternativeName)
@@ -88,6 +94,10 @@ class TMDB(Provider):
log.error('TheMovieDB - Failed to parse XML response from TheMovieDb: %s' % e)
return False
return results
def getInfo(self):
pass
def isDisabled(self):
if self.conf('api_key') == '':
+2 -8
View File
@@ -1,6 +1,7 @@
from __future__ import with_statement
from couchpotato.api import addApiView
from couchpotato.core.event import addEvent
from couchpotato.core.helpers.encoding import is_int
from couchpotato.core.helpers.request import getParams, jsonified
import ConfigParser
import os.path
@@ -60,7 +61,7 @@ class Settings():
return default
def cleanValue(self, value):
if(self.is_int(value)):
if(is_int(value)):
return int(value)
if str(value).lower() in self.bool:
@@ -91,13 +92,6 @@ class Settings():
if not self.p.has_option(section, option):
self.p.set(section, option, value)
def is_int(self, value):
try:
int(value)
return True
except ValueError:
return False
def addOptions(self, section_name, options):
self.options[section_name] = options
+20 -2
View File
@@ -2,7 +2,8 @@ from elixir.entity import Entity
from elixir.fields import Field
from elixir.options import options_defaults
from elixir.relationships import OneToMany, ManyToOne
from sqlalchemy.types import Integer, String, Unicode, UnicodeText, Boolean
from sqlalchemy.types import Integer, String, Unicode, UnicodeText, Boolean, \
Float
options_defaults["shortnames"] = True
@@ -19,13 +20,26 @@ class Movie(Entity):
The files belonging to the movie object are global for the whole movie
such as trailers, nfo, thumbnails"""
mooli_id = Field(Integer)
library = ManyToOne('Library')
profile = ManyToOne('Profile')
releases = OneToMany('Release')
files = OneToMany('File')
class Library(Entity):
title = Field(Unicode)
year = Field(Integer)
identifier = Field(Unicode)
rating = Field(Float)
plot = Field(UnicodeText)
tagline = Field(UnicodeText(255))
movie = OneToMany('Movie')
class Release(Entity):
"""Logically groups all files that belong to a certain release, such as
parts of a movie, subtitles."""
@@ -55,6 +69,7 @@ class Quality(Entity):
releases = OneToMany('Release')
profile_types = ManyToOne('ProfileType')
class Profile(Entity):
""""""
@@ -66,6 +81,7 @@ class Profile(Entity):
movie = OneToMany('Movie')
profile_type = OneToMany('ProfileType')
class ProfileType(Entity):
""""""
@@ -76,6 +92,7 @@ class ProfileType(Entity):
type = OneToMany('Quality')
profile = ManyToOne('Profile')
class File(Entity):
"""File that belongs to a release."""
@@ -114,6 +131,7 @@ class History(Entity):
message = Field(UnicodeText())
release = ManyToOne('Release')
class RenameHistory(Entity):
"""Remembers from where to where files have been moved."""