Version 237
This commit is contained in:
parent
3859d7ff83
commit
33c1a0b9e2
|
@ -8,6 +8,34 @@
|
|||
<div class="content">
|
||||
<h3>changelog</h3>
|
||||
<ul>
|
||||
<li><h3>version 237</h3></li>
|
||||
<ul>
|
||||
<li>added 'all local files' service that spans all local file domains</li>
|
||||
<li>improved trash service code</li>
|
||||
<li>trashed files now report their trashed timestamp in right-click menus</li>
|
||||
<li>trash views will sort oldest/newest by the trash timestamp</li>
|
||||
<li>renamed 'local files' to 'my files' to reduce initial confusion</li>
|
||||
<li>if you don't like 'my files', you can now rename the local files service under manage services!</li>
|
||||
<li>improved how some local file service metadata is stored</li>
|
||||
<li>cleaned and possibly fixed up some delete code</li>
|
||||
<li>cleaned up a bunch of misc service and file service code</li>
|
||||
<li>the client is more intelligent about what local files are -- you can now 'open externally' trashed files, for instance</li>
|
||||
<li>on multiple monitor systems, the new sizing system now bounds itself by the appropriate monitor's dimensions (previously, it was always consulting the primary, I think)</li>
|
||||
<li>if an expansion event causes a frame to grow off screen, the new sizing system will now attempt to move it up and left so it is completely visible</li>
|
||||
<li>fixed an important bug in the specific service autocomplete cache that was leading to several kinds of miscount--please regen your autocomplete cache at your convenience</li>
|
||||
<li>the client can now post additional messages on boot (you'll see one!)</li>
|
||||
<li>improved how errors with unusual characters are applied to failed import file status objects</li>
|
||||
<li>left double-click on the main gui greyspace now opens the new page chooser as well</li>
|
||||
<li>restored session pages now recover more gracefully from missing services</li>
|
||||
<li>shortened the 'stop after this many files' phrase, which was mis-sizing downloader panels</li>
|
||||
<li>changed several bits of old jank in the 'import options - files' collapsible. it is also now thinner</li>
|
||||
<li>misc gui improvements</li>
|
||||
<li>updated more of the menu system code</li>
|
||||
<li>the selection tags box now sizes its height more reasonably</li>
|
||||
<li>fixed 'check now' and 'reset cache' buttons on edit sub dialog</li>
|
||||
<li>subscriptions report better file import status on their popup</li>
|
||||
<li>misc cleanup</li>
|
||||
</ul>
|
||||
<li><h3>version 236</h3></li>
|
||||
<ul>
|
||||
<li>in prep for a network https upgrade, the client can now detect and escalate to https when making connections to hydrus services</li>
|
||||
|
|
|
@ -1668,7 +1668,7 @@ class ThumbnailCache( object ):
|
|||
|
||||
locations_manager = display_media.GetLocationsManager()
|
||||
|
||||
if locations_manager.HasLocal():
|
||||
if locations_manager.IsLocal():
|
||||
|
||||
try:
|
||||
|
||||
|
@ -2638,12 +2638,23 @@ class UndoManager( object ):
|
|||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
if data_type == HC.CONTENT_TYPE_FILES:
|
||||
if action in ( HC.CONTENT_UPDATE_ADD, HC.CONTENT_UPDATE_DELETE, HC.CONTENT_UPDATE_UNDELETE, HC.CONTENT_UPDATE_RESCIND_PETITION, HC.CONTENT_UPDATE_ADVANCED ): continue
|
||||
|
||||
if action in ( HC.CONTENT_UPDATE_ADD, HC.CONTENT_UPDATE_DELETE, HC.CONTENT_UPDATE_UNDELETE, HC.CONTENT_UPDATE_RESCIND_PETITION, HC.CONTENT_UPDATE_ADVANCED ):
|
||||
|
||||
continue
|
||||
|
||||
|
||||
elif data_type == HC.CONTENT_TYPE_MAPPINGS:
|
||||
|
||||
if action in ( HC.CONTENT_UPDATE_RESCIND_PETITION, HC.CONTENT_UPDATE_ADVANCED ): continue
|
||||
if action in ( HC.CONTENT_UPDATE_RESCIND_PETITION, HC.CONTENT_UPDATE_ADVANCED ):
|
||||
|
||||
continue
|
||||
|
||||
|
||||
else:
|
||||
|
||||
continue
|
||||
|
||||
else: continue
|
||||
|
||||
filtered_content_update = HydrusData.ContentUpdate( data_type, action, row )
|
||||
|
||||
|
@ -2930,4 +2941,4 @@ class WebSessionManagerClient( object ):
|
|||
return cookies
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -458,7 +458,7 @@ LOCAL_BOORU_SERVICE_KEY = 'local booru'
|
|||
|
||||
TRASH_SERVICE_KEY = 'trash'
|
||||
|
||||
COMBINED_LOCAL_FILES_SERVICE_KEY = 'all local files'
|
||||
COMBINED_LOCAL_FILE_SERVICE_KEY = 'all local files'
|
||||
|
||||
COMBINED_FILE_SERVICE_KEY = 'all known files'
|
||||
|
||||
|
|
|
@ -661,6 +661,11 @@ class Controller( HydrusController.HydrusController ):
|
|||
HydrusData.ShowText( 'The client has updated to version ' + str( HC.SOFTWARE_VERSION ) + '!' )
|
||||
|
||||
|
||||
for message in self._db.GetInitialMessages():
|
||||
|
||||
HydrusData.ShowText( message )
|
||||
|
||||
|
||||
|
||||
def LastShutdownWasBad( self ):
|
||||
|
||||
|
@ -888,7 +893,7 @@ class Controller( HydrusController.HydrusController ):
|
|||
|
||||
import ClientLocalServer
|
||||
|
||||
self._local_service = reactor.listenTCP( port, ClientLocalServer.HydrusServiceLocal( CC.LOCAL_FILE_SERVICE_KEY, HC.LOCAL_FILE, 'This is the local file service.' ), interface = '127.0.0.1' )
|
||||
self._local_service = reactor.listenTCP( port, ClientLocalServer.HydrusServiceLocal( CC.COMBINED_LOCAL_FILE_SERVICE_KEY, HC.COMBINED_LOCAL_FILE, 'This is the local file service.' ), interface = '127.0.0.1' )
|
||||
|
||||
try:
|
||||
|
||||
|
|
|
@ -1015,15 +1015,15 @@ def GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id ):
|
|||
|
||||
suffix = str( file_service_id ) + '_' + str( tag_service_id )
|
||||
|
||||
files_table_name = 'external_caches.specific_files_cache_' + suffix
|
||||
cache_files_table_name = 'external_caches.specific_files_cache_' + suffix
|
||||
|
||||
current_mappings_table_name = 'external_caches.specific_current_mappings_cache_' + suffix
|
||||
cache_current_mappings_table_name = 'external_caches.specific_current_mappings_cache_' + suffix
|
||||
|
||||
pending_mappings_table_name = 'external_caches.specific_pending_mappings_cache_' + suffix
|
||||
cache_pending_mappings_table_name = 'external_caches.specific_pending_mappings_cache_' + suffix
|
||||
|
||||
ac_cache_table_name = 'external_caches.specific_ac_cache_' + suffix
|
||||
|
||||
return ( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name )
|
||||
return ( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name )
|
||||
|
||||
class DB( HydrusDB.HydrusDB ):
|
||||
|
||||
|
@ -1033,6 +1033,8 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._updates_dir = os.path.join( db_dir, 'client_updates' )
|
||||
|
||||
self._initial_messages = []
|
||||
|
||||
HydrusDB.HydrusDB.__init__( self, controller, db_dir, db_name, no_wal = no_wal )
|
||||
|
||||
|
||||
|
@ -1061,13 +1063,15 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if len( valid_hash_ids ) > 0:
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO current_files VALUES ( ?, ?, ? );', ( ( service_id, hash_id, timestamp ) for ( hash_id, timestamp ) in rows if hash_id in valid_hash_ids ) )
|
||||
valid_rows = [ ( hash_id, timestamp ) for ( hash_id, timestamp ) in rows if hash_id in valid_hash_ids ]
|
||||
|
||||
splayed_valid_hash_ids = HydrusData.SplayListForDB( valid_hash_ids )
|
||||
|
||||
self._c.execute( 'DELETE FROM deleted_files WHERE service_id = ? AND hash_id IN ' + splayed_valid_hash_ids + ';', ( service_id, ) )
|
||||
# insert the files
|
||||
|
||||
num_deleted = self._GetRowCount()
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO current_files VALUES ( ?, ?, ? );', ( ( service_id, hash_id, timestamp ) for ( hash_id, timestamp ) in valid_rows ) )
|
||||
|
||||
self._c.execute( 'DELETE FROM file_transfers WHERE service_id = ? AND hash_id IN ' + splayed_valid_hash_ids + ';', ( service_id, ) )
|
||||
|
||||
info = self._c.execute( 'SELECT size, mime FROM files_info WHERE hash_id IN ' + splayed_valid_hash_ids + ';' ).fetchall()
|
||||
|
||||
|
@ -1077,32 +1081,39 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
service_info_updates = []
|
||||
|
||||
service_info_updates.append( ( -num_deleted, service_id, HC.SERVICE_INFO_NUM_DELETED_FILES ) )
|
||||
service_info_updates.append( ( delta_size, service_id, HC.SERVICE_INFO_TOTAL_SIZE ) )
|
||||
service_info_updates.append( ( num_files, service_id, HC.SERVICE_INFO_NUM_FILES ) )
|
||||
service_info_updates.append( ( num_inbox, service_id, HC.SERVICE_INFO_NUM_INBOX ) )
|
||||
|
||||
self._c.executemany( 'UPDATE service_info SET info = info + ? WHERE service_id = ? AND info_type = ?;', service_info_updates )
|
||||
|
||||
self._c.execute( 'DELETE FROM file_transfers WHERE service_id = ? AND hash_id IN ' + splayed_valid_hash_ids + ';', ( service_id, ) )
|
||||
|
||||
if service_id == self._local_file_service_id:
|
||||
|
||||
self._DeleteFiles( self._trash_service_id, valid_hash_ids, files_being_undeleted = True )
|
||||
|
||||
|
||||
if service_id == self._trash_service_id:
|
||||
|
||||
now = HydrusData.GetNow()
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO file_trash ( hash_id, timestamp ) VALUES ( ?, ? );', ( ( hash_id, now ) for hash_id in valid_hash_ids ) )
|
||||
|
||||
# now do special stuff
|
||||
|
||||
service = self._GetService( service_id )
|
||||
|
||||
service_type = service.GetServiceType()
|
||||
|
||||
if service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
# remove any records of previous deletion
|
||||
|
||||
if service_id == self._combined_local_file_service_id or service_type == HC.FILE_REPOSITORY:
|
||||
|
||||
self._c.execute( 'DELETE FROM deleted_files WHERE service_id = ? AND hash_id IN ' + splayed_valid_hash_ids + ';', ( service_id, ) )
|
||||
|
||||
num_deleted = self._GetRowCount()
|
||||
|
||||
service_info_updates.append( ( -num_deleted, service_id, HC.SERVICE_INFO_NUM_DELETED_FILES ) )
|
||||
|
||||
|
||||
# if we are adding to a local file domain, remove any from the trash and add to combined local file service if needed
|
||||
|
||||
if service_type == HC.LOCAL_FILE_DOMAIN:
|
||||
|
||||
self._DeleteFiles( self._trash_service_id, valid_hash_ids )
|
||||
|
||||
self._AddFiles( self._combined_local_file_service_id, valid_rows )
|
||||
|
||||
|
||||
# if we track tags for this service, update the a/c cache
|
||||
|
||||
if service_type in HC.AUTOCOMPLETE_CACHE_SPECIFIC_FILE_SERVICES:
|
||||
|
||||
tag_service_ids = self._GetServiceIds( HC.TAG_SERVICES )
|
||||
|
||||
|
@ -1112,6 +1123,10 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
|
||||
|
||||
# push the service updates, done
|
||||
|
||||
self._c.executemany( 'UPDATE service_info SET info = info + ? WHERE service_id = ? AND info_type = ?;', service_info_updates )
|
||||
|
||||
|
||||
|
||||
def _AddHydrusSession( self, service_key, session_key, expires ):
|
||||
|
@ -1123,21 +1138,18 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _AddService( self, service_key, service_type, name, info ):
|
||||
|
||||
if service_type in HC.LOCAL_SERVICES:
|
||||
if service_type == HC.LOCAL_BOORU:
|
||||
|
||||
if service_type == HC.LOCAL_BOORU:
|
||||
|
||||
current_time_struct = time.gmtime()
|
||||
|
||||
( current_year, current_month ) = ( current_time_struct.tm_year, current_time_struct.tm_mon )
|
||||
|
||||
if 'used_monthly_data' not in info: info[ 'used_monthly_data' ] = 0
|
||||
if 'max_monthly_data' not in info: info[ 'max_monthly_data' ] = None
|
||||
if 'used_monthly_requests' not in info: info[ 'used_monthly_requests' ] = 0
|
||||
if 'current_data_month' not in info: info[ 'current_data_month' ] = ( current_year, current_month )
|
||||
if 'port' not in info: info[ 'port' ] = None
|
||||
if 'upnp' not in info: info[ 'upnp' ] = None
|
||||
|
||||
current_time_struct = time.gmtime()
|
||||
|
||||
( current_year, current_month ) = ( current_time_struct.tm_year, current_time_struct.tm_mon )
|
||||
|
||||
if 'used_monthly_data' not in info: info[ 'used_monthly_data' ] = 0
|
||||
if 'max_monthly_data' not in info: info[ 'max_monthly_data' ] = None
|
||||
if 'used_monthly_requests' not in info: info[ 'used_monthly_requests' ] = 0
|
||||
if 'current_data_month' not in info: info[ 'current_data_month' ] = ( current_year, current_month )
|
||||
if 'port' not in info: info[ 'port' ] = None
|
||||
if 'upnp' not in info: info[ 'upnp' ] = None
|
||||
|
||||
|
||||
if service_type in HC.REMOTE_SERVICES:
|
||||
|
@ -1228,7 +1240,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._CacheCombinedFilesMappingsGenerate( service_id )
|
||||
|
||||
file_service_ids = self._GetServiceIds( ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ) )
|
||||
file_service_ids = self._GetServiceIds( HC.AUTOCOMPLETE_CACHE_SPECIFIC_FILE_SERVICES )
|
||||
|
||||
for file_service_id in file_service_ids:
|
||||
|
||||
|
@ -1236,7 +1248,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
|
||||
|
||||
if service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
if service_type in HC.AUTOCOMPLETE_CACHE_SPECIFIC_FILE_SERVICES:
|
||||
|
||||
tag_service_ids = self._GetServiceIds( HC.TAG_SERVICES )
|
||||
|
||||
|
@ -1964,7 +1976,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if hash_ids is None:
|
||||
|
||||
hash_ids = { hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM files_info, current_files USING ( hash_id ) WHERE service_id IN ' + HydrusData.SplayListForDB( ( self._local_file_service_id, self._trash_service_id ) ) + ' AND mime IN ' + HydrusData.SplayListForDB( HC.MIMES_WE_CAN_PHASH ) + ';' ) }
|
||||
hash_ids = { hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM files_info, current_files USING ( hash_id ) WHERE service_id = ? AND mime IN ' + HydrusData.SplayListForDB( HC.MIMES_WE_CAN_PHASH ) + ';', ( self._combined_local_file_service_id, ) ) }
|
||||
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO shape_maintenance_phash_regen ( hash_id ) VALUES ( ? );', ( ( hash_id, ) for hash_id in hash_ids ) )
|
||||
|
@ -2061,9 +2073,9 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _CacheSpecificMappingsAddFiles( self, file_service_id, tag_service_id, hash_ids ):
|
||||
|
||||
( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO ' + files_table_name + ' VALUES ( ? );', ( ( hash_id, ) for hash_id in hash_ids ) )
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO ' + cache_files_table_name + ' VALUES ( ? );', ( ( hash_id, ) for hash_id in hash_ids ) )
|
||||
|
||||
( current_mappings_table_name, deleted_mappings_table_name, pending_mappings_table_name, petitioned_mappings_table_name ) = GenerateMappingsTableNames( tag_service_id )
|
||||
|
||||
|
@ -2092,7 +2104,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if num_current > 0:
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO ' + current_mappings_table_name + ' ( hash_id, namespace_id, tag_id ) VALUES ( ?, ?, ? );', ( ( hash_id, namespace_id, tag_id ) for hash_id in current_hash_ids ) )
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO ' + cache_current_mappings_table_name + ' ( hash_id, namespace_id, tag_id ) VALUES ( ?, ?, ? );', ( ( hash_id, namespace_id, tag_id ) for hash_id in current_hash_ids ) )
|
||||
|
||||
|
||||
pending_hash_ids = pending_mapping_ids_dict[ ( namespace_id, tag_id ) ]
|
||||
|
@ -2101,7 +2113,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if num_pending > 0:
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO ' + pending_mappings_table_name + ' ( hash_id, namespace_id, tag_id ) VALUES ( ?, ?, ? );', ( ( hash_id, namespace_id, tag_id ) for hash_id in pending_hash_ids ) )
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO ' + cache_pending_mappings_table_name + ' ( hash_id, namespace_id, tag_id ) VALUES ( ?, ?, ? );', ( ( hash_id, namespace_id, tag_id ) for hash_id in pending_hash_ids ) )
|
||||
|
||||
|
||||
if num_current > 0 or num_pending > 0:
|
||||
|
@ -2121,7 +2133,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _CacheSpecificMappingsAddMappings( self, file_service_id, tag_service_id, mappings_ids ):
|
||||
|
||||
( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
|
||||
for ( namespace_id, tag_id, hash_ids ) in mappings_ids:
|
||||
|
||||
|
@ -2129,13 +2141,13 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if len( hash_ids ) > 0:
|
||||
|
||||
self._c.executemany( 'DELETE FROM ' + pending_mappings_table_name + ' WHERE hash_id = ? AND namespace_id = ? AND tag_id = ?;', ( ( hash_id, namespace_id, tag_id ) for hash_id in hash_ids ) )
|
||||
self._c.executemany( 'DELETE FROM ' + cache_pending_mappings_table_name + ' WHERE hash_id = ? AND namespace_id = ? AND tag_id = ?;', ( ( hash_id, namespace_id, tag_id ) for hash_id in hash_ids ) )
|
||||
|
||||
num_pending_rescinded = self._GetRowCount()
|
||||
|
||||
#
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO ' + current_mappings_table_name + ' ( hash_id, namespace_id, tag_id ) VALUES ( ?, ?, ? );', ( ( hash_id, namespace_id, tag_id ) for hash_id in hash_ids ) )
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO ' + cache_current_mappings_table_name + ' ( hash_id, namespace_id, tag_id ) VALUES ( ?, ?, ? );', ( ( hash_id, namespace_id, tag_id ) for hash_id in hash_ids ) )
|
||||
|
||||
num_added = self._GetRowCount()
|
||||
|
||||
|
@ -2155,22 +2167,22 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _CacheSpecificMappingsDrop( self, file_service_id, tag_service_id ):
|
||||
|
||||
( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
|
||||
self._c.execute( 'DROP TABLE ' + files_table_name + ';' )
|
||||
self._c.execute( 'DROP TABLE ' + cache_files_table_name + ';' )
|
||||
|
||||
self._c.execute( 'DROP TABLE ' + current_mappings_table_name + ';' )
|
||||
self._c.execute( 'DROP TABLE ' + cache_current_mappings_table_name + ';' )
|
||||
|
||||
self._c.execute( 'DROP TABLE ' + pending_mappings_table_name + ';' )
|
||||
self._c.execute( 'DROP TABLE ' + cache_pending_mappings_table_name + ';' )
|
||||
|
||||
self._c.execute( 'DROP TABLE ' + ac_cache_table_name + ';' )
|
||||
|
||||
|
||||
def _CacheSpecificMappingsDeleteFiles( self, file_service_id, tag_service_id, hash_ids ):
|
||||
|
||||
( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
|
||||
self._c.executemany( 'DELETE FROM ' + files_table_name + ' WHERE hash_id = ?;', ( ( hash_id, ) for hash_id in hash_ids ) )
|
||||
self._c.executemany( 'DELETE FROM ' + cache_files_table_name + ' WHERE hash_id = ?;', ( ( hash_id, ) for hash_id in hash_ids ) )
|
||||
|
||||
ac_cache_changes = []
|
||||
|
||||
|
@ -2178,11 +2190,11 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
splayed_group_of_hash_ids = HydrusData.SplayListForDB( group_of_hash_ids )
|
||||
|
||||
current_mapping_ids_raw = self._c.execute( 'SELECT namespace_id, tag_id, hash_id FROM ' + current_mappings_table_name + ' WHERE hash_id IN ' + splayed_group_of_hash_ids + ';' ).fetchall()
|
||||
current_mapping_ids_raw = self._c.execute( 'SELECT namespace_id, tag_id, hash_id FROM ' + cache_current_mappings_table_name + ' WHERE hash_id IN ' + splayed_group_of_hash_ids + ';' ).fetchall()
|
||||
|
||||
current_mapping_ids_dict = HydrusData.BuildKeyToSetDict( [ ( ( namespace_id, tag_id ), hash_id ) for ( namespace_id, tag_id, hash_id ) in current_mapping_ids_raw ] )
|
||||
|
||||
pending_mapping_ids_raw = self._c.execute( 'SELECT namespace_id, tag_id, hash_id FROM ' + pending_mappings_table_name + ' WHERE hash_id IN ' + splayed_group_of_hash_ids + ';' ).fetchall()
|
||||
pending_mapping_ids_raw = self._c.execute( 'SELECT namespace_id, tag_id, hash_id FROM ' + cache_pending_mappings_table_name + ' WHERE hash_id IN ' + splayed_group_of_hash_ids + ';' ).fetchall()
|
||||
|
||||
pending_mapping_ids_dict = HydrusData.BuildKeyToSetDict( [ ( ( namespace_id, tag_id ), hash_id ) for ( namespace_id, tag_id, hash_id ) in pending_mapping_ids_raw ] )
|
||||
|
||||
|
@ -2197,7 +2209,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if num_current > 0:
|
||||
|
||||
self._c.executemany( 'DELETE FROM ' + current_mappings_table_name + ' WHERE namespace_id = ? AND tag_id = ? AND hash_id = ?;', ( ( namespace_id, tag_id, hash_id ) for hash_id in current_hash_ids ) )
|
||||
self._c.executemany( 'DELETE FROM ' + cache_current_mappings_table_name + ' WHERE namespace_id = ? AND tag_id = ? AND hash_id = ?;', ( ( namespace_id, tag_id, hash_id ) for hash_id in current_hash_ids ) )
|
||||
|
||||
|
||||
pending_hash_ids = pending_mapping_ids_dict[ ( namespace_id, tag_id ) ]
|
||||
|
@ -2206,7 +2218,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if num_pending > 0:
|
||||
|
||||
self._c.executemany( 'DELETE FROM ' + pending_mappings_table_name + ' WHERE namespace_id = ? AND tag_id = ? AND hash_id = ?;', ( ( namespace_id, tag_id, hash_id ) for hash_id in pending_hash_ids ) )
|
||||
self._c.executemany( 'DELETE FROM ' + cache_pending_mappings_table_name + ' WHERE namespace_id = ? AND tag_id = ? AND hash_id = ?;', ( ( namespace_id, tag_id, hash_id ) for hash_id in pending_hash_ids ) )
|
||||
|
||||
|
||||
ac_cache_changes.append( ( namespace_id, tag_id, num_current, num_pending ) )
|
||||
|
@ -2223,7 +2235,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _CacheSpecificMappingsDeleteMappings( self, file_service_id, tag_service_id, mappings_ids ):
|
||||
|
||||
( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
|
||||
for ( namespace_id, tag_id, hash_ids ) in mappings_ids:
|
||||
|
||||
|
@ -2231,7 +2243,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if len( hash_ids ) > 0:
|
||||
|
||||
self._c.executemany( 'DELETE FROM ' + current_mappings_table_name + ' WHERE hash_id = ? AND namespace_id = ? AND tag_id = ?;', ( ( hash_id, namespace_id, tag_id ) for hash_id in hash_ids ) )
|
||||
self._c.executemany( 'DELETE FROM ' + cache_current_mappings_table_name + ' WHERE hash_id = ? AND namespace_id = ? AND tag_id = ?;', ( ( hash_id, namespace_id, tag_id ) for hash_id in hash_ids ) )
|
||||
|
||||
num_deleted = self._GetRowCount()
|
||||
|
||||
|
@ -2247,20 +2259,20 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _CacheSpecificMappingsFilterHashIds( self, file_service_id, tag_service_id, hash_ids ):
|
||||
|
||||
( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
|
||||
return [ hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM ' + files_table_name + ' WHERE hash_id IN ' + HydrusData.SplayListForDB( hash_ids ) + ';' ) ]
|
||||
return [ hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM ' + cache_files_table_name + ' WHERE hash_id IN ' + HydrusData.SplayListForDB( hash_ids ) + ';' ) ]
|
||||
|
||||
|
||||
def _CacheSpecificMappingsGenerate( self, file_service_id, tag_service_id ):
|
||||
|
||||
( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
|
||||
self._c.execute( 'CREATE TABLE ' + files_table_name + ' ( hash_id INTEGER PRIMARY KEY );' )
|
||||
self._c.execute( 'CREATE TABLE ' + cache_files_table_name + ' ( hash_id INTEGER PRIMARY KEY );' )
|
||||
|
||||
self._c.execute( 'CREATE TABLE ' + current_mappings_table_name + ' ( hash_id INTEGER, namespace_id INTEGER, tag_id INTEGER, PRIMARY KEY( hash_id, namespace_id, tag_id ) ) WITHOUT ROWID;' )
|
||||
self._c.execute( 'CREATE TABLE ' + cache_current_mappings_table_name + ' ( hash_id INTEGER, namespace_id INTEGER, tag_id INTEGER, PRIMARY KEY( hash_id, namespace_id, tag_id ) ) WITHOUT ROWID;' )
|
||||
|
||||
self._c.execute( 'CREATE TABLE ' + pending_mappings_table_name + ' ( hash_id INTEGER, namespace_id INTEGER, tag_id INTEGER, PRIMARY KEY( hash_id, namespace_id, tag_id ) ) WITHOUT ROWID;' )
|
||||
self._c.execute( 'CREATE TABLE ' + cache_pending_mappings_table_name + ' ( hash_id INTEGER, namespace_id INTEGER, tag_id INTEGER, PRIMARY KEY( hash_id, namespace_id, tag_id ) ) WITHOUT ROWID;' )
|
||||
|
||||
self._c.execute( 'CREATE TABLE ' + ac_cache_table_name + ' ( namespace_id INTEGER, tag_id INTEGER, current_count INTEGER, pending_count INTEGER, PRIMARY KEY( namespace_id, tag_id ) ) WITHOUT ROWID;' )
|
||||
|
||||
|
@ -2276,7 +2288,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _CacheSpecificMappingsGetAutocompleteCounts( self, file_service_id, tag_service_id, namespace_ids_to_tag_ids ):
|
||||
|
||||
( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
|
||||
results = []
|
||||
|
||||
|
@ -2290,7 +2302,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _CacheSpecificMappingsPendMappings( self, file_service_id, tag_service_id, mappings_ids ):
|
||||
|
||||
( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
|
||||
for ( namespace_id, tag_id, hash_ids ) in mappings_ids:
|
||||
|
||||
|
@ -2298,7 +2310,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if len( hash_ids ) > 0:
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO ' + pending_mappings_table_name + ' ( hash_id, namespace_id, tag_id ) VALUES ( ?, ?, ? );', ( ( hash_id, namespace_id, tag_id ) for hash_id in hash_ids ) )
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO ' + cache_pending_mappings_table_name + ' ( hash_id, namespace_id, tag_id ) VALUES ( ?, ?, ? );', ( ( hash_id, namespace_id, tag_id ) for hash_id in hash_ids ) )
|
||||
|
||||
num_added = self._GetRowCount()
|
||||
|
||||
|
@ -2315,7 +2327,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _CacheSpecificMappingsRescindPendingMappings( self, file_service_id, tag_service_id, mappings_ids ):
|
||||
|
||||
( files_table_name, current_mappings_table_name, pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
( cache_files_table_name, cache_current_mappings_table_name, cache_pending_mappings_table_name, ac_cache_table_name ) = GenerateSpecificMappingsCacheTableNames( file_service_id, tag_service_id )
|
||||
|
||||
for ( namespace_id, tag_id, hash_ids ) in mappings_ids:
|
||||
|
||||
|
@ -2323,7 +2335,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if len( hash_ids ) > 0:
|
||||
|
||||
self._c.executemany( 'DELETE FROM ' + pending_mappings_table_name + ' WHERE hash_id = ? AND namespace_id = ? AND tag_id = ?;', ( ( hash_id, namespace_id, tag_id ) for hash_id in hash_ids ) )
|
||||
self._c.executemany( 'DELETE FROM ' + cache_pending_mappings_table_name + ' WHERE hash_id = ? AND namespace_id = ? AND tag_id = ?;', ( ( hash_id, namespace_id, tag_id ) for hash_id in hash_ids ) )
|
||||
|
||||
num_deleted = self._GetRowCount()
|
||||
|
||||
|
@ -2402,7 +2414,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._controller.pub( 'message', job_key )
|
||||
|
||||
info = self._c.execute( 'SELECT hash_id, mime FROM current_files, files_info USING ( hash_id ) WHERE service_id IN ( ?, ? );', ( self._local_file_service_id, self._trash_service_id ) ).fetchall()
|
||||
info = self._c.execute( 'SELECT hash_id, mime FROM current_files, files_info USING ( hash_id ) WHERE service_id = ?;', ( self._combined_local_file_service_id, ) ).fetchall()
|
||||
|
||||
missing_count = 0
|
||||
deletee_hash_ids = []
|
||||
|
@ -2464,6 +2476,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._DeleteFiles( self._local_file_service_id, deletee_hash_ids )
|
||||
self._DeleteFiles( self._trash_service_id, deletee_hash_ids )
|
||||
self._DeleteFiles( self._combined_local_file_service_id, deletee_hash_ids )
|
||||
|
||||
final_text = 'done! '
|
||||
|
||||
|
@ -2562,9 +2575,6 @@ class DB( HydrusDB.HydrusDB ):
|
|||
self._c.execute( 'CREATE TABLE file_transfers ( service_id INTEGER REFERENCES services ON DELETE CASCADE, hash_id INTEGER, PRIMARY KEY( service_id, hash_id ) );' )
|
||||
self._c.execute( 'CREATE INDEX file_transfers_hash_id ON file_transfers ( hash_id );' )
|
||||
|
||||
self._c.execute( 'CREATE TABLE file_trash ( hash_id INTEGER PRIMARY KEY, timestamp INTEGER );' )
|
||||
self._c.execute( 'CREATE INDEX file_trash_timestamp ON file_trash ( timestamp );' )
|
||||
|
||||
self._c.execute( 'CREATE TABLE file_petitions ( service_id INTEGER REFERENCES services ON DELETE CASCADE, hash_id INTEGER, reason_id INTEGER, PRIMARY KEY( service_id, hash_id, reason_id ) );' )
|
||||
self._c.execute( 'CREATE INDEX file_petitions_hash_id_index ON file_petitions ( hash_id );' )
|
||||
|
||||
|
@ -2694,8 +2704,9 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
init_service_info = []
|
||||
|
||||
init_service_info.append( ( CC.LOCAL_FILE_SERVICE_KEY, HC.LOCAL_FILE, CC.LOCAL_FILE_SERVICE_KEY ) )
|
||||
init_service_info.append( ( CC.TRASH_SERVICE_KEY, HC.LOCAL_FILE, CC.TRASH_SERVICE_KEY ) )
|
||||
init_service_info.append( ( CC.COMBINED_LOCAL_FILE_SERVICE_KEY, HC.COMBINED_LOCAL_FILE, CC.COMBINED_LOCAL_FILE_SERVICE_KEY ) )
|
||||
init_service_info.append( ( CC.LOCAL_FILE_SERVICE_KEY, HC.LOCAL_FILE_DOMAIN, 'my files' ) )
|
||||
init_service_info.append( ( CC.TRASH_SERVICE_KEY, HC.LOCAL_FILE_TRASH_DOMAIN, CC.TRASH_SERVICE_KEY ) )
|
||||
init_service_info.append( ( CC.LOCAL_TAG_SERVICE_KEY, HC.LOCAL_TAG, CC.LOCAL_TAG_SERVICE_KEY ) )
|
||||
init_service_info.append( ( CC.COMBINED_FILE_SERVICE_KEY, HC.COMBINED_FILE, CC.COMBINED_FILE_SERVICE_KEY ) )
|
||||
init_service_info.append( ( CC.COMBINED_TAG_SERVICE_KEY, HC.COMBINED_TAG, CC.COMBINED_TAG_SERVICE_KEY ) )
|
||||
|
@ -2727,19 +2738,23 @@ class DB( HydrusDB.HydrusDB ):
|
|||
self._c.execute( 'COMMIT;' )
|
||||
|
||||
|
||||
def _DeleteFiles( self, service_id, hash_ids, files_being_undeleted = False ):
|
||||
def _DeleteFiles( self, service_id, hash_ids ):
|
||||
|
||||
splayed_hash_ids = HydrusData.SplayListForDB( hash_ids )
|
||||
|
||||
rows = self._c.execute( 'SELECT hash_id, timestamp FROM current_files WHERE service_id = ? AND hash_id IN ' + splayed_hash_ids + ';', ( service_id, ) ).fetchall()
|
||||
|
||||
valid_hash_ids = { row[ 0 ] for row in rows }
|
||||
valid_hash_ids = { hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM current_files WHERE service_id = ? AND hash_id IN ' + splayed_hash_ids + ';', ( service_id, ) ) }
|
||||
|
||||
if len( valid_hash_ids ) > 0:
|
||||
|
||||
splayed_valid_hash_ids = HydrusData.SplayListForDB( valid_hash_ids )
|
||||
|
||||
info = self._c.execute( 'SELECT size, mime FROM files_info WHERE hash_id IN ' + splayed_hash_ids + ';' ).fetchall()
|
||||
# remove them from the service
|
||||
|
||||
self._c.execute( 'DELETE FROM current_files WHERE service_id = ? AND hash_id IN ' + splayed_valid_hash_ids + ';', ( service_id, ) )
|
||||
|
||||
self._c.execute( 'DELETE FROM file_petitions WHERE service_id = ? AND hash_id IN ' + splayed_valid_hash_ids + ';', ( service_id, ) )
|
||||
|
||||
info = self._c.execute( 'SELECT size, mime FROM files_info WHERE hash_id IN ' + splayed_valid_hash_ids + ';' ).fetchall()
|
||||
|
||||
num_files = len( valid_hash_ids )
|
||||
delta_size = sum( ( size for ( size, mime ) in info ) )
|
||||
|
@ -2751,42 +2766,24 @@ class DB( HydrusDB.HydrusDB ):
|
|||
service_info_updates.append( ( -num_files, service_id, HC.SERVICE_INFO_NUM_FILES ) )
|
||||
service_info_updates.append( ( -num_inbox, service_id, HC.SERVICE_INFO_NUM_INBOX ) )
|
||||
|
||||
if service_id != self._trash_service_id:
|
||||
|
||||
# trash service doesn't keep track of what is deleted, as this is redundant
|
||||
|
||||
service_info_updates.append( ( num_files, service_id, HC.SERVICE_INFO_NUM_DELETED_FILES ) )
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO deleted_files ( service_id, hash_id ) VALUES ( ?, ? );', [ ( service_id, hash_id ) for hash_id in hash_ids ] )
|
||||
|
||||
|
||||
self._c.executemany( 'UPDATE service_info SET info = info + ? WHERE service_id = ? AND info_type = ?;', service_info_updates )
|
||||
|
||||
self._c.execute( 'DELETE FROM current_files WHERE service_id = ? AND hash_id IN ' + splayed_hash_ids + ';', ( service_id, ) )
|
||||
self._c.execute( 'DELETE FROM file_petitions WHERE service_id = ? AND hash_id IN ' + splayed_hash_ids + ';', ( service_id, ) )
|
||||
|
||||
if service_id == self._local_file_service_id:
|
||||
|
||||
self._AddFiles( self._trash_service_id, rows )
|
||||
|
||||
|
||||
if service_id == self._trash_service_id:
|
||||
|
||||
self._c.execute( 'DELETE FROM file_trash WHERE hash_id IN ' + splayed_hash_ids + ';' )
|
||||
|
||||
if not files_being_undeleted:
|
||||
|
||||
self._ArchiveFiles( hash_ids )
|
||||
|
||||
self._DeletePhysicalFiles( hash_ids )
|
||||
|
||||
|
||||
# now do special stuff
|
||||
|
||||
service = self._GetService( service_id )
|
||||
|
||||
service_type = service.GetServiceType()
|
||||
|
||||
if service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
# record the deleted row if appropriate
|
||||
|
||||
if service_id == self._combined_local_file_service_id or service_type == HC.FILE_REPOSITORY:
|
||||
|
||||
service_info_updates.append( ( num_files, service_id, HC.SERVICE_INFO_NUM_DELETED_FILES ) )
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO deleted_files ( service_id, hash_id ) VALUES ( ?, ? );', [ ( service_id, hash_id ) for hash_id in valid_hash_ids ] )
|
||||
|
||||
|
||||
# if we maintain tag counts for this service, update
|
||||
|
||||
if service_type in HC.AUTOCOMPLETE_CACHE_SPECIFIC_FILE_SERVICES:
|
||||
|
||||
tag_service_ids = self._GetServiceIds( HC.TAG_SERVICES )
|
||||
|
||||
|
@ -2796,9 +2793,44 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
|
||||
|
||||
# if the files are no longer in any local file services, send them to the trash
|
||||
|
||||
local_file_service_ids = self._GetServiceIds( ( HC.LOCAL_FILE_DOMAIN, ) )
|
||||
|
||||
if service_id in local_file_service_ids:
|
||||
|
||||
splayed_local_file_service_ids = HydrusData.SplayListForDB( local_file_service_ids )
|
||||
|
||||
non_orphan_hash_ids = { hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM current_files WHERE hash_id IN ' + splayed_valid_hash_ids + ' AND service_id IN ' + splayed_local_file_service_ids + ';' ) }
|
||||
|
||||
orphan_hash_ids = valid_hash_ids.difference( non_orphan_hash_ids )
|
||||
|
||||
if len( orphan_hash_ids ) > 0:
|
||||
|
||||
now = HydrusData.GetNow()
|
||||
|
||||
delete_rows = [ ( hash_id, now ) for hash_id in orphan_hash_ids ]
|
||||
|
||||
self._AddFiles( self._trash_service_id, delete_rows )
|
||||
|
||||
|
||||
|
||||
# if the files are being fully deleted, then physically delete them
|
||||
|
||||
if service_id == self._combined_local_file_service_id:
|
||||
|
||||
self._DeletePhysicalFiles( valid_hash_ids )
|
||||
|
||||
|
||||
# push the info updates, notify
|
||||
|
||||
self._c.executemany( 'UPDATE service_info SET info = info + ? WHERE service_id = ? AND info_type = ?;', service_info_updates )
|
||||
|
||||
self.pub_after_commit( 'notify_new_pending' )
|
||||
|
||||
|
||||
return valid_hash_ids
|
||||
|
||||
|
||||
def _DeleteHydrusSessionKey( self, service_key ):
|
||||
|
||||
|
@ -2863,6 +2895,8 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _DeletePhysicalFiles( self, hash_ids ):
|
||||
|
||||
self._ArchiveFiles( hash_ids )
|
||||
|
||||
hash_ids = set( hash_ids )
|
||||
|
||||
potentially_pending_upload_hash_ids = { hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM file_transfers;', ) }
|
||||
|
@ -2917,7 +2951,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._CacheCombinedFilesMappingsDrop( service_id )
|
||||
|
||||
file_service_ids = self._GetServiceIds( ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ) )
|
||||
file_service_ids = self._GetServiceIds( HC.AUTOCOMPLETE_CACHE_SPECIFIC_FILE_SERVICES )
|
||||
|
||||
for file_service_id in file_service_ids:
|
||||
|
||||
|
@ -2925,7 +2959,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
|
||||
|
||||
if service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
if service_type in HC.AUTOCOMPLETE_CACHE_SPECIFIC_FILE_SERVICES:
|
||||
|
||||
tag_service_ids = self._GetServiceIds( HC.TAG_SERVICES )
|
||||
|
||||
|
@ -3392,7 +3426,10 @@ class DB( HydrusDB.HydrusDB ):
|
|||
return result
|
||||
|
||||
|
||||
def _GetDownloads( self ): return { hash for ( hash, ) in self._c.execute( 'SELECT hash FROM file_transfers, hashes USING ( hash_id ) WHERE service_id = ?;', ( self._local_file_service_id, ) ) }
|
||||
def _GetDownloads( self ):
|
||||
|
||||
return { hash for ( hash, ) in self._c.execute( 'SELECT hash FROM file_transfers, hashes USING ( hash_id ) WHERE service_id = ?;', ( self._combined_local_file_service_id, ) ) }
|
||||
|
||||
|
||||
def _GetFileHashes( self, given_hashes, given_hash_type, desired_hash_type ):
|
||||
|
||||
|
@ -3444,7 +3481,10 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
predicates = []
|
||||
|
||||
if service_type in ( HC.COMBINED_FILE, HC.COMBINED_TAG ): predicates.extend( [ ClientSearch.Predicate( predicate_type, None ) for predicate_type in [ HC.PREDICATE_TYPE_SYSTEM_EVERYTHING, HC.PREDICATE_TYPE_SYSTEM_UNTAGGED, HC.PREDICATE_TYPE_SYSTEM_NUM_TAGS, HC.PREDICATE_TYPE_SYSTEM_LIMIT, HC.PREDICATE_TYPE_SYSTEM_HASH ] ] )
|
||||
if service_type in ( HC.COMBINED_FILE, HC.COMBINED_TAG ):
|
||||
|
||||
predicates.extend( [ ClientSearch.Predicate( predicate_type, None ) for predicate_type in [ HC.PREDICATE_TYPE_SYSTEM_EVERYTHING, HC.PREDICATE_TYPE_SYSTEM_UNTAGGED, HC.PREDICATE_TYPE_SYSTEM_NUM_TAGS, HC.PREDICATE_TYPE_SYSTEM_LIMIT, HC.PREDICATE_TYPE_SYSTEM_HASH ] ] )
|
||||
|
||||
elif service_type in HC.TAG_SERVICES:
|
||||
|
||||
service_info = self._GetServiceInfoSpecific( service_id, service_type, { HC.SERVICE_INFO_NUM_FILES } )
|
||||
|
@ -3455,7 +3495,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
predicates.extend( [ ClientSearch.Predicate( predicate_type, None ) for predicate_type in [ HC.PREDICATE_TYPE_SYSTEM_UNTAGGED, HC.PREDICATE_TYPE_SYSTEM_NUM_TAGS, HC.PREDICATE_TYPE_SYSTEM_LIMIT, HC.PREDICATE_TYPE_SYSTEM_HASH ] ] )
|
||||
|
||||
elif service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
elif service_type in HC.FILE_SERVICES:
|
||||
|
||||
service_info = self._GetServiceInfoSpecific( service_id, service_type, { HC.SERVICE_INFO_NUM_FILES, HC.SERVICE_INFO_NUM_INBOX } )
|
||||
|
||||
|
@ -3465,7 +3505,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if service_type == HC.FILE_REPOSITORY:
|
||||
|
||||
( num_local, ) = self._c.execute( 'SELECT COUNT( * ) FROM current_files AS remote_current_files, current_files USING ( hash_id ) WHERE remote_current_files.service_id = ? AND current_files.service_id = ?;', ( service_id, self._local_file_service_id ) ).fetchone()
|
||||
( num_local, ) = self._c.execute( 'SELECT COUNT( * ) FROM current_files AS remote_current_files, current_files USING ( hash_id ) WHERE remote_current_files.service_id = ? AND current_files.service_id = ?;', ( service_id, self._combined_local_file_service_id ) ).fetchone()
|
||||
|
||||
num_not_local = num_everything - num_local
|
||||
|
||||
|
@ -3919,7 +3959,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
must_be_inbox = system_predicates.MustBeInbox()
|
||||
must_be_archive = system_predicates.MustBeArchive()
|
||||
|
||||
if file_service_type == HC.LOCAL_FILE:
|
||||
if file_service_type in HC.LOCAL_FILE_SERVICES:
|
||||
|
||||
if must_not_be_local:
|
||||
|
||||
|
@ -3928,7 +3968,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
elif must_be_local or must_not_be_local:
|
||||
|
||||
local_hash_ids = [ id for ( id, ) in self._c.execute( 'SELECT hash_id FROM current_files WHERE service_id = ?;', ( self._local_file_service_id, ) ) ]
|
||||
local_hash_ids = [ id for ( id, ) in self._c.execute( 'SELECT hash_id FROM current_files WHERE service_id = ?;', ( self._combined_local_file_service_id, ) ) ]
|
||||
|
||||
if must_be_local:
|
||||
|
||||
|
@ -4404,14 +4444,21 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
def _GetHashIdStatus( self, hash_id ):
|
||||
|
||||
result = self._c.execute( 'SELECT 1 FROM deleted_files WHERE service_id = ? AND hash_id = ?;', ( self._local_file_service_id, hash_id ) ).fetchone()
|
||||
result = self._c.execute( 'SELECT 1 FROM deleted_files WHERE service_id = ? AND hash_id = ?;', ( self._combined_local_file_service_id, hash_id ) ).fetchone()
|
||||
|
||||
if result is not None:
|
||||
|
||||
return ( CC.STATUS_DELETED, None )
|
||||
|
||||
|
||||
result = self._c.execute( 'SELECT 1 FROM current_files WHERE service_id = ? AND hash_id = ?;', ( self._local_file_service_id, hash_id ) ).fetchone()
|
||||
result = self._c.execute( 'SELECT 1 FROM current_files WHERE service_id = ? AND hash_id = ?;', ( self._trash_service_id, hash_id ) ).fetchone()
|
||||
|
||||
if result is not None:
|
||||
|
||||
return ( CC.STATUS_DELETED, None )
|
||||
|
||||
|
||||
result = self._c.execute( 'SELECT 1 FROM current_files WHERE service_id = ? AND hash_id = ?;', ( self._combined_local_file_service_id, hash_id ) ).fetchone()
|
||||
|
||||
if result is not None:
|
||||
|
||||
|
@ -5152,7 +5199,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
hash_ids = { hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM current_files, files_info USING ( hash_id ) WHERE mime IN ' + HydrusData.SplayListForDB( HC.MIMES_WITH_THUMBNAILS ) + ' AND service_id = ?;', ( service_id, ) ) }
|
||||
|
||||
hash_ids.difference_update( ( hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM current_files WHERE service_id = ?;', ( self._local_file_service_id, ) ) ) )
|
||||
hash_ids.difference_update( ( hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM current_files WHERE service_id = ?;', ( self._combined_local_file_service_id, ) ) ) )
|
||||
|
||||
hashes = set( self._GetHashes( hash_ids ) )
|
||||
|
||||
|
@ -5280,10 +5327,14 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
service_type = service.GetServiceType()
|
||||
|
||||
if service_type == HC.LOCAL_FILE:
|
||||
if service_type == HC.COMBINED_LOCAL_FILE:
|
||||
|
||||
info_types = { HC.SERVICE_INFO_NUM_FILES, HC.SERVICE_INFO_TOTAL_SIZE, HC.SERVICE_INFO_NUM_DELETED_FILES }
|
||||
|
||||
elif service_type in ( HC.LOCAL_FILE_DOMAIN, HC.LOCAL_FILE_TRASH_DOMAIN ):
|
||||
|
||||
info_types = { HC.SERVICE_INFO_NUM_FILES, HC.SERVICE_INFO_TOTAL_SIZE }
|
||||
|
||||
elif service_type == HC.FILE_REPOSITORY:
|
||||
|
||||
info_types = { HC.SERVICE_INFO_NUM_FILES, HC.SERVICE_INFO_TOTAL_SIZE, HC.SERVICE_INFO_NUM_DELETED_FILES }
|
||||
|
@ -5352,7 +5403,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
save_it = True
|
||||
|
||||
if service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY, HC.IPFS ):
|
||||
if service_type in HC.FILE_SERVICES:
|
||||
|
||||
if info_type in ( HC.SERVICE_INFO_NUM_PENDING_FILES, HC.SERVICE_INFO_NUM_PETITIONED_FILES ): save_it = False
|
||||
|
||||
|
@ -5577,10 +5628,10 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
timestamp_cutoff = HydrusData.GetNow() - minimum_age
|
||||
|
||||
age_phrase = ' WHERE timestamp < ' + str( timestamp_cutoff ) + ' ORDER BY timestamp ASC'
|
||||
age_phrase = ' AND timestamp < ' + str( timestamp_cutoff ) + ' ORDER BY timestamp ASC'
|
||||
|
||||
|
||||
hash_ids = { hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM file_trash' + age_phrase + limit_phrase + ';' ) }
|
||||
hash_ids = { hash_id for ( hash_id, ) in self._c.execute( 'SELECT hash_id FROM current_files WHERE service_id = ?' + age_phrase + limit_phrase + ';', ( self._trash_service_id, ) ) }
|
||||
|
||||
return self._GetHashes( hash_ids )
|
||||
|
||||
|
@ -5710,7 +5761,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._ArchiveFiles( ( hash_id, ) )
|
||||
|
||||
self.pub_content_updates_after_commit( { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, set( ( hash, ) ) ) ] } )
|
||||
self.pub_content_updates_after_commit( { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, set( ( hash, ) ) ) ] } )
|
||||
|
||||
|
||||
elif status == CC.STATUS_NEW:
|
||||
|
@ -5846,6 +5897,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._local_file_service_id = self._GetServiceId( CC.LOCAL_FILE_SERVICE_KEY )
|
||||
self._trash_service_id = self._GetServiceId( CC.TRASH_SERVICE_KEY )
|
||||
self._combined_local_file_service_id = self._GetServiceId( CC.COMBINED_LOCAL_FILE_SERVICE_KEY )
|
||||
self._local_tag_service_id = self._GetServiceId( CC.LOCAL_TAG_SERVICE_KEY )
|
||||
self._combined_file_service_id = self._GetServiceId( CC.COMBINED_FILE_SERVICE_KEY )
|
||||
self._combined_tag_service_id = self._GetServiceId( CC.COMBINED_TAG_SERVICE_KEY )
|
||||
|
@ -5875,7 +5927,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
hash_id = self._GetHashId( hash )
|
||||
|
||||
result = self._c.execute( 'SELECT 1 FROM current_files WHERE service_id IN ( ?, ? ) AND hash_id = ?;', ( self._local_file_service_id, self._trash_service_id, hash_id ) ).fetchone()
|
||||
result = self._c.execute( 'SELECT 1 FROM current_files WHERE service_id = ? AND hash_id = ?;', ( self._combined_local_file_service_id, hash_id ) ).fetchone()
|
||||
|
||||
if result is None:
|
||||
|
||||
|
@ -6207,7 +6259,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
if service_type in ( HC.FILE_REPOSITORY, HC.LOCAL_FILE, HC.IPFS ):
|
||||
if service_type in HC.FILE_SERVICES:
|
||||
|
||||
if data_type == HC.CONTENT_TYPE_FILES:
|
||||
|
||||
|
@ -6224,7 +6276,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
elif action == HC.CONTENT_UPDATE_ADD:
|
||||
|
||||
if service_type in ( HC.FILE_REPOSITORY, HC.LOCAL_FILE ):
|
||||
if service_type in HC.LOCAL_FILE_SERVICES or service_type == HC.FILE_REPOSITORY:
|
||||
|
||||
( hash, size, mime, timestamp, width, height, duration, num_frames, num_words ) = row
|
||||
|
||||
|
@ -6253,7 +6305,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO file_transfers ( service_id, hash_id ) VALUES ( ?, ? );', [ ( service_id, hash_id ) for hash_id in hash_ids ] )
|
||||
|
||||
if service_key == CC.LOCAL_FILE_SERVICE_KEY: notify_new_downloads = True
|
||||
if service_key == CC.COMBINED_LOCAL_FILE_SERVICE_KEY: notify_new_downloads = True
|
||||
else: notify_new_pending = True
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_PETITION:
|
||||
|
@ -6298,8 +6350,23 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if action == HC.CONTENT_UPDATE_ARCHIVE: self._ArchiveFiles( hash_ids )
|
||||
elif action == HC.CONTENT_UPDATE_INBOX: self._InboxFiles( hash_ids )
|
||||
elif action == HC.CONTENT_UPDATE_DELETE: self._DeleteFiles( service_id, hash_ids )
|
||||
elif action == HC.CONTENT_UPDATE_UNDELETE: self._UndeleteFiles( hash_ids )
|
||||
elif action == HC.CONTENT_UPDATE_DELETE:
|
||||
|
||||
deleted_hash_ids = self._DeleteFiles( service_id, hash_ids )
|
||||
|
||||
if service_id == self._trash_service_id:
|
||||
|
||||
self._DeleteFiles( self._combined_local_file_service_id, deleted_hash_ids )
|
||||
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_UNDELETE:
|
||||
|
||||
splayed_hash_ids = HydrusData.SplayListForDB( hash_ids )
|
||||
|
||||
rows = self._c.execute( 'SELECT hash_id, timestamp FROM current_files WHERE service_id = ? AND hash_id IN ' + splayed_hash_ids + ';', ( self._combined_local_file_service_id, ) ).fetchall()
|
||||
|
||||
self._AddFiles( self._local_file_service_id, rows )
|
||||
|
||||
|
||||
|
||||
elif data_type == HC.CONTENT_TYPE_DIRECTORIES:
|
||||
|
@ -6679,8 +6746,14 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if do_pubsubs:
|
||||
|
||||
if notify_new_downloads: self.pub_after_commit( 'notify_new_downloads' )
|
||||
if notify_new_pending: self.pub_after_commit( 'notify_new_pending' )
|
||||
if notify_new_downloads:
|
||||
|
||||
self.pub_after_commit( 'notify_new_downloads' )
|
||||
|
||||
if notify_new_pending:
|
||||
|
||||
self.pub_after_commit( 'notify_new_pending' )
|
||||
|
||||
if notify_new_siblings:
|
||||
|
||||
self.pub_after_commit( 'notify_new_siblings_data' )
|
||||
|
@ -6935,7 +7008,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
self._controller.pub( 'message', job_key )
|
||||
|
||||
tag_service_ids = self._GetServiceIds( HC.TAG_SERVICES )
|
||||
file_service_ids = self._GetServiceIds( ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ) )
|
||||
file_service_ids = self._GetServiceIds( HC.AUTOCOMPLETE_CACHE_SPECIFIC_FILE_SERVICES )
|
||||
|
||||
for ( file_service_id, tag_service_id ) in itertools.product( file_service_ids, tag_service_ids ):
|
||||
|
||||
|
@ -7286,18 +7359,6 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
|
||||
|
||||
def _UndeleteFiles( self, hash_ids ):
|
||||
|
||||
splayed_hash_ids = HydrusData.SplayListForDB( hash_ids )
|
||||
|
||||
rows = self._c.execute( 'SELECT hash_id, timestamp FROM current_files WHERE service_id = ? AND hash_id IN ' + splayed_hash_ids + ';', ( self._trash_service_id, ) ).fetchall()
|
||||
|
||||
if len( rows ) > 0:
|
||||
|
||||
self._AddFiles( self._local_file_service_id, rows )
|
||||
|
||||
|
||||
|
||||
def _UpdateDB( self, version ):
|
||||
|
||||
self._controller.pub( 'splash_set_title_text', 'updating db to v' + str( version + 1 ) )
|
||||
|
@ -7684,7 +7745,7 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
if version == 201:
|
||||
|
||||
file_service_ids = self._GetServiceIds( ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ) )
|
||||
file_service_ids = self._GetServiceIds( ( HC.LOCAL_FILE_DOMAIN, HC.FILE_REPOSITORY ) )
|
||||
tag_service_ids = self._GetServiceIds( ( HC.LOCAL_TAG, HC.TAG_REPOSITORY ) )
|
||||
|
||||
for ( file_service_id, tag_service_id ) in itertools.product( file_service_ids, tag_service_ids ):
|
||||
|
@ -8606,6 +8667,62 @@ class DB( HydrusDB.HydrusDB ):
|
|||
|
||||
|
||||
|
||||
if version == 236:
|
||||
|
||||
self._controller.pub( 'splash_set_status_text', 'updating local files services' )
|
||||
|
||||
# update existing services
|
||||
|
||||
self._c.execute( 'UPDATE services SET name = ? WHERE service_key = ?;', ( 'my files', sqlite3.Binary( CC.LOCAL_FILE_SERVICE_KEY ) ) )
|
||||
|
||||
self._c.execute( 'UPDATE services SET service_type = ? WHERE service_key = ?;', ( HC.LOCAL_FILE_TRASH_DOMAIN, sqlite3.Binary( CC.TRASH_SERVICE_KEY ) ) )
|
||||
|
||||
# create new umbrella service that represents if we have the file or not locally
|
||||
|
||||
self._AddService( CC.COMBINED_LOCAL_FILE_SERVICE_KEY, HC.COMBINED_LOCAL_FILE, CC.COMBINED_LOCAL_FILE_SERVICE_KEY, {} )
|
||||
|
||||
combined_local_file_service_id = self._GetServiceId( CC.COMBINED_LOCAL_FILE_SERVICE_KEY )
|
||||
local_file_service_id = self._GetServiceId( CC.LOCAL_FILE_SERVICE_KEY )
|
||||
trash_service_id = self._GetServiceId( CC.TRASH_SERVICE_KEY )
|
||||
|
||||
# copy all local/trash records to the new umbrella service, and move deleted_files and pending_files responsibility over
|
||||
|
||||
rows = self._c.execute( 'SELECT hash_id, timestamp FROM current_files WHERE service_id IN ( ?, ? );', ( local_file_service_id, trash_service_id ) ).fetchall()
|
||||
|
||||
self._c.executemany( 'INSERT OR IGNORE INTO current_files VALUES ( ?, ?, ? );', ( ( combined_local_file_service_id, hash_id, timestamp ) for ( hash_id, timestamp ) in rows ) )
|
||||
|
||||
self._c.execute( 'UPDATE deleted_files SET service_id = ? WHERE service_id = ?;', ( combined_local_file_service_id, local_file_service_id ) )
|
||||
|
||||
self._c.execute( 'DELETE FROM service_info WHERE service_id = ? AND info_type = ?;', ( local_file_service_id, HC.SERVICE_INFO_NUM_DELETED_FILES ) )
|
||||
|
||||
self._c.execute( 'UPDATE file_transfers SET service_id = ? WHERE service_id = ?;', ( combined_local_file_service_id, local_file_service_id ) )
|
||||
|
||||
# now it has files, refresh the ac cache
|
||||
|
||||
self._controller.pub( 'splash_set_status_text', 'creating autocomplete cache for new service' )
|
||||
|
||||
tag_service_ids = self._GetServiceIds( HC.TAG_SERVICES )
|
||||
|
||||
for tag_service_id in tag_service_ids:
|
||||
|
||||
self._CacheSpecificMappingsDrop( combined_local_file_service_id, tag_service_id )
|
||||
|
||||
self._CacheSpecificMappingsGenerate( combined_local_file_service_id, tag_service_id )
|
||||
|
||||
|
||||
# trash current_files rows can now have their own timestamp
|
||||
|
||||
trash_rows = self._c.execute( 'SELECT hash_id, timestamp FROM file_trash;' ).fetchall()
|
||||
|
||||
self._c.executemany( 'UPDATE current_files SET timestamp = ? WHERE service_id = ? AND hash_id = ?;', ( ( timestamp, trash_service_id, hash_id ) for ( hash_id, timestamp ) in rows ) )
|
||||
|
||||
self._c.execute( 'DROP TABLE file_trash;' )
|
||||
|
||||
message = 'I have fixed an important miscounting bug in the autocomplete cache. Please go database->maintenance->regenerate autocomplete cache when it is convenient.'
|
||||
|
||||
self.pub_initial_message( message )
|
||||
|
||||
|
||||
self._controller.pub( 'splash_set_title_text', 'updated db to v' + str( version + 1 ) )
|
||||
|
||||
self._c.execute( 'UPDATE version SET version = ?;', ( version + 1, ) )
|
||||
|
@ -8676,9 +8793,9 @@ class DB( HydrusDB.HydrusDB ):
|
|||
if petitioned_mappings_ids is None: petitioned_mappings_ids = []
|
||||
if petitioned_rescinded_mappings_ids is None: petitioned_rescinded_mappings_ids = []
|
||||
|
||||
file_service_ids = self._GetServiceIds( ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ) )
|
||||
file_service_ids = self._GetServiceIds( HC.AUTOCOMPLETE_CACHE_SPECIFIC_FILE_SERVICES )
|
||||
|
||||
# this method grew into a monster that merged deleted, pending and current according to a heirarchy of services
|
||||
# this method grew into a monster that merged deleted, pending and current according to a hierarchy of services
|
||||
# this cost a lot of CPU time and was extremely difficult to maintain
|
||||
# now it attempts a simpler union, not letting delete overwrite a current or pending
|
||||
|
||||
|
@ -9287,12 +9404,22 @@ class DB( HydrusDB.HydrusDB ):
|
|||
self.pub_after_commit( 'content_updates_gui', service_keys_to_content_updates )
|
||||
|
||||
|
||||
def pub_initial_message( self, message ):
|
||||
|
||||
self._initial_messages.append( message )
|
||||
|
||||
|
||||
def pub_service_updates_after_commit( self, service_keys_to_service_updates ):
|
||||
|
||||
self.pub_after_commit( 'service_updates_data', service_keys_to_service_updates )
|
||||
self.pub_after_commit( 'service_updates_gui', service_keys_to_service_updates )
|
||||
|
||||
|
||||
def GetInitialMessages( self ):
|
||||
|
||||
return self._initial_messages
|
||||
|
||||
|
||||
def GetUpdatesDir( self ):
|
||||
|
||||
return self._updates_dir
|
||||
|
|
|
@ -123,15 +123,30 @@ def ConvertServiceKeysToContentUpdatesToPrettyString( service_keys_to_content_up
|
|||
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
if data_type == HC.CONTENT_TYPE_MAPPINGS: extra_words = ' tags for'
|
||||
if data_type == HC.CONTENT_TYPE_MAPPINGS:
|
||||
|
||||
extra_words = ' tags for'
|
||||
|
||||
|
||||
actions.add( HC.content_update_string_lookup[ action ] )
|
||||
|
||||
if action in ( HC.CONTENT_UPDATE_ARCHIVE, HC.CONTENT_UPDATE_INBOX ):
|
||||
|
||||
locations = set()
|
||||
|
||||
|
||||
num_files += len( content_update.GetHashes() )
|
||||
|
||||
|
||||
|
||||
s = ', '.join( locations ) + '->' + ', '.join( actions ) + extra_words + ' ' + HydrusData.ConvertIntToPrettyString( num_files ) + ' files'
|
||||
s = ''
|
||||
|
||||
if len( locations ) > 0:
|
||||
|
||||
s += ', '.join( locations ) + '->'
|
||||
|
||||
|
||||
s += ', '.join( actions ) + extra_words + ' ' + HydrusData.ConvertIntToPrettyString( num_files ) + ' files'
|
||||
|
||||
return s
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
|
|||
self._lock = threading.Lock()
|
||||
|
||||
self._notebook = wx.Notebook( self )
|
||||
self._notebook.Bind( wx.EVT_LEFT_DCLICK, self.EventNotebookLeftDoubleClick )
|
||||
self._notebook.Bind( wx.EVT_MIDDLE_DOWN, self.EventNotebookMiddleClick )
|
||||
self._notebook.Bind( wx.EVT_RIGHT_DOWN, self.EventNotebookMenu )
|
||||
self.Bind( wx.EVT_NOTEBOOK_PAGE_CHANGED, self.EventNotebookPageChanged )
|
||||
|
@ -95,7 +96,8 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
|
|||
|
||||
self._message_manager = ClientGUICommon.PopupMessageManager( self )
|
||||
|
||||
self.Bind( wx.EVT_MIDDLE_DOWN, self.EventFrameMiddleClick )
|
||||
self.Bind( wx.EVT_LEFT_DCLICK, self.EventFrameNewPage )
|
||||
self.Bind( wx.EVT_MIDDLE_DOWN, self.EventFrameNewPage )
|
||||
self.Bind( wx.EVT_CLOSE, self.EventClose )
|
||||
self.Bind( wx.EVT_MENU, self.EventMenu )
|
||||
self.Bind( wx.EVT_SET_FOCUS, self.EventFocus )
|
||||
|
@ -703,6 +705,13 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
|
|||
self._controller.pub( 'notify_new_undo' )
|
||||
|
||||
|
||||
def _DeleteGUISession( self, name ):
|
||||
|
||||
self._controller.Write( 'delete_serialisable_named', HydrusSerialisable.SERIALISABLE_TYPE_GUI_SESSION, name )
|
||||
|
||||
self._controller.pub( 'notify_new_sessions' )
|
||||
|
||||
|
||||
def _DeletePending( self, service_key ):
|
||||
|
||||
service = self._controller.GetServicesManager().GetService( service_key )
|
||||
|
@ -882,8 +891,8 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
|
|||
|
||||
def pages():
|
||||
|
||||
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'refresh' ), p( '&Refresh' ), p( 'Refresh the current view.' ) )
|
||||
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'show_hide_splitters' ), p( 'Show/Hide Management and Preview Panels' ), p( 'Show or hide the panels on the left.' ) )
|
||||
ClientGUIMenus.AppendMenuItem( menu, 'refresh', 'If the current page has a search, refresh it.', self, self._Refresh )
|
||||
ClientGUIMenus.AppendMenuItem( menu, 'show/hide management and preview panels', 'Show or hide the panels on the left.', self, self._ShowHideSplitters )
|
||||
|
||||
menu.AppendSeparator()
|
||||
|
||||
|
@ -897,13 +906,13 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
|
|||
|
||||
for name in gui_session_names:
|
||||
|
||||
load.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'load_gui_session', name ), name )
|
||||
ClientGUIMenus.AppendMenuItem( load, name, 'Close all other pages and load this session.', self, self._LoadGUISession, name )
|
||||
|
||||
|
||||
sessions.AppendMenu( CC.ID_NULL, p( 'Load' ), load )
|
||||
ClientGUIMenus.AppendMenu( sessions, load, 'load' )
|
||||
|
||||
|
||||
sessions.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'save_gui_session' ), p( 'Save Current' ) )
|
||||
ClientGUIMenus.AppendMenuItem( sessions, 'save current', 'Save the existing open pages as a session.', self, self._SaveGUISession )
|
||||
|
||||
if len( gui_session_names ) > 0 and gui_session_names != [ 'last session' ]:
|
||||
|
||||
|
@ -913,16 +922,18 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
|
|||
|
||||
if name != 'last session':
|
||||
|
||||
delete.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'delete_gui_session', name ), name )
|
||||
ClientGUIMenus.AppendMenuItem( delete, name, 'Delete this session.', self, self._DeleteGUISession, name )
|
||||
|
||||
|
||||
|
||||
sessions.AppendMenu( CC.ID_NULL, p( 'Delete' ), delete )
|
||||
ClientGUIMenus.AppendMenu( sessions, delete, 'delete' )
|
||||
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, p( 'Sessions' ), sessions )
|
||||
ClientGUIMenus.AppendMenu( menu, sessions, 'sessions' )
|
||||
|
||||
menu.AppendSeparator()
|
||||
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_page' ), p( 'Pick a New &Page' ), p( 'Pick a new page.' ) )
|
||||
|
||||
ClientGUIMenus.AppendMenuItem( menu, 'pick a new page', 'Choose a new page to open.', self, self._ChooseNewPage )
|
||||
|
||||
#
|
||||
|
||||
|
@ -938,11 +949,15 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
|
|||
|
||||
petition_resolve_file_services = [ repository for repository in file_repositories if repository.GetInfo( 'account' ).HasPermission( HC.RESOLVE_PETITIONS ) ]
|
||||
|
||||
search_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_page_query', CC.LOCAL_FILE_SERVICE_KEY ), p( '&New Local Search' ), p( 'Open a new search tab for your files' ) )
|
||||
search_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_page_query', CC.TRASH_SERVICE_KEY ), p( '&New Trash Search' ), p( 'Open a new search tab for your recently deleted files' ) )
|
||||
for service in file_repositories: search_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_page_query', service.GetServiceKey() ), p( 'New ' + service.GetName() + ' Search' ), p( 'Open a new search tab for ' + service.GetName() + '.' ) )
|
||||
ClientGUIMenus.AppendMenuItem( search_menu, 'my files', 'Open a new search tab for your files.', self, self._NewPageQuery, CC.LOCAL_FILE_SERVICE_KEY )
|
||||
ClientGUIMenus.AppendMenuItem( search_menu, 'trash', 'Open a new search tab for your recently deleted files.', self, self._NewPageQuery, CC.TRASH_SERVICE_KEY )
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, p( 'New Search Page' ), search_menu )
|
||||
for service in file_repositories:
|
||||
|
||||
ClientGUIMenus.AppendMenuItem( search_menu, service.GetName(), 'Open a new search tab for ' + service.GetName() + '.', self, self._NewPageQuery, service.GetServiceKey() )
|
||||
|
||||
|
||||
ClientGUIMenus.AppendMenu( menu, search_menu, 'new search page' )
|
||||
|
||||
#
|
||||
|
||||
|
@ -952,63 +967,68 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
|
|||
|
||||
for service in petition_resolve_tag_services:
|
||||
|
||||
petition_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'petitions', service.GetServiceKey() ), p( service.GetName() + ' Petitions' ), p( 'Open a petition tab for ' + service.GetName() ) )
|
||||
ClientGUIMenus.AppendMenuItem( petition_menu, service.GetName(), 'Open a new tag petition tab for ' + service.GetName() + '.', self, self._NewPagePetitions, service.GetServiceKey() )
|
||||
|
||||
|
||||
for service in petition_resolve_file_services:
|
||||
|
||||
petition_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'petitions', service.GetServiceKey() ), p( service.GetName() + ' Petitions' ), p( 'Open a petition tab for ' + service.GetName() ) )
|
||||
ClientGUIMenus.AppendMenuItem( petition_menu, service.GetName(), 'Open a new file petition tab for ' + service.GetName() + '.', self, self._NewPagePetitions, service.GetServiceKey() )
|
||||
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, p( 'New Petition Page' ), petition_menu )
|
||||
ClientGUIMenus.AppendMenu( menu, petition_menu, 'new petition page' )
|
||||
|
||||
|
||||
#
|
||||
|
||||
download_menu = wx.Menu()
|
||||
|
||||
download_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_page_of_images' ), p( '&New Page of Images Download Page' ), p( 'Open a new tab to download files from generic galleries or threads.' ) )
|
||||
download_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_thread_watcher' ), p( '&New Thread Watcher Page' ), p( 'Open a new tab to watch a thread.' ) )
|
||||
download_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_urls' ), p( '&New URL Download Page' ), p( 'Open a new tab to download some raw urls.' ) )
|
||||
ClientGUIMenus.AppendMenuItem( download_menu, 'url download', 'Open a new tab to download some raw urls.', self, self._NewPageImportURLs )
|
||||
ClientGUIMenus.AppendMenuItem( download_menu, 'thread watcher', 'Open a new tab to watch a thread.', self, self._NewPageImportThreadWatcher )
|
||||
ClientGUIMenus.AppendMenuItem( download_menu, 'webpage of images', 'Open a new tab to download files from generic galleries or threads.', self, self._NewPageImportPageOfImages )
|
||||
|
||||
submenu = wx.Menu()
|
||||
gallery_menu = wx.Menu()
|
||||
|
||||
ClientGUIMenus.AppendMenuItem( gallery_menu, 'booru', 'Open a new tab to download files from a booru.', self, self._NewPageImportBooru )
|
||||
ClientGUIMenus.AppendMenuItem( gallery_menu, 'deviant art', 'Open a new tab to download files from Deviant Art.', self, self._NewPageImportGallery, ClientDownloading.GalleryIdentifier( HC.SITE_TYPE_DEVIANT_ART ) )
|
||||
|
||||
submenu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_booru' ), p( 'Booru' ), p( 'Open a new tab to download files from a booru.' ) )
|
||||
submenu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_gallery', HC.SITE_TYPE_DEVIANT_ART ), p( 'Deviant Art' ), p( 'Open a new tab to download files from Deviant Art.' ) )
|
||||
hf_submenu = wx.Menu()
|
||||
hf_submenu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_gallery', HC.SITE_TYPE_HENTAI_FOUNDRY_ARTIST ), p( 'By Artist' ), p( 'Open a new tab to download files from Hentai Foundry.' ) )
|
||||
hf_submenu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_gallery', HC.SITE_TYPE_HENTAI_FOUNDRY_TAGS ), p( 'By Tags' ), p( 'Open a new tab to download files from Hentai Foundry.' ) )
|
||||
submenu.AppendMenu( CC.ID_NULL, p( '&Hentai Foundry' ), hf_submenu )
|
||||
submenu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_gallery', HC.SITE_TYPE_NEWGROUNDS ), p( 'Newgrounds' ), p( 'Open a new tab to download files from Newgrounds.' ) )
|
||||
|
||||
ClientGUIMenus.AppendMenuItem( hf_submenu, 'by artist', 'Open a new tab to download files from Hentai Foundry.', self, self._NewPageImportGallery, ClientDownloading.GalleryIdentifier( HC.SITE_TYPE_HENTAI_FOUNDRY_ARTIST ) )
|
||||
ClientGUIMenus.AppendMenuItem( hf_submenu, 'by tags', 'Open a new tab to download files from Hentai Foundry.', self, self._NewPageImportGallery, ClientDownloading.GalleryIdentifier( HC.SITE_TYPE_HENTAI_FOUNDRY_TAGS ) )
|
||||
|
||||
ClientGUIMenus.AppendMenu( gallery_menu, hf_submenu, 'hentai foundry' )
|
||||
|
||||
ClientGUIMenus.AppendMenuItem( gallery_menu, 'newgrounds', 'Open a new tab to download files from Newgrounds.', self, self._NewPageImportGallery, ClientDownloading.GalleryIdentifier( HC.SITE_TYPE_NEWGROUNDS ) )
|
||||
|
||||
result = self._controller.Read( 'serialisable_simple', 'pixiv_account' )
|
||||
|
||||
if result is not None:
|
||||
|
||||
pixiv_submenu = wx.Menu()
|
||||
pixiv_submenu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_gallery', HC.SITE_TYPE_PIXIV_ARTIST_ID ), p( 'By Artist Id' ), p( 'Open a new tab to download files from Pixiv.' ) )
|
||||
pixiv_submenu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_gallery', HC.SITE_TYPE_PIXIV_TAG ), p( 'By Tag' ), p( 'Open a new tab to download files from Hentai Pixiv.' ) )
|
||||
submenu.AppendMenu( CC.ID_NULL, p( '&Pixiv' ), pixiv_submenu )
|
||||
|
||||
ClientGUIMenus.AppendMenuItem( pixiv_submenu, 'by artist id', 'Open a new tab to download files from Pixiv.', self, self._NewPageImportGallery, ClientDownloading.GalleryIdentifier( HC.SITE_TYPE_PIXIV_ARTIST_ID ) )
|
||||
ClientGUIMenus.AppendMenuItem( pixiv_submenu, 'by tag', 'Open a new tab to download files from Pixiv.', self, self._NewPageImportGallery, ClientDownloading.GalleryIdentifier( HC.SITE_TYPE_PIXIV_TAG ) )
|
||||
|
||||
ClientGUIMenus.AppendMenu( gallery_menu, pixiv_submenu, 'pixiv' )
|
||||
|
||||
|
||||
submenu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'new_import_gallery', HC.SITE_TYPE_TUMBLR ), p( 'Tumblr' ), p( 'Open a new tab to download files from Tumblr.' ) )
|
||||
ClientGUIMenus.AppendMenuItem( gallery_menu, 'tumblr', 'Open a new tab to download files from tumblr.', self, self._NewPageImportGallery, ClientDownloading.GalleryIdentifier( HC.SITE_TYPE_TUMBLR ) )
|
||||
|
||||
download_menu.AppendMenu( CC.ID_NULL, p( '&New Gallery Download Page' ), submenu )
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, p( 'New Download Page' ), download_menu )
|
||||
ClientGUIMenus.AppendMenu( download_menu, gallery_menu, 'gallery' )
|
||||
ClientGUIMenus.AppendMenu( menu, download_menu, 'new download page' )
|
||||
|
||||
download_popup_menu = wx.Menu()
|
||||
|
||||
download_popup_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'start_youtube_download' ), p( '&A YouTube Video' ), p( 'Enter a YouTube URL and choose which formats you would like to download' ) )
|
||||
ClientGUIMenus.AppendMenuItem( download_popup_menu, 'a youtube video', 'Enter a YouTube URL and choose which formats you would like to download', self, self._StartYoutubeDownload )
|
||||
|
||||
has_ipfs = len( [ service for service in services if service.GetServiceType() == HC.IPFS ] )
|
||||
|
||||
if has_ipfs:
|
||||
|
||||
download_popup_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetPermanentId( 'start_ipfs_download' ), p( '&An IPFS Multihash' ), p( 'Enter an IPFS multihash and attempt to import whatever is returned' ) )
|
||||
ClientGUIMenus.AppendMenuItem( download_popup_menu, 'an ipfs multihash', 'Enter an IPFS multihash and attempt to import whatever is returned.', self, self._StartIPFSDownload )
|
||||
|
||||
|
||||
menu.AppendMenu( CC.ID_NULL, p( 'New Download Popup' ), download_popup_menu )
|
||||
ClientGUIMenus.AppendMenu( menu, download_popup_menu, 'new download popup' )
|
||||
|
||||
#
|
||||
|
||||
|
@ -1742,6 +1762,16 @@ class FrameGUI( ClientGUITopLevelWindows.FrameThatResizes ):
|
|||
|
||||
|
||||
|
||||
def _Refresh( self ):
|
||||
|
||||
page = self._notebook.GetCurrentPage()
|
||||
|
||||
if page is not None:
|
||||
|
||||
page.RefreshQuery()
|
||||
|
||||
|
||||
|
||||
def _RefreshStatusBar( self ):
|
||||
|
||||
if self._media_status_override is not None:
|
||||
|
@ -2009,6 +2039,16 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
if page is not None: page.SetSynchronisedWait()
|
||||
|
||||
|
||||
def _ShowHideSplitters( self ):
|
||||
|
||||
page = self._notebook.GetCurrentPage()
|
||||
|
||||
if page is not None:
|
||||
|
||||
page.ShowHideSplit()
|
||||
|
||||
|
||||
|
||||
def _StartIPFSDownload( self ):
|
||||
|
||||
ipfs_services = self._controller.GetServicesManager().GetServices( ( HC.IPFS, ) )
|
||||
|
@ -2443,7 +2483,7 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
|
||||
|
||||
|
||||
def EventFrameMiddleClick( self, event ):
|
||||
def EventFrameNewPage( self, event ):
|
||||
|
||||
self._ChooseNewPage()
|
||||
|
||||
|
@ -2607,9 +2647,7 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
elif command == 'redo': self._controller.pub( 'redo' )
|
||||
elif command == 'refresh':
|
||||
|
||||
page = self._notebook.GetCurrentPage()
|
||||
|
||||
if page is not None: page.RefreshQuery()
|
||||
self._Refresh()
|
||||
|
||||
elif command == 'review_services': self._ReviewServices()
|
||||
elif command == 'save_gui_session': self._SaveGUISession()
|
||||
|
@ -2617,9 +2655,7 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
elif command == 'set_search_focus': self._SetSearchFocus()
|
||||
elif command == 'show_hide_splitters':
|
||||
|
||||
page = self._notebook.GetCurrentPage()
|
||||
|
||||
if page is not None: page.ShowHideSplit()
|
||||
self._ShowHideSplitters()
|
||||
|
||||
elif command == 'site': webbrowser.open( 'https://hydrusnetwork.github.io/hydrus/' )
|
||||
elif command == 'start_ipfs_download': self._StartIPFSDownload()
|
||||
|
@ -2635,6 +2671,16 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
|
||||
|
||||
|
||||
def EventNotebookLeftDoubleClick( self, event ):
|
||||
|
||||
( tab_index, flags ) = self._notebook.HitTest( ( event.GetX(), event.GetY() ) )
|
||||
|
||||
if tab_index == wx.NOT_FOUND:
|
||||
|
||||
self._ChooseNewPage()
|
||||
|
||||
|
||||
|
||||
def EventNotebookMenu( self, event ):
|
||||
|
||||
( tab_index, flags ) = self._notebook.HitTest( ( event.GetX(), event.GetY() ) )
|
||||
|
|
|
@ -526,8 +526,11 @@ class AutoCompleteDropdownTags( AutoCompleteDropdown ):
|
|||
self._current_matches = []
|
||||
|
||||
file_service = HydrusGlobals.client_controller.GetServicesManager().GetService( self._file_service_key )
|
||||
|
||||
|
||||
tag_service = HydrusGlobals.client_controller.GetServicesManager().GetService( self._tag_service_key )
|
||||
|
||||
|
||||
self._file_repo_button = ClientGUICommon.BetterButton( self._dropdown_window, file_service.GetName(), self.FileButtonHit )
|
||||
self._file_repo_button.SetMinSize( ( 20, -1 ) )
|
||||
|
||||
|
@ -628,14 +631,19 @@ class AutoCompleteDropdownTags( AutoCompleteDropdown ):
|
|||
services_manager = HydrusGlobals.client_controller.GetServicesManager()
|
||||
|
||||
services = []
|
||||
services.append( services_manager.GetService( CC.COMBINED_FILE_SERVICE_KEY ) )
|
||||
|
||||
services.append( services_manager.GetService( CC.LOCAL_FILE_SERVICE_KEY ) )
|
||||
services.append( services_manager.GetService( CC.TRASH_SERVICE_KEY ) )
|
||||
services.append( services_manager.GetService( CC.COMBINED_LOCAL_FILE_SERVICE_KEY ) )
|
||||
services.extend( services_manager.GetServices( ( HC.FILE_REPOSITORY, ) ) )
|
||||
services.append( services_manager.GetService( CC.COMBINED_FILE_SERVICE_KEY ) )
|
||||
|
||||
menu = wx.Menu()
|
||||
|
||||
for service in services: menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'change_file_service', service.GetServiceKey() ), service.GetName() )
|
||||
for service in services:
|
||||
|
||||
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'change_file_service', service.GetServiceKey() ), service.GetName() )
|
||||
|
||||
|
||||
HydrusGlobals.client_controller.PopupMenu( self._file_repo_button, menu )
|
||||
|
||||
|
@ -655,13 +663,17 @@ class AutoCompleteDropdownTags( AutoCompleteDropdown ):
|
|||
services_manager = HydrusGlobals.client_controller.GetServicesManager()
|
||||
|
||||
services = []
|
||||
services.append( services_manager.GetService( CC.COMBINED_TAG_SERVICE_KEY ) )
|
||||
|
||||
services.append( services_manager.GetService( CC.LOCAL_TAG_SERVICE_KEY ) )
|
||||
services.extend( services_manager.GetServices( ( HC.TAG_REPOSITORY, ) ) )
|
||||
services.append( services_manager.GetService( CC.COMBINED_TAG_SERVICE_KEY ) )
|
||||
|
||||
menu = wx.Menu()
|
||||
|
||||
for service in services: menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'change_tag_service', service.GetServiceKey() ), service.GetName() )
|
||||
for service in services:
|
||||
|
||||
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'change_tag_service', service.GetServiceKey() ), service.GetName() )
|
||||
|
||||
|
||||
HydrusGlobals.client_controller.PopupMenu( self._tag_repo_button, menu )
|
||||
|
||||
|
@ -1273,4 +1285,4 @@ class AutoCompleteDropdownTagsWrite( AutoCompleteDropdownTags ):
|
|||
self._BroadcastCurrentText()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -950,7 +950,10 @@ class Canvas( wx.Window ):
|
|||
HydrusGlobals.client_controller.sub( self, 'ManageTags', 'canvas_manage_tags' )
|
||||
|
||||
|
||||
def _Archive( self ): HydrusGlobals.client_controller.Write( 'content_updates', { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, ( self._current_display_media.GetHash(), ) ) ] } )
|
||||
def _Archive( self ):
|
||||
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, ( self._current_display_media.GetHash(), ) ) ] } )
|
||||
|
||||
|
||||
def _CopyBMPToClipboard( self ):
|
||||
|
||||
|
@ -967,7 +970,7 @@ class Canvas( wx.Window ):
|
|||
|
||||
else:
|
||||
|
||||
if self._current_display_media.GetLocationsManager().HasLocal():
|
||||
if self._current_display_media.GetLocationsManager().IsLocal():
|
||||
|
||||
( other_hash, ) = HydrusGlobals.client_controller.Read( 'file_hashes', ( sha256_hash, ), 'sha256', hash_type )
|
||||
|
||||
|
@ -1162,7 +1165,10 @@ class Canvas( wx.Window ):
|
|||
return False
|
||||
|
||||
|
||||
def _Inbox( self ): HydrusGlobals.client_controller.Write( 'content_updates', { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, ( self._current_display_media.GetHash(), ) ) ] } )
|
||||
def _Inbox( self ):
|
||||
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, ( self._current_display_media.GetHash(), ) ) ] } )
|
||||
|
||||
|
||||
def _IsZoomable( self ):
|
||||
|
||||
|
@ -1543,7 +1549,7 @@ class Canvas( wx.Window ):
|
|||
|
||||
locations_manager = media.GetLocationsManager()
|
||||
|
||||
if not locations_manager.HasLocal():
|
||||
if not locations_manager.IsLocal():
|
||||
|
||||
media = None
|
||||
|
||||
|
@ -1582,7 +1588,7 @@ class Canvas( wx.Window ):
|
|||
|
||||
( initial_width, initial_height ) = initial_size
|
||||
|
||||
if self._current_display_media.GetLocationsManager().HasLocal() and initial_width > 0 and initial_height > 0:
|
||||
if self._current_display_media.GetLocationsManager().IsLocal() and initial_width > 0 and initial_height > 0:
|
||||
|
||||
show_action = self._GetShowAction( self._current_display_media )
|
||||
|
||||
|
@ -2501,12 +2507,12 @@ class CanvasMediaListFilter( CanvasMediaList ):
|
|||
self._deleted_hashes = [ media.GetHash() for media in self._deleted ]
|
||||
self._kept_hashes = [ media.GetHash() for media in self._kept ]
|
||||
|
||||
content_updates = []
|
||||
service_keys_to_content_updates = {}
|
||||
|
||||
content_updates.append( HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_DELETE, self._deleted_hashes ) )
|
||||
content_updates.append( HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, self._kept_hashes ) )
|
||||
service_keys_to_content_updates[ CC.LOCAL_FILE_SERVICE_KEY ] = [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_DELETE, self._deleted_hashes ) ]
|
||||
service_keys_to_content_updates[ CC.COMBINED_LOCAL_FILE_SERVICE_KEY ] = [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, self._kept_hashes ) ]
|
||||
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', { CC.LOCAL_FILE_SERVICE_KEY : content_updates } )
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', service_keys_to_content_updates )
|
||||
|
||||
self._kept = set()
|
||||
self._deleted = set()
|
||||
|
@ -3248,7 +3254,10 @@ class CanvasMediaListCustomFilter( CanvasMediaListNavigable ):
|
|||
HydrusGlobals.client_controller.pub( 'clipboard', 'text', path )
|
||||
|
||||
|
||||
def _Inbox( self ): HydrusGlobals.client_controller.Write( 'content_updates', { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, ( self._current_display_media.GetHash(), ) ) ] } )
|
||||
def _Inbox( self ):
|
||||
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, ( self._current_display_media.GetHash(), ) ) ] } )
|
||||
|
||||
|
||||
def EventShortcuts( self, event ):
|
||||
|
||||
|
@ -3894,7 +3903,7 @@ class EmbedButton( wx.Window ):
|
|||
|
||||
self._canvas_bmp = wx.EmptyBitmap( x, y, 24 )
|
||||
|
||||
if self._media.GetLocationsManager().HasLocal() and self._media.GetMime() in HC.MIMES_WITH_THUMBNAILS:
|
||||
if self._media.GetLocationsManager().IsLocal() and self._media.GetMime() in HC.MIMES_WITH_THUMBNAILS:
|
||||
|
||||
hash = self._media.GetHash()
|
||||
|
||||
|
@ -4024,7 +4033,7 @@ class OpenExternallyPanel( wx.Panel ):
|
|||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
if self._media.GetLocationsManager().HasLocal() and self._media.GetMime() in HC.MIMES_WITH_THUMBNAILS:
|
||||
if self._media.GetLocationsManager().IsLocal() and self._media.GetMime() in HC.MIMES_WITH_THUMBNAILS:
|
||||
|
||||
hash = self._media.GetHash()
|
||||
|
||||
|
|
|
@ -3115,7 +3115,10 @@ class ListBoxTagsSelectionManagementPanel( ListBoxTagsSelection ):
|
|||
|
||||
def ChangeTagServicePubsub( self, page_key, service_key ):
|
||||
|
||||
if page_key == self._page_key: self.ChangeTagService( service_key )
|
||||
if page_key == self._page_key:
|
||||
|
||||
self.ChangeTagService( service_key )
|
||||
|
||||
|
||||
|
||||
def IncrementTagsByMediaPubsub( self, page_key, media ):
|
||||
|
|
|
@ -316,7 +316,7 @@ class Dialog( wx.Dialog ):
|
|||
|
||||
def SetInitialSize( self, ( width, height ) ):
|
||||
|
||||
( display_width, display_height ) = wx.GetDisplaySize()
|
||||
( display_width, display_height ) = ClientGUITopLevelWindows.GetDisplaySize( self )
|
||||
|
||||
width = min( display_width, width )
|
||||
height = min( display_height, height )
|
||||
|
@ -2900,6 +2900,7 @@ class DialogPageChooser( Dialog ):
|
|||
|
||||
entries.append( ( 'page_query', CC.LOCAL_FILE_SERVICE_KEY ) )
|
||||
entries.append( ( 'page_query', CC.TRASH_SERVICE_KEY ) )
|
||||
entries.append( ( 'page_query', CC.COMBINED_LOCAL_FILE_SERVICE_KEY ) )
|
||||
|
||||
for service in self._services:
|
||||
|
||||
|
|
|
@ -2906,7 +2906,7 @@ class DialogManageImportFoldersEdit( ClientGUIDialogs.Dialog ):
|
|||
|
||||
( x, y ) = self.GetEffectiveMinSize()
|
||||
|
||||
( max_x, max_y ) = wx.GetDisplaySize()
|
||||
( max_x, max_y ) = ClientGUITopLevelWindows.GetDisplaySize( self )
|
||||
|
||||
x = min( x + 25, max_x )
|
||||
y = min( y + 25, max_y )
|
||||
|
@ -4006,20 +4006,16 @@ class DialogManageServices( ClientGUIDialogs.Dialog ):
|
|||
|
||||
#
|
||||
|
||||
manageable_service_types = HC.RESTRICTED_SERVICES + [ HC.LOCAL_TAG, HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL, HC.LOCAL_BOORU, HC.IPFS ]
|
||||
|
||||
for service_type in manageable_service_types:
|
||||
for service_type in HC.ALL_SERVICES:
|
||||
|
||||
if service_type == HC.LOCAL_RATING_LIKE: name = 'like/dislike ratings'
|
||||
elif service_type == HC.LOCAL_RATING_NUMERICAL: name = 'numerical ratings'
|
||||
elif service_type == HC.LOCAL_BOORU: name = 'booru'
|
||||
elif service_type == HC.LOCAL_TAG: name = 'local tags'
|
||||
elif service_type == HC.LOCAL_FILE_DOMAIN: name = 'local files'
|
||||
elif service_type == HC.TAG_REPOSITORY: name = 'tag repositories'
|
||||
elif service_type == HC.FILE_REPOSITORY: name = 'file repositories'
|
||||
#elif service_type == HC.MESSAGE_DEPOT: name = 'message repositories'
|
||||
elif service_type == HC.SERVER_ADMIN: name = 'administrative services'
|
||||
#elif service_type == HC.RATING_LIKE_REPOSITORY: name = 'like/dislike rating repositories'
|
||||
#elif service_type == HC.RATING_NUMERICAL_REPOSITORY: name = 'numerical rating repositories'
|
||||
elif service_type == HC.IPFS: name = 'ipfs daemons'
|
||||
else: continue
|
||||
|
||||
|
@ -4094,7 +4090,7 @@ class DialogManageServices( ClientGUIDialogs.Dialog ):
|
|||
|
||||
service_type = self._listbooks_to_service_types[ services_listbook ]
|
||||
|
||||
if service_type in HC.NONEDITABLE_SERVICES:
|
||||
if service_type in HC.NONADDREMOVEABLE_SERVICES:
|
||||
|
||||
self._add.Disable()
|
||||
self._remove.Disable()
|
||||
|
@ -4155,9 +4151,9 @@ class DialogManageServices( ClientGUIDialogs.Dialog ):
|
|||
service_key = HydrusData.GenerateKey()
|
||||
service_type = self._listbooks_to_service_types[ services_listbook ]
|
||||
|
||||
if service_type in HC.NONEDITABLE_SERVICES:
|
||||
if service_type in HC.NONADDREMOVEABLE_SERVICES:
|
||||
|
||||
wx.MessageBox( 'You cannot edit this type of service yet!' )
|
||||
wx.MessageBox( 'You cannot add or delete this type of service yet!' )
|
||||
|
||||
return
|
||||
|
||||
|
@ -4421,7 +4417,7 @@ class DialogManageServices( ClientGUIDialogs.Dialog ):
|
|||
|
||||
#
|
||||
|
||||
if service_type not in HC.NONEDITABLE_SERVICES:
|
||||
if service_type not in HC.NONRENAMEABLE_SERVICES:
|
||||
|
||||
if service_type in HC.REMOTE_SERVICES: title = 'name and credentials'
|
||||
else: title = 'name'
|
||||
|
@ -4551,7 +4547,7 @@ class DialogManageServices( ClientGUIDialogs.Dialog ):
|
|||
|
||||
#
|
||||
|
||||
if service_type not in HC.NONEDITABLE_SERVICES:
|
||||
if service_type not in HC.NONRENAMEABLE_SERVICES:
|
||||
|
||||
self._service_name.SetValue( name )
|
||||
|
||||
|
@ -4599,7 +4595,7 @@ class DialogManageServices( ClientGUIDialogs.Dialog ):
|
|||
|
||||
vbox = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
if service_type not in HC.NONEDITABLE_SERVICES:
|
||||
if service_type not in HC.NONRENAMEABLE_SERVICES:
|
||||
|
||||
rows = []
|
||||
|
||||
|
@ -4894,11 +4890,14 @@ class DialogManageServices( ClientGUIDialogs.Dialog ):
|
|||
|
||||
info = dict( info )
|
||||
|
||||
if service_type not in HC.NONEDITABLE_SERVICES:
|
||||
if service_type not in HC.NONRENAMEABLE_SERVICES:
|
||||
|
||||
name = self._service_name.GetValue()
|
||||
|
||||
if name == '': raise Exception( 'Please enter a name' )
|
||||
if name == '':
|
||||
|
||||
raise Exception( 'Please enter a name' )
|
||||
|
||||
|
||||
|
||||
if service_type in HC.REMOTE_SERVICES:
|
||||
|
|
|
@ -126,7 +126,7 @@ def CreateManagementControllerPetitions( petition_service_key ):
|
|||
|
||||
petition_service_type = petition_service.GetServiceType()
|
||||
|
||||
if petition_service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ): file_service_key = petition_service_key
|
||||
if petition_service_type in HC.LOCAL_FILE_SERVICES or petition_service_type == HC.FILE_REPOSITORY: file_service_key = petition_service_key
|
||||
else: file_service_key = CC.COMBINED_FILE_SERVICE_KEY
|
||||
|
||||
management_controller = CreateManagementController( MANAGEMENT_TYPE_PETITIONS, file_service_key = file_service_key )
|
||||
|
@ -534,6 +534,14 @@ class ManagementController( HydrusSerialisable.SerialisableBase ):
|
|||
|
||||
self._keys = { name : key.decode( 'hex' ) for ( name, key ) in serialisable_keys.items() }
|
||||
|
||||
if 'file_service' in self._keys:
|
||||
|
||||
if not HydrusGlobals.client_controller.GetServicesManager().ServiceExists( self._keys[ 'file_service' ] ):
|
||||
|
||||
self._keys[ 'file_service' ] = CC.COMBINED_LOCAL_FILE_SERVICE_KEY
|
||||
|
||||
|
||||
|
||||
self._simples = dict( serialisable_simples )
|
||||
|
||||
self._serialisables = { name : HydrusSerialisable.CreateFromSerialisableTuple( value ) for ( name, value ) in serialisables.items() }
|
||||
|
@ -1478,9 +1486,9 @@ class ManagementPanelGalleryImport( ManagementPanel ):
|
|||
|
||||
self._get_tags_if_redundant = wx.CheckBox( self._gallery_downloader_panel, label = 'get tags even if file is already in db' )
|
||||
self._get_tags_if_redundant.Bind( wx.EVT_CHECKBOX, self.EventGetTagsIfRedundant )
|
||||
self._get_tags_if_redundant.SetToolTipString( 'only fetch tags from the gallery if the file is new' )
|
||||
self._get_tags_if_redundant.SetToolTipString( 'if off, the downloader will only fetch tags from the gallery if the file is new' )
|
||||
|
||||
self._file_limit = ClientGUICommon.NoneableSpinCtrl( self._gallery_downloader_panel, 'stop searching once this many files are found', min = 1, none_phrase = 'no limit' )
|
||||
self._file_limit = ClientGUICommon.NoneableSpinCtrl( self._gallery_downloader_panel, 'stop after this many files', min = 1, none_phrase = 'no limit' )
|
||||
self._file_limit.Bind( wx.EVT_SPINCTRL, self.EventFileLimit )
|
||||
self._file_limit.SetToolTipString( 'per query, stop searching the gallery once this many files has been reached' )
|
||||
|
||||
|
@ -1546,7 +1554,7 @@ class ManagementPanelGalleryImport( ManagementPanel ):
|
|||
|
||||
self._MakeSort( vbox )
|
||||
|
||||
vbox.AddF( self._gallery_downloader_panel, CC.FLAGS_EXPAND_BOTH_WAYS )
|
||||
vbox.AddF( self._gallery_downloader_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
self._MakeCurrentSelectionTagsBox( vbox )
|
||||
|
||||
|
@ -2125,7 +2133,7 @@ class ManagementPanelPageOfImagesImport( ManagementPanel ):
|
|||
|
||||
self._MakeSort( vbox )
|
||||
|
||||
vbox.AddF( self._page_of_images_panel, CC.FLAGS_EXPAND_BOTH_WAYS )
|
||||
vbox.AddF( self._page_of_images_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
self._MakeCurrentSelectionTagsBox( vbox )
|
||||
|
||||
|
@ -2461,7 +2469,7 @@ class ManagementPanelPetitions( ManagementPanel ):
|
|||
self._MakeCollect( vbox )
|
||||
|
||||
vbox.AddF( self._petitions_info_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( self._petition_panel, CC.FLAGS_EXPAND_BOTH_WAYS )
|
||||
vbox.AddF( self._petition_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
self._MakeCurrentSelectionTagsBox( vbox )
|
||||
|
||||
|
@ -2524,7 +2532,7 @@ class ManagementPanelPetitions( ManagementPanel ):
|
|||
def _ShowHashes( self, hashes ):
|
||||
|
||||
file_service_key = self._management_controller.GetKey( 'file_service' )
|
||||
|
||||
|
||||
with wx.BusyCursor(): media_results = self._controller.Read( 'media_results', hashes )
|
||||
|
||||
panel = ClientGUIMedia.MediaPanelThumbnails( self._page, self._page_key, file_service_key, media_results )
|
||||
|
@ -3276,7 +3284,7 @@ class ManagementPanelURLsImport( ManagementPanel ):
|
|||
|
||||
self._MakeSort( vbox )
|
||||
|
||||
vbox.AddF( self._url_panel, CC.FLAGS_EXPAND_BOTH_WAYS )
|
||||
vbox.AddF( self._url_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
self._MakeCurrentSelectionTagsBox( vbox )
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
|
||||
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, hashes ) ] } )
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, hashes ) ] } )
|
||||
|
||||
|
||||
|
||||
|
@ -150,7 +150,7 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
else:
|
||||
|
||||
if display_media.GetLocationsManager().HasLocal():
|
||||
if display_media.GetLocationsManager().IsLocal():
|
||||
|
||||
( other_hash, ) = HydrusGlobals.client_controller.Read( 'file_hashes', ( sha256_hash, ), 'sha256', hash_type )
|
||||
|
||||
|
@ -430,6 +430,11 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
|
|||
self._PublishSelectionChange()
|
||||
|
||||
|
||||
def _Download( self, hashes ):
|
||||
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_PEND, hashes ) ] } )
|
||||
|
||||
|
||||
def _FullScreen( self, first_media = None ):
|
||||
|
||||
if self._focussed_media is not None:
|
||||
|
@ -461,7 +466,7 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
if first_media is None and self._focussed_media is not None: first_media = self._focussed_media
|
||||
|
||||
if first_media is not None and first_media.GetLocationsManager().HasLocal(): first_hash = first_media.GetDisplayMedia().GetHash()
|
||||
if first_media is not None and first_media.GetLocationsManager().IsLocal(): first_hash = first_media.GetDisplayMedia().GetHash()
|
||||
else: first_hash = None
|
||||
|
||||
canvas_frame = ClientGUICanvas.CanvasFrame( self.GetTopLevelParent() )
|
||||
|
@ -474,7 +479,7 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
def _Filter( self ):
|
||||
|
||||
media_results = self.GenerateMediaResults( has_location = CC.LOCAL_FILE_SERVICE_KEY, selected_media = set( self._selected_media ), for_media_viewer = True )
|
||||
media_results = self.GenerateMediaResults( has_location = CC.COMBINED_LOCAL_FILE_SERVICE_KEY, selected_media = set( self._selected_media ), for_media_viewer = True )
|
||||
|
||||
if len( media_results ) > 0:
|
||||
|
||||
|
@ -734,8 +739,14 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
else:
|
||||
|
||||
if not media.IsSelected(): self._DeselectSelect( self._selected_media, ( media, ) )
|
||||
else: self._PublishSelectionChange()
|
||||
if not media.IsSelected():
|
||||
|
||||
self._DeselectSelect( self._selected_media, ( media, ) )
|
||||
|
||||
else:
|
||||
|
||||
self._PublishSelectionChange()
|
||||
|
||||
|
||||
self._SetFocussedMedia( media )
|
||||
self._shift_focussed_media = media
|
||||
|
@ -762,7 +773,7 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
|
||||
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, hashes ) ] } )
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', { CC.COMBINED_LOCAL_FILE_SERVICE_KEY: [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, hashes ) ] } )
|
||||
|
||||
|
||||
|
||||
|
@ -840,7 +851,7 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
if self._focussed_media is not None:
|
||||
|
||||
if CC.LOCAL_FILE_SERVICE_KEY in self._focussed_media.GetLocationsManager().GetCurrent():
|
||||
if self._focussed_media.GetLocationsManager().IsLocal():
|
||||
|
||||
hash = self._focussed_media.GetHash()
|
||||
mime = self._focussed_media.GetMime()
|
||||
|
@ -904,8 +915,14 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
def _PublishSelectionChange( self, force_reload = False ):
|
||||
|
||||
if len( self._selected_media ) == 0: tags_media = self._sorted_media
|
||||
else: tags_media = self._selected_media
|
||||
if len( self._selected_media ) == 0:
|
||||
|
||||
tags_media = self._sorted_media
|
||||
|
||||
else:
|
||||
|
||||
tags_media = self._selected_media
|
||||
|
||||
|
||||
HydrusGlobals.client_controller.pub( 'new_tags_selection', self._page_key, tags_media, force_reload = force_reload )
|
||||
HydrusGlobals.client_controller.pub( 'new_page_status', self._page_key, self._GetPrettyStatus() )
|
||||
|
@ -1247,7 +1264,10 @@ class MediaPanel( ClientMedia.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
self._PublishSelectionChange( force_reload = force_reload )
|
||||
|
||||
if self._focussed_media is not None: self._HitMedia( self._focussed_media, False, False )
|
||||
if self._focussed_media is not None:
|
||||
|
||||
self._HitMedia( self._focussed_media, False, False )
|
||||
|
||||
|
||||
|
||||
def ProcessServiceUpdates( self, service_keys_to_service_updates ):
|
||||
|
@ -2072,7 +2092,10 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
self._Delete( data )
|
||||
|
||||
|
||||
elif command == 'download': HydrusGlobals.client_controller.Write( 'content_updates', { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_PEND, self._GetSelectedHashes( discriminant = CC.DISCRIMINANT_NOT_LOCAL ) ) ] } )
|
||||
elif command == 'download':
|
||||
|
||||
self._Download( self._GetSelectedHashes( discriminant = CC.DISCRIMINANT_NOT_LOCAL ) )
|
||||
|
||||
elif command == 'export_files': self._ExportFiles()
|
||||
elif command == 'export_tags': self._ExportTags()
|
||||
elif command == 'filter': self._Filter()
|
||||
|
@ -2086,7 +2109,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
elif command == 'open_externally': self._OpenExternally()
|
||||
elif command == 'petition': self._PetitionFiles( data )
|
||||
elif command == 'remove': self._Remove()
|
||||
elif command == 'rescind_download': HydrusGlobals.client_controller.Write( 'content_updates', { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_RESCIND_PEND, self._GetSelectedHashes( discriminant = CC.DISCRIMINANT_DOWNLOADING ) ) ] } )
|
||||
elif command == 'rescind_download': HydrusGlobals.client_controller.Write( 'content_updates', { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_RESCIND_PEND, self._GetSelectedHashes( discriminant = CC.DISCRIMINANT_DOWNLOADING ) ) ] } )
|
||||
elif command == 'rescind_petition': self._RescindPetitionFiles( data )
|
||||
elif command == 'rescind_upload': self._RescindUploadFiles( data )
|
||||
elif command == 'scroll_end': self._ScrollEnd( False )
|
||||
|
@ -2119,12 +2142,12 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
locations_manager = t.GetLocationsManager()
|
||||
|
||||
if locations_manager.HasLocal(): self._FullScreen( t )
|
||||
if locations_manager.IsLocal(): self._FullScreen( t )
|
||||
elif self._file_service_key != CC.COMBINED_FILE_SERVICE_KEY:
|
||||
|
||||
if len( locations_manager.GetCurrentRemote() ) > 0:
|
||||
|
||||
HydrusGlobals.client_controller.Write( 'content_updates', { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_PEND, t.GetHashes() ) ] } )
|
||||
self._Download( t.GetHashes() )
|
||||
|
||||
|
||||
|
||||
|
@ -2236,12 +2259,13 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
all_locations_managers = [ media.GetLocationsManager() for media in self._sorted_media ]
|
||||
selected_locations_managers = [ media.GetLocationsManager() for media in self._selected_media ]
|
||||
|
||||
selection_has_local_file_service = True in ( CC.LOCAL_FILE_SERVICE_KEY in locations_manager.GetCurrent() for locations_manager in selected_locations_managers )
|
||||
selection_has_local = True in ( locations_manager.IsLocal() for locations_manager in selected_locations_managers )
|
||||
selection_has_local_file_domain = True in ( CC.LOCAL_FILE_SERVICE_KEY in locations_manager.GetCurrent() for locations_manager in selected_locations_managers )
|
||||
selection_has_trash = True in ( CC.TRASH_SERVICE_KEY in locations_manager.GetCurrent() for locations_manager in selected_locations_managers )
|
||||
selection_has_inbox = True in ( media.HasInbox() for media in self._selected_media )
|
||||
selection_has_archive = True in ( media.HasArchive() for media in self._selected_media )
|
||||
|
||||
media_has_local_file_service = True in ( CC.LOCAL_FILE_SERVICE_KEY in locations_manager.GetCurrent() for locations_manager in all_locations_managers )
|
||||
media_has_local_file_domain = True in ( CC.LOCAL_FILE_SERVICE_KEY in locations_manager.GetCurrent() for locations_manager in all_locations_managers )
|
||||
media_has_trash = True in ( CC.TRASH_SERVICE_KEY in locations_manager.GetCurrent() for locations_manager in all_locations_managers )
|
||||
media_has_inbox = True in ( media.HasInbox() for media in self._sorted_media )
|
||||
media_has_archive = True in ( media.HasArchive() for media in self._sorted_media )
|
||||
|
@ -2274,9 +2298,9 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
select_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'select', 'archive' ), 'archive' )
|
||||
|
||||
|
||||
if media_has_local_file_service and media_has_trash:
|
||||
if media_has_local_file_domain and media_has_trash:
|
||||
|
||||
select_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'select', 'local' ), 'local files' )
|
||||
select_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'select', 'local' ), 'my files' )
|
||||
select_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'select', 'trash' ), 'trash' )
|
||||
|
||||
|
||||
|
@ -2411,7 +2435,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
disparate_petitioned_remote_service_keys = petitioned_remote_service_keys - common_petitioned_remote_service_keys
|
||||
disparate_deleted_remote_service_keys = deleted_remote_service_keys - common_deleted_remote_service_keys
|
||||
|
||||
some_downloading = True in ( CC.LOCAL_FILE_SERVICE_KEY in locations_manager.GetPending() for locations_manager in selected_locations_managers )
|
||||
some_downloading = True in ( locations_manager.IsDownloading() for locations_manager in selected_locations_managers )
|
||||
|
||||
pending_file_service_keys = pending_remote_service_keys.intersection( file_service_keys )
|
||||
petitioned_file_service_keys = petitioned_remote_service_keys.intersection( file_service_keys )
|
||||
|
@ -2459,14 +2483,14 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
# we can upload (set pending) to a repo_id when we have permission, a file is local, not current, not pending, and either ( not deleted or admin )
|
||||
|
||||
if locations_manager.HasLocal():
|
||||
if locations_manager.IsLocal():
|
||||
|
||||
uploadable_file_service_keys.update( upload_permission_file_service_keys - locations_manager.GetCurrentRemote() - locations_manager.GetPendingRemote() - ( locations_manager.GetDeletedRemote() - admin_permission_file_service_keys ) )
|
||||
|
||||
|
||||
# we can download (set pending to local) when we have permission, a file is not local and not already downloading and current
|
||||
|
||||
if not CC.LOCAL_FILE_SERVICE_KEY in locations_manager.GetCurrent() and not locations_manager.HasDownloading():
|
||||
if not locations_manager.IsLocal() and not locations_manager.IsDownloading():
|
||||
|
||||
downloadable_file_service_keys.update( download_permission_file_service_keys & locations_manager.GetCurrentRemote() )
|
||||
|
||||
|
@ -2488,7 +2512,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
# we can pin if a file is local, not current, not pending
|
||||
|
||||
if locations_manager.HasLocal():
|
||||
if locations_manager.IsLocal():
|
||||
|
||||
pinnable_ipfs_service_keys.update( ipfs_service_keys - locations_manager.GetCurrentRemote() - locations_manager.GetPendingRemote() )
|
||||
|
||||
|
@ -2632,7 +2656,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
#
|
||||
|
||||
if selection_has_local_file_service and multiple_selected:
|
||||
if selection_has_local and multiple_selected:
|
||||
|
||||
filter_menu = wx.Menu()
|
||||
|
||||
|
@ -2670,7 +2694,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'remove' ), remove_phrase )
|
||||
|
||||
if selection_has_local_file_service:
|
||||
if selection_has_local_file_domain:
|
||||
|
||||
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'delete', CC.LOCAL_FILE_SERVICE_KEY ), local_delete_phrase )
|
||||
|
||||
|
@ -2685,7 +2709,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
menu.AppendSeparator()
|
||||
|
||||
if selection_has_local_file_service:
|
||||
if selection_has_local:
|
||||
|
||||
menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'open_externally' ), '&open externally' )
|
||||
|
||||
|
@ -2696,7 +2720,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
copy_menu = wx.Menu()
|
||||
|
||||
if selection_has_local_file_service:
|
||||
if selection_has_local:
|
||||
|
||||
copy_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'copy_files' ), copy_phrase )
|
||||
|
||||
|
@ -2810,9 +2834,9 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
select_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'select', 'archive' ), 'archive' )
|
||||
|
||||
|
||||
if media_has_local_file_service and media_has_trash:
|
||||
if media_has_local_file_domain and media_has_trash:
|
||||
|
||||
select_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'select', 'local' ), 'local files' )
|
||||
select_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'select', 'local' ), 'my files' )
|
||||
select_menu.Append( ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetTemporaryId( 'select', 'trash' ), 'trash' )
|
||||
|
||||
|
||||
|
@ -3087,7 +3111,7 @@ class Thumbnail( Selectable ):
|
|||
|
||||
inbox = self.HasInbox()
|
||||
|
||||
local = self.GetLocationsManager().HasLocal()
|
||||
local = self.GetLocationsManager().IsLocal()
|
||||
|
||||
thumbnail_hydrus_bmp = HydrusGlobals.client_controller.GetCache( 'thumbnail' ).GetThumbnail( self )
|
||||
|
||||
|
@ -3278,7 +3302,7 @@ class Thumbnail( Selectable ):
|
|||
|
||||
icons_to_draw = []
|
||||
|
||||
if CC.LOCAL_FILE_SERVICE_KEY in locations_manager.GetPending():
|
||||
if locations_manager.IsDownloading():
|
||||
|
||||
icons_to_draw.append( CC.GlobalBMPs.downloading )
|
||||
|
||||
|
|
|
@ -202,15 +202,17 @@ class OptionsPanelImportFiles( OptionsPanel ):
|
|||
|
||||
self._auto_archive = wx.CheckBox( self, label = 'archive all imports' )
|
||||
self._auto_archive.Bind( wx.EVT_CHECKBOX, self.EventChanged )
|
||||
self._auto_archive.SetToolTipString( 'If this is set, all successful imports will be automatically archived rather than sent to the inbox.' )
|
||||
|
||||
self._exclude_deleted = wx.CheckBox( self, label = 'exclude already deleted files' )
|
||||
self._exclude_deleted.Bind( wx.EVT_CHECKBOX, self.EventChanged )
|
||||
self._exclude_deleted.SetToolTipString( 'If this is set and an incoming file has already been seen and deleted before by this client, the import will be abandoned. This is useful to make sure you do not keep importing and deleting the same bad files over and over. Files currently in the trash count as deleted.' )
|
||||
|
||||
self._min_size = ClientGUICommon.NoneableSpinCtrl( self, 'minimum size (KB): ', multiplier = 1024 )
|
||||
self._min_size = ClientGUICommon.NoneableSpinCtrl( self, 'size', unit = 'KB', multiplier = 1024 )
|
||||
self._min_size.SetValue( 5120 )
|
||||
self._min_size.Bind( wx.EVT_SPINCTRL, self.EventChanged )
|
||||
|
||||
self._min_resolution = ClientGUICommon.NoneableSpinCtrl( self, 'minimum resolution: ', num_dimensions = 2 )
|
||||
self._min_resolution = ClientGUICommon.NoneableSpinCtrl( self, 'resolution', num_dimensions = 2 )
|
||||
self._min_resolution.SetValue( ( 50, 50 ) )
|
||||
self._min_resolution.Bind( wx.EVT_SPINCTRL, self.EventChanged )
|
||||
|
||||
|
@ -218,6 +220,7 @@ class OptionsPanelImportFiles( OptionsPanel ):
|
|||
|
||||
vbox.AddF( self._auto_archive, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( self._exclude_deleted, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( wx.StaticText( self, label = 'minimum:' ), CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( self._min_size, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
vbox.AddF( self._min_resolution, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
|
@ -569,4 +572,4 @@ class OptionsPanelTags( OptionsPanel ):
|
|||
|
||||
self._service_keys_to_explicit_button_info = new_service_keys_to_explicit_button_info
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ class PanelPredicateSystemFileService( PanelPredicateSystem ):
|
|||
self._sign.SetSelection( 0 )
|
||||
self._current_pending.SetSelection( 0 )
|
||||
|
||||
services = HydrusGlobals.client_controller.GetServicesManager().GetServices( ( HC.FILE_REPOSITORY, HC.LOCAL_FILE, HC.IPFS ) )
|
||||
services = HydrusGlobals.client_controller.GetServicesManager().GetServices( HC.FILE_SERVICES )
|
||||
|
||||
for service in services: self._file_service_key.Append( service.GetName(), service.GetServiceKey() )
|
||||
self._file_service_key.SetSelection( 0 )
|
||||
|
@ -788,4 +788,4 @@ class PanelPredicateSystemWidth( PanelPredicateSystem ):
|
|||
|
||||
return info
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -686,7 +686,7 @@ class EditSubscriptionPanel( ClientGUIScrolledPanels.EditPanel ):
|
|||
wx.CallAfter( self.ProcessEvent, event )
|
||||
|
||||
|
||||
def CheckNow( self, event ):
|
||||
def CheckNow( self ):
|
||||
|
||||
self._check_now = True
|
||||
|
||||
|
@ -760,7 +760,7 @@ class EditSubscriptionPanel( ClientGUIScrolledPanels.EditPanel ):
|
|||
return subscription
|
||||
|
||||
|
||||
def ResetCache( self, event ):
|
||||
def ResetCache( self ):
|
||||
|
||||
message = '''Resetting this subscription's cache will delete ''' + HydrusData.ConvertIntToPrettyString( self._original_subscription.GetSeedCache().GetSeedCount() ) + ''' remembered urls, meaning when the subscription next runs, it will try to download those all over again. This may be expensive in time and data. Only do it if you are willing to wait. Do you want to do it?'''
|
||||
|
||||
|
|
|
@ -1965,7 +1965,7 @@ class ManageOptionsPanel( ClientGUIScrolledPanels.ManagePanel ):
|
|||
|
||||
def EventFullscreensUpdate( self, event ):
|
||||
|
||||
( width, height ) = wx.GetDisplaySize()
|
||||
( width, height ) = ClientGUITopLevelWindows.GetDisplaySize( self )
|
||||
|
||||
estimated_bytes_per_fullscreen = 3 * width * height
|
||||
|
||||
|
|
|
@ -61,28 +61,28 @@ class ReviewServicesPanel( ClientGUIScrolledPanels.ReviewPanel ):
|
|||
if service_type in HC.LOCAL_SERVICES: parent_listbook = self._local_listbook
|
||||
else: parent_listbook = self._remote_listbook
|
||||
|
||||
if service_type not in listbook_dict:
|
||||
|
||||
if service_type == HC.TAG_REPOSITORY: name = 'tag repositories'
|
||||
elif service_type == HC.FILE_REPOSITORY: name = 'file repositories'
|
||||
elif service_type == HC.MESSAGE_DEPOT: name = 'message depots'
|
||||
elif service_type == HC.SERVER_ADMIN: name = 'administrative servers'
|
||||
elif service_type == HC.LOCAL_FILE: name = 'files'
|
||||
elif service_type == HC.LOCAL_TAG: name = 'tags'
|
||||
elif service_type == HC.LOCAL_RATING_LIKE: name = 'like/dislike ratings'
|
||||
elif service_type == HC.LOCAL_RATING_NUMERICAL: name = 'numerical ratings'
|
||||
elif service_type == HC.LOCAL_BOORU: name = 'booru'
|
||||
elif service_type == HC.IPFS: name = 'ipfs'
|
||||
else: continue
|
||||
if service_type == HC.TAG_REPOSITORY: name = 'tag repositories'
|
||||
elif service_type == HC.FILE_REPOSITORY: name = 'file repositories'
|
||||
elif service_type == HC.MESSAGE_DEPOT: name = 'message depots'
|
||||
elif service_type == HC.SERVER_ADMIN: name = 'administrative servers'
|
||||
elif service_type in HC.LOCAL_FILE_SERVICES: name = 'files'
|
||||
elif service_type == HC.LOCAL_TAG: name = 'tags'
|
||||
elif service_type == HC.LOCAL_RATING_LIKE: name = 'like/dislike ratings'
|
||||
elif service_type == HC.LOCAL_RATING_NUMERICAL: name = 'numerical ratings'
|
||||
elif service_type == HC.LOCAL_BOORU: name = 'booru'
|
||||
elif service_type == HC.IPFS: name = 'ipfs'
|
||||
else: continue
|
||||
|
||||
if name not in listbook_dict:
|
||||
|
||||
listbook = ClientGUICommon.ListBook( parent_listbook )
|
||||
|
||||
listbook_dict[ service_type ] = listbook
|
||||
listbook_dict[ name ] = listbook
|
||||
|
||||
parent_listbook.AddPage( name, name, listbook )
|
||||
|
||||
|
||||
listbook = listbook_dict[ service_type ]
|
||||
listbook = listbook_dict[ name ]
|
||||
|
||||
name = service.GetName()
|
||||
|
||||
|
@ -166,11 +166,11 @@ class ReviewServicesPanel( ClientGUIScrolledPanels.ReviewPanel ):
|
|||
|
||||
self._info_panel = ClientGUICommon.StaticBox( self, 'service information' )
|
||||
|
||||
if service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
if service_type in HC.FILE_SERVICES:
|
||||
|
||||
self._files_text = wx.StaticText( self._info_panel, style = wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE )
|
||||
|
||||
if self._service_key != CC.TRASH_SERVICE_KEY:
|
||||
if service_type in ( HC.COMBINED_LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
|
||||
self._deleted_files_text = wx.StaticText( self._info_panel, style = wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE )
|
||||
|
||||
|
@ -196,10 +196,6 @@ class ReviewServicesPanel( ClientGUIScrolledPanels.ReviewPanel ):
|
|||
|
||||
self._bytes_text = wx.StaticText( self._info_panel, style = wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE )
|
||||
|
||||
elif service_type == HC.IPFS:
|
||||
|
||||
self._files_text = wx.StaticText( self._info_panel, style = wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE )
|
||||
|
||||
|
||||
|
||||
if service_type in HC.RESTRICTED_SERVICES:
|
||||
|
@ -280,7 +276,7 @@ class ReviewServicesPanel( ClientGUIScrolledPanels.ReviewPanel ):
|
|||
self._service_wide_update.Bind( wx.EVT_BUTTON, self.EventServiceWideUpdate )
|
||||
|
||||
|
||||
if self._service_key == CC.LOCAL_FILE_SERVICE_KEY:
|
||||
if self._service_key == CC.COMBINED_LOCAL_FILE_SERVICE_KEY:
|
||||
|
||||
self._delete_local_deleted = wx.Button( self, label = 'clear deleted file record' )
|
||||
self._delete_local_deleted.SetToolTipString( 'Make the client forget which files it has deleted from local files, resetting all the \'exclude already deleted files\' checks.' )
|
||||
|
@ -318,11 +314,11 @@ class ReviewServicesPanel( ClientGUIScrolledPanels.ReviewPanel ):
|
|||
|
||||
if service_type in HC.REPOSITORIES + HC.LOCAL_SERVICES + [ HC.IPFS ]:
|
||||
|
||||
if service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
if service_type in HC.FILE_SERVICES:
|
||||
|
||||
self._info_panel.AddF( self._files_text, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
if self._service_key != CC.TRASH_SERVICE_KEY:
|
||||
if service_type in ( HC.COMBINED_LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
|
||||
self._info_panel.AddF( self._deleted_files_text, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
|
@ -346,10 +342,6 @@ class ReviewServicesPanel( ClientGUIScrolledPanels.ReviewPanel ):
|
|||
self._info_panel.AddF( self._bytes, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
self._info_panel.AddF( self._bytes_text, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
elif service_type == HC.IPFS:
|
||||
|
||||
self._info_panel.AddF( self._files_text, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
|
||||
vbox.AddF( self._info_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
||||
|
||||
|
@ -407,11 +399,11 @@ class ReviewServicesPanel( ClientGUIScrolledPanels.ReviewPanel ):
|
|||
vbox.AddF( self._ipfs_shares_panel, CC.FLAGS_EXPAND_BOTH_WAYS )
|
||||
|
||||
|
||||
if service_type in HC.RESTRICTED_SERVICES + [ HC.LOCAL_TAG ] or self._service_key in ( CC.LOCAL_FILE_SERVICE_KEY, CC.TRASH_SERVICE_KEY ):
|
||||
if service_type in HC.RESTRICTED_SERVICES + [ HC.LOCAL_TAG ] or self._service_key in ( CC.COMBINED_LOCAL_FILE_SERVICE_KEY, CC.TRASH_SERVICE_KEY ):
|
||||
|
||||
repo_buttons_hbox = wx.BoxSizer( wx.HORIZONTAL )
|
||||
|
||||
if self._service_key == CC.LOCAL_FILE_SERVICE_KEY:
|
||||
if self._service_key == CC.COMBINED_LOCAL_FILE_SERVICE_KEY:
|
||||
|
||||
repo_buttons_hbox.AddF( self._delete_local_deleted, CC.FLAGS_VCENTER )
|
||||
|
||||
|
@ -595,14 +587,14 @@ class ReviewServicesPanel( ClientGUIScrolledPanels.ReviewPanel ):
|
|||
|
||||
service_info = self._controller.Read( 'service_info', self._service_key )
|
||||
|
||||
if service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
if service_type in HC.FILE_SERVICES:
|
||||
|
||||
num_files = service_info[ HC.SERVICE_INFO_NUM_FILES ]
|
||||
total_size = service_info[ HC.SERVICE_INFO_TOTAL_SIZE ]
|
||||
|
||||
self._files_text.SetLabelText( HydrusData.ConvertIntToPrettyString( num_files ) + ' files, totalling ' + HydrusData.ConvertIntToBytes( total_size ) )
|
||||
|
||||
if self._service_key != CC.TRASH_SERVICE_KEY:
|
||||
if service_type in ( HC.COMBINED_LOCAL_FILE, HC.FILE_REPOSITORY ):
|
||||
|
||||
num_deleted_files = service_info[ HC.SERVICE_INFO_NUM_DELETED_FILES ]
|
||||
|
||||
|
@ -636,13 +628,6 @@ class ReviewServicesPanel( ClientGUIScrolledPanels.ReviewPanel ):
|
|||
|
||||
self._num_shares.SetLabelText( HydrusData.ConvertIntToPrettyString( num_shares ) + ' shares currently active' )
|
||||
|
||||
elif service_type == HC.IPFS:
|
||||
|
||||
num_files = service_info[ HC.SERVICE_INFO_NUM_FILES ]
|
||||
total_size = service_info[ HC.SERVICE_INFO_TOTAL_SIZE ]
|
||||
|
||||
self._files_text.SetLabelText( HydrusData.ConvertIntToPrettyString( num_files ) + ' files, totalling ' + HydrusData.ConvertIntToBytes( total_size ) )
|
||||
|
||||
|
||||
|
||||
if service_type == HC.LOCAL_BOORU:
|
||||
|
@ -1083,4 +1068,4 @@ class ReviewServicesPanel( ClientGUIScrolledPanels.ReviewPanel ):
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,36 @@ import wx
|
|||
CHILD_POSITION_PADDING = 50
|
||||
FUZZY_PADDING = 30
|
||||
|
||||
def GetDisplayPosition( window ):
|
||||
|
||||
display_index = wx.Display.GetFromWindow( window )
|
||||
|
||||
if display_index == wx.NOT_FOUND:
|
||||
|
||||
display_index = 0 # default to primary
|
||||
|
||||
|
||||
display = wx.Display( display_index )
|
||||
|
||||
rect = display.GetClientArea()
|
||||
|
||||
return rect.GetPosition()
|
||||
|
||||
def GetDisplaySize( window ):
|
||||
|
||||
display_index = wx.Display.GetFromWindow( window )
|
||||
|
||||
if display_index == wx.NOT_FOUND:
|
||||
|
||||
display_index = 0 # default to primary
|
||||
|
||||
|
||||
display = wx.Display( display_index )
|
||||
|
||||
rect = display.GetClientArea()
|
||||
|
||||
return rect.GetSize()
|
||||
|
||||
def GetSafePosition( position ):
|
||||
|
||||
( p_x, p_y ) = position
|
||||
|
@ -67,7 +97,7 @@ def GetSafeSize( tlw, min_size, gravity ):
|
|||
|
||||
|
||||
|
||||
( display_width, display_height ) = wx.GetDisplaySize()
|
||||
( display_width, display_height ) = GetDisplaySize( tlw )
|
||||
|
||||
width = min( display_width, width )
|
||||
height = min( display_height, height )
|
||||
|
@ -86,15 +116,16 @@ def ExpandTLWIfPossible( tlw, frame_key, desired_size_delta ):
|
|||
|
||||
( desired_delta_width, desired_delta_height ) = desired_size_delta
|
||||
|
||||
min_width = current_width + desired_delta_width + FUZZY_PADDING
|
||||
min_height = current_height + desired_delta_height + FUZZY_PADDING
|
||||
desired_width = current_width + desired_delta_width + FUZZY_PADDING
|
||||
desired_height = current_height + desired_delta_height + FUZZY_PADDING
|
||||
|
||||
( width, height ) = GetSafeSize( tlw, ( min_width, min_height ), default_gravity )
|
||||
( width, height ) = GetSafeSize( tlw, ( desired_width, desired_height ), default_gravity )
|
||||
|
||||
if width > current_width or height > current_height:
|
||||
|
||||
tlw.SetSize( ( width, height ) )
|
||||
|
||||
SlideOffScreenTLWUpAndLeft( tlw )
|
||||
|
||||
|
||||
def SaveTLWSizeAndPosition( tlw, frame_key ):
|
||||
|
@ -197,6 +228,31 @@ def SetTLWSizeAndPosition( tlw, frame_key ):
|
|||
wx.CallAfter( tlw.ShowFullScreen, True, wx.FULLSCREEN_ALL )
|
||||
|
||||
|
||||
def SlideOffScreenTLWUpAndLeft( tlw ):
|
||||
|
||||
( tlw_width, tlw_height ) = tlw.GetSize()
|
||||
( tlw_x, tlw_y ) = tlw.GetPosition()
|
||||
|
||||
tlw_right = tlw_x + tlw_width
|
||||
tlw_bottom = tlw_y + tlw_height
|
||||
|
||||
( display_width, display_height ) = GetDisplaySize( tlw )
|
||||
( display_x, display_y ) = GetDisplayPosition( tlw )
|
||||
|
||||
display_right = display_x + display_width
|
||||
display_bottom = display_y + display_height
|
||||
|
||||
move_x = tlw_right > display_right
|
||||
move_y = tlw_bottom > display_bottom
|
||||
|
||||
if move_x or move_y:
|
||||
|
||||
delta_x = min( display_right - tlw_right, 0 )
|
||||
delta_y = min( display_bottom - tlw_bottom, 0 )
|
||||
|
||||
tlw.SetPosition( ( tlw_x + delta_x, tlw_y + delta_y ) )
|
||||
|
||||
|
||||
class NewDialog( wx.Dialog ):
|
||||
|
||||
def __init__( self, parent, title ):
|
||||
|
|
|
@ -2006,7 +2006,7 @@ class SeedCache( HydrusSerialisable.SerialisableBase ):
|
|||
|
||||
note = first_line + u'\u2026 (Copy note to see full error)'
|
||||
note += os.linesep
|
||||
note += traceback.format_exc()
|
||||
note += HydrusData.ToUnicode( traceback.format_exc() )
|
||||
|
||||
HydrusData.Print( 'Error when processing ' + seed + '!' )
|
||||
HydrusData.Print( traceback.format_exc() )
|
||||
|
@ -2215,8 +2215,18 @@ class Subscription( HydrusSerialisable.SerialisableBaseNamed ):
|
|||
|
||||
if status == CC.STATUS_SUCCESSFUL:
|
||||
|
||||
job_key.SetVariable( 'popup_text_1', x_out_of_y + 'import successful' )
|
||||
|
||||
successful_hashes.add( hash )
|
||||
|
||||
elif status == CC.STATUS_DELETED:
|
||||
|
||||
job_key.SetVariable( 'popup_text_1', x_out_of_y + 'previously deleted' )
|
||||
|
||||
elif status == CC.STATUS_REDUNDANT:
|
||||
|
||||
job_key.SetVariable( 'popup_text_1', x_out_of_y + 'already in db' )
|
||||
|
||||
|
||||
finally:
|
||||
|
||||
|
@ -2252,6 +2262,8 @@ class Subscription( HydrusSerialisable.SerialisableBaseNamed ):
|
|||
|
||||
status = CC.STATUS_FAILED
|
||||
|
||||
job_key.SetVariable( 'popup_text_1', x_out_of_y + 'file failed' )
|
||||
|
||||
self._seed_cache.UpdateSeedStatus( url, status, exception = e )
|
||||
|
||||
time.sleep( 10 )
|
||||
|
|
|
@ -80,7 +80,7 @@ def MergeTagsManagers( tags_managers ):
|
|||
|
||||
class LocationsManager( object ):
|
||||
|
||||
LOCAL_LOCATIONS = { CC.LOCAL_FILE_SERVICE_KEY, CC.TRASH_SERVICE_KEY }
|
||||
LOCAL_LOCATIONS = { CC.LOCAL_FILE_SERVICE_KEY, CC.TRASH_SERVICE_KEY, CC.COMBINED_LOCAL_FILE_SERVICE_KEY }
|
||||
|
||||
def __init__( self, current, deleted, pending, petitioned, urls = None, service_keys_to_filenames = None, current_to_timestamps = None ):
|
||||
|
||||
|
@ -217,9 +217,9 @@ class LocationsManager( object ):
|
|||
return self._urls
|
||||
|
||||
|
||||
def HasDownloading( self ): return CC.LOCAL_FILE_SERVICE_KEY in self._pending
|
||||
def IsDownloading( self ): return CC.COMBINED_LOCAL_FILE_SERVICE_KEY in self._pending
|
||||
|
||||
def HasLocal( self ): return len( self._current.intersection( self.LOCAL_LOCATIONS ) ) > 0
|
||||
def IsLocal( self ): return CC.COMBINED_LOCAL_FILE_SERVICE_KEY in self._current
|
||||
|
||||
def ProcessContentUpdate( self, service_key, content_update ):
|
||||
|
||||
|
@ -235,6 +235,14 @@ class LocationsManager( object ):
|
|||
if service_key == CC.LOCAL_FILE_SERVICE_KEY:
|
||||
|
||||
self._current.discard( CC.TRASH_SERVICE_KEY )
|
||||
self._pending.discard( CC.COMBINED_LOCAL_FILE_SERVICE_KEY )
|
||||
|
||||
if CC.COMBINED_LOCAL_FILE_SERVICE_KEY not in self._current:
|
||||
|
||||
self._current.add( CC.COMBINED_LOCAL_FILE_SERVICE_KEY )
|
||||
|
||||
self._current_to_timestamps[ CC.COMBINED_LOCAL_FILE_SERVICE_KEY ] = HydrusData.GetNow()
|
||||
|
||||
|
||||
|
||||
self._current_to_timestamps[ service_key ] = HydrusData.GetNow()
|
||||
|
@ -250,17 +258,20 @@ class LocationsManager( object ):
|
|||
|
||||
self._current.add( CC.TRASH_SERVICE_KEY )
|
||||
|
||||
self._current_to_timestamps[ CC.TRASH_SERVICE_KEY ] = self._current_to_timestamps[ CC.LOCAL_FILE_SERVICE_KEY ]
|
||||
self._current_to_timestamps[ CC.TRASH_SERVICE_KEY ] = HydrusData.GetNow()
|
||||
|
||||
elif service_key == CC.TRASH_SERVICE_KEY:
|
||||
|
||||
self._current.discard( CC.COMBINED_LOCAL_FILE_SERVICE_KEY )
|
||||
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_UNDELETE:
|
||||
|
||||
self._current.discard( CC.TRASH_SERVICE_KEY )
|
||||
|
||||
self._deleted.discard( CC.LOCAL_FILE_SERVICE_KEY )
|
||||
self._current.add( CC.LOCAL_FILE_SERVICE_KEY )
|
||||
|
||||
self._current_to_timestamps[ CC.LOCAL_FILE_SERVICE_KEY ] = self._current_to_timestamps[ CC.TRASH_SERVICE_KEY ]
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_PEND:
|
||||
|
||||
if service_key not in self._current: self._pending.add( service_key )
|
||||
|
@ -269,8 +280,14 @@ class LocationsManager( object ):
|
|||
|
||||
if service_key not in self._deleted: self._petitioned.add( service_key )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PEND: self._pending.discard( service_key )
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PETITION: self._petitioned.discard( service_key )
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PEND:
|
||||
|
||||
self._pending.discard( service_key )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PETITION:
|
||||
|
||||
self._petitioned.discard( service_key )
|
||||
|
||||
|
||||
|
||||
def ResetService( self, service_key ):
|
||||
|
@ -411,8 +428,24 @@ class MediaList( object ):
|
|||
elif sort_by_data == CC.SORT_BY_LARGEST: sort_function = lambda x: -deal_with_none( x.GetSize() )
|
||||
elif sort_by_data == CC.SORT_BY_SHORTEST: sort_function = lambda x: deal_with_none( x.GetDuration() )
|
||||
elif sort_by_data == CC.SORT_BY_LONGEST: sort_function = lambda x: -deal_with_none( x.GetDuration() )
|
||||
elif sort_by_data == CC.SORT_BY_OLDEST: sort_function = lambda x: deal_with_none( x.GetTimestamp( self._file_service_key ) )
|
||||
elif sort_by_data == CC.SORT_BY_NEWEST: sort_function = lambda x: -deal_with_none( x.GetTimestamp( self._file_service_key ) )
|
||||
elif sort_by_data in ( CC.SORT_BY_OLDEST, CC.SORT_BY_NEWEST ):
|
||||
|
||||
file_service = HydrusGlobals.client_controller.GetServicesManager().GetService( self._file_service_key )
|
||||
|
||||
file_service_type = file_service.GetServiceType()
|
||||
|
||||
if file_service_type == HC.LOCAL_FILE_DOMAIN:
|
||||
|
||||
file_service_key = CC.COMBINED_LOCAL_FILE_SERVICE_KEY
|
||||
|
||||
else:
|
||||
|
||||
file_service_key = self._file_service_key
|
||||
|
||||
|
||||
if sort_by_data == CC.SORT_BY_OLDEST: sort_function = lambda x: deal_with_none( x.GetTimestamp( file_service_key ) )
|
||||
elif sort_by_data == CC.SORT_BY_NEWEST: sort_function = lambda x: -deal_with_none( x.GetTimestamp( file_service_key ) )
|
||||
|
||||
elif sort_by_data == CC.SORT_BY_MIME: sort_function = lambda x: x.GetMime()
|
||||
|
||||
elif sort_by_type == 'namespaces':
|
||||
|
@ -647,11 +680,14 @@ class MediaList( object ):
|
|||
locations_manager = media.GetLocationsManager()
|
||||
|
||||
inbox_failed = discriminant == CC.DISCRIMINANT_INBOX and not media.HasInbox()
|
||||
local_failed = discriminant == CC.DISCRIMINANT_LOCAL and not locations_manager.HasLocal()
|
||||
not_local_failed = discriminant == CC.DISCRIMINANT_NOT_LOCAL and locations_manager.HasLocal()
|
||||
downloading_failed = discriminant == CC.DISCRIMINANT_DOWNLOADING and CC.LOCAL_FILE_SERVICE_KEY not in locations_manager.GetPending()
|
||||
local_failed = discriminant == CC.DISCRIMINANT_LOCAL and not locations_manager.IsLocal()
|
||||
not_local_failed = discriminant == CC.DISCRIMINANT_NOT_LOCAL and locations_manager.IsLocal()
|
||||
downloading_failed = discriminant == CC.DISCRIMINANT_DOWNLOADING and not locations_manager.IsDownloading()
|
||||
|
||||
if inbox_failed or local_failed or not_local_failed or downloading_failed: continue
|
||||
if inbox_failed or local_failed or not_local_failed or downloading_failed:
|
||||
|
||||
continue
|
||||
|
||||
|
||||
|
||||
if unrated is not None:
|
||||
|
@ -725,7 +761,10 @@ class MediaList( object ):
|
|||
|
||||
hashes = content_update.GetHashes()
|
||||
|
||||
for media in self._GetMedia( hashes, 'collections' ): media.ProcessContentUpdate( service_key, content_update )
|
||||
for media in self._GetMedia( hashes, 'collections' ):
|
||||
|
||||
media.ProcessContentUpdate( service_key, content_update )
|
||||
|
||||
|
||||
if data_type == HC.CONTENT_TYPE_FILES:
|
||||
|
||||
|
@ -754,7 +793,10 @@ class MediaList( object ):
|
|||
|
||||
for ( service_key, content_updates ) in service_keys_to_content_updates.items():
|
||||
|
||||
for content_update in content_updates: self.ProcessContentUpdate( service_key, content_update )
|
||||
for content_update in content_updates:
|
||||
|
||||
self.ProcessContentUpdate( service_key, content_update )
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1071,7 +1113,7 @@ class MediaSingleton( Media ):
|
|||
|
||||
locations_manager = self._media_result.GetLocationsManager()
|
||||
|
||||
if ( discriminant == CC.DISCRIMINANT_INBOX and not inbox ) or ( discriminant == CC.DISCRIMINANT_ARCHIVE and inbox ) or ( discriminant == CC.DISCRIMINANT_LOCAL and not locations_manager.HasLocal() ) or ( discriminant == CC.DISCRIMINANT_NOT_LOCAL and locations_manager.HasLocal() ):
|
||||
if ( discriminant == CC.DISCRIMINANT_INBOX and not inbox ) or ( discriminant == CC.DISCRIMINANT_ARCHIVE and inbox ) or ( discriminant == CC.DISCRIMINANT_LOCAL and not locations_manager.IsLocal() ) or ( discriminant == CC.DISCRIMINANT_NOT_LOCAL and locations_manager.IsLocal() ):
|
||||
|
||||
if ordered:
|
||||
|
||||
|
@ -1171,9 +1213,9 @@ class MediaSingleton( Media ):
|
|||
|
||||
current_service_keys = locations_manager.GetCurrent()
|
||||
|
||||
if CC.LOCAL_FILE_SERVICE_KEY in current_service_keys:
|
||||
if CC.COMBINED_LOCAL_FILE_SERVICE_KEY in current_service_keys:
|
||||
|
||||
timestamp = locations_manager.GetTimestamp( CC.LOCAL_FILE_SERVICE_KEY )
|
||||
timestamp = locations_manager.GetTimestamp( CC.COMBINED_LOCAL_FILE_SERVICE_KEY )
|
||||
|
||||
lines.append( 'imported ' + HydrusData.ConvertTimestampToPrettyAgo( timestamp ) )
|
||||
|
||||
|
@ -1182,12 +1224,12 @@ class MediaSingleton( Media ):
|
|||
|
||||
timestamp = locations_manager.GetTimestamp( CC.TRASH_SERVICE_KEY )
|
||||
|
||||
lines.append( 'imported ' + HydrusData.ConvertTimestampToPrettyAgo( timestamp ) + ', now in the trash' )
|
||||
lines.append( 'trashed ' + HydrusData.ConvertTimestampToPrettyAgo( timestamp ) )
|
||||
|
||||
|
||||
for service_key in current_service_keys:
|
||||
|
||||
if service_key in ( CC.LOCAL_FILE_SERVICE_KEY, CC.TRASH_SERVICE_KEY ):
|
||||
if service_key in ( CC.COMBINED_LOCAL_FILE_SERVICE_KEY, CC.LOCAL_FILE_SERVICE_KEY, CC.TRASH_SERVICE_KEY ):
|
||||
|
||||
continue
|
||||
|
||||
|
@ -1365,8 +1407,14 @@ class MediaResult( object ):
|
|||
|
||||
service_type = service.GetServiceType()
|
||||
|
||||
if service_type == HC.TAG_REPOSITORY: tags_manager.DeletePending( service_key )
|
||||
elif service_type in ( HC.FILE_REPOSITORY, HC.LOCAL_FILE ): locations_manager.DeletePending( service_key )
|
||||
if service_type in HC.TAG_SERVICES:
|
||||
|
||||
tags_manager.DeletePending( service_key )
|
||||
|
||||
elif service_type in HC.FILE_SERVICES:
|
||||
|
||||
locations_manager.DeletePending( service_key )
|
||||
|
||||
|
||||
|
||||
def Duplicate( self ):
|
||||
|
@ -1418,9 +1466,11 @@ class MediaResult( object ):
|
|||
|
||||
tags_manager.ProcessContentUpdate( service_key, content_update )
|
||||
|
||||
elif service_type in ( HC.FILE_REPOSITORY, HC.LOCAL_FILE, HC.IPFS ):
|
||||
elif service_type in HC.FILE_SERVICES:
|
||||
|
||||
if service_type == HC.LOCAL_FILE:
|
||||
previously_local = CC.COMBINED_LOCAL_FILE_SERVICE_KEY in locations_manager.GetCurrent()
|
||||
|
||||
if service_type in HC.LOCAL_FILE_SERVICES:
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ARCHIVE:
|
||||
|
||||
|
@ -1431,26 +1481,34 @@ class MediaResult( object ):
|
|||
inbox = True
|
||||
|
||||
|
||||
if service_key == CC.LOCAL_FILE_SERVICE_KEY:
|
||||
if service_type == CC.COMBINED_LOCAL_FILE_SERVICE_KEY:
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ADD and CC.TRASH_SERVICE_KEY not in locations_manager.GetCurrent():
|
||||
if action == HC.CONTENT_UPDATE_ADD:
|
||||
|
||||
inbox = True
|
||||
|
||||
|
||||
elif service_key == CC.TRASH_SERVICE_KEY:
|
||||
|
||||
if action == HC.CONTENT_UPDATE_DELETE:
|
||||
elif action == HC.CONTENT_UPDATE_DELETE:
|
||||
|
||||
inbox = False
|
||||
|
||||
|
||||
|
||||
self._tuple = ( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager )
|
||||
|
||||
|
||||
locations_manager.ProcessContentUpdate( service_key, content_update )
|
||||
|
||||
subsequently_local = CC.COMBINED_LOCAL_FILE_SERVICE_KEY in locations_manager.GetCurrent()
|
||||
|
||||
if not previously_local and subsequently_local:
|
||||
|
||||
inbox = True
|
||||
|
||||
if previously_local and not subsequently_local:
|
||||
|
||||
inbox = False
|
||||
|
||||
|
||||
self._tuple = ( hash, inbox, size, mime, width, height, duration, num_frames, num_words, tags_manager, locations_manager, ratings_manager )
|
||||
|
||||
elif service_type in HC.RATINGS_SERVICES:
|
||||
|
||||
ratings_manager.ProcessContentUpdate( service_key, content_update )
|
||||
|
@ -1868,8 +1926,14 @@ class TagsManager( TagsManagerSimple ):
|
|||
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
if action == HC.CONTENT_UPDATE_PETITION: ( tag, hashes, reason ) = row
|
||||
else: ( tag, hashes ) = row
|
||||
if action == HC.CONTENT_UPDATE_PETITION:
|
||||
|
||||
( tag, hashes, reason ) = row
|
||||
|
||||
else:
|
||||
|
||||
( tag, hashes ) = row
|
||||
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ADD:
|
||||
|
||||
|
@ -1892,7 +1956,10 @@ class TagsManager( TagsManagerSimple ):
|
|||
statuses_to_tags[ HC.PENDING ].add( tag )
|
||||
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PEND: statuses_to_tags[ HC.PENDING ].discard( tag )
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PEND:
|
||||
|
||||
statuses_to_tags[ HC.PENDING ].discard( tag )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_PETITION:
|
||||
|
||||
if tag in statuses_to_tags[ HC.CURRENT ]:
|
||||
|
@ -1914,4 +1981,4 @@ class TagsManager( TagsManagerSimple ):
|
|||
self._combined_is_calculated = False
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -254,6 +254,18 @@ class FileSearchContext( HydrusSerialisable.SerialisableBase ):
|
|||
self._file_service_key = file_service_key.decode( 'hex' )
|
||||
self._tag_service_key = tag_service_key.decode( 'hex' )
|
||||
|
||||
services_manager = HydrusGlobals.client_controller.GetServicesManager()
|
||||
|
||||
if not services_manager.ServiceExists( self._file_service_key ):
|
||||
|
||||
self._file_service_key = CC.COMBINED_LOCAL_FILE_SERVICE_KEY
|
||||
|
||||
|
||||
if not services_manager.ServiceExists( self._tag_service_key ):
|
||||
|
||||
self._tag_service_key = CC.COMBINED_TAG_SERVICE_KEY
|
||||
|
||||
|
||||
self._predicates = [ HydrusSerialisable.CreateFromSerialisableTuple( pred_tuple ) for pred_tuple in serialisable_predicates ]
|
||||
|
||||
self._InitialiseTemporaryVariables()
|
||||
|
|
|
@ -46,7 +46,7 @@ options = {}
|
|||
# Misc
|
||||
|
||||
NETWORK_VERSION = 17
|
||||
SOFTWARE_VERSION = 236
|
||||
SOFTWARE_VERSION = 237
|
||||
|
||||
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )
|
||||
|
||||
|
@ -145,7 +145,7 @@ permissions_string_lookup[ UNKNOWN_PERMISSION ] = 'unknown'
|
|||
|
||||
TAG_REPOSITORY = 0
|
||||
FILE_REPOSITORY = 1
|
||||
LOCAL_FILE = 2
|
||||
LOCAL_FILE_DOMAIN = 2
|
||||
MESSAGE_DEPOT = 3
|
||||
LOCAL_TAG = 5
|
||||
LOCAL_RATING_NUMERICAL = 6
|
||||
|
@ -156,6 +156,8 @@ COMBINED_TAG = 10
|
|||
COMBINED_FILE = 11
|
||||
LOCAL_BOORU = 12
|
||||
IPFS = 13
|
||||
LOCAL_FILE_TRASH_DOMAIN = 14
|
||||
COMBINED_LOCAL_FILE = 15
|
||||
SERVER_ADMIN = 99
|
||||
NULL_SERVICE = 100
|
||||
|
||||
|
@ -163,7 +165,9 @@ service_string_lookup = {}
|
|||
|
||||
service_string_lookup[ TAG_REPOSITORY ] = 'hydrus tag repository'
|
||||
service_string_lookup[ FILE_REPOSITORY ] = 'hydrus file repository'
|
||||
service_string_lookup[ LOCAL_FILE ] = 'hydrus local file service'
|
||||
service_string_lookup[ LOCAL_FILE_DOMAIN ] = 'hydrus local file domain'
|
||||
service_string_lookup[ LOCAL_FILE_TRASH_DOMAIN ] = 'hydrus trash domain'
|
||||
service_string_lookup[ COMBINED_LOCAL_FILE ] = 'hydrus local file service'
|
||||
service_string_lookup[ MESSAGE_DEPOT ] = 'hydrus message depot'
|
||||
service_string_lookup[ LOCAL_TAG ] = 'local tag service'
|
||||
service_string_lookup[ LOCAL_RATING_NUMERICAL ] = 'local numerical rating service'
|
||||
|
@ -177,16 +181,23 @@ service_string_lookup[ IPFS ] = 'ipfs daemon'
|
|||
service_string_lookup[ SERVER_ADMIN ] = 'hydrus server administration'
|
||||
service_string_lookup[ NULL_SERVICE ] = 'null service'
|
||||
|
||||
LOCAL_FILE_SERVICES = [ LOCAL_FILE_DOMAIN, LOCAL_FILE_TRASH_DOMAIN, COMBINED_LOCAL_FILE ]
|
||||
LOCAL_TAG_SERVICES = [ LOCAL_TAG ]
|
||||
|
||||
LOCAL_SERVICES = list( LOCAL_FILE_SERVICES ) + list( LOCAL_TAG_SERVICES ) + [ LOCAL_RATING_LIKE, LOCAL_RATING_NUMERICAL, LOCAL_BOORU ]
|
||||
|
||||
RATINGS_SERVICES = [ LOCAL_RATING_LIKE, LOCAL_RATING_NUMERICAL, RATING_LIKE_REPOSITORY, RATING_NUMERICAL_REPOSITORY ]
|
||||
REPOSITORIES = [ TAG_REPOSITORY, FILE_REPOSITORY, RATING_LIKE_REPOSITORY, RATING_NUMERICAL_REPOSITORY ]
|
||||
RESTRICTED_SERVICES = list( REPOSITORIES ) + [ SERVER_ADMIN, MESSAGE_DEPOT ]
|
||||
REMOTE_SERVICES = list( RESTRICTED_SERVICES ) + [ IPFS ]
|
||||
FILE_SERVICES = list( LOCAL_FILE_SERVICES ) + [ FILE_REPOSITORY, IPFS ]
|
||||
TAG_SERVICES = [ LOCAL_TAG, TAG_REPOSITORY ]
|
||||
LOCAL_SERVICES = [ LOCAL_FILE, LOCAL_TAG, LOCAL_RATING_LIKE, LOCAL_RATING_NUMERICAL, LOCAL_BOORU, COMBINED_FILE, COMBINED_TAG ]
|
||||
NONEDITABLE_SERVICES = [ LOCAL_BOORU, LOCAL_FILE, LOCAL_TAG ]
|
||||
ALL_SERVICES = list( REMOTE_SERVICES ) + list( LOCAL_SERVICES )
|
||||
NONADDREMOVEABLE_SERVICES = [ LOCAL_BOORU, LOCAL_FILE_DOMAIN, LOCAL_FILE_TRASH_DOMAIN, LOCAL_TAG ]
|
||||
NONRENAMEABLE_SERVICES = [ LOCAL_BOORU, LOCAL_FILE_TRASH_DOMAIN, LOCAL_TAG ]
|
||||
AUTOCOMPLETE_CACHE_SPECIFIC_FILE_SERVICES = [ LOCAL_FILE_DOMAIN, LOCAL_FILE_TRASH_DOMAIN, COMBINED_LOCAL_FILE, FILE_REPOSITORY ]
|
||||
ALL_SERVICES = list( REMOTE_SERVICES ) + list( LOCAL_SERVICES ) + [ COMBINED_FILE, COMBINED_TAG ]
|
||||
|
||||
SERVICES_WITH_THUMBNAILS = [ FILE_REPOSITORY, LOCAL_FILE ]
|
||||
SERVICES_WITH_THUMBNAILS = [ FILE_REPOSITORY, LOCAL_FILE_DOMAIN ]
|
||||
|
||||
DELETE_FILES_PETITION = 0
|
||||
DELETE_TAG_PETITION = 1
|
||||
|
|
|
@ -112,7 +112,7 @@ class HydrusResourceWelcome( Resource ):
|
|||
|
||||
Resource.__init__( self )
|
||||
|
||||
if service_type == HC.LOCAL_FILE: body = CLIENT_ROOT_MESSAGE
|
||||
if service_type == HC.COMBINED_LOCAL_FILE: body = CLIENT_ROOT_MESSAGE
|
||||
else: body = ROOT_MESSAGE_BEGIN + message + ROOT_MESSAGE_END
|
||||
|
||||
self._body = HydrusData.ToByteString( body )
|
||||
|
@ -604,4 +604,4 @@ class ResponseContext( object ):
|
|||
def HasPath( self ): return self._path is not None
|
||||
|
||||
def IsJSON( self ): return self._is_json
|
||||
|
||||
|
||||
|
|
|
@ -117,12 +117,12 @@ class TestManagers( unittest.TestCase ):
|
|||
hash_2 = HydrusData.GenerateKey()
|
||||
hash_3 = HydrusData.GenerateKey()
|
||||
|
||||
command_1 = { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, { hash_1 } ) ] }
|
||||
command_2 = { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, { hash_2 } ) ] }
|
||||
command_3 = { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, { hash_1, hash_3 } ) ] }
|
||||
command_1 = { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, { hash_1 } ) ] }
|
||||
command_2 = { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, { hash_2 } ) ] }
|
||||
command_3 = { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, { hash_1, hash_3 } ) ] }
|
||||
|
||||
command_1_inverted = { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, { hash_1 } ) ] }
|
||||
command_2_inverted = { CC.LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, { hash_2 } ) ] }
|
||||
command_1_inverted = { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, { hash_1 } ) ] }
|
||||
command_2_inverted = { CC.COMBINED_LOCAL_FILE_SERVICE_KEY : [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, { hash_2 } ) ] }
|
||||
|
||||
undo_manager = ClientCaches.UndoManager( HydrusGlobals.client_controller )
|
||||
|
||||
|
@ -130,15 +130,15 @@ class TestManagers( unittest.TestCase ):
|
|||
|
||||
undo_manager.AddCommand( 'content_updates', command_1 )
|
||||
|
||||
self.assertEqual( ( u'undo local files->archive 1 files', None ), undo_manager.GetUndoRedoStrings() )
|
||||
self.assertEqual( ( u'undo archive 1 files', None ), undo_manager.GetUndoRedoStrings() )
|
||||
|
||||
undo_manager.AddCommand( 'content_updates', command_2 )
|
||||
|
||||
self.assertEqual( ( u'undo local files->inbox 1 files', None ), undo_manager.GetUndoRedoStrings() )
|
||||
self.assertEqual( ( u'undo inbox 1 files', None ), undo_manager.GetUndoRedoStrings() )
|
||||
|
||||
undo_manager.Undo()
|
||||
|
||||
self.assertEqual( ( u'undo local files->archive 1 files', u'redo local files->inbox 1 files' ), undo_manager.GetUndoRedoStrings() )
|
||||
self.assertEqual( ( u'undo archive 1 files', u'redo inbox 1 files' ), undo_manager.GetUndoRedoStrings() )
|
||||
|
||||
self.assertEqual( HydrusGlobals.test_controller.GetWrite( 'content_updates' ), [ ( ( command_2_inverted, ), {} ) ] )
|
||||
|
||||
|
@ -146,7 +146,7 @@ class TestManagers( unittest.TestCase ):
|
|||
|
||||
self.assertEqual( HydrusGlobals.test_controller.GetWrite( 'content_updates' ), [ ( ( command_2, ), {} ) ] )
|
||||
|
||||
self.assertEqual( ( u'undo local files->inbox 1 files', None ), undo_manager.GetUndoRedoStrings() )
|
||||
self.assertEqual( ( u'undo inbox 1 files', None ), undo_manager.GetUndoRedoStrings() )
|
||||
|
||||
undo_manager.Undo()
|
||||
|
||||
|
@ -156,10 +156,10 @@ class TestManagers( unittest.TestCase ):
|
|||
|
||||
self.assertEqual( HydrusGlobals.test_controller.GetWrite( 'content_updates' ), [ ( ( command_1_inverted, ), {} ) ] )
|
||||
|
||||
self.assertEqual( ( None, u'redo local files->archive 1 files' ), undo_manager.GetUndoRedoStrings() )
|
||||
self.assertEqual( ( None, u'redo archive 1 files' ), undo_manager.GetUndoRedoStrings() )
|
||||
|
||||
undo_manager.AddCommand( 'content_updates', command_3 )
|
||||
|
||||
self.assertEqual( ( u'undo local files->archive 2 files', None ), undo_manager.GetUndoRedoStrings() )
|
||||
self.assertEqual( ( u'undo archive 2 files', None ), undo_manager.GetUndoRedoStrings() )
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -424,7 +424,7 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
service_keys_to_content_updates = {}
|
||||
|
||||
service_keys_to_content_updates[ CC.LOCAL_FILE_SERVICE_KEY ] = ( HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, ( hash, ) ), )
|
||||
service_keys_to_content_updates[ CC.COMBINED_LOCAL_FILE_SERVICE_KEY ] = ( HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, ( hash, ) ), )
|
||||
service_keys_to_content_updates[ CC.LOCAL_TAG_SERVICE_KEY ] = ( HydrusData.ContentUpdate( HC.CONTENT_TYPE_MAPPINGS, HC.CONTENT_UPDATE_ADD, ( 'car', ( hash, ) ) ), )
|
||||
|
||||
self._write( 'content_updates', service_keys_to_content_updates )
|
||||
|
@ -957,7 +957,7 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
service_keys_to_content_updates = {}
|
||||
|
||||
service_keys_to_content_updates[ CC.LOCAL_FILE_SERVICE_KEY ] = ( HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_PEND, ( hash, ) ), )
|
||||
service_keys_to_content_updates[ CC.COMBINED_LOCAL_FILE_SERVICE_KEY ] = ( HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_PEND, ( hash, ) ), )
|
||||
|
||||
self._write( 'content_updates', service_keys_to_content_updates )
|
||||
|
||||
|
@ -973,7 +973,7 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
service_keys_to_content_updates = {}
|
||||
|
||||
service_keys_to_content_updates[ CC.LOCAL_FILE_SERVICE_KEY ] = ( HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_RESCIND_PEND, ( hash, ) ), )
|
||||
service_keys_to_content_updates[ CC.COMBINED_LOCAL_FILE_SERVICE_KEY ] = ( HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_RESCIND_PEND, ( hash, ) ), )
|
||||
|
||||
self._write( 'content_updates', service_keys_to_content_updates )
|
||||
|
||||
|
@ -986,11 +986,11 @@ class TestClientDB( unittest.TestCase ):
|
|||
|
||||
def test_services( self ):
|
||||
|
||||
result = self._read( 'services', ( HC.LOCAL_FILE, HC.LOCAL_TAG ) )
|
||||
result = self._read( 'services', ( HC.LOCAL_FILE_DOMAIN, HC.LOCAL_FILE_TRASH_DOMAIN, HC.COMBINED_LOCAL_FILE, HC.LOCAL_TAG ) )
|
||||
|
||||
result_service_keys = { service.GetServiceKey() for service in result }
|
||||
|
||||
self.assertItemsEqual( { CC.TRASH_SERVICE_KEY, CC.LOCAL_FILE_SERVICE_KEY, CC.LOCAL_TAG_SERVICE_KEY }, result_service_keys )
|
||||
self.assertItemsEqual( { CC.TRASH_SERVICE_KEY, CC.LOCAL_FILE_SERVICE_KEY, CC.COMBINED_LOCAL_FILE_SERVICE_KEY, CC.LOCAL_TAG_SERVICE_KEY }, result_service_keys )
|
||||
|
||||
#
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ class TestServer( unittest.TestCase ):
|
|||
def TWISTEDSetup():
|
||||
|
||||
reactor.listenTCP( HC.DEFAULT_SERVER_ADMIN_PORT, ServerServer.HydrusServiceAdmin( self._admin_service.GetServiceKey(), HC.SERVER_ADMIN, 'hello' ) )
|
||||
reactor.listenTCP( HC.DEFAULT_LOCAL_FILE_PORT, ClientLocalServer.HydrusServiceLocal( CC.LOCAL_FILE_SERVICE_KEY, HC.LOCAL_FILE, 'hello' ) )
|
||||
reactor.listenTCP( HC.DEFAULT_LOCAL_FILE_PORT, ClientLocalServer.HydrusServiceLocal( CC.COMBINED_LOCAL_FILE_SERVICE_KEY, HC.COMBINED_LOCAL_FILE, 'hello' ) )
|
||||
reactor.listenTCP( HC.DEFAULT_LOCAL_BOORU_PORT, ClientLocalServer.HydrusServiceBooru( CC.LOCAL_BOORU_SERVICE_KEY, HC.LOCAL_BOORU, 'hello' ) )
|
||||
reactor.listenTCP( HC.DEFAULT_SERVICE_PORT, ServerServer.HydrusServiceRepositoryFile( self._file_service.GetServiceKey(), HC.FILE_REPOSITORY, 'hello' ) )
|
||||
reactor.listenTCP( HC.DEFAULT_SERVICE_PORT + 1, ServerServer.HydrusServiceRepositoryTag( self._tag_service.GetServiceKey(), HC.TAG_REPOSITORY, 'hello' ) )
|
||||
|
|
8
test.py
8
test.py
|
@ -85,9 +85,13 @@ class Controller( object ):
|
|||
self._reads[ 'options' ] = ClientDefaults.GetClientDefaultOptions()
|
||||
|
||||
services = []
|
||||
|
||||
services.append( ClientData.GenerateService( CC.LOCAL_BOORU_SERVICE_KEY, HC.LOCAL_BOORU, CC.LOCAL_BOORU_SERVICE_KEY, { 'max_monthly_data' : None, 'used_monthly_data' : 0 } ) )
|
||||
services.append( ClientData.GenerateService( CC.LOCAL_FILE_SERVICE_KEY, HC.LOCAL_FILE, CC.LOCAL_FILE_SERVICE_KEY, {} ) )
|
||||
services.append( ClientData.GenerateService( CC.COMBINED_LOCAL_FILE_SERVICE_KEY, HC.COMBINED_LOCAL_FILE, CC.COMBINED_LOCAL_FILE_SERVICE_KEY, {} ) )
|
||||
services.append( ClientData.GenerateService( CC.LOCAL_FILE_SERVICE_KEY, HC.LOCAL_FILE_DOMAIN, CC.LOCAL_FILE_SERVICE_KEY, {} ) )
|
||||
services.append( ClientData.GenerateService( CC.TRASH_SERVICE_KEY, HC.LOCAL_FILE_TRASH_DOMAIN, CC.LOCAL_FILE_SERVICE_KEY, {} ) )
|
||||
services.append( ClientData.GenerateService( CC.LOCAL_TAG_SERVICE_KEY, HC.LOCAL_TAG, CC.LOCAL_TAG_SERVICE_KEY, {} ) )
|
||||
|
||||
self._reads[ 'services' ] = services
|
||||
|
||||
client_files_locations = {}
|
||||
|
@ -366,4 +370,4 @@ if __name__ == '__main__':
|
|||
print( 'This was version ' + str( HC.SOFTWARE_VERSION ) )
|
||||
|
||||
raw_input()
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue