Browse Source

Nosql

pull/3111/head
Ruud 11 years ago
parent
commit
c3bc9c8591
  1. 6
      couchpotato/core/helpers/request.py
  2. 14
      couchpotato/core/media/_base/media/index.py
  3. 44
      couchpotato/core/media/_base/media/main.py
  4. 10
      couchpotato/core/media/movie/_base/main.py
  5. 10
      couchpotato/core/media/movie/_base/static/list.js
  6. 89
      couchpotato/core/media/movie/_base/static/movie.actions.js
  7. 22
      couchpotato/core/media/movie/_base/static/movie.js
  8. 2
      couchpotato/core/media/movie/_base/static/search.js
  9. 3
      couchpotato/core/media/movie/searcher/main.py
  10. 25
      couchpotato/core/media/movie/suggestion/main.py
  11. 4
      couchpotato/core/notifications/core/static/notification.js
  12. 21
      couchpotato/core/plugins/category/index.py
  13. 62
      couchpotato/core/plugins/category/main.py
  14. 8
      couchpotato/core/plugins/category/static/category.js
  15. 71
      couchpotato/core/plugins/profile/main.py
  16. 20
      couchpotato/core/plugins/profile/static/profile.js
  17. 3
      couchpotato/core/plugins/quality/main.py
  18. 2
      couchpotato/core/plugins/quality/static/quality.js
  19. 36
      couchpotato/core/plugins/release/main.py
  20. 5
      couchpotato/core/plugins/renamer/main.py
  21. 21
      couchpotato/core/plugins/scanner/main.py
  22. 27
      couchpotato/core/plugins/subtitle/main.py
  23. 2
      couchpotato/core/providers/info/_modifier/main.py
  24. 2
      couchpotato/core/providers/nzb/newznab/__init__.py
  25. 2
      couchpotato/core/settings/__init__.py
  26. 2
      couchpotato/runner.py
  27. 2
      couchpotato/static/scripts/page/home.js

6
couchpotato/core/helpers/request.py

@ -9,6 +9,7 @@ def getParams(params):
reg = re.compile('^[a-z0-9_\.]+$')
temp = {}
for param, value in sorted(params.items()):
nest = re.split("([\[\]]+)", param)
@ -44,7 +45,10 @@ def dictToList(params):
new = {}
for x, value in params.items():
try:
new_value = [dictToList(value[k]) for k in sorted(value.keys(), cmp = natcmp)]
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
sorted_keys = sorted(value.keys(), key = alphanum_key)
new_value = [dictToList(value[k]) for k in sorted_keys]
except:
new_value = value

14
couchpotato/core/media/_base/media/index.py

@ -92,20 +92,6 @@ from couchpotato.core.helpers.encoding import simplifyString"""
return key.rjust(32, '_').lower()
class YearIndex(TreeBasedIndex):
def __init__(self, *args, **kwargs):
kwargs['key_format'] = 'i'
super(YearIndex, self).__init__(*args, **kwargs)
def make_key(self, key):
return key
def make_key_value(self, data):
if data.get('_t') == 'media' and data.get('year') is not None:
return data['year'], None
class TitleIndex(TreeBasedIndex):
custom_header = """from CodernityDB.tree_index import TreeBasedIndex

44
couchpotato/core/media/_base/media/main.py

@ -1,13 +1,12 @@
import traceback
from couchpotato import get_session, tryInt, get_db
from couchpotato import tryInt, get_db
from couchpotato.api import addApiView
from couchpotato.core.event import fireEvent, fireEventAsync, addEvent
from couchpotato.core.helpers.encoding import toUnicode
from couchpotato.core.helpers.variable import splitString, getImdb, getTitle
from couchpotato.core.logger import CPLog
from couchpotato.core.media import MediaBase
from .index import MediaIMDBIndex, MediaStatusIndex, YearIndex, MediaTypeIndex, TitleSearchIndex, TitleIndex, StartsWithIndex
from couchpotato.core.settings.model import Media
from .index import MediaIMDBIndex, MediaStatusIndex, MediaTypeIndex, TitleSearchIndex, TitleIndex, StartsWithIndex
from string import ascii_lowercase
log = CPLog(__name__)
@ -102,12 +101,6 @@ class MediaPlugin(MediaBase):
log.debug('Index already exists')
db.edit_index(MediaTypeIndex(db.path, 'media_by_type'))
# Year index
try: db.add_index(YearIndex(db.path, 'media_year'))
except:
log.debug('Index already exists')
db.edit_index(YearIndex(db.path, 'media_year'))
# Title index
try: db.add_index(TitleIndex(db.path, 'media_title'))
except:
@ -377,46 +370,45 @@ class MediaPlugin(MediaBase):
def delete(self, media_id, delete_from = None):
try:
db = get_session()
db = get_db()
media = db.query(Media).filter_by(id = media_id).first()
media = db.get('id', media_id)
if media:
deleted = False
if delete_from == 'all':
db.delete(media)
db.commit()
deleted = True
else:
total_releases = len(media.releases)
media_releases = list(db.run('release', 'for_media', media['_id']))
total_releases = len(media_releases)
total_deleted = 0
new_movie_status = None
for release in media.releases:
new_media_status = None
for release in media_releases:
if delete_from in ['wanted', 'snatched', 'late']:
if release.get('status') != 'done':
db.delete(release)
total_deleted += 1
new_movie_status = 'done'
new_media_status = 'done'
elif delete_from == 'manage':
if release.get('status') == 'done':
db.delete(release)
total_deleted += 1
new_movie_status = 'active'
db.commit()
new_media_status = 'active'
if total_releases == total_deleted:
db.delete(media)
db.commit()
deleted = True
elif new_movie_status:
media.profile_id = None
media['status'] = new_status
db.commit()
elif new_media_status:
media['status'] = new_media_status
db.update(media)
else:
fireEvent('media.restatus', media.id, single = True)
fireEvent('media.restatus', media.get('_id'), single = True)
if deleted:
fireEvent('notify.frontend', type = 'movie.deleted', data = media.to_dict())
fireEvent('notify.frontend', type = 'media.deleted', data = media)
except:
log.error('Failed deleting media: %s', traceback.format_exc())
@ -453,7 +445,7 @@ class MediaPlugin(MediaBase):
move_to_wanted = True
profile = db.get('id', m['profile_id'])
media_releases = db.get_many('release', m['_id'])
media_releases = db.run('release', 'for_media', m['_id'])
for q_identifier in profile['qualities']:
index = profile['qualities'].index(q_identifier)

