Browse Source

Merge branch 'refs/heads/develop'

pull/228/head
Ruud 13 years ago
parent
commit
89315cb291
  1. 2
      couchpotato/core/_base/updater/main.py
  2. 2
      couchpotato/core/helpers/encoding.py
  3. 8
      couchpotato/core/helpers/request.py
  4. 12
      couchpotato/core/plugins/base.py
  5. 1
      couchpotato/core/plugins/library/main.py
  6. 43
      couchpotato/core/plugins/movie/main.py
  7. 2
      couchpotato/core/plugins/movie/static/movie.css
  8. 4
      couchpotato/core/providers/movie/imdbapi/main.py
  9. 2
      couchpotato/core/providers/nzb/mysterbin/main.py
  10. 4
      couchpotato/core/providers/nzb/newznab/__init__.py
  11. 8
      couchpotato/core/providers/nzb/nzbclub/main.py
  12. 9
      couchpotato/core/providers/nzb/nzbindex/main.py
  13. 2
      couchpotato/core/providers/nzb/nzbmatrix/main.py
  14. 33
      couchpotato/core/providers/nzb/nzbs/__init__.py
  15. 96
      couchpotato/core/providers/nzb/nzbs/main.py
  16. 2
      couchpotato/static/scripts/page/wanted.js

2
couchpotato/core/_base/updater/main.py

@ -56,7 +56,7 @@ class Updater(Plugin):
fireEventAsync('app.crappy_restart')
else:
if self.conf('notification'):
fireEvent('updater.available', message = 'A new update is available', data = self.updater.getVersion())
fireEvent('updater.available', message = 'A new update is available', data = self.updater.info())
def info(self):
return self.updater.info()

2
couchpotato/core/helpers/encoding.py

@ -15,7 +15,7 @@ def toSafeString(original):
def simplifyString(original):
string = stripAccents(original.lower())
string = toSafeString(' '.join(re.split('\W+', string)))
split = re.split('\W+', string.lower())
split = re.split('\W+|_', string.lower())
return toUnicode(' '.join(split))
def toUnicode(original, *args):

8
couchpotato/core/helpers/request.py

@ -3,7 +3,7 @@ from couchpotato.core.helpers.variable import natcmp
from flask.globals import current_app
from flask.helpers import json
from libs.werkzeug.urls import url_decode
from urllib import unquote_plus
from urllib import unquote
import flask
import re
@ -26,7 +26,7 @@ def getParams():
for item in nested:
if item is nested[-1]:
current[item] = toUnicode(unquote_plus(value)).encode('utf-8')
current[item] = toUnicode(unquote(value)).encode('utf-8')
else:
try:
current[item]
@ -35,7 +35,7 @@ def getParams():
current = current[item]
else:
temp[param] = toUnicode(unquote_plus(value)).encode('utf-8')
temp[param] = toUnicode(unquote(value)).encode('utf-8')
return dictToList(temp)
@ -57,7 +57,7 @@ def dictToList(params):
def getParam(attr, default = None):
try:
return toUnicode(unquote_plus(getattr(flask.request, 'args').get(attr, default))).encode('utf-8')
return toUnicode(unquote(getattr(flask.request, 'args').get(attr, default))).encode('utf-8')
except:
return default

12
couchpotato/core/plugins/base.py

@ -198,7 +198,7 @@ class Plugin(object):
log.error("Something went wrong when finishing the plugin function. Could not find the 'is_running' key")
def getCache(self, cache_key, url = None, timeout = 300, url_timeout = 10):
def getCache(self, cache_key, url = None, **kwargs):
cache = Env.get('cache').get(cache_key)
if cache:
if not Env.get('dev'): log.debug('Getting cache %s' % cache_key)
@ -206,8 +206,14 @@ class Plugin(object):
if url:
try:
data = self.urlopen(url, timeout = url_timeout)
self.setCache(cache_key, data, timeout = timeout)
cache_timeout = 300
if kwargs.get('cache_timeout'):
cache_timeout = kwargs.get('cache_timeout')
del kwargs['cache_timeout']
data = self.urlopen(url, **kwargs)
self.setCache(cache_key, data, timeout = cache_timeout)
return data
except:
pass

1
couchpotato/core/plugins/library/main.py

