More NoSQL
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
from itertools import izip
|
||||
from CodernityDB.hash_index import HashIndex
|
||||
from CodernityDB.tree_index import MultiTreeBasedIndex
|
||||
from CodernityDB.tree_index import MultiTreeBasedIndex, TreeBasedIndex
|
||||
from hashlib import md5
|
||||
|
||||
|
||||
class MediaIMDBIndex(HashIndex):
|
||||
@@ -15,19 +17,27 @@ class MediaIMDBIndex(HashIndex):
|
||||
if data.get('type') == 'media' and data.get('identifier'):
|
||||
return int(data['identifier'].strip('t')), None
|
||||
|
||||
def run_with_status(self, db, status = []):
|
||||
|
||||
class MediaStatusIndex(HashIndex):
|
||||
status = list(status if isinstance(status, (list, tuple)) else [status])
|
||||
|
||||
for s in status:
|
||||
for ms in db.get_many('media_status', s, with_doc = True):
|
||||
yield ms['doc']
|
||||
|
||||
|
||||
class MediaStatusIndex(TreeBasedIndex):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['key_format'] = 's'
|
||||
kwargs['key_format'] = '16s'
|
||||
super(MediaStatusIndex, self).__init__(*args, **kwargs)
|
||||
|
||||
def make_key(self, key):
|
||||
return int(key.strip('t'))
|
||||
return md5(key).digest()
|
||||
|
||||
def make_key_value(self, data):
|
||||
if data.get('type') == 'media' and data.get('identifier'):
|
||||
return int(data['identifier'].strip('t')), None
|
||||
if data.get('type') == 'media' and data.get('status'):
|
||||
return md5(data.get('status')).digest(), None
|
||||
|
||||
|
||||
class TitleIndex(MultiTreeBasedIndex):
|
||||
@@ -58,3 +68,17 @@ from itertools import izip"""
|
||||
|
||||
def make_key(self, key):
|
||||
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('type') == 'media' and data.get('year') is not None:
|
||||
return data['year'], None
|
||||
|
||||
@@ -6,7 +6,7 @@ from couchpotato.core.helpers.encoding import toUnicode
|
||||
from couchpotato.core.helpers.variable import mergeDicts, splitString, getImdb, getTitle
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.media import MediaBase
|
||||
from .index import MediaIMDBIndex, TitleIndex, MediaStatusIndex
|
||||
from .index import MediaIMDBIndex, TitleIndex, MediaStatusIndex, YearIndex
|
||||
from couchpotato.core.settings.model import Library, LibraryTitle, Release, \
|
||||
Media
|
||||
from sqlalchemy.orm import joinedload_all
|
||||
@@ -77,23 +77,32 @@ class MediaPlugin(MediaBase):
|
||||
|
||||
db = get_db()
|
||||
|
||||
# IMDB index
|
||||
try:
|
||||
db.add_index(MediaIMDBIndex(db.path, 'media'))
|
||||
except:
|
||||
log.debug('Index already exists')
|
||||
db.update_index(MediaIMDBIndex(db.path, 'media'))
|
||||
db.edit_index(MediaIMDBIndex(db.path, 'media'))
|
||||
|
||||
# Title index
|
||||
try:
|
||||
db.add_index(TitleIndex(db.path, 'media_title'))
|
||||
except:
|
||||
log.debug('Index already exists')
|
||||
db.update_index(TitleIndex(db.path, 'media_title'))
|
||||
db.edit_index(TitleIndex(db.path, 'media_title'))
|
||||
|
||||
# Status index
|
||||
try:
|
||||
db.add_index(MediaStatusIndex(db.path, 'media_status'))
|
||||
except:
|
||||
log.debug('Index already exists')
|
||||
db.update_index(MediaStatusIndex(db.path, 'media_status'))
|
||||
db.edit_index(MediaStatusIndex(db.path, 'media_status'))
|
||||
|
||||
# Year index
|
||||
try: db.add_index(YearIndex(db.path, 'year'))
|
||||
except:
|
||||
log.debug('Index already exists')
|
||||
db.edit_index(YearIndex(db.path, 'year'))
|
||||
|
||||
def refresh(self, id = '', **kwargs):
|
||||
handlers = []
|
||||
|
||||
@@ -86,7 +86,7 @@ class CoreNotifier(Notification):
|
||||
try:
|
||||
db = get_db()
|
||||
for n in db.all('notification', with_doc = True):
|
||||
if n['doc']['added'] <= (int(time.time()) - 2419200):
|
||||
if n['doc'].get('time', 0) <= (int(time.time()) - 2419200):
|
||||
db.delete(n['doc'])
|
||||
except:
|
||||
log.error('Failed cleaning notification: %s', traceback.format_exc())
|
||||
@@ -162,7 +162,7 @@ class CoreNotifier(Notification):
|
||||
|
||||
n = {
|
||||
'type': 'notification',
|
||||
'time': time.time(),
|
||||
'time': int(time.time()),
|
||||
'message': toUnicode(message),
|
||||
'data': data
|
||||
}
|
||||
@@ -276,7 +276,7 @@ class CoreNotifier(Notification):
|
||||
notifications = db.all('notification_unread', with_doc = True)
|
||||
|
||||
for n in notifications:
|
||||
if n['doc'].get('added') > (time.time() - 259200):
|
||||
if n['doc'].get('time') > (time.time() - 259200):
|
||||
messages.append(n['doc'])
|
||||
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
from hashlib import md5
|
||||
from CodernityDB.tree_index import TreeBasedIndex
|
||||
|
||||
|
||||
class CategoryIndex(TreeBasedIndex):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['key_format'] = '16s'
|
||||
super(CategoryIndex, self).__init__(*args, **kwargs)
|
||||
|
||||
def make_key(self, key):
|
||||
return md5(key).digest()
|
||||
|
||||
def make_key_value(self, data):
|
||||
if data.get('type') == 'category':
|
||||
return md5(data['media_id']).digest(), None
|
||||
@@ -1,10 +1,11 @@
|
||||
import traceback
|
||||
from couchpotato import get_session
|
||||
from couchpotato import get_session, 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
|
||||
|
||||
log = CPLog(__name__)
|
||||
@@ -13,8 +14,6 @@ log = CPLog(__name__)
|
||||
class CategoryPlugin(Plugin):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('category.all', self.all)
|
||||
|
||||
addApiView('category.save', self.save)
|
||||
addApiView('category.save_order', self.saveOrder)
|
||||
addApiView('category.delete', self.delete)
|
||||
@@ -26,6 +25,20 @@ class CategoryPlugin(Plugin):
|
||||
}"""}
|
||||
})
|
||||
|
||||
addEvent('category.all', self.all)
|
||||
addEvent('database.setup', self.databaseSetup)
|
||||
|
||||
def databaseSetup(self):
|
||||
|
||||
db = get_db()
|
||||
|
||||
# Release media_id index
|
||||
try:
|
||||
db.add_index(CategoryIndex(db.path, 'category'))
|
||||
except:
|
||||
log.debug('Index already exists')
|
||||
db.edit_index(CategoryIndex(db.path, 'category'))
|
||||
|
||||
def allView(self, **kwargs):
|
||||
|
||||
return {
|
||||
@@ -35,47 +48,45 @@ class CategoryPlugin(Plugin):
|
||||
|
||||
def all(self):
|
||||
|
||||
db = get_session()
|
||||
categories = db.query(Category).all()
|
||||
db = get_db()
|
||||
categories = db.all('category', with_doc = True)
|
||||
|
||||
temp = []
|
||||
for category in categories:
|
||||
temp.append(category.to_dict())
|
||||
temp.append(category['doc'])
|
||||
|
||||
pass #db.close()
|
||||
return temp
|
||||
|
||||
def save(self, **kwargs):
|
||||
|
||||
try:
|
||||
db = get_session()
|
||||
db = get_db()
|
||||
|
||||
c = db.query(Category).filter_by(id = kwargs.get('id')).first()
|
||||
if not c:
|
||||
c = Category()
|
||||
db.add(c)
|
||||
category = {
|
||||
'order': kwargs.get('order', 0),
|
||||
'label': toUnicode(kwargs.get('label', '')),
|
||||
'ignored': toUnicode(kwargs.get('ignored', '')),
|
||||
'preferred': toUnicode(kwargs.get('preferred', '')),
|
||||
'required': toUnicode(kwargs.get('required', '')),
|
||||
'destination': toUnicode(kwargs.get('destination', '')),
|
||||
}
|
||||
|
||||
c.order = kwargs.get('order', c.order if c.order else 0)
|
||||
c.label = toUnicode(kwargs.get('label', ''))
|
||||
c.ignored = toUnicode(kwargs.get('ignored', ''))
|
||||
c.preferred = toUnicode(kwargs.get('preferred', ''))
|
||||
c.required = toUnicode(kwargs.get('required', ''))
|
||||
c.destination = toUnicode(kwargs.get('destination', ''))
|
||||
try:
|
||||
c = db.get('id', kwargs.get('id'))
|
||||
category['order'] = c.get('order', category['order'])
|
||||
c.update(category)
|
||||
|
||||
db.commit()
|
||||
db.update(c)
|
||||
except:
|
||||
c = db.insert(category)
|
||||
c.update(category)
|
||||
|
||||
category_dict = c.to_dict()
|
||||
|
||||
pass #db.close()
|
||||
return {
|
||||
'success': True,
|
||||
'category': category_dict
|
||||
'category': c
|
||||
}
|
||||
except:
|
||||
log.error('Failed: %s', traceback.format_exc())
|
||||
db.rollback()
|
||||
finally:
|
||||
pass #db.close()
|
||||
|
||||
return {
|
||||
'success': False,
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
from hashlib import md5
|
||||
from CodernityDB.tree_index import TreeBasedIndex
|
||||
from CodernityDB.tree_index import TreeBasedIndex, MultiTreeBasedIndex
|
||||
|
||||
|
||||
class ReleaseIndex(TreeBasedIndex):
|
||||
class NameIndex(TreeBasedIndex):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['key_format'] = '16s'
|
||||
super(ReleaseIndex, self).__init__(*args, **kwargs)
|
||||
super(NameIndex, self).__init__(*args, **kwargs)
|
||||
|
||||
def make_key(self, key):
|
||||
return md5(key).digest()
|
||||
return key
|
||||
|
||||
def make_key_value(self, data):
|
||||
if data.get('type') == 'release':
|
||||
return md5(data['media_id']).digest(), None
|
||||
if data.get('type') == 'media' and data.get('title') is not None:
|
||||
return data.get('title'), None
|
||||
|
||||
def run_for_media(self, db, media_id):
|
||||
for release in db.get_many('release', media_id, with_doc=True):
|
||||
yield release['doc']
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import time
|
||||
from couchpotato import CPLog
|
||||
from couchpotato import CPLog, get_db
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
from .index import ReleaseIndex, MediaIMDBIndex, TitleIndex
|
||||
from .index import ReleaseIndex, NameIndex
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
@@ -10,9 +11,20 @@ class NoSQL(Plugin):
|
||||
|
||||
db = None
|
||||
|
||||
def __init__(self):
|
||||
|
||||
pass #addEvent('app.load2', self.test)
|
||||
|
||||
def test(self):
|
||||
|
||||
db = self.db
|
||||
db = get_db()
|
||||
|
||||
try: db.add_index(YearIndex(db.path, 'year'))
|
||||
except:
|
||||
log.debug('Index already exists')
|
||||
db.edit_index(YearIndex(db.path, 'year'))
|
||||
|
||||
return
|
||||
|
||||
try: db.add_index(ReleaseIndex(db.path, 'release'))
|
||||
except: log.debug('Index already exists')
|
||||
@@ -54,8 +66,6 @@ class NoSQL(Plugin):
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
for media in db.all('media', with_doc = True):
|
||||
doc = media['doc']
|
||||
for r in db.run('release', 'for_media', media['_id']):
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
from CodernityDB.hash_index import HashIndex
|
||||
from hashlib import md5
|
||||
|
||||
|
||||
class ProfileIndex(HashIndex):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['key_format'] = '16s'
|
||||
super(ProfileIndex, self).__init__(*args, **kwargs)
|
||||
|
||||
def make_key(self, key):
|
||||
return md5(key).digest()
|
||||
|
||||
def make_key_value(self, data):
|
||||
if data.get('type') == 'profile' and data.get('identifier'):
|
||||
return md5(data.get('identifier')).digest(), None
|
||||
@@ -5,6 +5,7 @@ from couchpotato.core.event import addEvent, fireEvent
|
||||
from couchpotato.core.helpers.encoding import toUnicode
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
from .index import ProfileIndex
|
||||
from couchpotato.core.settings.model import Profile, ProfileType, Media
|
||||
from sqlalchemy.orm import joinedload_all
|
||||
|
||||
@@ -30,9 +31,22 @@ class ProfilePlugin(Plugin):
|
||||
}"""}
|
||||
})
|
||||
|
||||
addEvent('database.setup', self.databaseSetup)
|
||||
|
||||
addEvent('app.initialize', self.fill, priority = 90)
|
||||
addEvent('app.load2', self.forceDefaults)
|
||||
|
||||
def databaseSetup(self):
|
||||
|
||||
db = get_db()
|
||||
|
||||
try:
|
||||
db.add_index(ProfileIndex(db.path, 'profile'))
|
||||
except:
|
||||
log.debug('Index already exists')
|
||||
db.edit_index(ProfileIndex(db.path, 'profile'))
|
||||
|
||||
|
||||
def forceDefaults(self):
|
||||
|
||||
# Get all active movies without profile
|
||||
@@ -112,15 +126,8 @@ class ProfilePlugin(Plugin):
|
||||
}
|
||||
|
||||
def default(self):
|
||||
|
||||
db = get_session()
|
||||
default = db.query(Profile) \
|
||||
.options(joinedload_all('types')) \
|
||||
.first()
|
||||
default_dict = default.to_dict(self.to_dict)
|
||||
pass #db.close()
|
||||
|
||||
return default_dict
|
||||
db = get_db()
|
||||
return db.get_many('profile', limit = 1, with_doc = True)[0]
|
||||
|
||||
def saveOrder(self, **kwargs):
|
||||
|
||||
@@ -187,7 +194,7 @@ class ProfilePlugin(Plugin):
|
||||
def fill(self):
|
||||
|
||||
try:
|
||||
db = get_session()
|
||||
db = get_db()
|
||||
|
||||
profiles = [{
|
||||
'label': 'Best',
|
||||
@@ -201,38 +208,32 @@ class ProfilePlugin(Plugin):
|
||||
}]
|
||||
|
||||
# Create default quality profile
|
||||
order = -2
|
||||
order = 0
|
||||
for profile in profiles:
|
||||
log.info('Creating default profile: %s', profile.get('label'))
|
||||
p = Profile(
|
||||
label = toUnicode(profile.get('label')),
|
||||
order = order
|
||||
)
|
||||
db.add(p)
|
||||
|
||||
quality_order = 0
|
||||
for quality in profile.get('qualities'):
|
||||
quality = fireEvent('quality.single', identifier = quality, single = True)
|
||||
profile_type = ProfileType(
|
||||
quality_id = quality.get('id'),
|
||||
profile = p,
|
||||
finish = True,
|
||||
wait_for = 0,
|
||||
order = quality_order
|
||||
)
|
||||
p.types.append(profile_type)
|
||||
pro = {
|
||||
'type': 'profile',
|
||||
'identifier': profile.get('label').lower(),
|
||||
'label': toUnicode(profile.get('label')),
|
||||
'order': order,
|
||||
'qualities': profile.get('qualities'),
|
||||
'finish': [],
|
||||
'wait_for': []
|
||||
}
|
||||
|
||||
quality_order += 1
|
||||
for q in profile.get('qualities'):
|
||||
pro['finish'].append(True)
|
||||
pro['wait_for'].append(0)
|
||||
|
||||
db.insert(pro)
|
||||
order += 1
|
||||
|
||||
db.commit()
|
||||
for x in db.all('profile', with_doc = True):
|
||||
log.info(x)
|
||||
|
||||
return True
|
||||
except:
|
||||
log.error('Failed: %s', traceback.format_exc())
|
||||
db.rollback()
|
||||
finally:
|
||||
pass #db.close()
|
||||
|
||||
return False
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
from hashlib import md5
|
||||
from CodernityDB.tree_index import TreeBasedIndex
|
||||
|
||||
|
||||
class ReleaseIndex(TreeBasedIndex):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['key_format'] = '16s'
|
||||
super(ReleaseIndex, self).__init__(*args, **kwargs)
|
||||
|
||||
def make_key(self, key):
|
||||
return md5(key).digest()
|
||||
|
||||
def make_key_value(self, data):
|
||||
if data.get('type') == 'release' and data.get('media_id'):
|
||||
return md5(data['media_id']).digest(), {'media_id': data.get('media_id')}
|
||||
|
||||
def run_for_media(self, db, media_id):
|
||||
for release in db.get_many('release', media_id, with_doc = True):
|
||||
yield release['doc']
|
||||
|
||||
def run_with_status(self, db, status = []):
|
||||
|
||||
status = list(status if isinstance(status, (list, tuple)) else [status])
|
||||
|
||||
for s in status:
|
||||
for ms in db.get_many('release_status', s, with_doc = True):
|
||||
yield ms['doc']
|
||||
|
||||
|
||||
class ReleaseStatusIndex(TreeBasedIndex):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['key_format'] = '16s'
|
||||
super(ReleaseStatusIndex, self).__init__(*args, **kwargs)
|
||||
|
||||
def make_key(self, key):
|
||||
return md5(key).digest()
|
||||
|
||||
def make_key_value(self, data):
|
||||
if data.get('type') == 'release' and data.get('status'):
|
||||
return md5(data.get('status')).digest(), None
|
||||
@@ -5,8 +5,9 @@ from couchpotato.core.helpers.encoding import ss, toUnicode
|
||||
from couchpotato.core.helpers.variable import getTitle
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
from .index import ReleaseIndex, ReleaseStatusIndex
|
||||
from couchpotato.core.plugins.scanner.main import Scanner
|
||||
from couchpotato.core.settings.model import File, Release as Relea, Media, \
|
||||
from couchpotato.core.settings.model import Release as Relea, Media, \
|
||||
ReleaseInfo
|
||||
from couchpotato.environment import Env
|
||||
from inspect import ismethod, isfunction
|
||||
@@ -23,8 +24,6 @@ log = CPLog(__name__)
|
||||
class Release(Plugin):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('release.add', self.add)
|
||||
|
||||
addApiView('release.manual_download', self.manualDownload, docs = {
|
||||
'desc': 'Send a release manually to the downloaders',
|
||||
'params': {
|
||||
@@ -50,6 +49,7 @@ class Release(Plugin):
|
||||
}
|
||||
})
|
||||
|
||||
addEvent('release.add', self.add)
|
||||
addEvent('release.download', self.download)
|
||||
addEvent('release.try_download_result', self.tryDownloadResult)
|
||||
addEvent('release.create_from_search', self.createFromSearch)
|
||||
@@ -58,43 +58,59 @@ class Release(Plugin):
|
||||
addEvent('release.clean', self.clean)
|
||||
addEvent('release.update_status', self.updateStatus)
|
||||
|
||||
addEvent('database.setup', self.databaseSetup)
|
||||
|
||||
# Clean releases that didn't have activity in the last week
|
||||
addEvent('app.load', self.cleanDone)
|
||||
addEvent('app.load2', self.cleanDone)
|
||||
fireEvent('schedule.interval', 'movie.clean_releases', self.cleanDone, hours = 4)
|
||||
|
||||
def cleanDone(self):
|
||||
def databaseSetup(self):
|
||||
|
||||
db = get_db()
|
||||
|
||||
# Release media_id index
|
||||
try:
|
||||
db.add_index(ReleaseIndex(db.path, 'release'))
|
||||
except:
|
||||
log.debug('Index already exists')
|
||||
db.edit_index(ReleaseIndex(db.path, 'release'))
|
||||
|
||||
# Release status index
|
||||
try:
|
||||
db.add_index(ReleaseStatusIndex(db.path, 'release_status'))
|
||||
except:
|
||||
log.debug('Index already exists')
|
||||
db.edit_index(ReleaseStatusIndex(db.path, 'release_status'))
|
||||
|
||||
def cleanDone(self):
|
||||
log.debug('Removing releases from dashboard')
|
||||
|
||||
now = time.time()
|
||||
week = 262080
|
||||
|
||||
done_status, available_status, snatched_status, downloaded_status, ignored_status = \
|
||||
fireEvent('status.get', ['done', 'available', 'snatched', 'downloaded', 'ignored'], single = True)
|
||||
|
||||
db = get_db()
|
||||
|
||||
# get movies last_edit more than a week ago
|
||||
medias = db.run('media', 'with_status', ['done'])
|
||||
|
||||
for media in medias:
|
||||
if media['last_edit'] > (now - week):
|
||||
if media.get('last_edit', 0) > (now - week):
|
||||
continue
|
||||
|
||||
for rel in db.run('release', 'for_media', media['_id']):
|
||||
|
||||
# Remove all available releases
|
||||
if rel['status'] in ['available']:
|
||||
fireEvent('release.delete', id = rel['_id'], single = True)
|
||||
self.delete(rel['_id'])
|
||||
|
||||
# Set all snatched and downloaded releases to ignored to make sure they are ignored when re-adding the move
|
||||
elif rel['status'] in ['snatched', 'downloaded']:
|
||||
self.updateStatus(id = rel['id'], status = ignored_status)
|
||||
|
||||
self.updateStatus(rel['_id'], status = 'ignore')
|
||||
|
||||
def add(self, group):
|
||||
|
||||
try:
|
||||
db = get_db()
|
||||
db = get_session()
|
||||
|
||||
identifier = '%s.%s.%s' % (group['library']['identifier'], group['meta_data'].get('audio', 'unknown'), group['meta_data']['quality']['identifier'])
|
||||
|
||||
@@ -160,9 +176,8 @@ class Release(Plugin):
|
||||
|
||||
try:
|
||||
db = get_db()
|
||||
|
||||
rel = db.get('release', release_id, with_doc = True)
|
||||
db.delete(rel['doc'])
|
||||
rel = db.get('id', release_id)
|
||||
db.delete(rel)
|
||||
return True
|
||||
except:
|
||||
log.error('Failed: %s', traceback.format_exc())
|
||||
@@ -173,16 +188,17 @@ class Release(Plugin):
|
||||
|
||||
try:
|
||||
db = get_db()
|
||||
rel = db.get('id', release_id)
|
||||
|
||||
rel = db.get('release', release_id, with_doc = True)
|
||||
files = []
|
||||
for release_file in rel['files']:
|
||||
if os.path.isfile(ss(release_file['path'])):
|
||||
files.append(release_file)
|
||||
|
||||
if len(rel['files']) == 0:
|
||||
if len(rel.get('files')) == 0:
|
||||
self.delete(rel['_id'])
|
||||
else:
|
||||
|
||||
files = []
|
||||
for release_file in rel.get('files'):
|
||||
if os.path.isfile(ss(release_file['path'])):
|
||||
files.append(release_file)
|
||||
|
||||
rel['files'] = files
|
||||
db.update(rel)
|
||||
|
||||
@@ -197,7 +213,7 @@ class Release(Plugin):
|
||||
db = get_db()
|
||||
|
||||
try:
|
||||
rel = db.get('release', release_id, with_doc = True)['doc']
|
||||
rel = db.get('id', release_id, with_doc = True)
|
||||
self.updateStatus(release_id, 'available' if rel['status'] in ['ignored', 'failed'] else 'ignored')
|
||||
|
||||
return {
|
||||
@@ -453,42 +469,34 @@ class Release(Plugin):
|
||||
'success': True
|
||||
}
|
||||
|
||||
def updateStatus(self, id, status = None):
|
||||
def updateStatus(self, release_id, status = None):
|
||||
if not status: return False
|
||||
|
||||
try:
|
||||
db = get_session()
|
||||
db = get_db()
|
||||
|
||||
rel = db.query(Relea).filter_by(id = id).first()
|
||||
if rel and status and rel.status_id != status.get('id'):
|
||||
rel = db.get('id', release_id)
|
||||
if rel and rel.get('status') != status:
|
||||
|
||||
item = {}
|
||||
for info in rel.info:
|
||||
item[info.identifier] = info.value
|
||||
|
||||
release_name = None
|
||||
if rel.files:
|
||||
for file_item in rel.files:
|
||||
if file_item.type.identifier == 'movie':
|
||||
release_name = os.path.basename(file_item.path)
|
||||
release_name = rel.get('name')
|
||||
if rel.get('files'):
|
||||
for file_item in rel.get('files', []):
|
||||
if file_item.get('type') == 'movie':
|
||||
release_name = os.path.basename(file_item.get('path'))
|
||||
break
|
||||
else:
|
||||
release_name = item['name']
|
||||
|
||||
#update status in Db
|
||||
log.debug('Marking release %s as %s', (release_name, status.get("label")))
|
||||
rel.status_id = status.get('id')
|
||||
rel.last_edit = int(time.time())
|
||||
db.commit()
|
||||
log.debug('Marking release %s as %s', (release_name, status))
|
||||
rel['status'] = status
|
||||
rel['last_edit'] = int(time.time())
|
||||
|
||||
db.update(rel)
|
||||
|
||||
#Update all movie info as there is no release update function
|
||||
fireEvent('notify.frontend', type = 'release.update_status', data = rel.to_dict())
|
||||
fireEvent('notify.frontend', type = 'release.update_status', data = rel)
|
||||
|
||||
return True
|
||||
except:
|
||||
log.error('Failed: %s', traceback.format_exc())
|
||||
db.rollback()
|
||||
finally:
|
||||
pass #db.close()
|
||||
|
||||
return False
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from couchpotato import get_session
|
||||
from couchpotato import get_session, get_db
|
||||
from couchpotato.api import addApiView
|
||||
from couchpotato.core.event import addEvent, fireEvent, fireEventAsync
|
||||
from couchpotato.core.helpers.encoding import toUnicode, ss, sp
|
||||
@@ -6,7 +6,7 @@ from couchpotato.core.helpers.variable import getExt, mergeDicts, getTitle, \
|
||||
getImdb, link, symlink, tryInt, splitString, fnEscape, isSubFolder
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
from couchpotato.core.settings.model import Library, File, Profile, Release, \
|
||||
from couchpotato.core.settings.model import Library, File, Profile, \
|
||||
ReleaseInfo
|
||||
from couchpotato.environment import Env
|
||||
from unrar2 import RarFile
|
||||
@@ -45,7 +45,7 @@ class Renamer(Plugin):
|
||||
addEvent('renamer.scan', self.scan)
|
||||
addEvent('renamer.check_snatched', self.checkSnatched)
|
||||
|
||||
addEvent('app.load', self.scan)
|
||||
addEvent('app.load2', self.scan)
|
||||
addEvent('app.load', self.setCrons)
|
||||
|
||||
# Enable / disable interval
|
||||
@@ -211,10 +211,6 @@ class Renamer(Plugin):
|
||||
nfo_name = self.conf('nfo_name')
|
||||
separator = self.conf('separator')
|
||||
|
||||
# Statuses
|
||||
done_status, active_status, downloaded_status, snatched_status, seeding_status = \
|
||||
fireEvent('status.get', ['done', 'active', 'downloaded', 'snatched', 'seeding'], single = True)
|
||||
|
||||
# Tag release folder as failed_rename in case no groups were found. This prevents check_snatched from removing the release from the downloader.
|
||||
if not groups and self.statusInfoComplete(release_download):
|
||||
self.tagRelease(release_download = release_download, tag = 'failed_rename')
|
||||
@@ -849,14 +845,10 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
|
||||
self.checking_snatched = True
|
||||
|
||||
snatched_status, ignored_status, failed_status, seeding_status, downloaded_status, missing_status = \
|
||||
fireEvent('status.get', ['snatched', 'ignored', 'failed', 'seeding', 'downloaded', 'missing'], single = True)
|
||||
|
||||
try:
|
||||
db = get_session()
|
||||
rels = db.query(Release).filter(
|
||||
Release.status_id.in_([snatched_status.get('id'), seeding_status.get('id'), missing_status.get('id')])
|
||||
).all()
|
||||
db = get_db()
|
||||
|
||||
rels = list(db.get_many('release', 'with_status', ['snatched', 'seeding', 'missing']))
|
||||
|
||||
if not rels:
|
||||
#No releases found that need status checking
|
||||
@@ -868,13 +860,12 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
no_status_support = []
|
||||
try:
|
||||
for rel in rels:
|
||||
rel_dict = rel.to_dict({'info': {}})
|
||||
if rel_dict['info'].get('download_id') and rel_dict['info'].get('download_downloader'):
|
||||
download_ids.append({'id': rel_dict['info']['download_id'], 'downloader': rel_dict['info']['download_downloader']})
|
||||
if rel['info'].get('download_id') and rel['info'].get('download_downloader'):
|
||||
download_ids.append({'id': rel['info']['download_id'], 'downloader': rel['info']['download_downloader']})
|
||||
|
||||
ds = rel_dict['info'].get('download_status_support')
|
||||
if ds == False or ds == 'False':
|
||||
no_status_support.append(ss(rel_dict['info'].get('download_downloader')))
|
||||
ds = rel['info'].get('download_status_support')
|
||||
if ds is False or ds == 'False':
|
||||
no_status_support.append(ss(rel['info'].get('download_downloader')))
|
||||
except:
|
||||
log.error('Error getting download IDs from database')
|
||||
self.checking_snatched = False
|
||||
@@ -899,35 +890,34 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
|
||||
try:
|
||||
for rel in rels:
|
||||
rel_dict = rel.to_dict({'info': {}})
|
||||
movie_dict = fireEvent('media.get', media_id = rel.movie_id, single = True)
|
||||
movie_dict = db.get('id', rel.get('media_id'))
|
||||
|
||||
if not isinstance(rel_dict['info'], dict):
|
||||
if not isinstance(rel['info'], dict):
|
||||
log.error('Faulty release found without any info, ignoring.')
|
||||
fireEvent('release.update_status', rel.id, status = ignored_status, single = True)
|
||||
fireEvent('release.update_status', rel.get('_id'), status = 'ignored', single = True)
|
||||
continue
|
||||
|
||||
# Check if download ID is available
|
||||
if not rel_dict['info'].get('download_id') or not rel_dict['info'].get('download_downloader'):
|
||||
log.debug('Download status functionality is not implemented for downloader (%s) of release %s.', (rel_dict['info'].get('download_downloader', 'unknown'), rel_dict['info']['name']))
|
||||
if not rel['info'].get('download_id') or not rel['info'].get('download_downloader'):
|
||||
log.debug('Download status functionality is not implemented for downloader (%s) of release %s.', (rel['info'].get('download_downloader', 'unknown'), rel['info']['name']))
|
||||
scan_required = True
|
||||
|
||||
# Continue with next release
|
||||
continue
|
||||
|
||||
# Find release in downloaders
|
||||
nzbname = self.createNzbName(rel_dict['info'], movie_dict)
|
||||
nzbname = self.createNzbName(rel['info'], movie_dict)
|
||||
|
||||
found_release = False
|
||||
for release_download in release_downloads:
|
||||
found_release = False
|
||||
if rel_dict['info'].get('download_id'):
|
||||
if release_download['id'] == rel_dict['info']['download_id'] and release_download['downloader'] == rel_dict['info']['download_downloader']:
|
||||
if rel['info'].get('download_id'):
|
||||
if release_download['id'] == rel['info']['download_id'] and release_download['downloader'] == rel['info']['download_downloader']:
|
||||
log.debug('Found release by id: %s', release_download['id'])
|
||||
found_release = True
|
||||
break
|
||||
else:
|
||||
if release_download['name'] == nzbname or rel_dict['info']['name'] in release_download['name'] or getImdb(release_download['name']) == movie_dict['library']['identifier']:
|
||||
if release_download['name'] == nzbname or rel['info']['name'] in release_download['name'] or getImdb(release_download['name']) == movie_dict['library']['identifier']:
|
||||
log.debug('Found release by release name or imdb ID: %s', release_download['name'])
|
||||
found_release = True
|
||||
break
|
||||
@@ -936,12 +926,12 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
log.info('%s not found in downloaders', nzbname)
|
||||
|
||||
#Check status if already missing and for how long, if > 1 week, set to ignored else to missing
|
||||
if rel.status_id == missing_status.get('id'):
|
||||
if rel.get('status') == 'missing':
|
||||
if rel.last_edit < int(time.time()) - 7 * 24 * 60 * 60:
|
||||
fireEvent('release.update_status', rel.id, status = ignored_status, single = True)
|
||||
fireEvent('release.update_status', rel.get('_id'), status = 'ignored', single = True)
|
||||
else:
|
||||
# Set the release to missing
|
||||
fireEvent('release.update_status', rel.id, status = missing_status, single = True)
|
||||
fireEvent('release.update_status', rel.get('_id'), status = 'missing', single = True)
|
||||
|
||||
# Continue with next release
|
||||
continue
|
||||
@@ -953,7 +943,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
# Check status of release
|
||||
if release_download['status'] == 'busy':
|
||||
# Set the release to snatched if it was missing before
|
||||
fireEvent('release.update_status', rel.id, status = snatched_status, single = True)
|
||||
fireEvent('release.update_status', rel.get('_id'), status = 'snatched', single = True)
|
||||
|
||||
# Tag folder if it is in the 'from' folder and it will not be processed because it is still downloading
|
||||
if self.movieInFromFolder(release_download['folder']):
|
||||
@@ -961,7 +951,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
|
||||
elif release_download['status'] == 'seeding':
|
||||
#If linking setting is enabled, process release
|
||||
if self.conf('file_action') != 'move' and not rel.status_id == seeding_status.get('id') and self.statusInfoComplete(release_download):
|
||||
if self.conf('file_action') != 'move' and not rel.status_id == 'seeding' and self.statusInfoComplete(release_download):
|
||||
log.info('Download of %s completed! It is now being processed while leaving the original files alone for seeding. Current ratio: %s.', (release_download['name'], release_download['seed_ratio']))
|
||||
|
||||
# Remove the downloading tag
|
||||
@@ -975,16 +965,16 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
log.debug('%s is seeding with ratio: %s', (release_download['name'], release_download['seed_ratio']))
|
||||
|
||||
# Set the release to seeding
|
||||
fireEvent('release.update_status', rel.id, status = seeding_status, single = True)
|
||||
fireEvent('release.update_status', rel.get('_id'), status = 'seeding', single = True)
|
||||
|
||||
elif release_download['status'] == 'failed':
|
||||
# Set the release to failed
|
||||
fireEvent('release.update_status', rel.id, status = failed_status, single = True)
|
||||
fireEvent('release.update_status', rel.get('_id'), status = 'failed', single = True)
|
||||
|
||||
fireEvent('download.remove_failed', release_download, single = True)
|
||||
|
||||
if self.conf('next_on_failed'):
|
||||
fireEvent('movie.searcher.try_next_release', media_id = rel.movie_id)
|
||||
fireEvent('movie.searcher.try_next_release', media_id = rel.get('media_id'))
|
||||
|
||||
elif release_download['status'] == 'completed':
|
||||
log.info('Download of %s completed!', release_download['name'])
|
||||
@@ -993,10 +983,10 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
if self.statusInfoComplete(release_download):
|
||||
|
||||
# If the release has been seeding, process now the seeding is done
|
||||
if rel.status_id == seeding_status.get('id'):
|
||||
if rel.get('status') == 'seeding':
|
||||
if self.conf('file_action') != 'move':
|
||||
# Set the release to done as the movie has already been renamed
|
||||
fireEvent('release.update_status', rel.id, status = downloaded_status, single = True)
|
||||
fireEvent('release.update_status', rel.get('_id'), status = 'downloaded', single = True)
|
||||
|
||||
# Allow the downloader to clean-up
|
||||
release_download.update({'pause': False, 'scan': False, 'process_complete': True})
|
||||
@@ -1008,7 +998,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
|
||||
else:
|
||||
# Set the release to snatched if it was missing before
|
||||
fireEvent('release.update_status', rel.id, status = snatched_status, single = True)
|
||||
fireEvent('release.update_status', rel.get('_id'), status = 'snatched', single = True)
|
||||
|
||||
# Remove the downloading tag
|
||||
self.untagRelease(release_download = release_download, tag = 'downloading')
|
||||
@@ -1044,8 +1034,11 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
|
||||
self.checking_snatched = False
|
||||
return True
|
||||
finally:
|
||||
pass #db.close()
|
||||
except:
|
||||
log.error('Failed checking snatched: %s', traceback.format_exc())
|
||||
|
||||
self.checking_snatched = False
|
||||
return False
|
||||
|
||||
def extendReleaseDownload(self, release_download):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user