10
couchpotato/core/media/movie/_base/main.py

@ -94,7 +94,7 @@ class MovieBase(MovieTypeBase):
'identifier': params.get('identifier'),
'status': status if status else 'active',
'profile_id': params.get('profile_id', default_profile.get('_id')),
'category_id': tryInt(cat_id) if cat_id is not None and tryInt(cat_id) > 0 else None,
'category_id': cat_id if cat_id is not None and len(cat_id) > 0 else None,
}
new = False
@ -135,7 +135,7 @@ class MovieBase(MovieTypeBase):
fireEvent('release.delete', release['_id'], single = True)
m['profile_id'] = params.get('profile_id', default_profile.get('id'))
m['category_id'] = tryInt(cat_id) if cat_id is not None and tryInt(cat_id) > 0 else (m.get('category_id') or None)
m['category_id'] = cat_id if cat_id is not None and len(cat_id) > 0 else (m.get('category_id') or None)
else:
log.debug('Movie already exists, not updating: %s', params)
added = False
@ -198,7 +198,7 @@ class MovieBase(MovieTypeBase):
cat_id = kwargs.get('category_id')
if cat_id is not None:
m['category_id'] = tryInt(cat_id) if tryInt(cat_id) > 0 else None
m['category_id'] = cat_id if len(cat_id) > 0 else None
# Remove releases
for rel in db.run('release', 'for_media', m['_id']):
@ -209,12 +209,12 @@ class MovieBase(MovieTypeBase):
if kwargs.get('default_title'):
m['title'] = kwargs.get('default_title')
print m
db.update(m)
fireEvent('media.restatus', m['_id'])
m = db.get('id', media_id)
movie_dict = db.run('media', 'to_dict', m['_id'])
fireEventAsync('movie.searcher.single', movie_dict, on_complete = self.createNotifyFront(media_id))

10
couchpotato/core/media/movie/_base/static/list.js