@ -68,6 +68,7 @@ class LibraryPlugin(Plugin):
do_update = False
else:
info = fireEvent('movie.info', merge = True, identifier = identifier)
del info['in_wanted'], info['in_library'] # Don't need those here
if not info or len(info) == 0:
log.error('Could not update, no movie info to work with: %s' % identifier)
return False

43
couchpotato/core/plugins/movie/main.py

@ -51,6 +51,12 @@ class MoviePlugin(Plugin):
'movies': array, movies found,
}"""}
})
addApiView('movie.get', self.getView, docs = {
'desc': 'Get a movie by id',
'params': {
'id': {'desc': 'The id of the movie'},
}
})
addApiView('movie.refresh', self.refresh, docs = {
'desc': 'Refresh a movie by id',
'params': {
@ -88,12 +94,25 @@ class MoviePlugin(Plugin):
addEvent('movie.list', self.list)
addEvent('movie.restatus', self.restatus)
def getView(self):
movie_id = getParam('id')
movie = self.get(movie_id) if movie_id else None
return jsonified({
'success': movie is not None,
'movie': movie,
})
def get(self, movie_id):
db = get_session()
m = db.query(Movie).filter_by(id = movie_id).first()
return m.to_dict(self.default_dict)
if m:
return m.to_dict(self.default_dict)
return None
def list(self, status = ['active'], limit_offset = None, starts_with = None, search = None):
@ -169,11 +188,9 @@ class MoviePlugin(Plugin):
status = [status]
q = db.query(Movie) \
.join(Movie.library, Library.titles) \
.join(Movie.library, Library.titles, Movie.status) \
.options(joinedload_all('library.titles')) \
.filter(LibraryTitle.default == True) \
.filter(or_(*[Movie.status.has(identifier = s) for s in status])) \
.group_by(Movie.id)
.filter(or_(*[Movie.status.has(identifier = s) for s in status]))
results = q.all()
@ -380,13 +397,15 @@ class MoviePlugin(Plugin):
total_deleted = 0
new_movie_status = None
for release in movie.releases:
if delete_from == 'wanted' and release.status_id != done_status.get('id'):
db.delete(release)
total_deleted += 1
if delete_from == 'wanted':
if release.status_id != done_status.get('id'):
db.delete(release)
total_deleted += 1
new_movie_status = 'done'
elif delete_from == 'manage' and release.status_id == done_status.get('id'):
db.delete(release)
total_deleted += 1
elif delete_from == 'manage':
if release.status_id == done_status.get('id'):
db.delete(release)
total_deleted += 1
new_movie_status = 'active'
db.commit()
@ -397,6 +416,8 @@ class MoviePlugin(Plugin):
new_status = fireEvent('status.get', new_movie_status, single = True)
movie.status_id = new_status.get('id')
db.commit()
else:
fireEvent('movie.restatus', movie.id, single = True)
return True

2
couchpotato/core/plugins/movie/static/movie.css

@ -288,7 +288,7 @@
text-align: left;
padding: 0 10px;
}
.movies .options .table.files .name { width: 605px; }
.movies .options .table.files .name { width: 590px; }
.movies .options .table .type { width: 130px; }
.movies .options .table .is_available { width: 90px; }
.movies .options .table .age,

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

@ -31,7 +31,7 @@ class IMDBAPI(MovieProvider):
return []
cache_key = 'imdbapi.cache.%s' % q
cached = self.getCache(cache_key, self.urls['search'] % tryUrlencode({'t': name_year.get('name'), 'y': name_year.get('year', '')}), url_timeout = 3)
cached = self.getCache(cache_key, self.urls['search'] % tryUrlencode({'t': name_year.get('name'), 'y': name_year.get('year', '')}), timeout = 3)
if cached:
result = self.parseMovie(cached)
@ -49,7 +49,7 @@ class IMDBAPI(MovieProvider):
return {}
cache_key = 'imdbapi.cache.%s' % identifier
cached = self.getCache(cache_key, self.urls['info'] % identifier, url_timeout = 3)
cached = self.getCache(cache_key, self.urls['info'] % identifier, timeout = 3)
if cached:
result = self.parseMovie(cached)

2
couchpotato/core/providers/nzb/mysterbin/main.py

@ -67,7 +67,7 @@ class Mysterbin(NZBProvider):
description = ''
if result.find('a', text = 'View NFO'):
description = toUnicode(self.getCache('mysterbin.%s' % myster_id, self.urls['nfo'] % myster_id, timeout = 25920000))
description = toUnicode(self.getCache('mysterbin.%s' % myster_id, self.urls['nfo'] % myster_id, cache_timeout = 25920000))
new = {
'id': myster_id,

4
couchpotato/core/providers/nzb/newznab/__init__.py

@ -10,7 +10,7 @@ config = [{
'tab': 'searcher',
'subtab': 'providers',
'name': 'newznab',
'description': 'Enable multiple NewzNab providers such as <a href="http://nzb.su" target="_blank">NZB.su</a>',
'description': 'Enable multiple NewzNab providers such as <a href="http://nzb.su" target="_blank">NZB.su</a> and <a href="http://nzbs.org" target="_blank">nzbs.org</a>',
'wizard': True,
'options': [
{
@ -23,7 +23,7 @@ config = [{
},
{
'name': 'host',
'default': 'nzb.su,dognzb.cr,beta.nzbs.org',
'default': 'nzb.su,dognzb.cr,nzbs.org',
'description': 'The hostname of your newznab provider',
},
{

8
couchpotato/core/providers/nzb/nzbclub/main.py

@ -1,3 +1,4 @@
from BeautifulSoup import BeautifulSoup
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.encoding import toUnicode, tryUrlencode
from couchpotato.core.helpers.rss import RSS
@ -57,7 +58,10 @@ class NZBClub(NZBProvider, RSS):
size = enclosure['length']
date = self.getTextElement(nzb, "pubDate")
description = toUnicode(self.getCache('nzbclub.%s' % nzbclub_id, self.getTextElement(nzb, "link"), timeout = 25920000))
full_description = self.getCache('nzbclub.%s' % nzbclub_id, self.getTextElement(nzb, "link"), cache_timeout = 25920000)
html = BeautifulSoup(full_description)
nfo_pre = html.find('pre', attrs = {'class':'nfo'})
description = toUnicode(nfo_pre.text) if nfo_pre else ''
new = {
'id': nzbclub_id,
@ -73,7 +77,7 @@ class NZBClub(NZBProvider, RSS):
}
new['score'] = fireEvent('score.calculate', new, movie, single = True)
if 'ARCHIVE inside ARCHIVE' in description:
if 'ARCHIVE inside ARCHIVE' in full_description:
log.info('Wrong: Seems to be passworded files: %s' % new['name'])
continue

9
couchpotato/core/providers/nzb/nzbindex/main.py

@ -1,3 +1,4 @@
from BeautifulSoup import BeautifulSoup
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.encoding import toUnicode, tryUrlencode
from couchpotato.core.helpers.rss import RSS
@ -62,9 +63,11 @@ class NzbIndex(NZBProvider, RSS):
try:
description = self.getTextElement(nzb, "description")
if ' nfo' in description.lower():
nfo_url = re.search('href="(?P<nfo>.+)"', description).group('nfo')
description = toUnicode(self.getCache('nzbindex.%s' % nzbindex_id, nfo_url, timeout = 25920000))
if '/nfo/' in description.lower():
nfo_url = re.search('href=\"(?P<nfo>.+)\" ', description).group('nfo')
full_description = self.getCache('nzbindex.%s' % nzbindex_id, url = nfo_url, cache_timeout = 25920000)
html = BeautifulSoup(full_description)
description = toUnicode(html.find('pre', attrs = {'id':'nfo0'}).text)
except:
pass

2
couchpotato/core/providers/nzb/nzbmatrix/main.py

@ -51,7 +51,7 @@ class NZBMatrix(NZBProvider, RSS):
cache_key = 'nzbmatrix.%s.%s' % (movie['library'].get('identifier'), cat_ids)
single_cat = True
data = self.getCache(cache_key, url)
data = self.getCache(cache_key, url, cache_timeout = 1800, headers = {'User-Agent': 'CouchPotato'})
if data:
try:
try:

33
couchpotato/core/providers/nzb/nzbs/__init__.py

@ -1,33 +0,0 @@
from .main import Nzbs
def start():
return Nzbs()
config = [{
'name': 'nzbs',
'groups': [
{
'tab': 'searcher',
'subtab': 'providers',
'name': 'nzbs',
'description': 'Id and Key can be found <a href="http://nzbs.org/index.php?action=rss" target="_blank">on your nzbs.org RSS page</a>.',
'wizard': True,
'options': [
{
'name': 'enabled',
'type': 'enabler',
},
{
'name': 'id',
'label': 'Id',
'description': 'The number after "&amp;i="',
},
{
'name': 'api_key',
'label': 'Api Key',
'description': 'The string after "&amp;h="'
},
],
},
],
}]

96
couchpotato/core/providers/nzb/nzbs/main.py

@ -1,96 +0,0 @@
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.encoding import simplifyString, tryUrlencode
from couchpotato.core.helpers.rss import RSS
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.nzb.base import NZBProvider
from dateutil.parser import parse
import time
import xml.etree.ElementTree as XMLTree
log = CPLog(__name__)
class Nzbs(NZBProvider, RSS):
urls = {
'download': 'https://nzbs.org/index.php?action=getnzb&nzbid=%s%s',
'nfo': 'https://nzbs.org/index.php?action=view&nzbid=%s&nfo=1',
'detail': 'https://nzbs.org/index.php?action=view&nzbid=%s',
'api': 'https://nzbs.org/rss.php',
}
cat_ids = [
([4], ['720p', '1080p']),
([2], ['cam', 'ts', 'dvdrip', 'tc', 'brrip', 'r5', 'scr']),
([9], ['dvdr']),
]
cat_backup_id = 't2'
http_time_between_calls = 3 # Seconds
def search(self, movie, quality):
results = []
if self.isDisabled() or not self.isAvailable(self.urls['api'] + '?test' + self.getApiExt()):
return results
cat_id = self.getCatId(quality.get('identifier'))
arguments = tryUrlencode({
'action':'search',
'q': simplifyString(movie['library']['titles'][0]['title']),
'catid': cat_id[0],
'i': self.conf('id'),
'h': self.conf('api_key'),
})
url = "%s?%s" % (self.urls['api'], arguments)
cache_key = 'nzbs.%s.%s' % (movie['library'].get('identifier'), str(cat_id))
data = self.getCache(cache_key, url)
if data:
try:
try:
data = XMLTree.fromstring(data)
nzbs = self.getElements(data, 'channel/item')
except Exception, e:
log.debug('%s, %s' % (self.getName(), e))
return results
for nzb in nzbs:
id = int(self.getTextElement(nzb, "link").partition('nzbid=')[2])
new = {
'id': id,
'type': 'nzb',
'provider': self.getName(),
'name': self.getTextElement(nzb, "title"),
'age': self.calculateAge(int(time.mktime(parse(self.getTextElement(nzb, "pubDate")).timetuple()))),
'size': self.parseSize(self.getTextElement(nzb, "description").split('</a><br />')[1].split('">')[1]),
'url': self.urls['download'] % (id, self.getApiExt()),
'download': self.download,
'detail_url': self.urls['detail'] % id,
'description': self.getTextElement(nzb, "description"),
'check_nzb': True,
}
new['score'] = fireEvent('score.calculate', new, movie, single = True)
is_correct_movie = fireEvent('searcher.correct_movie',
nzb = new, movie = movie, quality = quality,
imdb_results = False, single_category = False, single = True)
if is_correct_movie:
results.append(new)
self.found(new)
return results
except SyntaxError:
log.error('Failed to parse XML response from NZBMatrix.com')
return results
def isEnabled(self):
return NZBProvider.isEnabled(self) and self.conf('enabled') and self.conf('id') and self.conf('api_key')
def getApiExt(self):
return '&i=%s&h=%s' % (self.conf('id'), self.conf('api_key'))

2
couchpotato/static/scripts/page/wanted.js

@ -243,7 +243,7 @@ window.addEvent('domready', function(){
create: function(){
var self = this;
self.el = new Element('a.files', {
self.el = new Element('a.directory', {
'title': 'Available files',
'events': {
'click': self.showFiles.bind(self)

Loading…
Cancel
Save