2023-01-12 01:04:47 +00:00
|
|
|
#
|
|
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
import datetime
|
|
|
|
import os
|
|
|
|
import traceback
|
|
|
|
|
|
|
|
import exceptions_helper
|
|
|
|
from exceptions_helper import ex
|
|
|
|
|
|
|
|
import sickgear
|
|
|
|
from . import db, logger, network_timezones, properFinder, ui
|
2023-03-16 04:19:03 +00:00
|
|
|
from .scheduler import Job
|
2023-06-28 13:49:39 +00:00
|
|
|
from .config import backup_config
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# noinspection PyUnreachableCode
|
|
|
|
if False:
|
|
|
|
from sickgear.tv import TVShow
|
|
|
|
|
|
|
|
|
|
|
|
def clean_ignore_require_words():
|
|
|
|
"""
|
|
|
|
removes duplicate ignore/require words from shows and global lists
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
for s in sickgear.showList: # type: TVShow
|
|
|
|
# test before set to prevent dirty setter from setting unchanged shows to dirty
|
|
|
|
if s.rls_ignore_words - sickgear.IGNORE_WORDS != s.rls_ignore_words:
|
|
|
|
s.rls_ignore_words -= sickgear.IGNORE_WORDS
|
|
|
|
if 0 == len(s.rls_ignore_words):
|
|
|
|
s.rls_ignore_words_regex = False
|
|
|
|
if s.rls_require_words - sickgear.REQUIRE_WORDS != s.rls_require_words:
|
|
|
|
s.rls_require_words -= sickgear.REQUIRE_WORDS
|
|
|
|
if 0 == len(s.rls_require_words):
|
|
|
|
s.rls_require_words_regex = False
|
|
|
|
if s.rls_global_exclude_ignore & sickgear.IGNORE_WORDS != s.rls_global_exclude_ignore:
|
|
|
|
s.rls_global_exclude_ignore &= sickgear.IGNORE_WORDS
|
|
|
|
if s.rls_global_exclude_require & sickgear.REQUIRE_WORDS != s.rls_global_exclude_require:
|
|
|
|
s.rls_global_exclude_require &= sickgear.REQUIRE_WORDS
|
|
|
|
if s.dirty:
|
|
|
|
s.save_to_db()
|
|
|
|
except (BaseException, Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2023-03-16 04:19:03 +00:00
|
|
|
class ShowUpdater(Job):
|
2023-01-12 01:04:47 +00:00
|
|
|
def __init__(self):
|
2023-03-16 04:19:03 +00:00
|
|
|
super(ShowUpdater, self).__init__(self.job_run, kwargs={})
|
2023-01-12 01:04:47 +00:00
|
|
|
|
2023-03-16 04:19:03 +00:00
|
|
|
@staticmethod
|
|
|
|
def job_run():
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
update_datetime = datetime.datetime.now()
|
|
|
|
update_date = update_datetime.date()
|
|
|
|
|
|
|
|
# backup db's
|
|
|
|
if sickgear.db.db_supports_backup and 0 < sickgear.BACKUP_DB_MAX_COUNT:
|
|
|
|
logger.log('backing up all db\'s')
|
|
|
|
try:
|
2023-06-28 13:49:39 +00:00
|
|
|
backup_success = sickgear.db.backup_all_dbs(
|
|
|
|
sickgear.BACKUP_DB_PATH or os.path.join(sickgear.DATA_DIR, 'backup'))
|
|
|
|
if isinstance(backup_success, tuple) and backup_success[0]:
|
|
|
|
# backup config.ini
|
|
|
|
backup_config()
|
2023-01-12 01:04:47 +00:00
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('backup db error')
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# refresh network timezones
|
|
|
|
try:
|
|
|
|
network_timezones.update_network_dict()
|
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('network timezone update error')
|
|
|
|
logger.error(traceback.format_exc())
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# refresh webdl types
|
|
|
|
try:
|
|
|
|
properFinder.load_webdl_types()
|
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.debug('error loading webdl_types')
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# update xem id lists
|
|
|
|
try:
|
2023-03-16 04:19:03 +00:00
|
|
|
sickgear.scene_exceptions.ReleaseMap().fetch_xem_ids()
|
2023-01-12 01:04:47 +00:00
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('xem id list update error')
|
|
|
|
logger.error(traceback.format_exc())
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# update scene exceptions
|
|
|
|
try:
|
2023-03-16 04:19:03 +00:00
|
|
|
sickgear.scene_exceptions.ReleaseMap().fetch_exceptions()
|
2023-01-12 01:04:47 +00:00
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('scene exceptions update error')
|
|
|
|
logger.error(traceback.format_exc())
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# clear the data of unused providers
|
|
|
|
try:
|
|
|
|
sickgear.helpers.clear_unused_providers()
|
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('unused provider cleanup error')
|
|
|
|
logger.error(traceback.format_exc())
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# cleanup image cache
|
|
|
|
try:
|
|
|
|
sickgear.helpers.cleanup_cache()
|
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('image cache cleanup error')
|
|
|
|
logger.error(traceback.format_exc())
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# check tvinfo cache
|
|
|
|
try:
|
|
|
|
for i in sickgear.TVInfoAPI().all_sources:
|
|
|
|
sickgear.TVInfoAPI(i).setup().check_cache()
|
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('tvinfo cache check error')
|
|
|
|
logger.error(traceback.format_exc())
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# cleanup tvinfo cache
|
|
|
|
try:
|
|
|
|
for i in sickgear.TVInfoAPI().all_sources:
|
|
|
|
sickgear.TVInfoAPI(i).setup().clean_cache()
|
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('tvinfo cache cleanup error')
|
|
|
|
logger.error(traceback.format_exc())
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# cleanup ignore and require lists
|
|
|
|
try:
|
|
|
|
clean_ignore_require_words()
|
2023-02-10 14:15:50 +00:00
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('ignore, require words cleanup error')
|
|
|
|
logger.error(traceback.format_exc())
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# cleanup manual search history
|
|
|
|
sickgear.search_queue.remove_old_fifo(sickgear.search_queue.MANUAL_SEARCH_HISTORY)
|
|
|
|
|
|
|
|
# add missing mapped ids
|
|
|
|
if not sickgear.background_mapping_task.is_alive():
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.log('Updating the TV info mappings')
|
2023-01-12 01:04:47 +00:00
|
|
|
import threading
|
|
|
|
try:
|
|
|
|
sickgear.background_mapping_task = threading.Thread(
|
2023-03-16 04:19:03 +00:00
|
|
|
name='MAPPINGUPDATES', target=sickgear.indexermapper.load_mapped_ids, kwargs={'update': True})
|
2023-01-12 01:04:47 +00:00
|
|
|
sickgear.background_mapping_task.start()
|
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('missing mapped ids update error')
|
|
|
|
logger.error(traceback.format_exc())
|
2023-01-12 01:04:47 +00:00
|
|
|
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.log('Doing full update on all shows')
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# clean out cache directory, remove everything > 12 hours old
|
|
|
|
try:
|
|
|
|
sickgear.helpers.clear_cache()
|
|
|
|
except (BaseException, Exception):
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error('cache dir cleanup error')
|
|
|
|
logger.error(traceback.format_exc())
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# select 10 'Ended' tv_shows updated more than 90 days ago
|
2023-02-10 14:15:50 +00:00
|
|
|
# and all shows not updated more than 180 days ago to include in this update
|
2023-01-12 01:04:47 +00:00
|
|
|
stale_should_update = []
|
|
|
|
stale_update_date = (update_date - datetime.timedelta(days=90)).toordinal()
|
|
|
|
stale_update_date_max = (update_date - datetime.timedelta(days=180)).toordinal()
|
|
|
|
|
|
|
|
# last_update_date <= 90 days, sorted ASC because dates are ordinal
|
|
|
|
from sickgear.tv import TVidProdid
|
|
|
|
my_db = db.DBConnection()
|
|
|
|
# noinspection SqlRedundantOrderingDirection
|
|
|
|
mass_sql_result = my_db.mass_action([
|
|
|
|
['SELECT indexer || ? || indexer_id AS tvid_prodid'
|
|
|
|
' FROM tv_shows'
|
|
|
|
' WHERE last_update_indexer <= ?'
|
|
|
|
' AND last_update_indexer >= ?'
|
|
|
|
' ORDER BY last_update_indexer ASC LIMIT 10;',
|
|
|
|
[TVidProdid.glue, stale_update_date, stale_update_date_max]],
|
|
|
|
['SELECT indexer || ? || indexer_id AS tvid_prodid'
|
|
|
|
' FROM tv_shows'
|
|
|
|
' WHERE last_update_indexer < ?;',
|
|
|
|
[TVidProdid.glue, stale_update_date_max]]])
|
|
|
|
|
|
|
|
for sql_result in mass_sql_result:
|
|
|
|
for cur_result in sql_result:
|
|
|
|
stale_should_update.append(cur_result['tvid_prodid'])
|
|
|
|
|
|
|
|
# start update process
|
|
|
|
show_updates = {}
|
|
|
|
for src in sickgear.TVInfoAPI().search_sources:
|
|
|
|
tvinfo_config = sickgear.TVInfoAPI(src).api_params.copy()
|
|
|
|
t = sickgear.TVInfoAPI(src).setup(**tvinfo_config)
|
|
|
|
show_updates.update({src: t.get_updated_shows()})
|
|
|
|
|
|
|
|
pi_list = []
|
|
|
|
for cur_show_obj in sickgear.showList: # type: sickgear.tv.TVShow
|
|
|
|
|
|
|
|
try:
|
|
|
|
# if should_update returns True (not 'Ended') or show is selected stale 'Ended' then update,
|
|
|
|
# otherwise just refresh
|
2023-02-10 14:15:50 +00:00
|
|
|
if cur_show_obj.should_update(
|
|
|
|
update_date=update_date,
|
|
|
|
last_indexer_change=show_updates.get(cur_show_obj.tvid, {}).get(cur_show_obj.prodid)) \
|
2023-01-12 01:04:47 +00:00
|
|
|
or cur_show_obj.tvid_prodid in stale_should_update:
|
2023-02-10 14:15:50 +00:00
|
|
|
cur_queue_item = sickgear.show_queue_scheduler.action.update_show(
|
|
|
|
cur_show_obj, scheduled_update=True)
|
2023-01-12 01:04:47 +00:00
|
|
|
else:
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.debug(f'Not updating episodes for show {cur_show_obj.unique_name} because it\'s'
|
|
|
|
f' marked as ended and last/next episode is not within the grace period.')
|
2023-02-10 14:15:50 +00:00
|
|
|
cur_queue_item = sickgear.show_queue_scheduler.action.refresh_show(cur_show_obj, True, True)
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
pi_list.append(cur_queue_item)
|
|
|
|
|
|
|
|
except (exceptions_helper.CantUpdateException, exceptions_helper.CantRefreshException) as e:
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.error(f'Automatic update failed: {ex(e)}')
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
if len(pi_list):
|
|
|
|
sickgear.show_queue_scheduler.action.daily_update_running = True
|
|
|
|
|
2023-02-13 21:00:11 +00:00
|
|
|
ui.ProgressIndicators.set_indicator('dailyUpdate', ui.QueueProgressIndicator('Daily Update', pi_list))
|
2023-01-12 01:04:47 +00:00
|
|
|
|
2023-03-08 13:44:20 +00:00
|
|
|
logger.log('Added all shows to show queue for full update')
|
2023-01-12 01:04:47 +00:00
|
|
|
|
2023-03-16 04:19:03 +00:00
|
|
|
except(BaseException, Exception):
|
|
|
|
pass
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
pass
|