@ -63,7 +63,7 @@ var MovieList = new Class({
self.movies.each(function(movie){
if(movie.get('_id') == notification.data._id){
movie.destroy();
delete self.movies_added[notification.data.id];
delete self.movies_added[notification.data._id];
self.setCounter(self.counter_count-1);
self.total_movies--;
}
@ -77,7 +77,7 @@ var MovieList = new Class({
var self = this;
self.fireEvent('movieAdded', notification);
if(self.options.add_new && !self.movies_added[notification.data.id] && notification.data.status.identifier == self.options.status){
if(self.options.add_new && !self.movies_added[notification.data._id] && notification.data.status == self.options.status){
window.scroll(0,0);
self.createMovie(notification.data, 'top');
self.setCounter(self.counter_count+1);
@ -180,7 +180,7 @@ var MovieList = new Class({
m.fireEvent('injected');
self.movies.include(m)
self.movies_added[movie.id] = true;
self.movies_added[movie._id] = true;
},
createNavigation: function(){
@ -259,8 +259,8 @@ var MovieList = new Class({
self.mass_edit_select_class = new Form.Check(self.mass_edit_select);
Quality.getActiveProfiles().each(function(profile){
new Element('option', {
'value': profile.id ? profile.id : profile.data.id,
'text': profile.label ? profile.label : profile.data.label
'value': profile.get('_id'),
'text': profile.get('label')
}).inject(self.mass_edit_quality)
});

89
couchpotato/core/media/movie/_base/static/movie.actions.js

@ -127,7 +127,7 @@ MA.Release = new Class({
self.showHelper();
App.on('movie.searcher.ended', function(notification){
if(self.movie.data.id != notification.data.id) return;
if(self.movie.data._id != notification.data._id) return;
self.releases = null;
if(self.options_container){
@ -143,30 +143,7 @@ MA.Release = new Class({
if(e)
(e).preventDefault();
if(self.releases)
self.createReleases();
else {
self.movie.busy(true);
Api.request('release.for_movie', {
'data': {
'id': self.movie.data.id
},
'onComplete': function(json){
self.movie.busy(false, 1);
if(json && json.releases){
self.releases = json.releases;
self.createReleases();
}
else
alert('Something went wrong, check the logs.');
}
});
}
},
@ -189,9 +166,9 @@ MA.Release = new Class({
new Element('span.provider', {'text': 'Provider'})
).inject(self.release_container)
self.releases.each(function(release){
self.movie.data.releases.each(function(release){
var quality = Quality.getProfile(release.quality_id) || {},
var quality = Quality.getQuality(release.quality) || {},
info = release.info,
provider = self.get(release, 'provider') + (release.info['provider_extra'] ? self.get(release, 'provider_extra') : '');
@ -209,12 +186,12 @@ MA.Release = new Class({
// Create release
var item = new Element('div', {
'class': 'item '+status.identifier,
'id': 'release_'+release.id
'class': 'item '+release.status,
'id': 'release_'+release._id
}).adopt(
new Element('span.name', {'text': release_name, 'title': release_name}),
new Element('span.status', {'text': status.identifier, 'class': 'release_status '+release.status}),
new Element('span.quality', {'text': quality.get('label') || 'n/a'}),
new Element('span.status', {'text': release.status, 'class': 'release_status '+release.status}),
new Element('span.quality', {'text': quality.label || 'n/a'}),
new Element('span.size', {'text': release.info['size'] ? Math.floor(self.get(release, 'size')) : 'n/a'}),
new Element('span.age', {'text': self.get(release, 'age')}),
new Element('span.score', {'text': self.get(release, 'score')}),
@ -243,32 +220,32 @@ MA.Release = new Class({
).inject(self.release_container);
release['el'] = item;
if(status.identifier == 'ignored' || status.identifier == 'failed' || status.identifier == 'snatched'){
if(!self.last_release || (self.last_release && self.last_release.status.identifier != 'snatched' && status.identifier == 'snatched'))
if(release.status == 'ignored' || release.status == 'failed' || release.status == 'snatched'){
if(!self.last_release || (self.last_release && self.last_release.status != 'snatched' && release.status == 'snatched'))
self.last_release = release;
}
else if(!self.next_release && status.identifier == 'available'){
else if(!self.next_release && release.status == 'available'){
self.next_release = release;
}
var update_handle = function(notification) {
if(notification.data.id != release.id) return;
if(notification.data._id != release._id) return;
var q = self.movie.quality.getElement('.q_id' + release.quality_id),
var q = self.movie.quality.getElement('.q_' + release.quality),
new_status = notification.data.status;
release.el.set('class', 'item ' + new_status);
var status_el = release.el.getElement('.release_status');
status_el.set('class', 'release_status ' + new_status);
status_el.set('text', new_status.identifier);
status_el.set('text', new_status);
if(!q && (new_status == 'snatched' || new_status == 'seeding' || new_status == 'done'))
var q = self.addQuality(release.quality_id);
if(q && !q.hasClass(new_status)) {
q.removeClass(release.status).addClass(new_status);
q.set('title', q.get('title').replace(status, new_status));
q.set('title', q.get('title').replace(release.status, new_status));
}
}
@ -277,12 +254,12 @@ MA.Release = new Class({
});
if(self.last_release)
self.release_container.getElements('#release_'+self.last_release.id).addClass('last_release');
self.release_container.getElements('#release_'+self.last_release._id).addClass('last_release');
if(self.next_release)
self.release_container.getElements('#release_'+self.next_release.id).addClass('next_release');
self.release_container.getElements('#release_'+self.next_release._id).addClass('next_release');
if(self.next_release || (self.last_release && ['ignored', 'failed'].indexOf(self.last_release.status.identifier) === false)){
if(self.next_release || (self.last_release && ['ignored', 'failed'].indexOf(self.last_release.status) === false)){
self.trynext_container = new Element('div.buttons.try_container').inject(self.release_container, 'top');
@ -385,7 +362,7 @@ MA.Release = new Class({
download: function(release){
var self = this;
var release_el = self.release_container.getElement('#release_'+release.id),
var release_el = self.release_container.getElement('#release_'+release._id),
icon = release_el.getElement('.download.icon2');
if(icon)
@ -393,7 +370,7 @@ MA.Release = new Class({
Api.request('release.manual_download', {
'data': {
'id': release.id
'id': release._id
},
'onComplete': function(json){
if(icon)
@ -416,7 +393,7 @@ MA.Release = new Class({
Api.request('release.ignore', {
'data': {
'id': release.id
'id': release._id
},
})
@ -623,14 +600,14 @@ MA.Edit = new Class({
self.category_select.show();
categories.each(function(category){
var category_id = category.data.id;
var category_id = category.data._id;
new Element('option', {
'value': category_id,
'text': category.data.label
}).inject(self.category_select);
if(self.movie.category && self.movie.category.data && self.movie.category.data.id == category_id)
if(self.movie.category && self.movie.category.data && self.movie.category.data._id == category_id)
self.category_select.set('value', category_id);
});
@ -859,29 +836,7 @@ MA.Files = new Class({
var self = this;
(e).preventDefault();
if(self.releases)
self.showFiles();
else {
self.movie.busy(true);
Api.request('release.for_movie', {
'data': {
'id': self.movie.data.id
},
'onComplete': function(json){
self.movie.busy(false, 1);
if(json && json.releases){
self.releases = json.releases;
self.showFiles();
}
else
alert('Something went wrong, check the logs.');
}
});
}
},

22
couchpotato/core/media/movie/_base/static/movie.js

@ -27,7 +27,7 @@ var Movie = new Class({
// Do refresh with new data
self.global_events['movie.update'] = function(notification){
if(self.data.id != notification.data.id) return;
if(self.data._id != notification.data._id) return;
self.busy(false);
self.removeView();
@ -38,7 +38,7 @@ var Movie = new Class({
// Add spinner on load / search
['media.busy', 'movie.searcher.started'].each(function(listener){
self.global_events[listener] = function(notification){
if(notification.data && (self.data.id == notification.data.id || (typeOf(notification.data.id) == 'array' && notification.data.id.indexOf(self.data.id) > -1)))
if(notification.data && (self.data._id == notification.data._id || (typeOf(notification.data._id) == 'array' && notification.data._id.indexOf(self.data._id) > -1)))
self.busy(true);
}
App.on(listener, self.global_events[listener]);
@ -46,7 +46,7 @@ var Movie = new Class({
// Remove spinner
self.global_events['movie.searcher.ended'] = function(notification){
if(notification.data && self.data.id == notification.data.id)
if(notification.data && self.data._id == notification.data._id)
self.busy(false)
}
App.on('movie.searcher.ended', self.global_events['movie.searcher.ended']);
@ -54,12 +54,12 @@ var Movie = new Class({
// Reload when releases have updated
self.global_events['release.update_status'] = function(notification){
var data = notification.data
if(data && self.data.id == data.movie_id){
if(data && self.data._id == data.movie_id){
if(!self.data.releases)
self.data.releases = [];
self.data.releases.push({'quality_identifier': data.quality_identifier, 'status': data.status});
self.data.releases.push({'quality': data.quality, 'status': data.status});
self.updateReleases();
}
}
@ -197,7 +197,7 @@ var Movie = new Class({
if(self.profile.data)
self.profile.getTypes().each(function(type){
var q = self.addQuality(type.quality_identifier || type.get('quality_identifier'));
var q = self.addQuality(type.get('quality'));
if((type.finish == true || type.get('finish')) && !q.hasClass('finish')){
q.addClass('finish');
q.set('title', q.get('title') + ' Will finish searching for this movie if this quality is found.')
@ -222,11 +222,11 @@ var Movie = new Class({
self.data.releases.each(function(release){
var q = self.quality.getElement('.q_id'+ release.quality_id),
var q = self.quality.getElement('.q_'+ release.quality),
status = release.status;
if(!q && (status == 'snatched' || status == 'seeding' || status == 'done'))
var q = self.addQuality(release.quality_identifier)
var q = self.addQuality(release.quality)
if (q && !q.hasClass(status)){
q.addClass(status);
@ -236,13 +236,13 @@ var Movie = new Class({
});
},
addQuality: function(quality_identifier){
addQuality: function(quality){
var self = this;
var q = Quality.getQuality(quality_identifier);
var q = Quality.getQuality(quality);
return new Element('span', {
'text': q.label,
'class': 'q_'+q.identifier + ' q_id' + q.id,
'class': 'q_'+q.identifier,
'title': ''
}).inject(self.quality);

2
couchpotato/core/media/movie/_base/static/search.js

@ -184,7 +184,7 @@ Block.Search.MovieItem = new Class({
self.category_select.show();
categories.each(function(category){
new Element('option', {
'value': category.data.id,
'value': category.data._id,
'text': category.data.label
}).inject(self.category_select);
});

3
couchpotato/core/media/movie/searcher/main.py

@ -139,7 +139,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
profile = db.get('id', movie['profile_id'])
quality_order = fireEvent('quality.order', single = True)
media_releases = db.get_many('release', movie['_id'])
media_releases = db.run('release', 'for_media', movie['_id'])
ret = False
@ -202,7 +202,6 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
fireEvent('notify.frontend', type = 'movie.searcher.ended', data = {'id': movie['_id']})
pass #db.close()
return ret
def correctRelease(self, nzb = None, media = None, quality = None, **kwargs):

25
couchpotato/core/media/movie/suggestion/main.py

@ -1,12 +1,9 @@
from couchpotato import get_session
from couchpotato import get_db
from couchpotato.api import addApiView
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.variable import splitString, removeDuplicate
from couchpotato.core.plugins.base import Plugin
from couchpotato.core.settings.model import Media, Library
from couchpotato.environment import Env
from sqlalchemy.orm import joinedload_all
from sqlalchemy.sql.expression import or_
class Suggestion(Plugin):
@ -28,12 +25,9 @@ class Suggestion(Plugin):
else:
if not movies or len(movies) == 0:
db = get_session()
active_movies = db.query(Media) \
.options(joinedload_all('library')) \
.filter(or_(*[Media.status.has(identifier = s) for s in ['active', 'done']])).all()
movies = [x.library.identifier for x in active_movies]
pass #db.close()
db = get_db()
active_movies = db.run('media', 'with_status', ['active', 'done'])
movies = [x['identifier'] for x in active_movies]
if not ignored or len(ignored) == 0:
ignored = splitString(Env.prop('suggest_ignore', default = ''))
@ -88,15 +82,10 @@ class Suggestion(Plugin):
# Get new results and add them
if len(new_suggestions) - 1 < limit:
db = get_session()
active_movies = db.query(Media) \
.join(Library) \
.with_entities(Library.identifier) \
.filter(Media.status_id.in_([active_status.get('id'), done_status.get('id')])).all()
movies = [x[0] for x in active_movies]
db = get_db()
active_movies = db.run('media', 'with_status', ['active', 'done'])
movies = [x['identifier'] for x in active_movies]
movies.extend(seen)
pass #db.close()
ignored.extend([x.get('imdb') for x in cached_suggestion])
suggestions = fireEvent('movie.suggest', movies = movies, ignore = removeDuplicate(ignored), single = True)

4
couchpotato/core/notifications/core/static/notification.js

@ -77,7 +77,7 @@ var NotificationBase = new Class({
var ids = []
rn.each(function(n){
ids.include(n.id)
ids.include(n._id)
})
}
@ -187,7 +187,7 @@ var NotificationBase = new Class({
new Element('a.close.icon2', {
'events': {
'click': function(){
self.markAsRead([data.id]);
self.markAsRead([data._id]);
hide_message();
}
}

21
couchpotato/core/plugins/category/index.py

@ -1,16 +1,29 @@
from hashlib import md5
from CodernityDB.tree_index import TreeBasedIndex
class CategoryIndex(TreeBasedIndex):
def __init__(self, *args, **kwargs):
kwargs['key_format'] = '32s'
kwargs['key_format'] = 'i'
super(CategoryIndex, self).__init__(*args, **kwargs)
def make_key(self, key):
return md5(key).hexdigest()
return key
def make_key_value(self, data):
if data.get('_t') == 'category':
return md5(data['media_id']).hexdigest(), None
return data.get('order', -99), None
class CategoryMediaIndex(TreeBasedIndex):
def __init__(self, *args, **kwargs):
kwargs['key_format'] = '32s'
super(CategoryMediaIndex, self).__init__(*args, **kwargs)
def make_key(self, key):
return str(key)
def make_key_value(self, data):
if data.get('_t') == 'media' and data.get('category_id'):
return str(data.get('category_id')), None

62
couchpotato/core/plugins/category/main.py

@ -1,12 +1,11 @@
import traceback
from couchpotato import get_session, get_db
from couchpotato import get_db
from couchpotato.api import addApiView
from couchpotato.core.event import addEvent
from couchpotato.core.helpers.encoding import toUnicode
from couchpotato.core.logger import CPLog
from couchpotato.core.plugins.base import Plugin
from .index import CategoryIndex
from couchpotato.core.settings.model import Media, Category
from .index import CategoryIndex, CategoryMediaIndex
log = CPLog(__name__)
@ -32,18 +31,25 @@ class CategoryPlugin(Plugin):
db = get_db()
# Release media_id index
# Category index
try:
db.add_index(CategoryIndex(db.path, 'category'))
except:
log.debug('Index already exists')
db.edit_index(CategoryIndex(db.path, 'category'))
# Category media_id index
try:
db.add_index(CategoryMediaIndex(db.path, 'category_media'))
except:
log.debug('Index already exists')
db.edit_index(CategoryMediaIndex(db.path, 'category_media'))
def allView(self, **kwargs):
return {
'success': True,
'list': self.all()
'categories': self.all()
}
def all(self):
@ -51,11 +57,7 @@ class CategoryPlugin(Plugin):
db = get_db()
categories = db.all('category', with_doc = True)
temp = []
for category in categories:
temp.append(category['doc'])
return temp
return [x['doc'] for x in categories]
def save(self, **kwargs):
@ -63,7 +65,8 @@ class CategoryPlugin(Plugin):
db = get_db()
category = {
'order': kwargs.get('order', 0),
'_t': 'category',
'order': kwargs.get('order', 999),
'label': toUnicode(kwargs.get('label', '')),
'ignored': toUnicode(kwargs.get('ignored', '')),
'preferred': toUnicode(kwargs.get('preferred', '')),
@ -96,26 +99,21 @@ class CategoryPlugin(Plugin):
def saveOrder(self, **kwargs):
try:
db = get_session()
db = get_db()
order = 0
for category_id in kwargs.get('ids', []):
c = db.query(Category).filter_by(id = category_id).first()
c.order = order
c = db.get('id', category_id)
c['order'] = order
db.update(c)
order += 1
db.commit()
pass #db.close()
return {
'success': True
}
except:
log.error('Failed: %s', traceback.format_exc())
db.rollback()
finally:
pass #db.close()
return {
'success': False
@ -124,32 +122,27 @@ class CategoryPlugin(Plugin):
def delete(self, id = None, **kwargs):
try:
db = get_session()
db = get_db()
success = False
message = ''
try:
c = db.query(Category).filter_by(id = id).first()
c = db.get('id', id)
db.delete(c)
db.commit()
# Force defaults on all empty category movies
self.removeFromMovie(id)
success = True
except Exception as e:
message = log.error('Failed deleting category: %s', e)
except:
message = log.error('Failed deleting category: %s', traceback.format_exc())
pass #db.close()
return {
'success': success,
'message': message
}
except:
log.error('Failed: %s', traceback.format_exc())
db.rollback()
finally:
pass #db.close()
return {
'success': False
@ -158,15 +151,12 @@ class CategoryPlugin(Plugin):
def removeFromMovie(self, category_id):
try:
db = get_session()
movies = db.query(Media).filter(Media.category_id == category_id).all()
db = get_db()
movies = [x['doc'] for x in db.get_many('category_media', category_id, with_doc = True)]
if len(movies) > 0:
for movie in movies:
movie.category_id = None
db.commit()
movie['category_id'] = None
db.update(movie)
except:
log.error('Failed: %s', traceback.format_exc())
db.rollback()
finally:
pass #db.close()

8
couchpotato/core/plugins/category/static/category.js

@ -86,7 +86,7 @@ var CategoryListBase = new Class({
getCategory: function(id){
return this.categories.filter(function(category){
return category.data.id == id
return category.data._id == id
}).pick()
},
@ -121,7 +121,7 @@ var CategoryListBase = new Class({
).inject(self.content)
Array.each(self.categories, function(category){
new Element('li', {'data-id': category.data.id}).adopt(
new Element('li', {'data-id': category.data._id}).adopt(
new Element('span.category_label', {
'text': category.data.label
}),
@ -258,7 +258,7 @@ var Category = new Class({
var self = this;
var data = {
'id' : self.data.id,
'id' : self.data._id,
'label' : self.el.getElement('.category_label input').get('value'),
'required' : self.el.getElement('.category_required input').get('value'),
'preferred' : self.el.getElement('.category_preferred input').get('value'),
@ -286,7 +286,7 @@ var Category = new Class({
(e).preventDefault();
Api.request('category.delete', {
'data': {
'id': self.data.id
'id': self.data._id
},
'useSpinner': true,
'spinnerOptions': {

71
couchpotato/core/plugins/profile/main.py

@ -1,8 +1,9 @@
import traceback
from couchpotato import get_session, get_db
from couchpotato import get_session, get_db, tryInt
from couchpotato.api import addApiView
from couchpotato.core.event import addEvent
from couchpotato.core.helpers.encoding import toUnicode
from couchpotato.core.helpers.variable import splitString
from couchpotato.core.logger import CPLog
from couchpotato.core.plugins.base import Plugin
from .index import ProfileIndex
@ -78,45 +79,41 @@ class ProfilePlugin(Plugin):
def save(self, **kwargs):
try:
db = get_session()
p = db.query(Profile).filter_by(id = kwargs.get('id')).first()
if not p:
p = Profile()
db.add(p)
p.label = toUnicode(kwargs.get('label'))
p.order = kwargs.get('order', p.order if p.order else 0)
p.core = kwargs.get('core', False)
db = get_db()
#delete old types
[db.delete(t) for t in p.types]
profile = {
'label': toUnicode(kwargs.get('label')),
'order': tryInt(kwargs.get('order', 999)),
'core': kwargs.get('core', False),
'qualities': [],
'wait_for': [],
'finish': []
}
# Update types
order = 0
for type in kwargs.get('types', []):
t = ProfileType(
order = order,
finish = type.get('finish') if order > 0 else 1,
wait_for = kwargs.get('wait_for'),
quality_id = type.get('quality_id')
)
p.types.append(t)
profile['qualities'].append(type.get('quality'))
profile['wait_for'].append(tryInt(type.get('wait_for')))
profile['finish'].append((tryInt(type.get('finish')) == 1) if order > 0 else True)
order += 1
db.commit()
id = kwargs.get('id')
try:
p = db.get('id', id)
except:
p = db.insert(profile)
p.update(profile)
profile_dict = p.to_dict(self.to_dict)
p['order'] = tryInt(kwargs.get('order', p.get('order', 999)))
db.update(p)
return {
'success': True,
'profile': profile_dict
'profile': p
}
except:
log.error('Failed: %s', traceback.format_exc())
db.rollback()
finally:
pass #db.close()
return {
'success': False
@ -129,26 +126,23 @@ class ProfilePlugin(Plugin):
def saveOrder(self, **kwargs):
try:
db = get_session()
db = get_db()
order = 0
for profile in kwargs.get('ids', []):
p = db.query(Profile).filter_by(id = profile).first()
p.hide = kwargs.get('hidden')[order]
p.order = order
order += 1
for profile_id in kwargs.get('ids', []):
p = db.get('id', profile_id)
p['hide'] = tryInt(kwargs.get('hidden')[order]) == 1
p['order'] = order
db.update(p)
db.commit()
order += 1
return {
'success': True
}
except:
log.error('Failed: %s', traceback.format_exc())
db.rollback()
finally:
pass #db.close()
return {
'success': False
@ -180,9 +174,6 @@ class ProfilePlugin(Plugin):
}
except:
log.error('Failed: %s', traceback.format_exc())
db.rollback()
finally:
pass #db.close()
return {
'success': False

20
couchpotato/core/plugins/profile/static/profile.js

@ -57,14 +57,16 @@ var Profile = new Class({
self.makeSortable();
// Combine qualities and properties into types
if(data.qualities){
data.types = [];
data.qualities.each(function(quality, nr){
data.types.include({
'quality_identifier': quality,
'quality': quality,
'finish': data.finish[nr] || false,
'wait_for': data.wait_for[nr] || 0
})
});
}
if(data.types)
data.types.each(self.addType.bind(self));
@ -112,16 +114,16 @@ var Profile = new Class({
var self = this;
var data = {
'id' : self.data.id,
'id' : self.data._id,
'label' : self.el.getElement('.quality_label input').get('value'),
'wait_for' : self.el.getElement('.wait_for input').get('value'),
'types': []
}
Array.each(self.type_container.getElements('.type'), function(type){
if(!type.hasClass('deleted') && type.getElement('select').get('value') > 0)
if(!type.hasClass('deleted') && type.getElement('select').get('value') != -1)
data.types.include({
'quality_identifier': type.getElement('select').get('value'),
'quality': type.getElement('select').get('value'),
'finish': +type.getElement('input[type=checkbox]').checked,
'wait_for': 0
});
@ -156,7 +158,7 @@ var Profile = new Class({
var self = this;
return self.types.filter(function(type){
return type.get('quality_identifier')
return type.get('quality')
});
},
@ -173,7 +175,7 @@ var Profile = new Class({
(e).preventDefault();
Api.request('profile.delete', {
'data': {
'id': self.data.id
'id': self.data._id
},
'useSpinner': true,
'spinnerOptions': {
@ -275,7 +277,7 @@ Profile.Type = new Class({
new Element('span.handle')
);
self.el[self.data.quality_identifier ? 'removeClass' : 'addClass']('is_empty');
self.el[self.data.quality ? 'removeClass' : 'addClass']('is_empty');
self.finish_class = new Form.Check(self.finish);
@ -302,7 +304,7 @@ Profile.Type = new Class({
}).inject(self.qualities)
});
self.qualities.set('value', self.data.quality_identifier);
self.qualities.set('value', self.data.quality);
return self.qualities;
@ -312,7 +314,7 @@ Profile.Type = new Class({
var self = this;
return {
'quality_identifier': self.qualities.get('value'),
'quality': self.qualities.get('value'),
'finish': +self.finish.checked,
'wait_for': 0
}

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

@ -138,9 +138,6 @@ class QualityPlugin(Plugin):
}
except:
log.error('Failed: %s', traceback.format_exc())
db.rollback()
finally:
pass #db.close()
return {
'success': False

2
couchpotato/core/plugins/quality/static/quality.js

@ -117,7 +117,7 @@ var QualityBase = new Class({
Array.each(self.profiles, function(profile){
var check;
new Element('li', {'data-id': profile.data.id}).adopt(
new Element('li', {'data-id': profile.data._id}).adopt(
check = new Element('input.inlay[type=checkbox]', {
'checked': !profile.data.hide,
'events': {

36
couchpotato/core/plugins/release/main.py

@ -42,18 +42,11 @@ class Release(Plugin):
'id': {'type': 'id', 'desc': 'ID of the release object in release-table'}
}
})
addApiView('release.for_movie', self.forMovieView, docs = {
'desc': 'Returns all releases for a movie. Ordered by score(desc)',
'params': {
'id': {'type': 'id', 'desc': 'ID of the movie'}
}
})
addEvent('release.add', self.add)
addEvent('release.download', self.download)
addEvent('release.try_download_result', self.tryDownloadResult)
addEvent('release.create_from_search', self.createFromSearch)
addEvent('release.for_movie', self.forMovie)
addEvent('release.delete', self.delete)
addEvent('release.clean', self.clean)
addEvent('release.update_status', self.updateStatus)
@ -266,7 +259,6 @@ class Release(Plugin):
if success:
fireEvent('notify.frontend', type = 'release.manual_download', data = True, message = 'Successfully snatched "%s"' % item['name'])
pass #db.close()
return {
'success': success == True
}
@ -352,10 +344,7 @@ class Release(Plugin):
except:
log.error('Failed storing download status: %s', traceback.format_exc())
db.rollback()
return False
finally:
pass #db.close()
return True
@ -431,31 +420,6 @@ class Release(Plugin):
return []
def forMovie(self, id = None):
db = get_session()
releases_raw = db.query(Relea) \
.options(joinedload_all('info')) \
.options(joinedload_all('files')) \
.filter(Relea.movie_id == id) \
.all()
releases = [r.to_dict({'info': {}, 'files': {}}) for r in releases_raw]
releases = sorted(releases, key = lambda k: k['info'].get('score', 0), reverse = True)
pass #db.close()
return releases
def forMovieView(self, id = None, **kwargs):
releases = self.forMovie(id)
return {
'releases': releases,
'success': True
}
def updateStatus(self, release_id, status = None):
if not status: return False

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

@ -591,7 +591,6 @@ class Renamer(Plugin):
break
self.renaming_started = False
pass #db.close()
def getRenameExtras(self, extra_type = '', replacements = None, folder_name = '', file_name = '', destination = '', group = None, current_file = '', remove_multiple = False):
if not group: group = {}
@ -845,7 +844,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
try:
db = get_db()
rels = list(db.get_many('release', 'with_status', ['snatched', 'seeding', 'missing']))
rels = list(db.run('release', 'with_status', ['snatched', 'seeding', 'missing']))
if not rels:
#No releases found that need status checking
@ -1058,8 +1057,6 @@ Remove it if you want it to be renamed (again, or at least let it try again)
if not rls:
log.error('Download ID %s from downloader %s not found in releases', (release_download.get('id'), release_download.get('downloader')))
pass #db.close()
if rls:
rls_dict = rls.to_dict({'info':{}})

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

@ -1,11 +1,9 @@
from couchpotato import get_session
from couchpotato.core.event import fireEvent, addEvent
from couchpotato.core.helpers.encoding import toUnicode, simplifyString, ss, sp
from couchpotato.core.helpers.encoding import toUnicode, simplifyString, sp
from couchpotato.core.helpers.variable import getExt, getImdb, tryInt, \
splitString
from couchpotato.core.logger import CPLog
from couchpotato.core.plugins.base import Plugin
from couchpotato.core.settings.model import File
from enzyme.exceptions import NoParserError, ParseError
from guessit import guess_movie_info
from subliminal.videos import Video
@ -352,7 +350,6 @@ class Scanner(Plugin):
release_download = None
# Determine file types
db = get_session()
processed_movies = {}
while True and not self.shuttingDown():
try:
@ -439,7 +436,6 @@ class Scanner(Plugin):
else:
log.debug('Found no movies in the folder %s', folder)
pass #db.close()
return processed_movies
def getMetaData(self, group, folder = '', release_download = None):
@ -594,21 +590,6 @@ class Scanner(Plugin):
except:
pass
# Check if path is already in db
if not imdb_id:
db = get_session()
for cf in files['movie']:
f = db.query(File).filter_by(path = toUnicode(cf)).first()
try:
imdb_id = f.library[0].identifier
log.debug('Found movie via database: %s', cf)
cur_file = cf
break
except:
pass
pass #db.close()
# Search based on identifiers
if not imdb_id:
for identifier in group['identifiers']:

27
couchpotato/core/plugins/subtitle/main.py

@ -1,10 +1,8 @@
from couchpotato import get_session
from couchpotato.core.event import addEvent, fireEvent
from couchpotato.core.event import addEvent
from couchpotato.core.helpers.encoding import toUnicode, sp
from couchpotato.core.helpers.variable import splitString
from couchpotato.core.logger import CPLog
from couchpotato.core.plugins.base import Plugin
from couchpotato.core.settings.model import Library, FileType
from couchpotato.environment import Env
import subliminal
import traceback
@ -19,29 +17,6 @@ class Subtitle(Plugin):
def __init__(self):
addEvent('renamer.before', self.searchSingle)
def searchLibrary(self):
# Get all active and online movies
db = get_session()
library = db.query(Library).all()
for movie in library.movies:
for release in movie.releases:
# get releases and their movie files
if release.get('status') == 'done':
files = []
for file in release.files.filter(FileType.status.has(identifier = 'movie')).all():
files.append(file.path)
# get subtitles for those files
subliminal.list_subtitles(files, cache_dir = Env.get('cache_dir'), multi = True, languages = self.getLanguages(), services = self.services)
pass #db.close()
def searchSingle(self, group):
if self.isDisabled(): return

2
couchpotato/core/providers/info/_modifier/main.py

@ -100,7 +100,7 @@ class MovieResultModifier(Plugin):
if media.get('status') == 'active':
temp['in_wanted'] = media
for release in db.get_many('release', media.get('_id'), with_doc = True):
for release in db.run('release', 'for_media', media.get('_id')):
if release.get('status') == 'done':
temp['in_library'] = media
except:

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

@ -29,7 +29,7 @@ config = [{
},
{
'name': 'host',
'default': 'nzb.su,dognzb.cr,nzbs.org,https://index.nzbgeek.info, https://smackdownonyou.com, https://www.nzbfinder.ws',
'default': 'api.nzb.su,dognzb.cr,nzbs.org,https://index.nzbgeek.info, https://smackdownonyou.com, https://www.nzbfinder.ws',
'description': 'The hostname of your newznab provider',
},
{

2
couchpotato/core/settings/__init__.py

@ -228,7 +228,7 @@ class Settings(object):
propert = db.get('property', identifier, with_doc = True)
prop = propert['doc']['value']
except:
self.log.debug('Property doesn\'t exist: %s', traceback.format_exc(0))
self.log.debug('Property "%s" doesn\'t exist: %s', (identifier, traceback.format_exc(0)))
return prop

2
couchpotato/runner.py

@ -86,8 +86,6 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En
db_path = toUnicode(os.path.join(data_dir, 'database'))
# Check if database exists
print db_path
db = ThreadSafeDatabase(db_path)
db_exists = db.exists()
if db_exists:

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

@ -62,7 +62,7 @@ Page.Home = new Class({
// Track movie added
var after_search = function(data){
if(notification.data.id != data.data.id) return;
if(notification.data._id != data.data._id) return;
// Force update after search
self.available_list.update();

Loading…
Cancel
Save