<s> import ClientDownloading <EOL> import ClientFiles <EOL> import ClientThreading <EOL> import collections <EOL> import hashlib <EOL> import httplib <EOL> import itertools <EOL> import HydrusConstants as HC <EOL> import HydrusData <EOL> import HydrusEncryption <EOL> import HydrusExceptions <EOL> import HydrusImageHandling <EOL> import HydrusNATPunch <EOL> import HydrusPaths <EOL> import HydrusSerialisable <EOL> import HydrusTagArchive <EOL> import HydrusTags <EOL> import HydrusThreading <EOL> import ClientConstants as CC <EOL> import os <EOL> import Queue <EOL> import random <EOL> import shutil <EOL> import sqlite3 <EOL> import stat <EOL> import sys <EOL> import threading <EOL> import time <EOL> import traceback <EOL> import wx <EOL> import yaml <EOL> def DAEMONCheckExportFolders ( controller ) : <EOL> options = controller . GetOptions ( ) <EOL> if not options [ '<STR_LIT>' ] : <EOL> export_folders = controller . Read ( '<STR_LIT>' , HydrusSerialisable . SERIALISABLE_TYPE_EXPORT_FOLDER ) <EOL> for export_folder in export_folders : <EOL> if options [ '<STR_LIT>' ] : <EOL> break <EOL> export_folder . DoWork ( ) <EOL> def DAEMONCheckImportFolders ( controller ) : <EOL> options = controller . GetOptions ( ) <EOL> if not options [ '<STR_LIT>' ] : <EOL> import_folders = controller . Read ( '<STR_LIT>' , HydrusSerialisable . SERIALISABLE_TYPE_IMPORT_FOLDER ) <EOL> for import_folder in import_folders : <EOL> if options [ '<STR_LIT>' ] : <EOL> break <EOL> import_folder . DoWork ( ) <EOL> def DAEMONCheckMouseIdle ( controller ) : <EOL> wx . CallAfter ( controller . CheckMouseIdle ) <EOL> def DAEMONDownloadFiles ( controller ) : <EOL> hashes = controller . Read ( '<STR_LIT>' ) <EOL> num_downloads = len ( hashes ) <EOL> if num_downloads > <NUM_LIT:0> : <EOL> successful_hashes = set ( ) <EOL> job_key = ClientThreading . JobKey ( ) <EOL> job_key . SetVariable ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> controller . pub ( '<STR_LIT:message>' , job_key ) <EOL> for hash in hashes : <EOL> job_key . SetVariable ( '<STR_LIT>' , '<STR_LIT>' + HydrusData . ConvertIntToPrettyString ( num_downloads - len ( successful_hashes ) ) + '<STR_LIT>' ) <EOL> ( media_result , ) = controller . Read ( '<STR_LIT>' , CC . COMBINED_FILE_SERVICE_KEY , ( hash , ) ) <EOL> service_keys = list ( media_result . GetLocationsManager ( ) . GetCurrent ( ) ) <EOL> random . shuffle ( service_keys ) <EOL> for service_key in service_keys : <EOL> if service_key == CC . LOCAL_FILE_SERVICE_KEY : break <EOL> elif service_key == CC . TRASH_SERVICE_KEY : continue <EOL> try : <EOL> file_repository = controller . GetServicesManager ( ) . GetService ( service_key ) <EOL> except : <EOL> continue <EOL> if file_repository . CanDownload ( ) : <EOL> try : <EOL> request_args = { '<STR_LIT>' : hash . encode ( '<STR_LIT>' ) } <EOL> ( os_file_handle , temp_path ) = HydrusPaths . GetTempPath ( ) <EOL> try : <EOL> file_repository . Request ( HC . GET , '<STR_LIT:file>' , request_args = request_args , temp_path = temp_path ) <EOL> controller . WaitUntilPubSubsEmpty ( ) <EOL> controller . WriteSynchronous ( '<STR_LIT>' , temp_path , override_deleted = True ) <EOL> successful_hashes . add ( hash ) <EOL> break <EOL> finally : <EOL> HydrusPaths . CleanUpTempPath ( os_file_handle , temp_path ) <EOL> except HydrusExceptions . ServerBusyException : <EOL> job_key . SetVariable ( '<STR_LIT>' , file_repository . GetName ( ) + '<STR_LIT>' ) <EOL> time . sleep ( <NUM_LIT:30> ) <EOL> job_key . Delete ( ) <EOL> controller . pub ( '<STR_LIT>' ) <EOL> return <EOL> except Exception as e : <EOL> HydrusData . ShowText ( '<STR_LIT>' ) <EOL> HydrusData . ShowException ( e ) <EOL> if HydrusThreading . IsThreadShuttingDown ( ) : <EOL> return <EOL> if len ( successful_hashes ) > <NUM_LIT:0> : <EOL> job_key . SetVariable ( '<STR_LIT>' , HydrusData . ConvertIntToPrettyString ( len ( successful_hashes ) ) + '<STR_LIT>' ) <EOL> else : <EOL> job_key . SetVariable ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> job_key . Delete ( ) <EOL> def DAEMONFlushServiceUpdates ( controller , list_of_service_keys_to_service_updates ) : <EOL> service_keys_to_service_updates = HydrusData . MergeKeyToListDicts ( list_of_service_keys_to_service_updates ) <EOL> controller . WriteSynchronous ( '<STR_LIT>' , service_keys_to_service_updates ) <EOL> def DAEMONMaintainTrash ( controller ) : <EOL> if HC . options [ '<STR_LIT>' ] is not None : <EOL> max_size = HC . options [ '<STR_LIT>' ] * <NUM_LIT> <EOL> service_info = controller . Read ( '<STR_LIT>' , CC . TRASH_SERVICE_KEY ) <EOL> while service_info [ HC . SERVICE_INFO_TOTAL_SIZE ] > max_size : <EOL> if HydrusThreading . IsThreadShuttingDown ( ) : <EOL> return <EOL> hashes = controller . Read ( '<STR_LIT>' ) <EOL> if len ( hashes ) == <NUM_LIT:0> : <EOL> return <EOL> content_update = HydrusData . ContentUpdate ( HC . CONTENT_TYPE_FILES , HC . CONTENT_UPDATE_DELETE , hashes ) <EOL> service_keys_to_content_updates = { CC . TRASH_SERVICE_KEY : [ content_update ] } <EOL> controller . WaitUntilPubSubsEmpty ( ) <EOL> controller . WriteSynchronous ( '<STR_LIT>' , service_keys_to_content_updates ) <EOL> service_info = controller . Read ( '<STR_LIT>' , CC . TRASH_SERVICE_KEY ) <EOL> if HC . options [ '<STR_LIT>' ] is not None : <EOL> max_age = HC . options [ '<STR_LIT>' ] * <NUM_LIT> <EOL> hashes = controller . Read ( '<STR_LIT>' , minimum_age = max_age ) <EOL> while len ( hashes ) > <NUM_LIT:0> : <EOL> if HydrusThreading . IsThreadShuttingDown ( ) : <EOL> return <EOL> content_update = HydrusData . ContentUpdate ( HC . CONTENT_TYPE_FILES , HC . CONTENT_UPDATE_DELETE , hashes ) <EOL> service_keys_to_content_updates = { CC . TRASH_SERVICE_KEY : [ content_update ] } <EOL> controller . WaitUntilPubSubsEmpty ( ) <EOL> controller . WriteSynchronous ( '<STR_LIT>' , service_keys_to_content_updates ) <EOL> hashes = controller . Read ( '<STR_LIT>' , minimum_age = max_age ) <EOL> def DAEMONRebalanceClientFiles ( controller ) : <EOL> if controller . CurrentlyIdle ( ) : <EOL> controller . GetClientFilesManager ( ) . Rebalance ( ) <EOL> def DAEMONSynchroniseAccounts ( controller ) : <EOL> services = controller . GetServicesManager ( ) . GetServices ( HC . RESTRICTED_SERVICES ) <EOL> options = controller . GetOptions ( ) <EOL> do_notify = False <EOL> for service in services : <EOL> service_key = service . GetServiceKey ( ) <EOL> service_type = service . GetServiceType ( ) <EOL> account = service . GetInfo ( '<STR_LIT>' ) <EOL> credentials = service . GetCredentials ( ) <EOL> if service_type in HC . REPOSITORIES : <EOL> if options [ '<STR_LIT>' ] : continue <EOL> info = service . GetInfo ( ) <EOL> if info [ '<STR_LIT>' ] : continue <EOL> if account . IsStale ( ) and credentials . HasAccessKey ( ) and not service . HasRecentError ( ) : <EOL> try : <EOL> response = service . Request ( HC . GET , '<STR_LIT>' ) <EOL> account = response [ '<STR_LIT>' ] <EOL> account . MakeFresh ( ) <EOL> controller . WriteSynchronous ( '<STR_LIT>' , { service_key : [ HydrusData . ServiceUpdate ( HC . SERVICE_UPDATE_ACCOUNT , account ) ] } ) <EOL> do_notify = True <EOL> except HydrusExceptions . NetworkException as e : <EOL> HydrusData . Print ( '<STR_LIT>' + service . GetName ( ) + '<STR_LIT::>' ) <EOL> HydrusData . Print ( e ) <EOL> except Exception : <EOL> HydrusData . Print ( '<STR_LIT>' + service . GetName ( ) + '<STR_LIT::>' ) <EOL> HydrusData . Print ( traceback . format_exc ( ) ) <EOL> if do_notify : <EOL> controller . pub ( '<STR_LIT>' ) <EOL> def DAEMONSynchroniseRepositories ( controller ) : <EOL> options = controller . GetOptions ( ) <EOL> if not options [ '<STR_LIT>' ] : <EOL> services = controller . GetServicesManager ( ) . GetServices ( HC . REPOSITORIES ) <EOL> for service in services : <EOL> if options [ '<STR_LIT>' ] : <EOL> break <EOL> if controller . CurrentlyIdle ( ) : <EOL> service . Sync ( only_when_idle = True ) <EOL> time . sleep ( <NUM_LIT:5> ) <EOL> def DAEMONSynchroniseSubscriptions ( controller ) : <EOL> options = controller . GetOptions ( ) <EOL> subscription_names = controller . Read ( '<STR_LIT>' , HydrusSerialisable . SERIALISABLE_TYPE_SUBSCRIPTION ) <EOL> for name in subscription_names : <EOL> p1 = options [ '<STR_LIT>' ] <EOL> p2 = controller . ViewIsShutdown ( ) <EOL> if p1 or p2 : <EOL> return <EOL> subscription = controller . Read ( '<STR_LIT>' , HydrusSerialisable . SERIALISABLE_TYPE_SUBSCRIPTION , name ) <EOL> subscription . Sync ( ) <EOL> def DAEMONUPnP ( controller ) : <EOL> try : <EOL> local_ip = HydrusNATPunch . GetLocalIP ( ) <EOL> current_mappings = HydrusNATPunch . GetUPnPMappings ( ) <EOL> our_mappings = { ( internal_client , internal_port ) : external_port for ( description , internal_client , internal_port , external_ip_address , external_port , protocol , enabled ) in current_mappings } <EOL> except : <EOL> return <EOL> services = controller . GetServicesManager ( ) . GetServices ( ( HC . LOCAL_BOORU , ) ) <EOL> for service in services : <EOL> info = service . GetInfo ( ) <EOL> internal_port = info [ '<STR_LIT:port>' ] <EOL> upnp = info [ '<STR_LIT>' ] <EOL> if ( local_ip , internal_port ) in our_mappings : <EOL> current_external_port = our_mappings [ ( local_ip , internal_port ) ] <EOL> if upnp is None or current_external_port != upnp : HydrusNATPunch . RemoveUPnPMapping ( current_external_port , '<STR_LIT>' ) <EOL> for service in services : <EOL> info = service . GetInfo ( ) <EOL> internal_port = info [ '<STR_LIT:port>' ] <EOL> upnp = info [ '<STR_LIT>' ] <EOL> if upnp is not None : <EOL> if ( local_ip , internal_port ) not in our_mappings : <EOL> service_type = service . GetServiceType ( ) <EOL> external_port = upnp <EOL> protocol = '<STR_LIT>' <EOL> description = HC . service_string_lookup [ service_type ] + '<STR_LIT>' + local_ip + '<STR_LIT::>' + str ( internal_port ) <EOL> duration = <NUM_LIT> <EOL> HydrusNATPunch . AddUPnPMapping ( local_ip , internal_port , external_port , protocol , description , duration = duration ) </s>
