Browse Source

Merge branch 'refs/heads/mano3m-develop_wait_for_better' into develop

pull/3529/head
Ruud 11 years ago
parent
commit
733f925c75
  1. 28
      couchpotato/core/media/_base/media/main.py
  2. 2
      couchpotato/core/media/movie/_base/main.py
  3. 24
      couchpotato/core/media/movie/searcher.py
  4. 4
      couchpotato/core/plugins/profile/main.py
  5. 11
      couchpotato/core/plugins/profile/static/profile.js
  6. 17
      couchpotato/core/plugins/quality/main.py
  7. 20
      couchpotato/core/plugins/release/main.py
  8. 27
      couchpotato/core/plugins/renamer.py

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

@ -1,3 +1,6 @@
from datetime import timedelta
from operator import itemgetter
import time
import traceback import traceback
from string import ascii_lowercase from string import ascii_lowercase
@ -452,20 +455,20 @@ class MediaPlugin(MediaBase):
if not m['profile_id']: if not m['profile_id']:
m['status'] = 'done' m['status'] = 'done'
else: else:
move_to_wanted = True m['status'] = 'active'
try: try:
profile = db.get('id', m['profile_id']) profile = db.get('id', m['profile_id'])
media_releases = fireEvent('release.for_media', m['_id'], single = True) media_releases = fireEvent('release.for_media', m['_id'], single = True)
done_releases = [release for release in media_releases if release.get('status') == 'done']
for q_identifier in profile['qualities']: if done_releases:
index = profile['qualities'].index(q_identifier) # Only look at latest added release
release = sorted(done_releases, key = itemgetter('last_edit'), reverse = True)[0]
for release in media_releases: # Check if we are finished with the media
if q_identifier == release['quality'] and (release.get('status') == 'done' and profile['finish'][index]): if fireEvent('quality.isfinish', {'identifier': release['quality'], 'is_3d': release.get('is_3d', False)}, profile, timedelta(seconds = time.time() - release['last_edit']).days, single = True):
move_to_wanted = False m['status'] = 'done'
m['status'] = 'active' if move_to_wanted else 'done'
except RecordNotFound: except RecordNotFound:
log.debug('Failed restatus: %s', traceback.format_exc()) log.debug('Failed restatus: %s', traceback.format_exc())
@ -473,7 +476,10 @@ class MediaPlugin(MediaBase):
if previous_status != m['status']: if previous_status != m['status']:
db.update(m) db.update(m)
return True # Tag media as recent
self.tag(media_id, 'recent')
return m['status']
except: except:
log.error('Failed restatus: %s', traceback.format_exc()) log.error('Failed restatus: %s', traceback.format_exc())

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

@ -236,7 +236,7 @@ class MovieBase(MovieTypeBase):
db.update(m) db.update(m)
fireEvent('media.restatus', m['_id']) fireEvent('media.restatus', m['_id'], single = True)
m = db.get('id', media_id) m = db.get('id', media_id)

24
couchpotato/core/media/movie/searcher.py

@ -120,8 +120,19 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
if not movie['profile_id'] or (movie['status'] == 'done' and not manual): if not movie['profile_id'] or (movie['status'] == 'done' and not manual):
log.debug('Movie doesn\'t have a profile or already done, assuming in manage tab.') log.debug('Movie doesn\'t have a profile or already done, assuming in manage tab.')
fireEvent('media.restatus', movie['_id'], single = True)
return return
default_title = getTitle(movie)
if not default_title:
log.error('No proper info found for movie, removing it from library to stop it from causing more issues.')
fireEvent('media.delete', movie['_id'], single = True)
return
# Update media status and check if it is still not done (due to the stop searching after feature
if fireEvent('media.restatus', movie['_id'], single = True) == 'done':
log.debug('No better quality found, marking movie %s as done.', default_title)
pre_releases = fireEvent('quality.pre_releases', single = True) pre_releases = fireEvent('quality.pre_releases', single = True)
release_dates = fireEvent('movie.update_release_dates', movie['_id'], merge = True) release_dates = fireEvent('movie.update_release_dates', movie['_id'], merge = True)
@ -133,12 +144,6 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
ignore_eta = manual ignore_eta = manual
total_result_count = 0 total_result_count = 0
default_title = getTitle(movie)
if not default_title:
log.error('No proper info found for movie, removing it from library to cause it from having more issues.')
fireEvent('media.delete', movie['_id'], single = True)
return
fireEvent('notify.frontend', type = 'movie.searcher.started', data = {'_id': movie['_id']}, message = 'Searching for "%s"' % default_title) fireEvent('notify.frontend', type = 'movie.searcher.started', data = {'_id': movie['_id']}, message = 'Searching for "%s"' % default_title)
# Ignore eta once every 7 days # Ignore eta once every 7 days
@ -154,8 +159,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
profile = db.get('id', movie['profile_id']) profile = db.get('id', movie['profile_id'])
ret = False ret = False
index = 0 for index, q_identifier in enumerate(profile.get('qualities', [])):
for q_identifier in profile.get('qualities'):
quality_custom = { quality_custom = {
'index': index, 'index': index,
'quality': q_identifier, 'quality': q_identifier,
@ -164,8 +168,6 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
'3d': profile['3d'][index] if profile.get('3d') else False '3d': profile['3d'][index] if profile.get('3d') else False
} }
index += 1
could_not_be_released = not self.couldBeReleased(q_identifier in pre_releases, release_dates, movie['info']['year']) could_not_be_released = not self.couldBeReleased(q_identifier in pre_releases, release_dates, movie['info']['year'])
if not alway_search and could_not_be_released: if not alway_search and could_not_be_released:
too_early_to_search.append(q_identifier) too_early_to_search.append(q_identifier)
@ -189,7 +191,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
# Don't search for quality lower then already available. # Don't search for quality lower then already available.
if has_better_quality > 0: if has_better_quality > 0:
log.info('Better quality (%s) already available or snatched for %s', (q_identifier, default_title)) log.info('Better quality (%s) already available or snatched for %s', (q_identifier, default_title))
fireEvent('media.restatus', movie['_id']) fireEvent('media.restatus', movie['_id'], single = True)
break break
quality = fireEvent('quality.single', identifier = q_identifier, single = True) quality = fireEvent('quality.single', identifier = q_identifier, single = True)

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

@ -88,6 +88,7 @@ class ProfilePlugin(Plugin):
'core': kwargs.get('core', False), 'core': kwargs.get('core', False),
'qualities': [], 'qualities': [],
'wait_for': [], 'wait_for': [],
'stop_after': [],
'finish': [], 'finish': [],
'3d': [] '3d': []
} }
@ -97,6 +98,7 @@ class ProfilePlugin(Plugin):
for type in kwargs.get('types', []): for type in kwargs.get('types', []):
profile['qualities'].append(type.get('quality')) profile['qualities'].append(type.get('quality'))
profile['wait_for'].append(tryInt(kwargs.get('wait_for', 0))) profile['wait_for'].append(tryInt(kwargs.get('wait_for', 0)))
profile['stop_after'].append(tryInt(kwargs.get('stop_after', 0)))
profile['finish'].append((tryInt(type.get('finish')) == 1) if order > 0 else True) profile['finish'].append((tryInt(type.get('finish')) == 1) if order > 0 else True)
profile['3d'].append(tryInt(type.get('3d'))) profile['3d'].append(tryInt(type.get('3d')))
order += 1 order += 1
@ -217,6 +219,7 @@ class ProfilePlugin(Plugin):
'qualities': profile.get('qualities'), 'qualities': profile.get('qualities'),
'finish': [], 'finish': [],
'wait_for': [], 'wait_for': [],
'stop_after': [],
'3d': [] '3d': []
} }
@ -224,6 +227,7 @@ class ProfilePlugin(Plugin):
for q in profile.get('qualities'): for q in profile.get('qualities'):
pro['finish'].append(True) pro['finish'].append(True)
pro['wait_for'].append(0) pro['wait_for'].append(0)
pro['stop_after'].append(0)
pro['3d'].append(threed.pop() if threed else False) pro['3d'].append(threed.pop() if threed else False)
db.insert(pro) db.insert(pro)

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

