hydrus/include/ClientImportWatchers.py

1246 lines
38 KiB
Python
Raw Normal View History

2018-05-23 21:05:06 +00:00
import ClientConstants as CC
import ClientDownloading
import ClientImporting
import ClientImportOptions
import ClientNetworkingJobs
import ClientParsing
import collections
import HydrusConstants as HC
import HydrusData
import HydrusExceptions
import HydrusGlobals as HG
import HydrusSerialisable
import threading
import time
import wx
class MultipleWatcherImport( HydrusSerialisable.SerialisableBase ):
SERIALISABLE_TYPE = HydrusSerialisable.SERIALISABLE_TYPE_MULTIPLE_WATCHER_IMPORT
SERIALISABLE_NAME = 'Multiple Watcher'
SERIALISABLE_VERSION = 1
def __init__( self, url = None ):
HydrusSerialisable.SerialisableBase.__init__( self )
self._lock = threading.Lock()
self._page_key = 'initialising page key'
self._watchers = HydrusSerialisable.SerialisableList()
self._watcher_keys_to_watchers = {}
self._watchers_repeating_job = None
self._status_dirty = True
self._status_cache = None
self._status_cache_generation_time = 0
#
if url is not None:
watcher = WatcherImport()
watcher.SetURL( url )
self._AddWatcher( watcher )
self._last_pubbed_value_range = ( 0, 0 )
self._next_pub_value_check_time = 0
def _AddWatcher( self, watcher ):
publish_to_page = False
watcher.Repage( self._page_key, publish_to_page )
self._watchers.append( watcher )
watcher_key = watcher.GetWatcherKey()
self._watcher_keys_to_watchers[ watcher_key ] = watcher
def _RegenerateStatus( self ):
statuses_to_counts = collections.Counter()
for watcher in self._watchers:
seed_cache = watcher.GetSeedCache()
statuses_to_counts.update( seed_cache.GetStatusesToCounts() )
self._status_cache = ClientImporting.GenerateSeedCacheStatus( statuses_to_counts )
self._status_dirty = False
self._status_cache_generation_time = HydrusData.GetNow()
def _GetSerialisableInfo( self ):
serialisable_watchers = self._watchers.GetSerialisableTuple()
return serialisable_watchers
def _InitialiseFromSerialisableInfo( self, serialisable_info ):
serialisable_watchers = serialisable_info
self._watchers = HydrusSerialisable.CreateFromSerialisableTuple( serialisable_watchers )
self._watcher_keys_to_watchers = { watcher.GetWatcherKey() : watcher for watcher in self._watchers }
def _RemoveWatcher( self, watcher_key ):
if watcher_key not in self._watcher_keys_to_watchers:
return
watcher = self._watcher_keys_to_watchers[ watcher_key ]
publish_to_page = False
watcher.Repage( 'dead page key', publish_to_page )
self._watchers.remove( watcher )
del self._watcher_keys_to_watchers[ watcher_key ]
def _SetDirty( self ):
self._status_dirty = True
def AddURL( self, url ):
if url == '':
return
with self._lock:
if url in ( watcher.GetURL() for watcher in self._watchers ):
return
watcher = WatcherImport()
watcher.SetURL( url )
publish_to_page = False
watcher.Start( self._page_key, publish_to_page )
self._AddWatcher( watcher )
def AddWatcher( self, watcher ):
with self._lock:
self._AddWatcher( watcher )
self._SetDirty()
2018-05-30 20:13:21 +00:00
def GetNumDead( self ):
2018-05-23 21:05:06 +00:00
with self._lock:
2018-05-30 20:13:21 +00:00
return len( [ watcher for watcher in self._watchers if watcher.IsDead() ] )
2018-05-23 21:05:06 +00:00
def GetTotalStatus( self ):
with self._lock:
if self._status_dirty:
self._RegenerateStatus()
return self._status_cache
def GetValueRange( self ):
with self._lock:
total_value = 0
total_range = 0
for watcher in self._watchers:
( value, range ) = watcher.GetValueRange()
if value != range:
total_value += value
total_range += range
return ( total_value, total_range )
def GetWatchers( self ):
with self._lock:
return list( self._watchers )
2018-05-30 20:13:21 +00:00
def GetWatcherKeys( self ):
with self._lock:
return set( self._watcher_keys_to_watchers.keys() )
2018-05-23 21:05:06 +00:00
def RemoveWatcher( self, watcher_key ):
with self._lock:
self._RemoveWatcher( watcher_key )
self._SetDirty()
def Start( self, page_key ):
with self._lock:
self._page_key = page_key
2018-05-30 20:13:21 +00:00
# set a 2s period so the page value/range is breddy snappy
self._watchers_repeating_job = HG.client_controller.CallRepeating( ClientImporting.GetRepeatingJobInitialDelay(), 2.0, self.REPEATINGWorkOnWatchers )
2018-05-23 21:05:06 +00:00
publish_to_page = False
for watcher in self._watchers:
watcher.Start( page_key, publish_to_page )
def REPEATINGWorkOnWatchers( self ):
with self._lock:
if ClientImporting.PageImporterShouldStopWorking( self._page_key ):
self._watchers_repeating_job.Cancel()
return
if not self._status_dirty: # if we think we are clean
for watcher in self._watchers:
seed_cache = watcher.GetSeedCache()
if seed_cache.GetStatusGenerationTime() > self._status_cache_generation_time: # has there has been an update?
self._SetDirty()
break
if HydrusData.TimeHasPassed( self._next_pub_value_check_time ):
self._next_pub_value_check_time = HydrusData.GetNow() + 5
current_value_range = self.GetValueRange()
if current_value_range != self._last_pubbed_value_range:
self._last_pubbed_value_range = current_value_range
HG.client_controller.pub( 'refresh_page_name', self._page_key )
# something like:
# if any are dead, do some stuff with them based on some options here
# might want to have this work on a 30s period or something
HydrusSerialisable.SERIALISABLE_TYPES_TO_OBJECT_TYPES[ HydrusSerialisable.SERIALISABLE_TYPE_MULTIPLE_WATCHER_IMPORT ] = MultipleWatcherImport
class WatcherImport( HydrusSerialisable.SerialisableBase ):
SERIALISABLE_TYPE = HydrusSerialisable.SERIALISABLE_TYPE_WATCHER_IMPORT
SERIALISABLE_NAME = 'Watcher'
SERIALISABLE_VERSION = 4
MIN_CHECK_PERIOD = 30
def __init__( self ):
HydrusSerialisable.SerialisableBase.__init__( self )
file_import_options = HG.client_controller.new_options.GetDefaultFileImportOptions( 'loud' )
new_options = HG.client_controller.new_options
tag_import_options = new_options.GetDefaultTagImportOptions( ClientDownloading.GalleryIdentifier( HC.SITE_TYPE_WATCHER ) )
self._page_key = 'initialising page key'
self._publish_to_page = False
self._url = ''
self._seed_cache = ClientImporting.SeedCache()
self._urls_to_filenames = {}
self._urls_to_md5_base64 = {}
self._checker_options = new_options.GetDefaultWatcherCheckerOptions()
self._file_import_options = file_import_options
self._tag_import_options = tag_import_options
self._last_check_time = 0
self._checking_status = ClientImporting.CHECKER_STATUS_OK
self._subject = 'unknown subject'
self._next_check_time = None
self._download_control_file_set = None
self._download_control_file_clear = None
self._download_control_checker_set = None
self._download_control_checker_clear = None
self._check_now = False
self._files_paused = False
self._checking_paused = False
self._no_work_until = 0
self._no_work_until_reason = ''
self._file_velocity_status = ''
self._current_action = ''
self._watcher_status = ''
self._watcher_key = HydrusData.GenerateKey()
self._lock = threading.Lock()
self._last_pubbed_page_name = ''
self._files_repeating_job = None
self._checker_repeating_job = None
HG.client_controller.sub( self, 'NotifySeedsUpdated', 'seed_cache_seeds_updated' )
def _CheckWatchableURL( self ):
error_occurred = False
watcher_status_should_stick = True
( url_type, match_name, can_parse ) = HG.client_controller.network_engine.domain_manager.GetURLParseCapability( self._url )
if url_type != HC.URL_TYPE_WATCHABLE:
error_occurred = True
watcher_status = 'Did not understand the given URL as watchable!'
elif not can_parse:
error_occurred = True
watcher_status = 'Could not parse the given URL!'
if not error_occurred:
2018-05-30 20:13:21 +00:00
try:
# convert to API url as appropriate
( url_to_check, parser ) = HG.client_controller.network_engine.domain_manager.GetURLToFetchAndParser( self._url )
except HydrusExceptions.URLMatchException:
2018-05-23 21:05:06 +00:00
error_occurred = True
watcher_status = 'Could not find a parser for the given URL!'
if error_occurred:
self._FinishCheck( watcher_status, error_occurred, watcher_status_should_stick )
return
#
with self._lock:
self._watcher_status = 'checking watchable url'
try:
network_job = ClientNetworkingJobs.NetworkJobWatcherPage( self._watcher_key, 'GET', url_to_check )
network_job.OverrideBandwidth()
HG.client_controller.network_engine.AddJob( network_job )
with self._CheckerNetworkJobPresentationContextFactory( network_job ):
network_job.WaitUntilDone()
data = network_job.GetContent()
parsing_context = {}
parsing_context[ 'watcher_url' ] = self._url
parsing_context[ 'url' ] = url_to_check
all_parse_results = parser.Parse( parsing_context, data )
subject = ClientParsing.GetTitleFromAllParseResults( all_parse_results )
if subject is None:
subject = ''
with self._lock:
self._subject = subject
( num_new, num_already_in ) = ClientImporting.UpdateSeedCacheWithAllParseResults( self._seed_cache, all_parse_results, source_url = self._url, tag_import_options = self._tag_import_options )
watcher_status = 'checked OK - ' + HydrusData.ConvertIntToPrettyString( num_new ) + ' new urls'
watcher_status_should_stick = False
if num_new > 0:
ClientImporting.WakeRepeatingJob( self._files_repeating_job )
except HydrusExceptions.ShutdownException:
return
except HydrusExceptions.ParseException as e:
error_occurred = True
watcher_status = 'Was unable to parse the returned data! Full error written to log!'
HydrusData.PrintException( e )
except HydrusExceptions.NotFoundException:
error_occurred = True
with self._lock:
self._checking_status = ClientImporting.CHECKER_STATUS_404
watcher_status = ''
except HydrusExceptions.NetworkException as e:
self._DelayWork( 4 * 3600, 'Network problem: ' + HydrusData.ToUnicode( e ) )
watcher_status = ''
HydrusData.PrintException( e )
except Exception as e:
error_occurred = True
watcher_status = HydrusData.ToUnicode( e )
HydrusData.PrintException( e )
self._FinishCheck( watcher_status, error_occurred, watcher_status_should_stick )
def _DelayWork( self, time_delta, reason ):
self._no_work_until = HydrusData.GetNow() + time_delta
self._no_work_until_reason = reason
def _FileNetworkJobPresentationContextFactory( self, network_job ):
def enter_call():
with self._lock:
if self._download_control_file_set is not None:
wx.CallAfter( self._download_control_file_set, network_job )
def exit_call():
with self._lock:
if self._download_control_file_clear is not None:
wx.CallAfter( self._download_control_file_clear )
return ClientImporting.NetworkJobPresentationContext( enter_call, exit_call )
def _FinishCheck( self, watcher_status, error_occurred, watcher_status_should_stick ):
if error_occurred:
# the [DEAD] stuff can override watcher status, so let's give a brief time for this to display the error
with self._lock:
self._checking_paused = True
self._watcher_status = watcher_status
time.sleep( 5 )
with self._lock:
if self._check_now:
self._check_now = False
self._watcher_status = watcher_status
self._last_check_time = HydrusData.GetNow()
self._UpdateFileVelocityStatus()
self._UpdateNextCheckTime()
self._PublishPageName()
if not watcher_status_should_stick:
time.sleep( 5 )
with self._lock:
self._watcher_status = ''
def _GetSerialisableInfo( self ):
serialisable_seed_cache = self._seed_cache.GetSerialisableTuple()
serialisable_checker_options = self._checker_options.GetSerialisableTuple()
serialisable_file_options = self._file_import_options.GetSerialisableTuple()
serialisable_tag_options = self._tag_import_options.GetSerialisableTuple()
return ( self._url, serialisable_seed_cache, self._urls_to_filenames, self._urls_to_md5_base64, serialisable_checker_options, serialisable_file_options, serialisable_tag_options, self._last_check_time, self._files_paused, self._checking_paused, self._checking_status, self._subject, self._no_work_until, self._no_work_until_reason )
def _HasURL( self ):
return self._url != ''
def _InitialiseFromSerialisableInfo( self, serialisable_info ):
( self._url, serialisable_seed_cache, self._urls_to_filenames, self._urls_to_md5_base64, serialisable_checker_options, serialisable_file_options, serialisable_tag_options, self._last_check_time, self._files_paused, self._checking_paused, self._checking_status, self._subject, self._no_work_until, self._no_work_until_reason ) = serialisable_info
self._seed_cache = HydrusSerialisable.CreateFromSerialisableTuple( serialisable_seed_cache )
self._checker_options = HydrusSerialisable.CreateFromSerialisableTuple( serialisable_checker_options )
self._file_import_options = HydrusSerialisable.CreateFromSerialisableTuple( serialisable_file_options )
self._tag_import_options = HydrusSerialisable.CreateFromSerialisableTuple( serialisable_tag_options )
def _PublishPageName( self ):
new_options = HG.client_controller.new_options
cannot_rename = not new_options.GetBoolean( 'permit_watchers_to_name_their_pages' )
if cannot_rename:
page_name = 'watcher'
elif self._subject in ( '', 'unknown subject' ):
page_name = 'watcher'
else:
page_name = self._subject
if self._checking_status == ClientImporting.CHECKER_STATUS_404:
thread_watcher_not_found_page_string = new_options.GetNoneableString( 'thread_watcher_not_found_page_string' )
if thread_watcher_not_found_page_string is not None:
page_name = thread_watcher_not_found_page_string + ' ' + page_name
elif self._checking_status == ClientImporting.CHECKER_STATUS_DEAD:
thread_watcher_dead_page_string = new_options.GetNoneableString( 'thread_watcher_dead_page_string' )
if thread_watcher_dead_page_string is not None:
page_name = thread_watcher_dead_page_string + ' ' + page_name
elif self._checking_paused:
thread_watcher_paused_page_string = new_options.GetNoneableString( 'thread_watcher_paused_page_string' )
if thread_watcher_paused_page_string is not None:
page_name = thread_watcher_paused_page_string + ' ' + page_name
if page_name != self._last_pubbed_page_name:
self._last_pubbed_page_name = page_name
if self._publish_to_page:
HG.client_controller.pub( 'rename_page', self._page_key, page_name )
def _CheckerNetworkJobPresentationContextFactory( self, network_job ):
def enter_call():
with self._lock:
if self._download_control_checker_set is not None:
wx.CallAfter( self._download_control_checker_set, network_job )
def exit_call():
with self._lock:
if self._download_control_checker_clear is not None:
wx.CallAfter( self._download_control_checker_clear )
return ClientImporting.NetworkJobPresentationContext( enter_call, exit_call )
def _UpdateFileVelocityStatus( self ):
self._file_velocity_status = self._checker_options.GetPrettyCurrentVelocity( self._seed_cache, self._last_check_time )
def _UpdateNextCheckTime( self ):
if self._check_now:
self._next_check_time = self._last_check_time + self.MIN_CHECK_PERIOD
else:
if not HydrusData.TimeHasPassed( self._no_work_until ):
self._next_check_time = self._no_work_until + 1
else:
if self._checking_status != ClientImporting.CHECKER_STATUS_404:
if self._checker_options.IsDead( self._seed_cache, self._last_check_time ):
self._checking_status = ClientImporting.CHECKER_STATUS_DEAD
self._checking_paused = True
self._next_check_time = self._checker_options.GetNextCheckTime( self._seed_cache, self._last_check_time )
def _UpdateSerialisableInfo( self, version, old_serialisable_info ):
if version == 1:
( url, serialisable_seed_cache, urls_to_filenames, urls_to_md5_base64, serialisable_file_options, serialisable_tag_options, times_to_check, check_period, last_check_time, paused ) = old_serialisable_info
checker_options = ClientImportOptions.CheckerOptions( intended_files_per_check = 8, never_faster_than = 300, never_slower_than = 86400, death_file_velocity = ( 1, 86400 ) )
serialisable_checker_options = checker_options.GetSerialisableTuple()
files_paused = paused
checking_paused = paused
new_serialisable_info = ( url, serialisable_seed_cache, urls_to_filenames, urls_to_md5_base64, serialisable_checker_options, serialisable_file_options, serialisable_tag_options, last_check_time, files_paused, checking_paused )
return ( 2, new_serialisable_info )
if version == 2:
( url, serialisable_seed_cache, urls_to_filenames, urls_to_md5_base64, serialisable_checker_options, serialisable_file_options, serialisable_tag_options, last_check_time, files_paused, checking_paused ) = old_serialisable_info
checking_status = ClientImporting.CHECKER_STATUS_OK
subject = 'unknown subject'
new_serialisable_info = ( url, serialisable_seed_cache, urls_to_filenames, urls_to_md5_base64, serialisable_checker_options, serialisable_file_options, serialisable_tag_options, last_check_time, files_paused, checking_paused, checking_status, subject )
return ( 3, new_serialisable_info )
if version == 3:
( url, serialisable_seed_cache, urls_to_filenames, urls_to_md5_base64, serialisable_checker_options, serialisable_file_options, serialisable_tag_options, last_check_time, files_paused, checking_paused, checking_status, subject ) = old_serialisable_info
no_work_until = 0
no_work_until_reason = ''
new_serialisable_info = ( url, serialisable_seed_cache, urls_to_filenames, urls_to_md5_base64, serialisable_checker_options, serialisable_file_options, serialisable_tag_options, last_check_time, files_paused, checking_paused, checking_status, subject, no_work_until, no_work_until_reason )
return ( 4, new_serialisable_info )
def _WorkOnFiles( self ):
seed = self._seed_cache.GetNextSeed( CC.STATUS_UNKNOWN )
if seed is None:
return
did_substantial_work = False
try:
def status_hook( text ):
with self._lock:
self._current_action = text
did_substantial_work = seed.WorkOnFileURL( self._file_import_options, status_hook, ClientImporting.GenerateWatcherNetworkJobFactory( self._watcher_key ), self._FileNetworkJobPresentationContextFactory, tag_import_options = self._tag_import_options )
with self._lock:
should_present = self._publish_to_page and seed.ShouldPresent( self._file_import_options )
page_key = self._page_key
if should_present:
seed.PresentToPage( page_key )
did_substantial_work = True
except HydrusExceptions.ShutdownException:
return
except HydrusExceptions.VetoException as e:
status = CC.STATUS_VETOED
note = HydrusData.ToUnicode( e )
seed.SetStatus( status, note = note )
if isinstance( e, HydrusExceptions.CancelledException ):
time.sleep( 2 )
except HydrusExceptions.NotFoundException:
status = CC.STATUS_VETOED
note = '404'
seed.SetStatus( status, note = note )
except Exception as e:
status = CC.STATUS_ERROR
seed.SetStatus( status, exception = e )
time.sleep( 3 )
finally:
self._seed_cache.NotifySeedsUpdated( ( seed, ) )
with self._lock:
self._current_action = ''
if did_substantial_work:
time.sleep( ClientImporting.DID_SUBSTANTIAL_FILE_WORK_MINIMUM_SLEEP_TIME )
def CheckNow( self ):
with self._lock:
self._check_now = True
self._checking_paused = False
self._no_work_until = 0
self._no_work_until_reason = ''
self._checking_status = ClientImporting.CHECKER_STATUS_OK
self._UpdateNextCheckTime()
ClientImporting.WakeRepeatingJob( self._checker_repeating_job )
def CurrentlyAlive( self ):
with self._lock:
return self._checking_status == ClientImporting.CHECKER_STATUS_OK
def CurrentlyWorking( self ):
with self._lock:
finished = not self._seed_cache.WorkToDo()
return not finished and not self._files_paused
def GetCheckerOptions( self ):
with self._lock:
return self._checker_options
def GetOptions( self ):
with self._lock:
return ( self._url, self._file_import_options, self._tag_import_options )
def GetPresentedHashes( self ):
return self._seed_cache.GetPresentedHashes( self._file_import_options )
def GetSeedCache( self ):
return self._seed_cache
def GetSimpleStatus( self ):
with self._lock:
if self._checking_status == ClientImporting.CHECKER_STATUS_404:
return '404'
elif self._checking_status == ClientImporting.CHECKER_STATUS_DEAD:
return 'DEAD'
elif self._checking_paused or self._files_paused:
return 'paused'
else:
return ''
def GetStatus( self ):
with self._lock:
2018-05-30 20:13:21 +00:00
if self._checking_status == ClientImporting.CHECKER_STATUS_404:
2018-05-23 21:05:06 +00:00
watcher_status = 'URL 404'
elif self._checking_status == ClientImporting.CHECKER_STATUS_DEAD:
watcher_status = 'URL DEAD'
2018-05-30 20:13:21 +00:00
elif not HydrusData.TimeHasPassed( self._no_work_until ):
watcher_status = self._no_work_until_reason + ' - ' + 'next check ' + HydrusData.ConvertTimestampToPrettyPending( self._next_check_time )
2018-05-23 21:05:06 +00:00
else:
watcher_status = self._watcher_status
return ( self._current_action, self._files_paused, self._file_velocity_status, self._next_check_time, watcher_status, self._subject, self._checking_status, self._check_now, self._checking_paused )
def GetSubject( self ):
with self._lock:
if self._subject in ( None, '' ):
return 'unknown subject'
else:
return self._subject
def GetWatcherKey( self ):
with self._lock:
return self._watcher_key
def GetURL( self ):
with self._lock:
return self._url
def GetValueRange( self ):
with self._lock:
return self._seed_cache.GetValueRange()
def HasURL( self ):
with self._lock:
return self._HasURL()
2018-05-30 20:13:21 +00:00
def _IsDead( self ):
return self._checking_status in ( ClientImporting.CHECKER_STATUS_404, ClientImporting.CHECKER_STATUS_DEAD )
2018-05-23 21:05:06 +00:00
def IsDead( self ):
with self._lock:
2018-05-30 20:13:21 +00:00
return self._IsDead()
2018-05-23 21:05:06 +00:00
def NotifySeedsUpdated( self, seed_cache_key, seeds ):
if seed_cache_key == self._seed_cache.GetSeedCacheKey():
ClientImporting.WakeRepeatingJob( self._files_repeating_job )
def PausePlayChecker( self ):
with self._lock:
2018-05-30 20:13:21 +00:00
if self._checking_paused and self._IsDead():
2018-05-23 21:05:06 +00:00
return # watcher is dead, so don't unpause until a checknow event
else:
self._checking_paused = not self._checking_paused
ClientImporting.WakeRepeatingJob( self._checker_repeating_job )
def PausePlayFiles( self ):
with self._lock:
self._files_paused = not self._files_paused
ClientImporting.WakeRepeatingJob( self._files_repeating_job )
2018-05-30 20:13:21 +00:00
def PausePlay( self ):
with self._lock:
if self._checking_paused:
if self._IsDead(): # can't unpause checker until a checknow event
self._files_paused = not self._files_paused
else:
self._checking_paused = False
self._files_paused = False
ClientImporting.WakeRepeatingJob( self._checker_repeating_job )
ClientImporting.WakeRepeatingJob( self._files_repeating_job )
else:
self._checking_paused = True
self._files_paused = True
2018-05-23 21:05:06 +00:00
def Repage( self, page_key, publish_to_page ):
with self._lock:
self._page_key = page_key
self._publish_to_page = publish_to_page
def SetDownloadControlChecker( self, download_control ):
with self._lock:
self._download_control_checker_set = download_control.SetNetworkJob
self._download_control_checker_clear = download_control.ClearNetworkJob
def SetDownloadControlFile( self, download_control ):
with self._lock:
self._download_control_file_set = download_control.SetNetworkJob
self._download_control_file_clear = download_control.ClearNetworkJob
def SetFileImportOptions( self, file_import_options ):
with self._lock:
self._file_import_options = file_import_options
def SetTagImportOptions( self, tag_import_options ):
with self._lock:
self._tag_import_options = tag_import_options
def SetURL( self, url ):
if url is None:
url = ''
if url != '':
url = HG.client_controller.network_engine.domain_manager.NormaliseURL( url )
with self._lock:
self._url = url
ClientImporting.WakeRepeatingJob( self._checker_repeating_job )
def SetCheckerOptions( self, checker_options ):
with self._lock:
self._checker_options = checker_options
self._checking_paused = False
self._UpdateNextCheckTime()
self._UpdateFileVelocityStatus()
ClientImporting.WakeRepeatingJob( self._checker_repeating_job )
def Start( self, page_key, publish_to_page ):
self._page_key = page_key
self._publish_to_page = publish_to_page
self._UpdateNextCheckTime()
self._PublishPageName()
self._UpdateFileVelocityStatus()
self._files_repeating_job = HG.client_controller.CallRepeating( ClientImporting.GetRepeatingJobInitialDelay(), ClientImporting.REPEATING_JOB_TYPICAL_PERIOD, self.REPEATINGWorkOnFiles )
self._checker_repeating_job = HG.client_controller.CallRepeating( ClientImporting.GetRepeatingJobInitialDelay(), ClientImporting.REPEATING_JOB_TYPICAL_PERIOD, self.REPEATINGWorkOnChecker )
def REPEATINGWorkOnFiles( self ):
with self._lock:
if ClientImporting.PageImporterShouldStopWorking( self._page_key ):
self._files_repeating_job.Cancel()
return
work_to_do = self._seed_cache.WorkToDo() and not ( self._files_paused or HG.client_controller.PageClosedButNotDestroyed( self._page_key ) )
while work_to_do:
try:
self._WorkOnFiles()
HG.client_controller.WaitUntilViewFree()
except Exception as e:
HydrusData.ShowException( e )
with self._lock:
if ClientImporting.PageImporterShouldStopWorking( self._page_key ):
self._files_repeating_job.Cancel()
return
work_to_do = self._seed_cache.WorkToDo() and not ( self._files_paused or HG.client_controller.PageClosedButNotDestroyed( self._page_key ) )
def REPEATINGWorkOnChecker( self ):
with self._lock:
if ClientImporting.PageImporterShouldStopWorking( self._page_key ):
self._checker_repeating_job.Cancel()
return
able_to_check = self._HasURL() and not self._checking_paused
check_due = HydrusData.TimeHasPassed( self._next_check_time )
no_delays = HydrusData.TimeHasPassed( self._no_work_until )
page_shown = not HG.client_controller.PageClosedButNotDestroyed( self._page_key )
time_to_check = able_to_check and check_due and no_delays and page_shown
if time_to_check:
try:
self._CheckWatchableURL()
except Exception as e:
HydrusData.ShowException( e )
HydrusSerialisable.SERIALISABLE_TYPES_TO_OBJECT_TYPES[ HydrusSerialisable.SERIALISABLE_TYPE_WATCHER_IMPORT ] = WatcherImport