#
# This file is part of SickGear.
#
# SickGear is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SickGear is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SickGear. If not, see .
from __future__ import with_statement
import traceback
# noinspection PyPep8Naming
from exceptions_helper import ex
from . import db, generic_queue, logger, helpers, ui
# noinspection PyUnreachableCode
if False:
from six import integer_types
from typing import AnyStr, Dict, List, Optional
from .tv import TVShow
from lib.tvinfo_base import CastList
class PeopleQueue(generic_queue.GenericQueue):
def __init__(self):
generic_queue.GenericQueue.__init__(self, cache_db_tables=['people_queue'])
self.queue_name = 'PEOPLEQUEUE' # type: AnyStr
def load_queue(self):
try:
my_db = db.DBConnection('cache.db')
queue_sql = my_db.select('SELECT * FROM people_queue')
for q in queue_sql:
if PeopleQueueActions.SHOWCAST == q['action_id']:
try:
show_obj = helpers.find_show_by_id({q['indexer']: q['indexer_id']})
except (BaseException, Exception):
continue
if not show_obj:
continue
self.add_cast_update(show_obj=show_obj, show_info_cast=None, uid=q['uid'], force=bool(q['forced']),
scheduled_update=bool(q['scheduled']), add_to_db=False)
except (BaseException, Exception) as e:
logger.error('Exception loading queue %s: %s' % (self.__class__.__name__, ex(e)))
try:
my_db = db.DBConnection()
if not my_db.has_flag('cast_loaded'):
import sickgear
[self.add_cast_update(s, show_info_cast=None, scheduled_update=True)
for s in sickgear.showList if not s.cast_list]
my_db.set_flag('cast_loaded')
except (BaseException, Exception):
pass
def _clear_sql(self):
return [
['DELETE FROM people_queue']
]
def _get_item_sql(self, item):
# type: (PeopleQueueItem) -> List[List]
return [
['INSERT OR IGNORE INTO people_queue (indexer, indexer_id, action_id, forced, scheduled, uid)'
' VALUES (?,?,?,?,?,?)',
[item.show_obj.tvid, item.show_obj.prodid, item.action_id, int(item.force), int(item.scheduled_update),
item.uid]]
]
def _delete_item_from_db_sql(self, item):
# type: (PeopleQueueItem) -> List[List]
return [
['DELETE FROM people_queue WHERE uid = ?', [item.uid]]
]
def queue_data(self):
# type: (...) -> Dict[AnyStr, List[AnyStr, Dict]]
data = {'main_cast': []}
with self.lock:
for cur_item in [self.currentItem] + self.queue: # type: PeopleQueueItem
if not cur_item or not cur_item.show_obj:
continue
result_item = {'name': cur_item.show_obj.name, 'tvid_prodid': cur_item.show_obj.tvid_prodid,
'uid': cur_item.uid, 'forced': cur_item.force}
if isinstance(cur_item, CastQueueItem):
data['main_cast'].append(result_item)
return data
def show_in_queue(self, show_obj, check_inprogress=False):
# type: (TVShow, Optional[bool]) -> bool
with self.lock:
return any(1 for q in ((self.currentItem and [self.currentItem]) or []) + self.queue
if show_obj == q.show_obj and (True, q.inProgress)[check_inprogress])
def abort_cast_update(self, show_obj):
# type: (TVShow) -> None
if show_obj:
with self.lock:
to_remove = []
for c in ((self.currentItem and [self.currentItem]) or []) + self.queue:
if show_obj == c.show_obj:
try:
to_remove.append(c.uid)
except (BaseException, Exception):
pass
try:
c.stop.set()
except (BaseException, Exception):
pass
if to_remove:
try:
self.remove_from_queue(to_remove)
except (BaseException, Exception):
pass
def add_cast_update(self, show_obj, show_info_cast, uid=None, add_to_db=True, force=False, scheduled_update=False,
switch=False):
# type: (TVShow, Optional[CastList], AnyStr, bool, bool, bool, bool) -> CastQueueItem
"""
:param show_obj: TV Show object
:param show_info_cast: TV Info object
:param uid: unique id
:param add_to_db: add to queue db table
:param force:
:param scheduled_update: suppresses ui notifications
:param switch: part of id switch
"""
with self.lock:
if not self.show_in_queue(show_obj):
cast_item = CastQueueItem(show_obj=show_obj, show_info_cast=show_info_cast, uid=uid, force=force,
scheduled_update=scheduled_update, switch=switch)
self.add_item(cast_item, add_to_db=add_to_db)
return cast_item
class PeopleQueueActions(object):
SHOWCAST = 1
names = {
SHOWCAST: 'Show Cast',
}
class PeopleQueueItem(generic_queue.QueueItem):
def __init__(self, action_id, show_obj, uid=None, force=False, **kwargs):
# type: (integer_types, TVShow, AnyStr, bool, Dict) -> PeopleQueueItem
"""
:param action_id:
:param show_obj: show object
"""
generic_queue.QueueItem.__init__(self, PeopleQueueActions.names[action_id], action_id, uid=uid)
self.show_obj = show_obj # type: TVShow
self.force = force # type: bool
def finish(self):
self.show_obj = None
super(PeopleQueueItem, self).finish()
class CastQueueItem(PeopleQueueItem):
def __init__(self, show_obj, show_info_cast=None, uid=None, force=False, scheduled_update=False, switch=False,
**kwargs):
# type: (TVShow, CastList, AnyStr, bool, bool, bool, Dict) -> CastQueueItem
"""
:param show_obj: show obj
:param show_info_cast: show info cast list
:param scheduled_update: suppresses ui notifications
:param switch: part of id switch
"""
PeopleQueueItem.__init__(self, PeopleQueueActions.SHOWCAST, show_obj, uid=uid, force=force, **kwargs)
self.show_info_cast = show_info_cast # type: Optional[CastList]
self.scheduled_update = scheduled_update # type: bool
self.switch = switch # type: bool
def run(self):
PeopleQueueItem.run(self)
if self.show_obj:
logger.log('Starting cast update for show %s' % self.show_obj.unique_name)
old_cast = self.show_obj.cast_list_id()
if not self.scheduled_update and not self.switch:
ui.notifications.message('Starting cast update for show %s' % self.show_obj.unique_name)
try:
self.show_obj.load_cast_from_tvinfo(self.show_info_cast, force=self.force, stop_event=self.stop)
update_success = True
except (BaseException, Exception) as e:
update_success = False
logger.error('Exception in cast update queue: %s' % ex(e))
logger.debug('Traceback: %s' % traceback.format_exc())
if update_success and (old_cast != self.show_obj.cast_list_id()):
logger.debug('Update show nfo with new cast data')
self.show_obj.write_show_nfo(force=True)
logger.log('Finished cast update for show %s' % self.show_obj.unique_name)
if not self.scheduled_update and not self.switch:
ui.notifications.message('Finished cast update for show %s' % self.show_obj.unique_name)
self.finish()
def finish(self):
self.show_info_cast = None
super(CastQueueItem, self).finish()
def __str__(self):
return '' % (self.show_obj.unique_name, ('', ' - forced')[self.force])
def __repr__(self):
return self.__str__()