@ -44,6 +44,7 @@ var Profile = new Class({
'value': data.wait_for && data.wait_for.length > 0 ? data.wait_for[0] : 0 'value': data.wait_for && data.wait_for.length > 0 ? data.wait_for[0] : 0
}), }),
new Element('span', {'text':'day(s) for a better quality.'}) new Element('span', {'text':'day(s) for a better quality.'})
// "Wait the entered number of days for a checked quality, before downloading a lower quality release."
), ),
new Element('div.qualities.ctrlHolder').adopt( new Element('div.qualities.ctrlHolder').adopt(
new Element('label', {'text': 'Search for'}), new Element('label', {'text': 'Search for'}),
@ -51,6 +52,15 @@ var Profile = new Class({
new Element('div.formHint', { new Element('div.formHint', {
'html': "Search these qualities (2 minimum), from top to bottom. Use the checkbox, to stop searching after it found this quality." 'html': "Search these qualities (2 minimum), from top to bottom. Use the checkbox, to stop searching after it found this quality."
}) })
),
new Element('div.stop_after.ctrlHolder').adopt(
new Element('span', {'text':'Keep searching'}),
new Element('input.inlay.xsmall', {
'type':'text',
'value': data.stop_after && data.stop_after.length > 0 ? data.stop_after[0] : 0
}),
new Element('span', {'text':'day(s) for a better checked quality.'})
// "After a checked quality is found and downloaded, continue searching for even better quality releases for the entered number of days."
) )
); );
@ -117,6 +127,7 @@ var Profile = new Class({
'id' : self.data._id, 'id' : self.data._id,
'label' : self.el.getElement('.quality_label input').get('value'), 'label' : self.el.getElement('.quality_label input').get('value'),
'wait_for' : self.el.getElement('.wait_for input').get('value'), 'wait_for' : self.el.getElement('.wait_for input').get('value'),
'stop_after' : self.el.getElement('.stop_after input').get('value'),
'types': [] 'types': []
}; };

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

@ -379,26 +379,31 @@ class QualityPlugin(Plugin):
if score.get(q.get('identifier')): if score.get(q.get('identifier')):
score[q.get('identifier')]['score'] -= 1 score[q.get('identifier')]['score'] -= 1
def isFinish(self, quality, profile): def isFinish(self, quality, profile, release_age = 0):
if not isinstance(profile, dict) or not profile.get('qualities'): if not isinstance(profile, dict) or not profile.get('qualities'):
return False # No profile so anything (scanned) is good enough
return True
try: try:
quality_order = [i for i, identifier in enumerate(profile['qualities']) if identifier == quality['identifier'] and bool(profile['3d'][i] if profile.get('3d') else 0) == bool(quality.get('is_3d', 0))][0] index = [i for i, identifier in enumerate(profile['qualities']) if identifier == quality['identifier'] and bool(profile['3d'][i] if profile.get('3d') else False) == bool(quality.get('is_3d', False))][0]
return profile['finish'][quality_order]
if index == 0 or profile['finish'][index] and int(release_age) >= int(profile['stop_after'][0]):
return True
return False
except: except:
return False return False
def isHigher(self, quality, compare_with, profile = None): def isHigher(self, quality, compare_with, profile = None):
if not isinstance(profile, dict) or not profile.get('qualities'): if not isinstance(profile, dict) or not profile.get('qualities'):
profile = {'qualities': self.order} profile = fireEvent('profile.default', single = True)
# Try to find quality in profile, if not found: a quality we do not want is lower than anything else # Try to find quality in profile, if not found: a quality we do not want is lower than anything else
try: try:
quality_order = [i for i, identifier in enumerate(profile['qualities']) if identifier == quality['identifier'] and bool(profile['3d'][i] if profile.get('3d') else 0) == bool(quality.get('is_3d', 0))][0] quality_order = [i for i, identifier in enumerate(profile['qualities']) if identifier == quality['identifier'] and bool(profile['3d'][i] if profile.get('3d') else 0) == bool(quality.get('is_3d', 0))][0]
except: except:
log.debug('Quality %s not found in profile identifiers %s', (quality['identifier'] + (' 3D' if quality.get('is_3d', 0) else ''), \ log.debug('Quality %s not found in profile identifiers %s', (quality['identifier'] + (' 3D' if quality.get('is_3d', 0) else ''), \
[identifier + ('3D' if (profile['3d'][i] if profile.get('3d') else 0) else '') for i, identifier in enumerate(profile['qualities'])])) [identifier + (' 3D' if (profile['3d'][i] if profile.get('3d') else 0) else '') for i, identifier in enumerate(profile['qualities'])]))
return 'lower' return 'lower'
# Try to find compare quality in profile, if not found: anything is higher than a not wanted quality # Try to find compare quality in profile, if not found: anything is higher than a not wanted quality

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

@ -100,9 +100,9 @@ class Release(Plugin):
if rel['status'] in ['available']: if rel['status'] in ['available']:
self.delete(rel['_id']) self.delete(rel['_id'])
# Set all snatched and downloaded releases to ignored to make sure they are ignored when re-adding the move # Set all snatched and downloaded releases to ignored to make sure they are ignored when re-adding the media
elif rel['status'] in ['snatched', 'downloaded']: elif rel['status'] in ['snatched', 'downloaded']:
self.updateStatus(rel['_id'], status = 'ignore') self.updateStatus(rel['_id'], status = 'ignored')
fireEvent('media.untag', media.get('_id'), 'recent', single = True) fireEvent('media.untag', media.get('_id'), 'recent', single = True)
@ -164,7 +164,7 @@ class Release(Plugin):
release['files'] = dict((k, [toUnicode(x) for x in v]) for k, v in group['files'].items() if v) release['files'] = dict((k, [toUnicode(x) for x in v]) for k, v in group['files'].items() if v)
db.update(release) db.update(release)
fireEvent('media.restatus', media['_id']) fireEvent('media.restatus', media['_id'], single = True)
return True return True
except: except:
@ -331,24 +331,14 @@ class Release(Plugin):
if media['status'] == 'active': if media['status'] == 'active':
profile = db.get('id', media['profile_id']) profile = db.get('id', media['profile_id'])
finished = False if fireEvent('quality.isfinish', {'identifier': rls['quality'], 'is_3d': rls.get('is_3d', False)}, profile, single = True):
if rls['quality'] in profile['qualities']:
nr = profile['qualities'].index(rls['quality'])
finished = profile['finish'][nr]
if finished:
log.info('Renamer disabled, marking media as finished: %s', log_movie) log.info('Renamer disabled, marking media as finished: %s', log_movie)
# Mark release done # Mark release done
self.updateStatus(rls['_id'], status = 'done') self.updateStatus(rls['_id'], status = 'done')
# Mark media done # Mark media done
mdia = db.get('id', media['_id']) fireEvent('media.restatus', media['_id'], single = True)
mdia['status'] = 'done'
mdia['last_edit'] = int(time.time())
db.update(mdia)
fireEvent('media.tag', media['_id'], 'recent', single = True)
return True return True

27
couchpotato/core/plugins/renamer.py

@ -446,22 +446,19 @@ class Renamer(Plugin):
# Before renaming, remove the lower quality files # Before renaming, remove the lower quality files
remove_leftovers = True remove_leftovers = True
# Mark movie "done" once it's found the quality with the finish check # Get media quality profile
profile = None profile = None
try: if media.get('profile_id'):
if media.get('status') == 'active' and media.get('profile_id'): try:
profile = db.get('id', media['profile_id']) profile = db.get('id', media['profile_id'])
if fireEvent('quality.isfinish', group['meta_data']['quality'], profile, single = True): except:
mdia = db.get('id', media['_id']) # Set profile to None as it does not exist anymore
mdia['status'] = 'done' mdia = db.get('id', media['_id'])
mdia['last_edit'] = int(time.time()) mdia['profile_id'] = None
db.update(mdia) db.update(mdia)
log.error('Error getting quality profile for %s: %s', (media_title, traceback.format_exc()))
# List movie on dashboard else:
fireEvent('media.tag', media['_id'], 'recent', single = True) log.debug('Media has no quality profile: %s', media_title)
except:
log.error('Failed marking movie finished: %s', (traceback.format_exc()))
# Mark media for dashboard # Mark media for dashboard
mark_as_recent = False mark_as_recent = False
@ -474,7 +471,7 @@ class Renamer(Plugin):
# This is where CP removes older, lesser quality releases or releases that are not wanted anymore # This is where CP removes older, lesser quality releases or releases that are not wanted anymore
is_higher = fireEvent('quality.ishigher', \ is_higher = fireEvent('quality.ishigher', \
group['meta_data']['quality'], {'identifier': release['quality'], 'is_3d': release.get('is_3d', 0)}, profile, single = True) group['meta_data']['quality'], {'identifier': release['quality'], 'is_3d': release.get('is_3d', False)}, profile, single = True)
if is_higher == 'higher': if is_higher == 'higher':
log.info('Removing lesser or not wanted quality %s for %s.', (media_title, release.get('quality'))) log.info('Removing lesser or not wanted quality %s for %s.', (media_title, release.get('quality')))

Loading…
Cancel
Save