Version 72
This commit is contained in:
parent
849ccb68db
commit
00ea2d6096
|
@ -12,7 +12,7 @@
|
|||
<ul>
|
||||
<li>collapsed the four mappings tables into two tables</li>
|
||||
<li>merged the two active_mappings tables into the mappings table</li>
|
||||
<li>made a _great_ number of changes to how mappings and active_mappings are stored and processed throughout</li>
|
||||
<li>made a <i>great</i> number of changes to how mappings and active_mappings are stored and processed throughout</li>
|
||||
<li>'active' and 'null' nomenclature is now 'combined'; null service_ids are now just ints</li>
|
||||
<li>improved deletepending so it isn't so tough on the a/c cache</li>
|
||||
<li>tags regex dialog entries 'for all files' and 'just for this file' was all broke</li>
|
||||
|
|
|
@ -175,8 +175,6 @@ sort_string_lookup[ SORT_BY_RANDOM ] = 'random order'
|
|||
THUMBNAIL_MARGIN = 2
|
||||
THUMBNAIL_BORDER = 1
|
||||
|
||||
UNKNOWN_ACCOUNT_TYPE = HC.AccountType( 'unknown account', [], ( None, None ) )
|
||||
|
||||
def AddPaddingToDimensions( dimensions, padding ):
|
||||
|
||||
( x, y ) = dimensions
|
||||
|
@ -353,8 +351,6 @@ def GetThumbnailPath( hash ):
|
|||
|
||||
return HC.CLIENT_THUMBNAILS_DIR + os.path.sep + first_two_chars + os.path.sep + hash_encoded
|
||||
|
||||
def GetUnknownAccount(): return HC.Account( 0, UNKNOWN_ACCOUNT_TYPE, 0, None, ( 0, 0 ) )
|
||||
|
||||
def IterateAllFilePaths():
|
||||
|
||||
hex_chars = '0123456789abcdef'
|
||||
|
@ -403,7 +399,7 @@ def MergeTags( tags_managers ):
|
|||
|
||||
# now let's merge so we have s_i : s_t_t
|
||||
|
||||
merged_tags = {}
|
||||
merged_tags = collections.defaultdict( HC.default_dict_set )
|
||||
|
||||
for ( service_identifier, several_statuses_to_tags ) in s_i_s_t_t_dict.items():
|
||||
|
||||
|
@ -413,7 +409,7 @@ def MergeTags( tags_managers ):
|
|||
# [( status, tags )]
|
||||
flattened_s_t_t = itertools.chain.from_iterable( s_t_t_tupled )
|
||||
|
||||
statuses_to_tags = collections.defaultdict( set )
|
||||
statuses_to_tags = HC.default_dict_set()
|
||||
|
||||
for ( status, tags ) in flattened_s_t_t: statuses_to_tags[ status ].update( tags )
|
||||
|
||||
|
@ -605,7 +601,10 @@ def ParseImportablePaths( raw_paths, include_subdirs = True ):
|
|||
if len( odd_paths ) > 0:
|
||||
|
||||
print( 'Because of mime, the client could not import the following files:' )
|
||||
for odd_path in odd_paths: print( odd_path )
|
||||
|
||||
for odd_path in odd_paths:
|
||||
try: print( odd_path )
|
||||
except: pass
|
||||
|
||||
wx.MessageBox( 'The ' + str( len( odd_paths ) ) + ' files that were not jpegs, pngs, bmps or gifs will not be added. If you are interested, their paths have been written to the log.' )
|
||||
|
||||
|
@ -856,11 +855,9 @@ class CDPPFileServiceIdentifiers():
|
|||
|
||||
def HasLocal( self ): return HC.LOCAL_FILE_SERVICE_IDENTIFIER in self._current
|
||||
|
||||
def ProcessContentUpdate( self, content_update ):
|
||||
def ProcessContentUpdate( self, service_identifier, content_update ):
|
||||
|
||||
action = content_update.GetAction()
|
||||
|
||||
service_identifier = content_update.GetServiceIdentifier()
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ADD:
|
||||
|
||||
|
@ -914,11 +911,9 @@ class LocalRatings():
|
|||
|
||||
def GetServiceIdentifiersToRatings( self ): return self._service_identifiers_to_ratings
|
||||
|
||||
def ProcessContentUpdate( self, content_update ):
|
||||
def ProcessContentUpdate( self, service_identifier, content_update ):
|
||||
|
||||
service_identifier = content_update.GetServiceIdentifier()
|
||||
|
||||
action = content_update.GetAction()
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
if action == HC.CONTENT_UPDATE_RATING:
|
||||
|
||||
|
@ -953,7 +948,7 @@ class ConnectionToService():
|
|||
|
||||
error_message = 'Could not connect.'
|
||||
|
||||
if self._service_identifier is not None: HC.pubsub.pub( 'service_update_db', HC.ServiceUpdate( HC.SERVICE_UPDATE_ERROR, self._service_identifier, error_message ) )
|
||||
if self._service_identifier is not None: HC.pubsub.pub( 'service_updates_delayed', { self._service_identifier : [ HC.ServiceUpdate( HC.SERVICE_UPDATE_ERROR, error_message ) ] })
|
||||
|
||||
raise Exception( error_message )
|
||||
|
||||
|
@ -1114,13 +1109,7 @@ class ConnectionToService():
|
|||
|
||||
account.MakeFresh()
|
||||
|
||||
HC.pubsub.pub( 'service_update_db', HC.ServiceUpdate( HC.SERVICE_UPDATE_ACCOUNT, self._service_identifier, account ) )
|
||||
|
||||
elif request == 'update':
|
||||
|
||||
update = response
|
||||
|
||||
HC.pubsub.pub( 'service_update_db', HC.ServiceUpdate( HC.SERVICE_UPDATE_NEXT_BEGIN, self._service_identifier, update.GetNextBegin() ) )
|
||||
wx.GetApp().Write( 'service_updates', { self._service_identifier : [ HC.ServiceUpdate( HC.SERVICE_UPDATE_ACCOUNT, account ) ] } )
|
||||
|
||||
|
||||
return response
|
||||
|
@ -1152,9 +1141,9 @@ class CPRemoteRatingsServiceIdentifiers():
|
|||
|
||||
def GetServiceIdentifiersToCP( self ): return self._service_identifiers_to_cp
|
||||
|
||||
def ProcessContentUpdate( self, content_update ):
|
||||
def ProcessContentUpdate( self, service_identifier, content_update ):
|
||||
|
||||
service_identifier = content_update.GetServiceIdentifier()
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
if service_identifier in self._service_identifiers_to_cp: ( current, pending ) = self._service_identifiers_to_cp[ service_identifier ]
|
||||
else:
|
||||
|
@ -1164,8 +1153,6 @@ class CPRemoteRatingsServiceIdentifiers():
|
|||
self._service_identifiers_to_cp[ service_identifier ] = ( current, pending )
|
||||
|
||||
|
||||
action = content_update.GetAction()
|
||||
|
||||
# this may well need work; need to figure out how to set the pending back to None after an upload. rescind seems ugly
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ADD:
|
||||
|
@ -1305,7 +1292,7 @@ class FileQueryResult():
|
|||
self._hashes = set( self._hashes_ordered )
|
||||
|
||||
HC.pubsub.sub( self, 'ProcessContentUpdates', 'content_updates_data' )
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdate', 'service_update_data' )
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdates', 'service_updates_data' )
|
||||
HC.pubsub.sub( self, 'RecalcCombinedTags', 'new_tag_service_precedence' )
|
||||
|
||||
|
||||
|
@ -1350,56 +1337,64 @@ class FileQueryResult():
|
|||
|
||||
def GetMediaResults( self ): return [ self._hashes_to_media_results[ hash ] for hash in self._hashes_ordered ]
|
||||
|
||||
def ProcessContentUpdates( self, content_updates ):
|
||||
def ProcessContentUpdates( self, service_identifiers_to_content_updates ):
|
||||
|
||||
for content_update in content_updates:
|
||||
for ( service_identifier, content_updates ) in service_identifiers_to_content_updates.items():
|
||||
|
||||
action = content_update.GetAction()
|
||||
|
||||
service_identifier = content_update.GetServiceIdentifier()
|
||||
|
||||
service_type = service_identifier.GetType()
|
||||
|
||||
hashes = content_update.GetHashes()
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ARCHIVE:
|
||||
for content_update in content_updates:
|
||||
|
||||
if 'system:inbox' in self._predicates: self._Remove( hashes )
|
||||
hashes = content_update.GetHashes()
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_INBOX:
|
||||
|
||||
if 'system:archive' in self._predicates: self._Remove( hashes )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_DELETE and service_identifier == self._file_service_identifier: self._Remove( hashes )
|
||||
|
||||
for hash in self._hashes.intersection( hashes ):
|
||||
|
||||
media_result = self._hashes_to_media_results[ hash ]
|
||||
|
||||
media_result.ProcessContentUpdate( content_update )
|
||||
if len( hashes ) > 0:
|
||||
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
service_type = service_identifier.GetType()
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ARCHIVE:
|
||||
|
||||
if 'system:inbox' in self._predicates: self._Remove( hashes )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_INBOX:
|
||||
|
||||
if 'system:archive' in self._predicates: self._Remove( hashes )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_DELETE and service_identifier == self._file_service_identifier: self._Remove( hashes )
|
||||
|
||||
for hash in self._hashes.intersection( hashes ):
|
||||
|
||||
media_result = self._hashes_to_media_results[ hash ]
|
||||
|
||||
media_result.ProcessContentUpdate( service_identifier, content_update )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def ProcessServiceUpdate( self, update ):
|
||||
def ProcessServiceUpdates( self, service_identifiers_to_service_updates ):
|
||||
|
||||
action = update.GetAction()
|
||||
|
||||
service_identifier = update.GetServiceIdentifier()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_DELETE_PENDING:
|
||||
for ( service_identifier, service_updates ) in service_identifiers_to_service_updates.items():
|
||||
|
||||
for media_result in self._hashes_to_media_results.values(): media_result.DeletePending( service_identifier )
|
||||
|
||||
elif action == HC.SERVICE_UPDATE_RESET:
|
||||
|
||||
for media_result in self._hashes_to_media_results.values(): media_result.ResetService( service_identifier )
|
||||
for service_update in service_updates:
|
||||
|
||||
( action, row ) = service_update.ToTuple()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_DELETE_PENDING:
|
||||
|
||||
for media_result in self._hashes_to_media_results.values(): media_result.DeletePending( service_identifier )
|
||||
|
||||
elif action == HC.SERVICE_UPDATE_RESET:
|
||||
|
||||
for media_result in self._hashes_to_media_results.values(): media_result.ResetService( service_identifier )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class FileSearchContext():
|
||||
|
||||
def __init__( self, file_service_identifier = HC.LOCAL_FILE_SERVICE_IDENTIFIER, tag_service_identifier = HC.COMBINED_TAG_SERVICE_IDENTIFIER, include_current_tags = True, include_pending_tags = True, predicates = [] ):
|
||||
def __init__( self, file_service_identifier = HC.COMBINED_FILE_SERVICE_IDENTIFIER, tag_service_identifier = HC.COMBINED_TAG_SERVICE_IDENTIFIER, include_current_tags = True, include_pending_tags = True, predicates = [] ):
|
||||
|
||||
self._file_service_identifier = file_service_identifier
|
||||
self._tag_service_identifier = tag_service_identifier
|
||||
|
@ -1816,7 +1811,7 @@ class Imageboard( HC.HydrusYAMLBase ):
|
|||
|
||||
def IsOkToPost( self, media_result ):
|
||||
|
||||
( hash, inbox, size, mime, timestamp, width, height, duration, num_frames, num_words, tags, file_service_identifiers, local_ratings, remote_ratings ) = media_result.GetInfo()
|
||||
( hash, inbox, size, mime, timestamp, width, height, duration, num_frames, num_words, tags, file_service_identifiers, local_ratings, remote_ratings ) = media_result.ToTuple()
|
||||
|
||||
if RESTRICTION_MIN_RESOLUTION in self._restrictions:
|
||||
|
||||
|
@ -2009,23 +2004,21 @@ class MediaResult():
|
|||
|
||||
def GetTimestamp( self ): return self._tuple[4]
|
||||
|
||||
def GetInfo( self ): return self._tuple
|
||||
|
||||
def ProcessContentUpdate( self, content_update ):
|
||||
def ProcessContentUpdate( self, service_identifier, content_update ):
|
||||
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
( hash, inbox, size, mime, timestamp, width, height, duration, num_frames, num_words, tags_manager, file_service_identifiers_cdpp, local_ratings, remote_ratings ) = self._tuple
|
||||
|
||||
service_identifier = content_update.GetServiceIdentifier()
|
||||
|
||||
service_type = service_identifier.GetType()
|
||||
|
||||
if service_type in ( HC.LOCAL_TAG, HC.TAG_REPOSITORY ): tags_manager.ProcessContentUpdate( content_update )
|
||||
if service_type in ( HC.LOCAL_TAG, HC.TAG_REPOSITORY ):
|
||||
try: tags_manager.ProcessContentUpdate( service_identifier, content_update )
|
||||
except: print( traceback.format_exc() )
|
||||
elif service_type in ( HC.FILE_REPOSITORY, HC.LOCAL_FILE ):
|
||||
|
||||
if service_type == HC.LOCAL_FILE:
|
||||
|
||||
action = content_update.GetAction()
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ADD and not file_service_identifiers_cdpp.HasLocal(): inbox = True
|
||||
elif action == HC.CONTENT_UPDATE_ARCHIVE: inbox = False
|
||||
elif action == HC.CONTENT_UPDATE_INBOX: inbox = True
|
||||
|
@ -2034,12 +2027,12 @@ class MediaResult():
|
|||
self._tuple = ( hash, inbox, size, mime, timestamp, width, height, duration, num_frames, num_words, tags_manager, file_service_identifiers_cdpp, local_ratings, remote_ratings )
|
||||
|
||||
|
||||
file_service_identifiers_cdpp.ProcessContentUpdate( content_update )
|
||||
file_service_identifiers_cdpp.ProcessContentUpdate( service_identifier, content_update )
|
||||
|
||||
elif service_type in HC.RATINGS_SERVICES:
|
||||
|
||||
if service_type in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ): local_ratings.ProcessContentUpdate( content_update )
|
||||
else: remote_ratings.ProcessContentUpdate( content_update )
|
||||
if service_type in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ): local_ratings.ProcessContentUpdate( service_identifier, content_update )
|
||||
else: remote_ratings.ProcessContentUpdate( service_identifier, content_update )
|
||||
|
||||
|
||||
|
||||
|
@ -2053,6 +2046,8 @@ class MediaResult():
|
|||
elif service_type == HC.FILE_REPOSITORY: file_service_identifiers_cdpp.ResetService( service_identifier )
|
||||
|
||||
|
||||
def ToTuple( self ): return self._tuple
|
||||
|
||||
class MenuEventIdToActionCache():
|
||||
|
||||
def __init__( self ):
|
||||
|
@ -2203,7 +2198,7 @@ class ServiceRemote( Service ):
|
|||
self._credentials = credentials
|
||||
self._last_error = last_error
|
||||
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdate', 'service_update_data' )
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdates', 'service_updates_data' )
|
||||
|
||||
|
||||
def GetConnection( self ): return ConnectionToService( self._service_identifier, self._credentials )
|
||||
|
@ -2216,18 +2211,24 @@ class ServiceRemote( Service ):
|
|||
|
||||
def SetCredentials( self, credentials ): self._credentials = credentials
|
||||
|
||||
def ProcessServiceUpdate( self, update ):
|
||||
def ProcessServiceUpdates( self, service_identifiers_to_service_updates ):
|
||||
|
||||
if update.GetServiceIdentifier() == self._service_identifier:
|
||||
for ( service_identifier, service_updates ) in service_identifiers_to_service_updates.items():
|
||||
|
||||
action = update.GetAction()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_ERROR: self._last_error = int( time.time() )
|
||||
elif action == HC.SERVICE_UPDATE_RESET:
|
||||
for service_update in service_updates:
|
||||
|
||||
self._service_identifier = update.GetInfo()
|
||||
|
||||
self._last_error = 0
|
||||
if service_identifier == self._service_identifier:
|
||||
|
||||
( action, row ) = service_update.ToTuple()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_ERROR: self._last_error = int( time.time() )
|
||||
elif action == HC.SERVICE_UPDATE_RESET:
|
||||
|
||||
self._service_identifier = row
|
||||
|
||||
self._last_error = 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2269,26 +2270,32 @@ class ServiceRemoteRestricted( ServiceRemote ):
|
|||
else: return True
|
||||
|
||||
|
||||
def ProcessServiceUpdate( self, update ):
|
||||
def ProcessServiceUpdates( self, service_identifiers_to_service_updates ):
|
||||
|
||||
ServiceRemote.ProcessServiceUpdate( self, update )
|
||||
ServiceRemote.ProcessServiceUpdates( self, service_identifiers_to_service_updates )
|
||||
|
||||
if update.GetServiceIdentifier() == self.GetServiceIdentifier():
|
||||
for ( service_identifier, service_updates ) in service_identifiers_to_service_updates.items():
|
||||
|
||||
action = update.GetAction()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_ACCOUNT:
|
||||
for service_update in service_updates:
|
||||
|
||||
account = update.GetInfo()
|
||||
|
||||
self._account = account
|
||||
self._last_error = 0
|
||||
|
||||
elif action == HC.SERVICE_UPDATE_REQUEST_MADE:
|
||||
|
||||
num_bytes = update.GetInfo()
|
||||
|
||||
self._account.RequestMade( num_bytes )
|
||||
if service_identifier == self.GetServiceIdentifier():
|
||||
|
||||
( action, row ) = service_update.ToTuple()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_ACCOUNT:
|
||||
|
||||
account = row
|
||||
|
||||
self._account = account
|
||||
self._last_error = 0
|
||||
|
||||
elif action == HC.SERVICE_UPDATE_REQUEST_MADE:
|
||||
|
||||
num_bytes = row
|
||||
|
||||
self._account.RequestMade( num_bytes )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2337,26 +2344,34 @@ class ServiceRemoteRestrictedRepository( ServiceRemoteRestricted ):
|
|||
|
||||
|
||||
|
||||
def ProcessServiceUpdate( self, update ):
|
||||
def ProcessServiceUpdates( self, service_identifiers_to_service_updates ):
|
||||
|
||||
ServiceRemoteRestricted.ProcessServiceUpdate( self, update )
|
||||
ServiceRemoteRestricted.ProcessServiceUpdates( self, service_identifiers_to_service_updates )
|
||||
|
||||
if update.GetServiceIdentifier() == self.GetServiceIdentifier():
|
||||
for ( service_identifier, service_updates ) in service_identifiers_to_service_updates.items():
|
||||
|
||||
action = update.GetAction()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_NEXT_BEGIN:
|
||||
for service_update in service_updates:
|
||||
|
||||
next_begin = update.GetInfo()
|
||||
|
||||
self.SetNextBegin( next_begin )
|
||||
|
||||
elif action == HC.SERVICE_UPDATE_RESET:
|
||||
|
||||
self._service_identifier = update.GetInfo()
|
||||
|
||||
self._first_begin = 0
|
||||
self._next_begin = 0
|
||||
if service_identifier == self.GetServiceIdentifier():
|
||||
|
||||
( action, row ) = service_update.ToTuple()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_NEXT_BEGIN:
|
||||
|
||||
( begin, end ) = row
|
||||
|
||||
next_begin = end + 1
|
||||
|
||||
self.SetNextBegin( next_begin )
|
||||
|
||||
elif action == HC.SERVICE_UPDATE_RESET:
|
||||
|
||||
self._service_identifier = row
|
||||
|
||||
self._first_begin = 0
|
||||
self._next_begin = 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2423,28 +2438,32 @@ class ServiceRemoteRestrictedDepot( ServiceRemoteRestricted ):
|
|||
|
||||
def HasCheckDue( self ): return self._last_check + self._check_period + 5 < int( time.time() )
|
||||
|
||||
def ProcessServiceUpdate( self, update ):
|
||||
def ProcessServiceUpdates( self, service_identifiers_to_service_updates ):
|
||||
|
||||
ServiceRemoteRestricted.ProcessServiceUpdate( self, update )
|
||||
ServiceRemoteRestricted.ProcessServiceUpdates( self, update )
|
||||
|
||||
if update.GetServiceIdentifier() == self.GetServiceIdentifier():
|
||||
for ( service_identifier, service_updates ) in service_identifiers_to_service_updates.items():
|
||||
|
||||
action = update.GetAction()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_LAST_CHECK:
|
||||
for service_update in service_updates:
|
||||
|
||||
last_check = update.GetInfo()
|
||||
if service_identifier == self.GetServiceIdentifier():
|
||||
|
||||
( action, row ) = service_update.ToTuple()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_LAST_CHECK:
|
||||
|
||||
last_check = row
|
||||
|
||||
self._last_check = last_check
|
||||
|
||||
elif action == HC.SERVICE_UPDATE_RESET:
|
||||
|
||||
self._service_identifier = row
|
||||
|
||||
self._last_check = 0
|
||||
|
||||
|
||||
|
||||
self._last_check = last_check
|
||||
|
||||
elif action == HC.SERVICE_UPDATE_RESET:
|
||||
|
||||
self._service_identifier = update.GetInfo()
|
||||
|
||||
self._last_check = 0
|
||||
|
||||
|
||||
|
||||
|
||||
class ServiceRemoteRestrictedDepotMessage( ServiceRemoteRestrictedDepot ):
|
||||
|
||||
|
@ -2491,17 +2510,14 @@ class TagsManager():
|
|||
|
||||
for service_identifier in t_s_p:
|
||||
|
||||
if service_identifier in self._service_identifiers_to_statuses_to_tags:
|
||||
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
combined_current.update( statuses_to_tags[ HC.CURRENT ] )
|
||||
combined_current.difference_update( statuses_to_tags[ HC.DELETED ] )
|
||||
combined_current.difference_update( statuses_to_tags[ HC.DELETED_PENDING ] )
|
||||
|
||||
combined_pending.update( statuses_to_tags[ HC.DELETED_PENDING ] )
|
||||
combined_pending.update( statuses_to_tags[ HC.PENDING ] )
|
||||
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
combined_current.update( statuses_to_tags[ HC.CURRENT ] )
|
||||
combined_current.difference_update( statuses_to_tags[ HC.DELETED ] )
|
||||
combined_current.difference_update( statuses_to_tags[ HC.DELETED_PENDING ] )
|
||||
|
||||
combined_pending.update( statuses_to_tags[ HC.DELETED_PENDING ] )
|
||||
combined_pending.update( statuses_to_tags[ HC.PENDING ] )
|
||||
|
||||
|
||||
combined_statuses_to_tags = collections.defaultdict( set )
|
||||
|
@ -2523,31 +2539,28 @@ class TagsManager():
|
|||
self._chapters = set()
|
||||
self._pages = set()
|
||||
|
||||
if HC.COMBINED_TAG_SERVICE_IDENTIFIER in self._service_identifiers_to_statuses_to_tags:
|
||||
combined_statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_IDENTIFIER ]
|
||||
|
||||
combined_current = combined_statuses_to_tags[ HC.CURRENT ]
|
||||
combined_pending = combined_statuses_to_tags[ HC.PENDING ]
|
||||
|
||||
for tag in combined_current.union( combined_pending ):
|
||||
|
||||
combined_statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_IDENTIFIER ]
|
||||
|
||||
combined_current = combined_statuses_to_tags[ HC.CURRENT ]
|
||||
combined_pending = combined_statuses_to_tags[ HC.PENDING ]
|
||||
|
||||
for tag in combined_current.union( combined_pending ):
|
||||
if ':' in tag:
|
||||
|
||||
if ':' in tag:
|
||||
( namespace, tag ) = tag.split( ':', 1 )
|
||||
|
||||
if namespace == 'creator': self._creators.add( tag )
|
||||
elif namespace == 'series': self._series.add( tag )
|
||||
elif namespace == 'title': self._titles.add( tag )
|
||||
elif namespace in ( 'volume', 'chapter', 'page' ):
|
||||
|
||||
( namespace, tag ) = tag.split( ':', 1 )
|
||||
try: tag = int( tag )
|
||||
except: pass
|
||||
|
||||
if namespace == 'creator': self._creators.add( tag )
|
||||
elif namespace == 'series': self._series.add( tag )
|
||||
elif namespace == 'title': self._titles.add( tag )
|
||||
elif namespace in ( 'volume', 'chapter', 'page' ):
|
||||
|
||||
try: tag = int( tag )
|
||||
except: pass
|
||||
|
||||
if namespace == 'volume': self._volumes.add( tag )
|
||||
elif namespace == 'chapter': self._chapters.add( tag )
|
||||
elif namespace == 'page': self._pages.add( tag )
|
||||
|
||||
if namespace == 'volume': self._volumes.add( tag )
|
||||
elif namespace == 'chapter': self._chapters.add( tag )
|
||||
elif namespace == 'page': self._pages.add( tag )
|
||||
|
||||
|
||||
|
||||
|
@ -2564,57 +2577,42 @@ class TagsManager():
|
|||
|
||||
def DeletePending( self, service_identifier ):
|
||||
|
||||
if service_identifier in self._service_identifiers_to_statuses_to_tags:
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
if len( statuses_to_tags[ HC.PENDING ] ) + len( statuses_to_tags[ HC.DELETED_PENDING ] ) + len( statuses_to_tags[ HC.PETITIONED ] ) > 0:
|
||||
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
statuses_to_tags[ HC.DELETED ].update( statuses_to_tags[ HC.DELETED_PENDING ] )
|
||||
|
||||
if len( statuses_to_tags[ HC.PENDING ] ) + len( statuses_to_tags[ HC.DELETED_PENDING ] ) + len( statuses_to_tags[ HC.PETITIONED ] ) > 0:
|
||||
|
||||
statuses_to_tags[ HC.DELETED ].update( statuses_to_tags[ HC.DELETED_PENDING ] )
|
||||
|
||||
statuses_to_tags[ HC.PENDING ] = set()
|
||||
statuses_to_tags[ HC.DELETED_PENDING ] = set()
|
||||
statuses_to_tags[ HC.PETITIONED ] = set()
|
||||
|
||||
self._RecalcCombined()
|
||||
|
||||
statuses_to_tags[ HC.PENDING ] = set()
|
||||
statuses_to_tags[ HC.DELETED_PENDING ] = set()
|
||||
statuses_to_tags[ HC.PETITIONED ] = set()
|
||||
|
||||
self._RecalcCombined()
|
||||
|
||||
|
||||
|
||||
def GetCurrent( self, service_identifier = HC.COMBINED_TAG_SERVICE_IDENTIFIER ):
|
||||
|
||||
if service_identifier in self._service_identifiers_to_statuses_to_tags:
|
||||
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
return set( statuses_to_tags[ HC.CURRENT ] )
|
||||
|
||||
else: return set()
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
return set( statuses_to_tags[ HC.CURRENT ] )
|
||||
|
||||
|
||||
def GetDeleted( self, service_identifier = HC.COMBINED_TAG_SERVICE_IDENTIFIER ):
|
||||
|
||||
if service_identifier in self._service_identifiers_to_statuses_to_tags:
|
||||
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
return statuses_to_tags[ HC.DELETED ].union( statuses_to_tags[ HC.DELETED_PENDING ] )
|
||||
|
||||
else: return set()
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
return statuses_to_tags[ HC.DELETED ].union( statuses_to_tags[ HC.DELETED_PENDING ] )
|
||||
|
||||
|
||||
def GetNamespaceSlice( self, namespaces ):
|
||||
|
||||
if HC.COMBINED_TAG_SERVICE_IDENTIFIER in self._service_identifiers_to_statuses_to_tags:
|
||||
|
||||
combined_statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_IDENTIFIER ]
|
||||
|
||||
combined_current = combined_statuses_to_tags[ HC.CURRENT ]
|
||||
combined_pending = combined_statuses_to_tags[ HC.PENDING ]
|
||||
|
||||
return frozenset( [ tag for tag in list( combined_current ) + list( combined_pending ) if True in ( tag.startswith( namespace + ':' ) for namespace in namespaces ) ] )
|
||||
|
||||
else: return frozenset()
|
||||
combined_statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_IDENTIFIER ]
|
||||
|
||||
combined_current = combined_statuses_to_tags[ HC.CURRENT ]
|
||||
combined_pending = combined_statuses_to_tags[ HC.PENDING ]
|
||||
|
||||
return frozenset( ( tag for tag in list( combined_current ) + list( combined_pending ) if True in ( tag.startswith( namespace + ':' ) for namespace in namespaces ) ) )
|
||||
|
||||
|
||||
def GetNumTags( self, tag_service_identifier, include_current_tags = True, include_pending_tags = False ):
|
||||
|
@ -2631,59 +2629,40 @@ class TagsManager():
|
|||
|
||||
def GetPending( self, service_identifier = HC.COMBINED_TAG_SERVICE_IDENTIFIER ):
|
||||
|
||||
if service_identifier in self._service_identifiers_to_statuses_to_tags:
|
||||
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
return statuses_to_tags[ HC.DELETED_PENDING ].union( statuses_to_tags[ HC.PENDING ] )
|
||||
|
||||
else: return set()
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
return statuses_to_tags[ HC.DELETED_PENDING ].union( statuses_to_tags[ HC.PENDING ] )
|
||||
|
||||
|
||||
def GetPetitioned( self, service_identifier = HC.COMBINED_TAG_SERVICE_IDENTIFIER ):
|
||||
|
||||
if service_identifier in self._service_identifiers_to_statuses_to_tags:
|
||||
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
return set( statuses_to_tags[ HC.PETITIONED ] )
|
||||
|
||||
else: return set()
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
return set( statuses_to_tags[ HC.PETITIONED ] )
|
||||
|
||||
|
||||
def GetServiceIdentifiersToStatusesToTags( self ): return self._service_identifiers_to_statuses_to_tags
|
||||
|
||||
def GetStatusesToTags( self, service_identifier ):
|
||||
|
||||
if service_identifier in self._service_identifiers_to_statuses_to_tags: return self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
else: return collections.defaultdict( set )
|
||||
|
||||
def GetStatusesToTags( self, service_identifier ): return self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
def HasTag( self, tag ):
|
||||
|
||||
if HC.COMBINED_TAG_SERVICE_IDENTIFIER in self._service_identifiers_to_statuses_to_tags:
|
||||
|
||||
combined_statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_IDENTIFIER ]
|
||||
|
||||
return tag in combined_statuses_to_tags[ HC.CURRENT ] or tag in combined_statuses_to_tags[ HC.PENDING ]
|
||||
|
||||
else: return False
|
||||
combined_statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_IDENTIFIER ]
|
||||
|
||||
return tag in combined_statuses_to_tags[ HC.CURRENT ] or tag in combined_statuses_to_tags[ HC.PENDING ]
|
||||
|
||||
|
||||
def ProcessContentUpdate( self, content_update ):
|
||||
|
||||
service_identifier = content_update.GetServiceIdentifier()
|
||||
|
||||
if service_identifier not in self._service_identifiers_to_statuses_to_tags: self._service_identifiers_to_statuses_to_tags[ service_identifier ] = collections.defaultdict( set )
|
||||
def ProcessContentUpdate( self, service_identifier, content_update ):
|
||||
|
||||
statuses_to_tags = self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
action = content_update.GetAction()
|
||||
( 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_ADD:
|
||||
|
||||
tag = content_update.GetInfo()
|
||||
|
||||
statuses_to_tags[ HC.CURRENT ].add( tag )
|
||||
|
||||
statuses_to_tags[ HC.DELETED ].discard( tag )
|
||||
|
@ -2692,8 +2671,6 @@ class TagsManager():
|
|||
|
||||
elif action == HC.CONTENT_UPDATE_DELETE:
|
||||
|
||||
tag = content_update.GetInfo()
|
||||
|
||||
if tag in statuses_to_tags[ HC.PENDING ]:
|
||||
|
||||
statuses_to_tags[ HC.DELETED_PENDING ].add( tag )
|
||||
|
@ -2707,84 +2684,38 @@ class TagsManager():
|
|||
|
||||
statuses_to_tags[ HC.PETITIONED ].discard( tag )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_EDIT_LOG:
|
||||
elif action == HC.CONTENT_UPDATE_PENDING:
|
||||
|
||||
edit_log = content_update.GetInfo()
|
||||
|
||||
for ( action, info ) in edit_log:
|
||||
if tag in statuses_to_tags[ HC.DELETED ]:
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ADD:
|
||||
|
||||
tag = info
|
||||
|
||||
statuses_to_tags[ HC.CURRENT ].add( tag )
|
||||
|
||||
statuses_to_tags[ HC.DELETED ].discard( tag )
|
||||
statuses_to_tags[ HC.DELETED_PENDING ].discard( tag )
|
||||
statuses_to_tags[ HC.PENDING ].discard( tag )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_DELETE:
|
||||
|
||||
tag = info
|
||||
|
||||
if tag in statuses_to_tags[ HC.PENDING ]:
|
||||
|
||||
statuses_to_tags[ HC.DELETED_PENDING ].add( tag )
|
||||
statuses_to_tags[ HC.PENDING ].discard( tag )
|
||||
|
||||
else:
|
||||
|
||||
statuses_to_tags[ HC.DELETED ].add( tag )
|
||||
statuses_to_tags[ HC.CURRENT ].discard( tag )
|
||||
|
||||
|
||||
statuses_to_tags[ HC.PETITIONED ].discard( tag )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_PENDING:
|
||||
|
||||
tag = info
|
||||
|
||||
if tag in statuses_to_tags[ HC.DELETED ]:
|
||||
|
||||
statuses_to_tags[ HC.DELETED_PENDING ].add( tag )
|
||||
statuses_to_tags[ HC.DELETED ].discard( tag )
|
||||
|
||||
else: statuses_to_tags[ HC.PENDING ].add( tag )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PENDING:
|
||||
|
||||
tag = info
|
||||
|
||||
if tag in statuses_to_tags[ HC.DELETED_PENDING ]:
|
||||
|
||||
statuses_to_tags[ HC.DELETED ].add( tag )
|
||||
statuses_to_tags[ HC.DELETED_PENDING ].discard( tag )
|
||||
|
||||
else: statuses_to_tags[ HC.PENDING ].discard( tag )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_PETITION:
|
||||
|
||||
( tag, reason ) = info
|
||||
|
||||
statuses_to_tags[ HC.PETITIONED ].add( tag )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PETITION:
|
||||
|
||||
tag = info
|
||||
|
||||
statuses_to_tags[ HC.PETITIONED ].discard( tag )
|
||||
|
||||
statuses_to_tags[ HC.DELETED_PENDING ].add( tag )
|
||||
statuses_to_tags[ HC.DELETED ].discard( tag )
|
||||
|
||||
else: statuses_to_tags[ HC.PENDING ].add( tag )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PENDING:
|
||||
|
||||
if tag in statuses_to_tags[ HC.DELETED_PENDING ]:
|
||||
|
||||
statuses_to_tags[ HC.DELETED ].add( tag )
|
||||
statuses_to_tags[ HC.DELETED_PENDING ].discard( tag )
|
||||
|
||||
else: statuses_to_tags[ HC.PENDING ].discard( tag )
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_PETITION: statuses_to_tags[ HC.PETITIONED ].add( tag )
|
||||
elif action == HC.CONTENT_UPDATE_RESCIND_PETITION: statuses_to_tags[ HC.PETITIONED ].discard( tag )
|
||||
|
||||
self._RecalcCombined()
|
||||
|
||||
|
||||
def ResetService( self, service_identifier ):
|
||||
|
||||
self._service_identifiers_to_statuses_to_tags[ service_identifier ] = collections.defaultdict[ set ]
|
||||
|
||||
self._RecalcCombined()
|
||||
if service_identifier in self._service_identifiers_to_statuses_to_tags:
|
||||
|
||||
del self._service_identifiers_to_statuses_to_tags[ service_identifier ]
|
||||
|
||||
self._RecalcCombined()
|
||||
|
||||
|
||||
|
||||
class TagParentsManager():
|
||||
|
@ -2831,11 +2762,16 @@ class TagParentsManager():
|
|||
|
||||
def _RefreshParents( self ):
|
||||
|
||||
raw_parents = wx.GetApp().Read( 'tag_parents' )
|
||||
service_identifiers_to_statuses_to_pairs = wx.GetApp().Read( 'tag_parents' )
|
||||
|
||||
self._parents = collections.defaultdict( dict )
|
||||
|
||||
for ( service_identifier, pairs ) in raw_parents.items(): self._parents[ service_identifier ] = HC.BuildKeyToListDict( pairs )
|
||||
for ( service_identifier, statuses_to_pairs ) in service_identifiers_to_statuses_to_pairs.items():
|
||||
|
||||
pairs = statuses_to_pairs[ HC.CURRENT ].union( statuses_to_pairs[ HC.DELETED_PENDING ] ).union( statuses_to_pairs[ HC.PENDING ] )
|
||||
|
||||
self._parents[ service_identifier ] = HC.BuildKeyToListDict( pairs )
|
||||
|
||||
|
||||
|
||||
def ExpandPredicates( self, service_identifier, predicates ):
|
||||
|
@ -2886,6 +2822,7 @@ class TagSiblingsManager():
|
|||
self._tag_service_precedence = wx.GetApp().Read( 'tag_service_precedence' )
|
||||
|
||||
# I should offload this to a thread (rather than the gui thread), and have an event to say when it is ready
|
||||
# gui requests should pause until it is ready, which should kick in during refreshes, too!
|
||||
|
||||
self._RefreshSiblings()
|
||||
|
||||
|
@ -2896,7 +2833,7 @@ class TagSiblingsManager():
|
|||
|
||||
def _RefreshSiblings( self ):
|
||||
|
||||
unprocessed_siblings = wx.GetApp().Read( 'tag_siblings' )
|
||||
service_identifiers_to_statuses_to_pairs = wx.GetApp().Read( 'tag_siblings' )
|
||||
|
||||
t_s_p = list( self._tag_service_precedence )
|
||||
|
||||
|
@ -2909,35 +2846,33 @@ class TagSiblingsManager():
|
|||
|
||||
for service_identifier in t_s_p:
|
||||
|
||||
if service_identifier in unprocessed_siblings:
|
||||
statuses_to_pairs = service_identifiers_to_statuses_to_pairs[ service_identifier ]
|
||||
|
||||
pairs = statuses_to_pairs[ HC.CURRENT ].union( statuses_to_pairs[ HC.DELETED_PENDING ] ).union( statuses_to_pairs[ HC.PENDING ] )
|
||||
|
||||
for ( old, new ) in pairs:
|
||||
|
||||
some_siblings = unprocessed_siblings[ service_identifier ]
|
||||
|
||||
for ( old, new ) in some_siblings:
|
||||
if old not in processed_siblings:
|
||||
|
||||
if old not in processed_siblings:
|
||||
next_new = new
|
||||
|
||||
we_have_a_loop = False
|
||||
|
||||
while next_new in processed_siblings:
|
||||
|
||||
next_new = new
|
||||
next_new = processed_siblings[ next_new ]
|
||||
|
||||
we_have_a_loop = False
|
||||
|
||||
while next_new in processed_siblings:
|
||||
if next_new == old:
|
||||
|
||||
next_new = processed_siblings[ next_new ]
|
||||
we_have_a_loop = True
|
||||
|
||||
if next_new == old:
|
||||
|
||||
we_have_a_loop = True
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
|
||||
|
||||
if not we_have_a_loop: processed_siblings[ old ] = new
|
||||
|
||||
|
||||
if not we_have_a_loop: processed_siblings[ old ] = new
|
||||
|
||||
|
||||
processed_siblings.update( unprocessed_siblings[ service_identifier ] )
|
||||
|
||||
|
||||
# now to collapse chains
|
||||
|
|
|
@ -184,7 +184,7 @@ class Controller( wx.App ):
|
|||
|
||||
message = 'This instance of the client had a problem connecting to the database, which probably means an old instance is still closing.'
|
||||
message += os.linesep + os.linesep
|
||||
message += 'If the old instance does not close for a very long time, you can usually safely force-close it from task manager.'
|
||||
message += 'If the old instance does not close for a _very_ long time, you can usually safely force-close it from task manager.'
|
||||
|
||||
with ClientGUIDialogs.DialogYesNo( None, message, yes_label = 'wait a bit, then try again', no_label = 'quit now' ) as dlg:
|
||||
|
||||
|
|
1505
include/ClientDB.py
1505
include/ClientDB.py
File diff suppressed because it is too large
Load Diff
|
@ -105,17 +105,9 @@ class FrameGUI( ClientGUICommon.Frame ):
|
|||
|
||||
def _THREADUploadPending( self, service_identifier, job_key, cancel_event ):
|
||||
|
||||
# old:
|
||||
|
||||
#wx.GetApp().Write( 'upload_pending', service_identifier, job_key, cancel_event )
|
||||
|
||||
#return
|
||||
|
||||
# new
|
||||
|
||||
try:
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, 0, 4, u'gathering pending and petitioned' )
|
||||
HC.pubsub.pub( 'progress_update', job_key, 0, 3, u'gathering pending and petitioned' )
|
||||
|
||||
result = wx.GetApp().Read( 'pending', service_identifier )
|
||||
|
||||
|
@ -123,113 +115,106 @@ class FrameGUI( ClientGUICommon.Frame ):
|
|||
|
||||
service = wx.GetApp().Read( 'service', service_identifier )
|
||||
|
||||
if service_type == HC.TAG_REPOSITORY:
|
||||
if service_type == HC.FILE_REPOSITORY:
|
||||
|
||||
( mappings_object, petitions_object ) = result
|
||||
( upload_hashes, update ) = result
|
||||
|
||||
if len( mappings_object ) > 0 or len( petitions_object ) > 0:
|
||||
num_uploads = len( upload_hashes )
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, 1, num_uploads + 3, u'connecting to repository' )
|
||||
|
||||
connection = service.GetConnection()
|
||||
|
||||
good_hashes = []
|
||||
|
||||
error_messages = set()
|
||||
|
||||
for ( index, hash ) in enumerate( upload_hashes ):
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, 1, 4, u'connecting to repository' )
|
||||
HC.pubsub.pub( 'progress_update', job_key, index + 2, num_uploads + 3, u'Uploading file ' + HC.ConvertIntToPrettyString( index + 1 ) + ' of ' + HC.ConvertIntToPrettyString( num_uploads ) )
|
||||
|
||||
connection = service.GetConnection()
|
||||
if cancel_event.isSet(): break
|
||||
|
||||
if len( mappings_object ) > 0:
|
||||
try:
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, 2, 4, u'posting new mappings' )
|
||||
file = wx.GetApp().Read( 'file', hash )
|
||||
|
||||
try: connection.Post( 'mappings', mappings = mappings_object )
|
||||
except Exception as e: raise Exception( 'Encountered an error while uploading public_mappings:' + os.linesep + unicode( e ) )
|
||||
connection.Post( 'file', file = file )
|
||||
|
||||
|
||||
if len( petitions_object ) > 0:
|
||||
good_hashes.append( hash )
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, 3, 4, u'posting new petitions' )
|
||||
except Exception as e:
|
||||
|
||||
try: connection.Post( 'petitions', petitions = petitions_object )
|
||||
except Exception as e: raise Exception( 'Encountered an error while uploading petitions:' + os.linesep + unicode( e ) )
|
||||
message = 'Error: ' + unicode( e )
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, num_uploads + 1, num_uploads + 3, message )
|
||||
|
||||
print( message )
|
||||
|
||||
time.sleep( 1 )
|
||||
|
||||
|
||||
num_mappings = sum( [ len( hashes ) for ( tag, hashes ) in mappings_object ] )
|
||||
num_deleted_mappings = sum( [ len( hashes ) for ( reason, tag, hashes ) in petitions_object ] )
|
||||
|
||||
HC.pubsub.pub( 'log_message', 'upload mappings', 'uploaded ' + HC.ConvertIntToPrettyString( num_mappings ) + ' mappings to and deleted ' + HC.ConvertIntToPrettyString( num_deleted_mappings ) + ' mappings from ' + service_identifier.GetName() )
|
||||
|
||||
content_updates = []
|
||||
|
||||
content_updates += [ HC.ContentUpdate( HC.CONTENT_UPDATE_ADD, service_identifier, hashes, info = tag ) for ( tag, hashes ) in mappings_object ]
|
||||
content_updates += [ HC.ContentUpdate( HC.CONTENT_UPDATE_DELETE, service_identifier, hashes, info = tag ) for ( reason, tag, hashes ) in petitions_object ]
|
||||
|
||||
wx.GetApp().Write( 'content_updates', content_updates )
|
||||
|
||||
|
||||
elif service_type == HC.FILE_REPOSITORY:
|
||||
if len( good_hashes ) > 0: HC.pubsub.pub( 'log_message', 'upload files', 'uploaded ' + HC.ConvertIntToPrettyString( len( good_hashes ) ) + ' files to ' + service_identifier.GetName() )
|
||||
|
||||
( uploads, petitions_object ) = result
|
||||
|
||||
( num_uploads, num_petitions ) = ( len( uploads ), len( petitions_object ) )
|
||||
|
||||
if num_uploads > 0 or num_petitions > 0:
|
||||
if not update.IsEmpty():
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, 1, num_uploads + 3, u'connecting to repository' )
|
||||
|
||||
connection = service.GetConnection()
|
||||
|
||||
good_hashes = []
|
||||
|
||||
if num_uploads > 0:
|
||||
try:
|
||||
|
||||
error_messages = set()
|
||||
HC.pubsub.pub( 'progress_update', job_key, num_uploads + 1, num_uploads + 3, u'uploading petitions' )
|
||||
|
||||
for ( index, hash ) in enumerate( uploads ):
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, index + 2, num_uploads + 3, u'Uploading file ' + HC.ConvertIntToPrettyString( index + 1 ) + ' of ' + HC.ConvertIntToPrettyString( num_uploads ) )
|
||||
|
||||
if cancel_event.isSet(): break
|
||||
|
||||
try:
|
||||
|
||||
file = wx.GetApp().Read( 'file', hash )
|
||||
|
||||
connection.Post( 'file', file = file )
|
||||
|
||||
good_hashes.append( hash )
|
||||
|
||||
except Exception as e:
|
||||
|
||||
message = 'Error: ' + unicode( e )
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, num_uploads + 1, num_uploads + 3, message )
|
||||
|
||||
print( message )
|
||||
|
||||
time.sleep( 1 )
|
||||
|
||||
|
||||
connection.Post( 'update', update = update )
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, num_uploads + 1, num_uploads + 3, u'saving changes to local database' )
|
||||
HC.pubsub.pub( 'log_message', 'upload files', 'uploaded a file update to ' + service_identifier.GetName() )
|
||||
|
||||
|
||||
if num_petitions > 0:
|
||||
except Exception as e:
|
||||
|
||||
try:
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, num_uploads + 2, num_uploads + 3, u'uploading petitions' )
|
||||
|
||||
connection.Post( 'petitions', petitions = petitions_object )
|
||||
|
||||
except Exception as e: raise Exception( 'Encountered an error while trying to uploads petitions to '+ service_name + ':' + os.linesep + unicode( e ) )
|
||||
print( traceback.format_exc() )
|
||||
|
||||
raise Exception( 'Encountered an error while trying to uploads petitions to '+ service_identifier.GetName() + ':' + os.linesep + unicode( e ) )
|
||||
|
||||
|
||||
HC.pubsub.pub( 'log_message', 'upload files', 'uploaded ' + HC.ConvertIntToPrettyString( num_uploads ) + ' files to and deleted ' + HC.ConvertIntToPrettyString( num_petitions ) + ' files from ' + service_identifier.GetName() )
|
||||
|
||||
content_updates = []
|
||||
|
||||
content_updates.append( HC.ContentUpdate( HC.CONTENT_UPDATE_ADD, service_identifier, good_hashes ) )
|
||||
content_updates.append( HC.ContentUpdate( HC.CONTENT_UPDATE_DELETE, service_identifier, petitions_object.GetHashes() ) )
|
||||
|
||||
wx.GetApp().Write( 'content_updates', content_updates )
|
||||
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, num_uploads + 2, num_uploads + 3, u'saving changes to local database' )
|
||||
|
||||
content_updates = []
|
||||
|
||||
media_results = wx.GetApp().Read( 'media_results', CC.FileSearchContext(), good_hashes )
|
||||
|
||||
for media_result in media_results:
|
||||
|
||||
( hash, inbox, size, mime, timestamp, width, height, duration, num_frames, num_words, tags_manager, file_service_identifiers_cdpp, local_ratings, remote_ratings ) = media_result.ToTuple()
|
||||
|
||||
timestamp = int( time.time() )
|
||||
|
||||
content_update_row = ( hash, size, mime, timestamp, width, height, duration, num_frames, num_words )
|
||||
|
||||
content_updates.append( HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_ADD, content_update_row ) )
|
||||
|
||||
|
||||
content_updates.extend( update.GetContentUpdates( for_client = True ) )
|
||||
|
||||
service_identfiers_to_content_updates = { service_identifier : content_updates }
|
||||
|
||||
elif service_type == HC.TAG_REPOSITORY:
|
||||
|
||||
update = result
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, 1, 3, u'connecting to repository' )
|
||||
|
||||
connection = service.GetConnection()
|
||||
|
||||
HC.pubsub.pub( 'progress_update', job_key, 2, 3, u'posting update' )
|
||||
|
||||
try: connection.Post( 'update', update = update )
|
||||
except Exception as e: raise Exception( 'Encountered an error while uploading tags:' + os.linesep + unicode( e ) )
|
||||
|
||||
HC.pubsub.pub( 'log_message', 'upload mappings', 'uploaded a tag update to ' + service_identifier.GetName() )
|
||||
|
||||
service_identfiers_to_content_updates = { service_identifier : update.GetContentUpdates( for_client = True ) }
|
||||
|
||||
|
||||
wx.GetApp().Write( 'content_updates', service_identfiers_to_content_updates )
|
||||
|
||||
except Exception as e:
|
||||
|
||||
|
@ -1317,8 +1302,8 @@ The password is cleartext here but obscured in the entry dialog. Enter a blank p
|
|||
|
||||
if service_type == HC.TAG_REPOSITORY:
|
||||
|
||||
num_pending = info[ HC.SERVICE_INFO_NUM_PENDING_MAPPINGS ]
|
||||
num_petitioned = info[ HC.SERVICE_INFO_NUM_PETITIONED_MAPPINGS ]
|
||||
num_pending = info[ HC.SERVICE_INFO_NUM_PENDING_MAPPINGS ] + info[ HC.SERVICE_INFO_NUM_PENDING_TAG_SIBLINGS ] + info[ HC.SERVICE_INFO_NUM_PENDING_TAG_PARENTS ]
|
||||
num_petitioned = info[ HC.SERVICE_INFO_NUM_PETITIONED_MAPPINGS ] + info[ HC.SERVICE_INFO_NUM_PETITIONED_TAG_SIBLINGS ] + info[ HC.SERVICE_INFO_NUM_PETITIONED_TAG_PARENTS ]
|
||||
|
||||
elif service_type == HC.FILE_REPOSITORY:
|
||||
|
||||
|
@ -2081,7 +2066,7 @@ class FrameReviewServicesServicePanel( wx.ScrolledWindow ):
|
|||
self._timer_updates.Start( 1000, wx.TIMER_CONTINUOUS )
|
||||
|
||||
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdate', 'service_update_gui' )
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdates', 'service_updates_gui' )
|
||||
HC.pubsub.sub( self, 'AddThumbnailCount', 'add_thumbnail_count' )
|
||||
|
||||
|
||||
|
@ -2317,20 +2302,24 @@ class FrameReviewServicesServicePanel( wx.ScrolledWindow ):
|
|||
self._updates_text.SetLabel( HC.ConvertIntToPrettyString( num_updates_downloaded ) + '/' + HC.ConvertIntToPrettyString( num_updates ) + ' - ' + self._service.GetUpdateStatus() )
|
||||
|
||||
|
||||
def ProcessServiceUpdate( self, update ):
|
||||
def ProcessServiceUpdates( self, service_identifiers_to_service_updates ):
|
||||
|
||||
service_identifier = update.GetServiceIdentifier()
|
||||
|
||||
if service_identifier == self._service_identifier:
|
||||
for ( service_identifier, service_updates ) in service_identifiers_to_service_updates.items():
|
||||
|
||||
action = update.GetAction()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_RESET: self._service_identifier = update.GetInfo()
|
||||
|
||||
if action in ( HC.SERVICE_UPDATE_ACCOUNT, HC.SERVICE_UPDATE_REQUEST_MADE ): wx.CallLater( 200, self._DisplayAccountInfo )
|
||||
else:
|
||||
wx.CallLater( 200, self._DisplayService )
|
||||
wx.CallLater( 400, self.Layout ) # ugly hack, but it works for now
|
||||
for service_update in service_updates:
|
||||
|
||||
if service_identifier == self._service_identifier:
|
||||
|
||||
( action, row ) = service_update.ToTuple()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_RESET: self._service_identifier = row
|
||||
|
||||
if action in ( HC.SERVICE_UPDATE_ACCOUNT, HC.SERVICE_UPDATE_REQUEST_MADE ): wx.CallLater( 600, self._DisplayAccountInfo )
|
||||
else:
|
||||
wx.CallLater( 200, self._DisplayService )
|
||||
wx.CallLater( 400, self.Layout ) # ugly hack, but it works for now
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -482,13 +482,25 @@ class CanvasPanel( Canvas, wx.Window ):
|
|||
if page_key == self._page_key: self.SetMedia( media )
|
||||
|
||||
|
||||
def ProcessContentUpdates( self, updates ):
|
||||
def ProcessContentUpdates( self, service_identifiers_to_content_updates ):
|
||||
|
||||
if self._current_display_media is not None:
|
||||
|
||||
my_hash = self._current_display_media.GetHash()
|
||||
|
||||
if True in ( my_hash in update.GetHashes() for update in updates ):
|
||||
do_redraw = False
|
||||
|
||||
for ( service_identifier, content_updates ) in service_identifiers_to_content_updates.items():
|
||||
|
||||
if True in ( my_hash in content_update.GetHashes() for content_update in content_updates ):
|
||||
|
||||
do_redraw = True
|
||||
|
||||
break
|
||||
|
||||
|
||||
|
||||
if do_redraw:
|
||||
|
||||
self._DrawBackgroundBitmap()
|
||||
|
||||
|
@ -937,13 +949,13 @@ class CanvasFullscreenMediaList( ClientGUIMixins.ListeningMediaList, Canvas, Cli
|
|||
|
||||
def KeepCursorAlive( self ): self._timer_cursor_hide.Start( 800, wx.TIMER_ONE_SHOT )
|
||||
|
||||
def ProcessContentUpdates( self, updates ):
|
||||
def ProcessContentUpdates( self, service_identifiers_to_content_updates ):
|
||||
|
||||
next_media = self._GetNext( self._current_media )
|
||||
|
||||
if next_media == self._current_media: next_media = None
|
||||
|
||||
ClientGUIMixins.ListeningMediaList.ProcessContentUpdates( self, updates )
|
||||
ClientGUIMixins.ListeningMediaList.ProcessContentUpdates( self, service_identifiers_to_content_updates )
|
||||
|
||||
if self.HasNoMedia(): self.EventClose( None )
|
||||
elif self.HasMedia( self._current_media ):
|
||||
|
@ -980,7 +992,7 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
|
|||
HC.pubsub.sub( self, 'AddMediaResult', 'add_media_result' )
|
||||
|
||||
|
||||
def _Archive( self ): wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( HC.CONTENT_UPDATE_ARCHIVE, HC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
|
||||
def _Archive( self ): wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPES_FILES, HC.CONTENT_UPDATE_ARCHIVE, ( self._current_media.GetHash(), ) ) ] } )
|
||||
|
||||
def _CopyLocalUrlToClipboard( self ):
|
||||
|
||||
|
@ -1012,13 +1024,13 @@ class CanvasFullscreenMediaListBrowser( CanvasFullscreenMediaList ):
|
|||
|
||||
with ClientGUIDialogs.DialogYesNo( self, 'Delete this file from the database?' ) as dlg:
|
||||
|
||||
if dlg.ShowModal() == wx.ID_YES: wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( HC.CONTENT_UPDATE_DELETE, HC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
|
||||
if dlg.ShowModal() == wx.ID_YES: wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPES_FILES, HC.CONTENT_UPDATE_DELETE, ( self._current_media.GetHash(), ) ) ] } )
|
||||
|
||||
|
||||
self.SetFocus() # annoying bug because of the modal dialog
|
||||
|
||||
|
||||
def _Inbox( self ): wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( HC.CONTENT_UPDATE_INBOX, HC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
|
||||
def _Inbox( self ): wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPES_FILES, HC.CONTENT_UPDATE_INBOX, ( self._current_media.GetHash(), ) ) ] } )
|
||||
|
||||
def _PausePlaySlideshow( self ):
|
||||
|
||||
|
@ -1258,7 +1270,7 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
HC.pubsub.sub( self, 'AddMediaResult', 'add_media_result' )
|
||||
|
||||
|
||||
def _Archive( self ): wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( HC.CONTENT_UPDATE_ARCHIVE, HC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
|
||||
def _Archive( self ): wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPES_FILES, HC.CONTENT_UPDATE_ARCHIVE, ( self._current_media.GetHash(), ) ) ] } )
|
||||
|
||||
def _CopyLocalUrlToClipboard( self ):
|
||||
|
||||
|
@ -1290,13 +1302,13 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
with ClientGUIDialogs.DialogYesNo( self, 'Delete this file from the database?' ) as dlg:
|
||||
|
||||
if dlg.ShowModal() == wx.ID_YES: wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( HC.CONTENT_UPDATE_DELETE, HC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
|
||||
if dlg.ShowModal() == wx.ID_YES: wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPES_FILES, HC.CONTENT_UPDATE_DELETE, ( self._current_media.GetHash(), ) ) ] } )
|
||||
|
||||
|
||||
self.SetFocus() # annoying bug because of the modal dialog
|
||||
|
||||
|
||||
def _Inbox( self ): wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( HC.CONTENT_UPDATE_INBOX, HC.LOCAL_FILE_SERVICE_IDENTIFIER, ( self._current_media.GetHash(), ) ) ] )
|
||||
def _Inbox( self ): wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPES_FILES, HC.CONTENT_UPDATE_INBOX, ( self._current_media.GetHash(), ) ) ] } )
|
||||
|
||||
def EventKeyDown( self, event ):
|
||||
|
||||
|
@ -1307,6 +1319,8 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
key_dict = self._actions[ modifier ]
|
||||
|
||||
hashes = set( ( self._current_media.GetHash(), ) )
|
||||
|
||||
if key in key_dict:
|
||||
|
||||
( service_identifier, action ) = key_dict[ key ]
|
||||
|
@ -1348,8 +1362,10 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
if service_type == HC.LOCAL_TAG:
|
||||
|
||||
if action in current: edit_log = [ ( HC.CONTENT_UPDATE_DELETE, action ) ]
|
||||
else: edit_log = [ ( HC.CONTENT_UPDATE_ADD, action ) ]
|
||||
if action in current: content_update_action = HC.CONTENT_UPDATE_DELETE
|
||||
else: content_update_action = HC.CONTENT_UPDATE_ADD
|
||||
|
||||
row = ( action, hashes )
|
||||
|
||||
else:
|
||||
|
||||
|
@ -1362,26 +1378,38 @@ class CanvasFullscreenMediaListCustomFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
with wx.TextEntryDialog( self, message ) as dlg:
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK: edit_log = [ ( HC.CONTENT_UPDATE_PETITION, ( action, dlg.GetValue() ) ) ]
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
|
||||
content_update_action = HC.CONTENT_UPDATE_PETITION
|
||||
|
||||
row = ( dlg.GetValue(), action, hashes )
|
||||
|
||||
else: return
|
||||
|
||||
|
||||
|
||||
else:
|
||||
|
||||
if action in pending: edit_log = [ ( HC.CONTENT_UPDATE_RESCIND_PENDING, action ) ]
|
||||
else: edit_log = [ ( HC.CONTENT_UPDATE_PENDING, action ) ]
|
||||
if action in pending: content_update_action = HC.CONTENT_UPDATE_RESCIND_PENDING
|
||||
else: content_update_action = HC.CONTENT_UPDATE_PENDING
|
||||
|
||||
row = ( action, hashes )
|
||||
|
||||
|
||||
|
||||
content_update = HC.ContentUpdate( HC.CONTENT_UPDATE_EDIT_LOG, service_identifier, ( self._current_media.GetHash(), ), info = edit_log )
|
||||
content_update = HC.ContentUpdate( HC.CONTENT_DATA_TYPES_MAPPINGS, content_update_action, row )
|
||||
|
||||
elif service_type in ( HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ):
|
||||
|
||||
content_update = HC.ContentUpdate( HC.CONTENT_UPDATE_RATING, service_identifier, ( self._current_media.GetHash(), ), info = action )
|
||||
# maybe this needs to be more complicated, if action is, say, remove the rating?
|
||||
# ratings needs a good look at anyway
|
||||
|
||||
row = ( action, hashes )
|
||||
|
||||
content_update = HC.ContentUpdate( HC.CONTENT_DATA_TYPES_RATINGS, HC.CONTENT_UPDATE_ADD, row )
|
||||
|
||||
|
||||
wx.GetApp().Write( 'content_updates', ( content_update, ) )
|
||||
wx.GetApp().Write( 'content_updates', { service_identifier : [ content_update ] } )
|
||||
|
||||
|
||||
else:
|
||||
|
@ -1597,10 +1625,10 @@ class CanvasFullscreenMediaListFilter( CanvasFullscreenMediaList ):
|
|||
|
||||
content_updates = []
|
||||
|
||||
content_updates.append( HC.ContentUpdate( HC.CONTENT_UPDATE_DELETE, HC.LOCAL_FILE_SERVICE_IDENTIFIER, self._deleted_hashes ) )
|
||||
content_updates.append( HC.ContentUpdate( HC.CONTENT_UPDATE_ARCHIVE, HC.LOCAL_FILE_SERVICE_IDENTIFIER, self._kept_hashes ) )
|
||||
content_updates.append( HC.ContentUpdate( HC.CONTENT_DATA_TYPES_FILES, HC.CONTENT_UPDATE_DELETE, self._deleted_hashes ) )
|
||||
content_updates.append( HC.ContentUpdate( HC.CONTENT_DATA_TYPES_FILES, HC.CONTENT_UPDATE_ARCHIVE, self._kept_hashes ) )
|
||||
|
||||
wx.GetApp().Write( 'content_updates', content_updates )
|
||||
wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : content_updates } )
|
||||
|
||||
self._kept = set()
|
||||
self._deleted = set()
|
||||
|
@ -1778,10 +1806,10 @@ class RatingsFilterFrameLike( CanvasFullscreenMediaListFilter ):
|
|||
|
||||
content_updates = []
|
||||
|
||||
content_updates.extend( [ HC.ContentUpdate( HC.CONTENT_UPDATE_RATING, self._rating_service_identifier, ( hash, ), info = 0.0 ) for hash in self._deleted_hashes ] )
|
||||
content_updates.extend( [ HC.ContentUpdate( HC.CONTENT_UPDATE_RATING, self._rating_service_identifier, ( hash, ), info = 1.0 ) for hash in self._kept_hashes ] )
|
||||
content_updates.extend( [ HC.ContentUpdate( HC.CONTENT_DATA_TYPES_RATINGS, HC.CONTENT_UPDATE_ADD, ( 0.0, set( ( hash, ) ) ) ) for hash in self._deleted_hashes ] )
|
||||
content_updates.extend( [ HC.ContentUpdate( HC.CONTENT_DATA_TYPES_RATINGS, HC.CONTENT_UPDATE_ADD, ( 1.0, set( ( hash, ) ) ) ) for hash in self._kept_hashes ] )
|
||||
|
||||
wx.GetApp().Write( 'content_updates', content_updates )
|
||||
wx.GetApp().Write( 'content_updates', { self._rating_service_identifier : content_updates } )
|
||||
|
||||
self._kept = set()
|
||||
self._deleted = set()
|
||||
|
@ -1917,7 +1945,7 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
self._ShowNewMedia()
|
||||
|
||||
HC.pubsub.sub( self, 'ProcessContentUpdates', 'content_updates_gui' )
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdate', 'service_update_gui' )
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdates', 'service_updates_gui' )
|
||||
|
||||
HC.pubsub.pub( 'set_focus', self._page_key, None )
|
||||
|
||||
|
@ -2357,8 +2385,8 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
|
||||
def normalise_rating( rating ): return round( rating / self._score_gap ) * self._score_gap
|
||||
|
||||
certain_ratings = [ ( media.GetHash(), normalise_rating( ( min + max ) / 2 ) ) for ( media, ( min, max ) ) in self._media_to_current_scores_dict.items() if max - min < self._score_gap ]
|
||||
uncertain_ratings = [ ( media.GetHash(), min, max ) for ( media, ( min, max ) ) in self._media_to_current_scores_dict.items() if max - min >= self._score_gap and self._media_to_current_scores_dict[ media ] != self._media_to_initial_scores_dict[ media ] ]
|
||||
certain_ratings = [ ( normalise_rating( ( min + max ) / 2 ), media.GetHash() ) for ( media, ( min, max ) ) in self._media_to_current_scores_dict.items() if max - min < self._score_gap ]
|
||||
uncertain_ratings = [ ( min, max, media.GetHash() ) for ( media, ( min, max ) ) in self._media_to_current_scores_dict.items() if max - min >= self._score_gap and self._media_to_current_scores_dict[ media ] != self._media_to_initial_scores_dict[ media ] ]
|
||||
|
||||
with ClientGUIDialogs.DialogFinishRatingFiltering( self, len( certain_ratings ), len( uncertain_ratings ) ) as dlg:
|
||||
|
||||
|
@ -2376,10 +2404,10 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
|
||||
content_updates = []
|
||||
|
||||
content_updates.extend( [ HC.ContentUpdate( HC.CONTENT_UPDATE_RATING, self._service_identifier, ( hash, ), info = rating ) for ( hash, rating ) in certain_ratings ] )
|
||||
content_updates.extend( [ HC.ContentUpdate( HC.CONTENT_UPDATE_RATINGS_FILTER, self._service_identifier, ( hash, ), info = ( min, max ) ) for ( hash, min, max ) in uncertain_ratings ] )
|
||||
content_updates.extend( [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_RATINGS, HC.CONTENT_UPDATE_ADD, ( rating, set( ( hash, ) ) ) ) for ( rating, hash ) in certain_ratings ] )
|
||||
content_updates.extend( [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_RATINGS, HC.CONTENT_UPDATE_RATINGS_FILTER, ( min, max, set( ( hash, ) ) ) ) for ( min, max, hash ) in uncertain_ratings ] )
|
||||
|
||||
wx.GetApp().Write( 'content_updates', content_updates )
|
||||
wx.GetApp().Write( 'content_updates', { self._service_identifier : content_updates } )
|
||||
|
||||
except: wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
|
@ -2448,21 +2476,24 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
wx.GetApp().Write( 'save_options' )
|
||||
|
||||
|
||||
def ProcessContentUpdates( self, content_updates ):
|
||||
def ProcessContentUpdates( self, service_identifiers_to_content_updates ):
|
||||
|
||||
redraw = False
|
||||
|
||||
my_hashes = self._file_query_result.GetHashes()
|
||||
|
||||
for content_update in content_updates:
|
||||
for ( service_identifier, content_updates ) in service_identifiers_to_content_updates.items():
|
||||
|
||||
content_update_hashes = content_update.GetHashes()
|
||||
|
||||
if len( my_hashes.intersection( content_update_hashes ) ) > 0:
|
||||
for content_update in content_updates:
|
||||
|
||||
redraw = True
|
||||
content_update_hashes = content_update.GetHashes()
|
||||
|
||||
break
|
||||
if len( my_hashes.intersection( content_update_hashes ) ) > 0:
|
||||
|
||||
redraw = True
|
||||
|
||||
break
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2473,7 +2504,7 @@ class RatingsFilterFrameNumerical( ClientGUICommon.Frame ):
|
|||
|
||||
|
||||
|
||||
def ProcessServiceUpdate( self, update ):
|
||||
def ProcessServiceUpdates( self, service_identifiers_to_service_updates ):
|
||||
|
||||
self._left_window.RefreshBackground()
|
||||
self._right_window.RefreshBackground()
|
||||
|
|
|
@ -2212,6 +2212,16 @@ class SaneListCtrl( wx.ListCtrl, ListCtrlAutoWidthMixin, ColumnSorterMixin ):
|
|||
|
||||
|
||||
|
||||
def GetIndexFromClientData( self, data ):
|
||||
|
||||
for index in range( self.GetItemCount() ):
|
||||
|
||||
if self.GetClientData( index ) == data: return index
|
||||
|
||||
|
||||
raise Exception( 'Data not found!' )
|
||||
|
||||
|
||||
def GetListCtrl( self ): return self
|
||||
|
||||
def RemoveAllSelected( self ):
|
||||
|
@ -3182,10 +3192,16 @@ class TagsBoxManage( TagsBox ):
|
|||
|
||||
for tag in all_tags:
|
||||
|
||||
if tag in self._petitioned_tags: tag_string = '(-) ' + tag
|
||||
elif tag in self._current_tags: tag_string = tag
|
||||
elif tag in self._pending_tags: tag_string = '(+) ' + tag
|
||||
else: tag_string = '(X) ' + tag
|
||||
if tag in self._petitioned_tags: prefix = HC.ConvertStatusToPrefix( HC.PETITIONED )
|
||||
elif tag in self._current_tags: prefix = HC.ConvertStatusToPrefix( HC.CURRENT )
|
||||
elif tag in self._pending_tags:
|
||||
|
||||
if tag in self._deleted_tags: prefix = HC.ConvertStatusToPrefix( HC.DELETED_PENDING )
|
||||
else: prefix = HC.ConvertStatusToPrefix( HC.PENDING )
|
||||
|
||||
else: prefix = HC.ConvertStatusToPrefix( HC.DELETED )
|
||||
|
||||
tag_string = prefix + ' ' + tag
|
||||
|
||||
sibling = siblings_manager.GetSibling( tag )
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -631,7 +631,7 @@ class ManagementPanelDumper( ManagementPanel ):
|
|||
|
||||
for ( service_identifier, namespaces ) in advanced_tag_options.items():
|
||||
|
||||
tags = media.GetTagsManager()
|
||||
tags_manager = media.GetTagsManager()
|
||||
|
||||
current = tags_manager.GetCurrent( service_identifier )
|
||||
pending = tags_manager.GetPending( service_identifier )
|
||||
|
@ -1697,9 +1697,9 @@ class ManagementPanelImportWithQueueAdvanced( ManagementPanelImportWithQueue ):
|
|||
|
||||
service_identifiers_to_tags = HydrusDownloading.ConvertTagsToServiceIdentifiersToTags( tags, advanced_tag_options )
|
||||
|
||||
content_updates = HydrusDownloading.ConvertServiceIdentifiersToTagsToContentUpdates( hash, service_identifiers_to_tags )
|
||||
content_updates = HydrusDownloading.ConvertServiceIdentifiersToTagsToServiceIdentifiersToContentUpdates( hash, service_identifiers_to_tags )
|
||||
|
||||
wx.GetApp().WriteDaemon( 'content_updates', content_updates )
|
||||
wx.GetApp().WriteDaemon( 'content_updates', service_identifiers_to_content_updates )
|
||||
|
||||
|
||||
HC.pubsub.pub( 'import_done', self._page_key, 'redundant' )
|
||||
|
@ -2380,11 +2380,13 @@ class ManagementPanelImportThreadWatcher( ManagementPanelImport ):
|
|||
|
||||
class ManagementPanelPetitions( ManagementPanel ):
|
||||
|
||||
def __init__( self, parent, page, page_key, file_service_identifier ):
|
||||
def __init__( self, parent, page, page_key, file_service_identifier, petition_service_identifier ):
|
||||
|
||||
self._petition_service_identifier = petition_service_identifier
|
||||
|
||||
ManagementPanel.__init__( self, parent, page, page_key, file_service_identifier )
|
||||
|
||||
self._service = wx.GetApp().Read( 'service', file_service_identifier )
|
||||
self._service = wx.GetApp().Read( 'service', self._petition_service_identifier )
|
||||
self._can_ban = self._service.GetAccount().HasPermission( HC.MANAGE_USERS )
|
||||
|
||||
self._num_petitions = None
|
||||
|
@ -2476,7 +2478,7 @@ class ManagementPanelPetitions( ManagementPanel ):
|
|||
|
||||
search_context = CC.FileSearchContext( self._file_service_identifier )
|
||||
|
||||
with wx.BusyCursor(): file_query_result = wx.GetApp().Read( 'media_results', search_context, self._current_petition.GetPetitionHashes() )
|
||||
with wx.BusyCursor(): file_query_result = wx.GetApp().Read( 'media_results', search_context, self._current_petition.GetHashes() )
|
||||
|
||||
panel = ClientGUIMedia.MediaPanelThumbnails( self._page, self._page_key, self._file_service_identifier, [], file_query_result )
|
||||
|
||||
|
@ -2498,26 +2500,13 @@ class ManagementPanelPetitions( ManagementPanel ):
|
|||
|
||||
def EventApprove( self, event ):
|
||||
|
||||
update = self._current_petition.GetApproval()
|
||||
|
||||
connection = self._service.GetConnection()
|
||||
|
||||
petition_object = self._current_petition.GetClientPetition()
|
||||
connection.Post( 'update', update = update )
|
||||
|
||||
connection.Post( 'petitions', petitions = petition_object )
|
||||
|
||||
if isinstance( self._current_petition, HC.ServerFilePetition ):
|
||||
|
||||
hashes = self._current_petition.GetPetitionHashes()
|
||||
|
||||
content_updates = [ HC.ContentUpdate( HC.CONTENT_UPDATE_DELETE, self._file_service_identifier, hashes ) ]
|
||||
|
||||
elif isinstance( self._current_petition, HC.ServerMappingPetition ):
|
||||
|
||||
( reason, tag, hashes ) = self._current_petition.GetPetitionInfo()
|
||||
|
||||
content_updates = [ HC.ContentUpdate( HC.CONTENT_UPDATE_DELETE, self._file_service_identifier, hashes, tag ) ]
|
||||
|
||||
|
||||
wx.GetApp().WriteDaemon( 'content_updates', content_updates )
|
||||
wx.GetApp().WriteDaemon( 'content_updates', { self._petition_service_identifier : update.GetContentUpdates( for_client = True ) } )
|
||||
|
||||
self._current_petition = None
|
||||
|
||||
|
@ -2528,12 +2517,11 @@ class ManagementPanelPetitions( ManagementPanel ):
|
|||
|
||||
def EventDeny( self, event ):
|
||||
|
||||
update = self._current_petition.GetDenial()
|
||||
|
||||
connection = self._service.GetConnection()
|
||||
|
||||
petition_object = self._current_petition.GetClientPetitionDenial()
|
||||
|
||||
# needs work
|
||||
connection.Post( 'petition_denial', petition_denial = petition_object )
|
||||
connection.Post( 'update', update = update )
|
||||
|
||||
self._current_petition = None
|
||||
|
||||
|
@ -2564,7 +2552,7 @@ class ManagementPanelPetitions( ManagementPanel ):
|
|||
|
||||
def EventModifyPetitioner( self, event ):
|
||||
|
||||
with ClientGUIDialogs.DialogModifyAccounts( self, self._file_service_identifier, ( self._current_petition.GetPetitionerIdentifier(), ) ) as dlg: dlg.ShowModal()
|
||||
with ClientGUIDialogs.DialogModifyAccounts( self, self._petition_service_identifier, ( self._current_petition.GetPetitionerIdentifier(), ) ) as dlg: dlg.ShowModal()
|
||||
|
||||
|
||||
def EventRefreshNumPetitions( self, event ):
|
||||
|
|
|
@ -96,7 +96,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
hashes = self._GetSelectedHashes( CC.DISCRIMINANT_INBOX )
|
||||
|
||||
if len( hashes ) > 0: wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( HC.CONTENT_UPDATE_ARCHIVE, HC.LOCAL_FILE_SERVICE_IDENTIFIER, hashes ) ] )
|
||||
if len( hashes ) > 0: wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_ARCHIVE, hashes ) ] } )
|
||||
|
||||
|
||||
def _CopyHashToClipboard( self ):
|
||||
|
@ -189,7 +189,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
if dlg.ShowModal() == wx.ID_YES:
|
||||
|
||||
try: wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( HC.CONTENT_UPDATE_DELETE, file_service_identifier, hashes ) ] )
|
||||
try: wx.GetApp().Write( 'content_updates', { file_service_identifier : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_DELETE, hashes ) ] } )
|
||||
except: wx.MessageBox( traceback.format_exc() )
|
||||
|
||||
|
||||
|
@ -199,7 +199,11 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
hashes = self._GetSelectedHashes()
|
||||
|
||||
wx.GetApp().Write( 'petition_files', file_service_identifier, hashes, 'admin' )
|
||||
content_update = HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_PETITION, ( hashes, 'admin' ) )
|
||||
|
||||
service_identifiers_to_content_updates = { file_service_identifier : ( content_update, ) }
|
||||
|
||||
wx.GetApp().Write( 'content_updates', service_identifiers_to_content_updates )
|
||||
|
||||
|
||||
|
||||
|
@ -299,7 +303,14 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
|
||||
|
||||
def _GetSelectedHashes( self, discriminant = None, not_uploaded_to = None ): return HC.IntelligentMassUnion( ( media.GetHashes( discriminant, not_uploaded_to ) for media in self._selected_media ) )
|
||||
def _GetSelectedHashes( self, discriminant = None, not_uploaded_to = None ):
|
||||
|
||||
result = set()
|
||||
|
||||
for media in self._selected_media: result.update( media.GetHashes( discriminant, not_uploaded_to ) )
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _GetSimilarTo( self ):
|
||||
|
||||
|
@ -366,7 +377,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
hashes = self._GetSelectedHashes( CC.DISCRIMINANT_ARCHIVE )
|
||||
|
||||
if len( hashes ) > 0: wx.GetApp().Write( 'content_updates', [ HC.ContentUpdate( HC.CONTENT_UPDATE_INBOX, HC.LOCAL_FILE_SERVICE_IDENTIFIER, hashes ) ] )
|
||||
if len( hashes ) > 0: wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_INBOX, hashes ) ] } )
|
||||
|
||||
|
||||
def _ManageRatings( self ):
|
||||
|
@ -444,7 +455,14 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
with wx.TextEntryDialog( self, message ) as dlg:
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK: wx.GetApp().Write( 'petition_files', file_service_identifier, hashes, dlg.GetValue() )
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
|
||||
content_update = HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_PETITION, ( hashes, dlg.GetValue() ) )
|
||||
|
||||
service_identifiers_to_content_updates = { file_service_identifier : ( content_update, ) }
|
||||
|
||||
wx.GetApp().Write( 'content_updates', service_identifiers_to_content_updates )
|
||||
|
||||
|
||||
|
||||
self.SetFocus()
|
||||
|
@ -574,7 +592,7 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
if hashes is not None and len( hashes ) > 0:
|
||||
|
||||
try: wx.GetApp().Write( 'add_uploads', file_service_identifier, hashes )
|
||||
try: wx.GetApp().Write( 'content_updates', { file_service_identifier : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_PENDING, hashes ) ] } )
|
||||
except Exception as e: wx.MessageBox( unicode( e ) )
|
||||
|
||||
|
||||
|
@ -638,25 +656,26 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
|
||||
|
||||
|
||||
def ProcessContentUpdates( self, content_updates ):
|
||||
def ProcessContentUpdates( self, service_identifiers_to_content_updates ):
|
||||
|
||||
ClientGUIMixins.ListeningMediaList.ProcessContentUpdates( self, content_updates )
|
||||
ClientGUIMixins.ListeningMediaList.ProcessContentUpdates( self, service_identifiers_to_content_updates )
|
||||
|
||||
for content_update in content_updates:
|
||||
|
||||
service_identifier = content_update.GetServiceIdentifier()
|
||||
for ( service_identifier, content_updates ) in service_identifiers_to_content_updates.items():
|
||||
|
||||
service_type = service_identifier.GetType()
|
||||
|
||||
hashes = content_update.GetHashes()
|
||||
|
||||
affected_media = self._GetMedia( hashes )
|
||||
|
||||
action = content_update.GetAction()
|
||||
|
||||
if action == HC.CONTENT_UPDATE_DELETE and service_type in ( HC.FILE_REPOSITORY, HC.LOCAL_FILE ) and self._focussed_media in affected_media: self._SetFocussedMedia( None )
|
||||
|
||||
if len( affected_media ) > 0: self._ReblitMedia( affected_media )
|
||||
for content_update in content_updates:
|
||||
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
hashes = content_update.GetHashes()
|
||||
|
||||
affected_media = self._GetMedia( hashes )
|
||||
|
||||
if action == HC.CONTENT_UPDATE_DELETE and service_type in ( HC.FILE_REPOSITORY, HC.LOCAL_FILE ) and self._focussed_media in affected_media: self._SetFocussedMedia( None )
|
||||
|
||||
if len( affected_media ) > 0: self._ReblitMedia( affected_media )
|
||||
|
||||
|
||||
|
||||
self._PublishSelectionChange()
|
||||
|
@ -664,22 +683,26 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
|
|||
if self._focussed_media is not None: self._HitMedia( self._focussed_media, False, False )
|
||||
|
||||
|
||||
def ProcessServiceUpdate( self, update ):
|
||||
def ProcessServiceUpdates( self, service_identifiers_to_service_updates ):
|
||||
|
||||
ClientGUIMixins.ListeningMediaList.ProcessServiceUpdate( self, update )
|
||||
ClientGUIMixins.ListeningMediaList.ProcessServiceUpdates( self, service_identifiers_to_service_updates )
|
||||
|
||||
action = update.GetAction()
|
||||
|
||||
service_identifier = update.GetServiceIdentifier()
|
||||
|
||||
if action in ( HC.SERVICE_UPDATE_DELETE_PENDING, HC.SERVICE_UPDATE_RESET ):
|
||||
for ( service_identifier, service_updates ) in service_identifiers_to_service_updates.items():
|
||||
|
||||
self._RefitCanvas()
|
||||
for service_update in service_updates:
|
||||
|
||||
( action, row ) = service_update.ToTuple()
|
||||
|
||||
if action in ( HC.SERVICE_UPDATE_DELETE_PENDING, HC.SERVICE_UPDATE_RESET ):
|
||||
|
||||
self._RefitCanvas()
|
||||
|
||||
self._ReblitCanvas()
|
||||
|
||||
|
||||
self._PublishSelectionChange()
|
||||
|
||||
|
||||
self._ReblitCanvas()
|
||||
|
||||
|
||||
self._PublishSelectionChange()
|
||||
|
||||
|
||||
def SetFocussedMedia( self, page_key, media ):
|
||||
|
@ -1102,7 +1125,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
elif command == 'custom_filter': self._CustomFilter()
|
||||
elif command == 'delete': self._Delete( data )
|
||||
elif command == 'deselect': self._DeselectAll()
|
||||
elif command == 'download': wx.GetApp().Write( 'add_downloads', data, self._GetSelectedHashes( CC.DISCRIMINANT_NOT_LOCAL ) )
|
||||
elif command == 'download': wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_PENDING, self._GetSelectedHashes( CC.DISCRIMINANT_NOT_LOCAL ) ) ] } )
|
||||
elif command == 'export': self._ExportFiles()
|
||||
elif command == 'export special': self._ExportFilesSpecial()
|
||||
elif command == 'filter': self._Filter()
|
||||
|
@ -1145,7 +1168,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
if t is not None:
|
||||
|
||||
if t.GetFileServiceIdentifiersCDPP().HasLocal(): self._FullScreen( t )
|
||||
elif self._file_service_identifier != HC.COMBINED_FILE_SERVICE_IDENTIFIER: wx.GetApp().Write( 'add_downloads', self._file_service_identifier, t.GetHashes() )
|
||||
elif self._file_service_identifier != HC.COMBINED_FILE_SERVICE_IDENTIFIER: wx.GetApp().Write( 'content_updates', { HC.LOCAL_FILE_SERVICE_IDENTIFIER : [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_FILES, HC.CONTENT_UPDATE_PENDING, t.GetHashes() ) ] } )
|
||||
|
||||
|
||||
|
||||
|
@ -1249,7 +1272,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
petitioned_phrase = 'all petitioned from'
|
||||
deleted_phrase = 'all deleted from'
|
||||
|
||||
download_phrase = 'download all possible from'
|
||||
download_phrase = 'download all possible'
|
||||
upload_phrase = 'upload all possible to'
|
||||
petition_phrase = 'petition all possible for removal from'
|
||||
remote_delete_phrase = 'delete all possible from'
|
||||
|
@ -1274,7 +1297,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
petitioned_phrase = 'petitioned from'
|
||||
deleted_phrase = 'deleted from'
|
||||
|
||||
download_phrase = 'download from'
|
||||
download_phrase = 'download'
|
||||
upload_phrase = 'upload to'
|
||||
petition_phrase = 'petition for removal from'
|
||||
remote_delete_phrase = 'delete from'
|
||||
|
@ -1295,29 +1318,31 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
# info about the files
|
||||
|
||||
def MassUnion( lists ): return { item for item in itertools.chain.from_iterable( lists ) }
|
||||
|
||||
all_current_file_service_identifiers = [ service_identifiers.GetCurrentRemote() for service_identifiers in all_service_identifiers ]
|
||||
|
||||
current_file_service_identifiers = HC.IntelligentMassIntersect( all_current_file_service_identifiers )
|
||||
|
||||
some_current_file_service_identifiers = HC.IntelligentMassUnion( all_current_file_service_identifiers ) - current_file_service_identifiers
|
||||
some_current_file_service_identifiers = MassUnion( all_current_file_service_identifiers ) - current_file_service_identifiers
|
||||
|
||||
all_pending_file_service_identifiers = [ service_identifiers.GetPendingRemote() for service_identifiers in all_service_identifiers ]
|
||||
|
||||
pending_file_service_identifiers = HC.IntelligentMassIntersect( all_pending_file_service_identifiers )
|
||||
|
||||
some_pending_file_service_identifiers = HC.IntelligentMassUnion( all_pending_file_service_identifiers ) - pending_file_service_identifiers
|
||||
some_pending_file_service_identifiers = MassUnion( all_pending_file_service_identifiers ) - pending_file_service_identifiers
|
||||
|
||||
all_petitioned_file_service_identifiers = [ service_identifiers.GetPetitionedRemote() for service_identifiers in all_service_identifiers ]
|
||||
|
||||
petitioned_file_service_identifiers = HC.IntelligentMassIntersect( all_petitioned_file_service_identifiers )
|
||||
|
||||
some_petitioned_file_service_identifiers = HC.IntelligentMassUnion( all_petitioned_file_service_identifiers ) - petitioned_file_service_identifiers
|
||||
some_petitioned_file_service_identifiers = MassUnion( all_petitioned_file_service_identifiers ) - petitioned_file_service_identifiers
|
||||
|
||||
all_deleted_file_service_identifiers = [ service_identifiers.GetDeletedRemote() for service_identifiers in all_service_identifiers ]
|
||||
|
||||
deleted_file_service_identifiers = HC.IntelligentMassIntersect( all_deleted_file_service_identifiers )
|
||||
|
||||
some_deleted_file_service_identifiers = HC.IntelligentMassUnion( all_deleted_file_service_identifiers ) - deleted_file_service_identifiers
|
||||
some_deleted_file_service_identifiers = MassUnion( all_deleted_file_service_identifiers ) - deleted_file_service_identifiers
|
||||
|
||||
# valid commands for the files
|
||||
|
||||
|
@ -1396,7 +1421,7 @@ class MediaPanelThumbnails( MediaPanel ):
|
|||
|
||||
if len( selection_downloadable_file_service_identifiers ) > 0 or len( selection_uploadable_file_service_identifiers ) > 0 or len( selection_petitionable_file_service_identifiers ) > 0 or len( selection_deletable_file_service_identifiers ) > 0 or len( selection_modifyable_file_service_identifiers ) > 0:
|
||||
|
||||
if len( selection_downloadable_file_service_identifiers ) > 0: AddFileServiceIdentifiersToMenu( menu, selection_downloadable_file_service_identifiers, download_phrase, 'download' )
|
||||
if len( selection_downloadable_file_service_identifiers ) > 0: menu.Append( CC.MENU_EVENT_ID_TO_ACTION_CACHE.GetId( 'download' ), download_phrase )
|
||||
|
||||
if len( selection_uploadable_file_service_identifiers ) > 0: AddFileServiceIdentifiersToMenu( menu, selection_uploadable_file_service_identifiers, upload_phrase, 'upload' )
|
||||
|
||||
|
@ -1958,13 +1983,20 @@ class ThumbnailMediaCollection( Thumbnail, ClientGUIMixins.MediaCollection ):
|
|||
Thumbnail.__init__( self, file_service_identifier )
|
||||
|
||||
|
||||
def ProcessContentUpdate( self, content_update ):
|
||||
def ProcessContentUpdate( self, service_identifier, content_update ):
|
||||
|
||||
ClientGUIMixins.MediaCollection.ProcessContentUpdate( self, content_update )
|
||||
ClientGUIMixins.MediaCollection.ProcessContentUpdate( self, service_identifier, content_update )
|
||||
|
||||
if content_update.GetAction() == HC.CONTENT_UPDATE_ADD and content_update.GetServiceIdentifier() == HC.LOCAL_FILE_SERVICE_IDENTIFIER:
|
||||
if service_identifier == HC.LOCAL_FILE_SERVICE_IDENTIFIER:
|
||||
|
||||
if self.GetDisplayMedia() in self._GetMedia( content_update.GetHashes() ): self.ReloadFromDB()
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ADD:
|
||||
|
||||
hashes = row
|
||||
|
||||
if self.GetDisplayMedia().GetHash() in hashes: self.ReloadFromDB()
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1976,10 +2008,15 @@ class ThumbnailMediaSingleton( Thumbnail, ClientGUIMixins.MediaSingleton ):
|
|||
Thumbnail.__init__( self, file_service_identifier )
|
||||
|
||||
|
||||
def ProcessContentUpdate( self, content_update ):
|
||||
def ProcessContentUpdate( self, servce_identifier, content_update ):
|
||||
|
||||
ClientGUIMixins.MediaSingleton.ProcessContentUpdate( self, content_update )
|
||||
ClientGUIMixins.MediaSingleton.ProcessContentUpdate( self, service_identifier, content_update )
|
||||
|
||||
if content_update.GetAction() == HC.CONTENT_UPDATE_ADD and content_update.GetServiceIdentifier() == HC.LOCAL_FILE_SERVICE_IDENTIFIER: self.ReloadFromDB()
|
||||
if service_identifier == HC.LOCAL_FILE_SERVICE_IDENTIFIER:
|
||||
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ADD: self.ReloadFromDB()
|
||||
|
||||
|
||||
|
|
@ -36,7 +36,14 @@ class MediaList():
|
|||
|
||||
def _GetFirst( self ): return self._sorted_media[ 0 ]
|
||||
|
||||
def _GetHashes( self ): return HC.IntelligentMassUnion( [ media.GetHashes() for media in self._sorted_media ] )
|
||||
def _GetHashes( self ):
|
||||
|
||||
result = set()
|
||||
|
||||
for media in self._sorted_media: result.update( media.GetHashes() )
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _GetLast( self ): return self._sorted_media[ -1 ]
|
||||
|
||||
|
@ -217,19 +224,37 @@ class MediaList():
|
|||
|
||||
def HasNoMedia( self ): return len( self._sorted_media ) == 0
|
||||
|
||||
def ProcessContentUpdate( self, content_update ):
|
||||
def ProcessContentUpdate( self, service_identifier, content_update ):
|
||||
|
||||
action = content_update.GetAction()
|
||||
|
||||
service_identifier = content_update.GetServiceIdentifier()
|
||||
( data_type, action, row ) = content_update.ToTuple()
|
||||
|
||||
hashes = content_update.GetHashes()
|
||||
|
||||
for media in self._GetMedia( hashes, 'collections' ): media.ProcessContentUpdate( content_update )
|
||||
for media in self._GetMedia( hashes, 'collections' ): media.ProcessContentUpdate( service_identifier, content_update )
|
||||
|
||||
if action == HC.CONTENT_UPDATE_ARCHIVE:
|
||||
if data_type == HC.CONTENT_DATA_TYPE_FILES:
|
||||
|
||||
if HC.SYSTEM_PREDICATE_INBOX in self._predicates:
|
||||
if action == HC.CONTENT_UPDATE_ARCHIVE:
|
||||
|
||||
if HC.SYSTEM_PREDICATE_INBOX in self._predicates:
|
||||
|
||||
affected_singleton_media = self._GetMedia( hashes, 'singletons' )
|
||||
affected_collected_media = [ media for media in self._collected_media if media.HasNoMedia() ]
|
||||
|
||||
self._RemoveMedia( affected_singleton_media, affected_collected_media )
|
||||
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_INBOX:
|
||||
|
||||
if HC.SYSTEM_PREDICATE_ARCHIVE in self._predicates:
|
||||
|
||||
affected_singleton_media = self._GetMedia( hashes, 'singletons' )
|
||||
affected_collected_media = [ media for media in self._collected_media if media.HasNoMedia() ]
|
||||
|
||||
self._RemoveMedia( affected_singleton_media, affected_collected_media )
|
||||
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_DELETE and service_identifier == self._file_service_identifier:
|
||||
|
||||
affected_singleton_media = self._GetMedia( hashes, 'singletons' )
|
||||
affected_collected_media = [ media for media in self._collected_media if media.HasNoMedia() ]
|
||||
|
@ -237,38 +262,28 @@ class MediaList():
|
|||
self._RemoveMedia( affected_singleton_media, affected_collected_media )
|
||||
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_INBOX:
|
||||
|
||||
|
||||
def ProcessContentUpdates( self, service_identifiers_to_content_updates ):
|
||||
|
||||
for ( service_identifier, content_updates ) in service_identifiers_to_content_updates.items():
|
||||
|
||||
if HC.SYSTEM_PREDICATE_ARCHIVE in self._predicates:
|
||||
|
||||
affected_singleton_media = self._GetMedia( hashes, 'singletons' )
|
||||
affected_collected_media = [ media for media in self._collected_media if media.HasNoMedia() ]
|
||||
|
||||
self._RemoveMedia( affected_singleton_media, affected_collected_media )
|
||||
|
||||
|
||||
elif action == HC.CONTENT_UPDATE_DELETE and service_identifier == self._file_service_identifier:
|
||||
|
||||
affected_singleton_media = self._GetMedia( hashes, 'singletons' )
|
||||
affected_collected_media = [ media for media in self._collected_media if media.HasNoMedia() ]
|
||||
|
||||
self._RemoveMedia( affected_singleton_media, affected_collected_media )
|
||||
for content_update in content_updates: self.ProcessContentUpdate( service_identifier, content_update )
|
||||
|
||||
|
||||
|
||||
def ProcessContentUpdates( self, content_updates ):
|
||||
def ProcessServiceUpdates( self, service_identifiers_to_service_updates ):
|
||||
|
||||
for content_update in content_updates: self.ProcessContentUpdate( content_update )
|
||||
|
||||
|
||||
def ProcessServiceUpdate( self, update ):
|
||||
|
||||
action = update.GetAction()
|
||||
|
||||
service_identifier = update.GetServiceIdentifier()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_DELETE_PENDING: self.DeletePending( service_identifier )
|
||||
elif action == HC.SERVICE_UPDATE_RESET: self.ResetService( service_identifier )
|
||||
for ( service_identifier, service_updates ) in service_identifiers_to_service_updates.items():
|
||||
|
||||
for service_update in service_updates:
|
||||
|
||||
( action, row ) = service_update.ToTuple()
|
||||
|
||||
if action == HC.SERVICE_UPDATE_DELETE_PENDING: self.DeletePending( service_identifier )
|
||||
elif action == HC.SERVICE_UPDATE_RESET: self.ResetService( service_identifier )
|
||||
|
||||
|
||||
|
||||
|
||||
def ResetService( self, service_identifier ):
|
||||
|
@ -387,7 +402,7 @@ class ListeningMediaList( MediaList ):
|
|||
MediaList.__init__( self, *args )
|
||||
|
||||
HC.pubsub.sub( self, 'ProcessContentUpdates', 'content_updates_gui' )
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdate', 'service_update_gui' )
|
||||
HC.pubsub.sub( self, 'ProcessServiceUpdates', 'service_updates_gui' )
|
||||
|
||||
|
||||
class MediaCollection( MediaList, Media ):
|
||||
|
@ -422,7 +437,9 @@ class MediaCollection( MediaList, Media ):
|
|||
|
||||
def _RecalcInternals( self ):
|
||||
|
||||
self._hashes = HC.IntelligentMassUnion( [ media.GetHashes() for media in self._sorted_media ] )
|
||||
self._hashes = set()
|
||||
|
||||
for media in self._sorted_media: self._hashes.update( media.GetHashes() )
|
||||
|
||||
self._archive = True in ( media.HasArchive() for media in self._sorted_media )
|
||||
self._inbox = True in ( media.HasInbox() for media in self._sorted_media )
|
||||
|
@ -472,7 +489,14 @@ class MediaCollection( MediaList, Media ):
|
|||
def GetHashes( self, discriminant = None, not_uploaded_to = None ):
|
||||
|
||||
if discriminant is None and not_uploaded_to is None: return self._hashes
|
||||
else: return HC.IntelligentMassUnion( [ media.GetHashes( discriminant, not_uploaded_to ) for media in self._sorted_media ] )
|
||||
else:
|
||||
|
||||
result = set()
|
||||
|
||||
for media in self._sorted_media: result.update( media.GetHashes( discriminant, not_uploaded_to ) )
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def GetHashes( self, discriminant = None, not_uploaded_to = None ):
|
||||
|
@ -546,9 +570,9 @@ class MediaCollection( MediaList, Media ):
|
|||
|
||||
def IsSizeDefinite( self ): return self._size_definite
|
||||
|
||||
def ProcessContentUpdate( self, content_update ):
|
||||
def ProcessContentUpdate( self, service_identifier, content_update ):
|
||||
|
||||
MediaList.ProcessContentUpdate( self, content_update )
|
||||
MediaList.ProcessContentUpdate( self, service_identifier, content_update )
|
||||
|
||||
self._RecalcInternals()
|
||||
|
||||
|
@ -615,7 +639,7 @@ class MediaSingleton( Media ):
|
|||
|
||||
def GetPrettyInfo( self ):
|
||||
|
||||
( hash, inbox, size, mime, timestamp, width, height, duration, num_frames, num_words, tags_manager, file_service_identifiers, local_ratings, remote_ratings ) = self._media_result.GetInfo()
|
||||
( hash, inbox, size, mime, timestamp, width, height, duration, num_frames, num_words, tags_manager, file_service_identifiers, local_ratings, remote_ratings ) = self._media_result.ToTuple()
|
||||
|
||||
info_string = HC.ConvertIntToBytes( size ) + ' ' + HC.mime_string_lookup[ mime ]
|
||||
|
||||
|
|
|
@ -354,7 +354,19 @@ class PageImportURL( PageImport ):
|
|||
|
||||
class PagePetitions( PageWithMedia ):
|
||||
|
||||
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelPetitions( self._search_preview_split, self, self._page_key, self._file_service_identifier )
|
||||
def __init__( self, parent, petition_service_identifier ):
|
||||
|
||||
self._petition_service_identifier = petition_service_identifier
|
||||
|
||||
petition_service_type = petition_service_identifier.GetType()
|
||||
|
||||
if petition_service_type in ( HC.LOCAL_FILE, HC.FILE_REPOSITORY ): self._file_service_identifier = self._petition_service_identifier
|
||||
else: self._file_service_identifier = HC.COMBINED_FILE_SERVICE_IDENTIFIER
|
||||
|
||||
PageWithMedia.__init__( self, parent, self._file_service_identifier )
|
||||
|
||||
|
||||
def _InitManagementPanel( self ): self._management_panel = ClientGUIManagement.ManagementPanelPetitions( self._search_preview_split, self, self._page_key, self._file_service_identifier, self._petition_service_identifier )
|
||||
|
||||
def _InitMediaPanel( self ): self._media_panel = ClientGUIMedia.MediaPanelNoQuery( self, self._page_key, self._file_service_identifier )
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import collections
|
||||
import httplib
|
||||
import HydrusPubSub
|
||||
import itertools
|
||||
import locale
|
||||
import os
|
||||
import Queue
|
||||
|
@ -29,8 +30,8 @@ TEMP_DIR = BASE_DIR + os.path.sep + 'temp'
|
|||
|
||||
# Misc
|
||||
|
||||
NETWORK_VERSION = 9
|
||||
SOFTWARE_VERSION = 71
|
||||
NETWORK_VERSION = 10
|
||||
SOFTWARE_VERSION = 72
|
||||
|
||||
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )
|
||||
|
||||
|
@ -46,6 +47,12 @@ repos_or_subs_changed = False
|
|||
|
||||
# Enums
|
||||
|
||||
CONTENT_DATA_TYPE_MAPPINGS = 0
|
||||
CONTENT_DATA_TYPE_TAG_SIBLINGS = 1
|
||||
CONTENT_DATA_TYPE_TAG_PARENTS = 2
|
||||
CONTENT_DATA_TYPE_FILES = 3
|
||||
CONTENT_DATA_TYPE_RATINGS = 4
|
||||
|
||||
CONTENT_UPDATE_ADD = 0
|
||||
CONTENT_UPDATE_DELETE = 1
|
||||
CONTENT_UPDATE_PENDING = 2
|
||||
|
@ -57,6 +64,8 @@ CONTENT_UPDATE_ARCHIVE = 7
|
|||
CONTENT_UPDATE_INBOX = 8
|
||||
CONTENT_UPDATE_RATING = 9
|
||||
CONTENT_UPDATE_RATINGS_FILTER = 10
|
||||
CONTENT_UPDATE_DENY_PEND = 11
|
||||
CONTENT_UPDATE_DENY_PETITION = 12
|
||||
|
||||
GET_DATA = 0
|
||||
POST_DATA = 1
|
||||
|
@ -103,7 +112,7 @@ service_string_lookup[ SERVER_ADMIN ] = 'hydrus server administration'
|
|||
|
||||
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 ]
|
||||
RESTRICTED_SERVICES = ( REPOSITORIES ) + [ SERVER_ADMIN, MESSAGE_DEPOT ]
|
||||
REMOTE_SERVICES = list( RESTRICTED_SERVICES )
|
||||
ALL_SERVICES = list( REMOTE_SERVICES ) + [ LOCAL_FILE, LOCAL_TAG, LOCAL_RATING_LIKE, LOCAL_RATING_NUMERICAL ]
|
||||
|
||||
|
@ -148,6 +157,10 @@ SERVICE_INFO_NUM_PENDING_MAPPINGS = 15
|
|||
SERVICE_INFO_NUM_PETITIONED_MAPPINGS = 16
|
||||
SERVICE_INFO_NUM_PENDING_FILES = 15
|
||||
SERVICE_INFO_NUM_PETITIONED_FILES = 16
|
||||
SERVICE_INFO_NUM_PENDING_TAG_SIBLINGS = 17
|
||||
SERVICE_INFO_NUM_PETITIONED_TAG_SIBLINGS = 18
|
||||
SERVICE_INFO_NUM_PENDING_TAG_PARENTS = 19
|
||||
SERVICE_INFO_NUM_PETITIONED_TAG_PARENTS = 20
|
||||
|
||||
SERVICE_UPDATE_ACCOUNT = 0
|
||||
SERVICE_UPDATE_DELETE_PENDING = 1
|
||||
|
@ -156,6 +169,7 @@ SERVICE_UPDATE_NEXT_BEGIN = 3
|
|||
SERVICE_UPDATE_RESET = 4
|
||||
SERVICE_UPDATE_REQUEST_MADE = 5
|
||||
SERVICE_UPDATE_LAST_CHECK = 6
|
||||
SERVICE_UPDATE_NEWS = 7
|
||||
|
||||
ADD = 0
|
||||
DELETE = 1
|
||||
|
@ -412,8 +426,7 @@ repository_requests.append( ( GET, 'num_petitions', RESOLVE_PETITIONS ) )
|
|||
repository_requests.append( ( GET, 'petition', RESOLVE_PETITIONS ) )
|
||||
repository_requests.append( ( GET, 'update', GET_DATA ) )
|
||||
repository_requests.append( ( POST, 'news', GENERAL_ADMIN ) )
|
||||
repository_requests.append( ( POST, 'petition_denial', RESOLVE_PETITIONS ) )
|
||||
repository_requests.append( ( POST, 'petitions', ( POST_PETITIONS, RESOLVE_PETITIONS ) ) )
|
||||
repository_requests.append( ( POST, 'update', POST_DATA ) )
|
||||
|
||||
file_repository_requests = list( repository_requests )
|
||||
file_repository_requests.append( ( GET, 'file', GET_DATA ) )
|
||||
|
@ -422,7 +435,6 @@ file_repository_requests.append( ( GET, 'thumbnail', GET_DATA ) )
|
|||
file_repository_requests.append( ( POST, 'file', POST_DATA ) )
|
||||
|
||||
tag_repository_requests = list( repository_requests )
|
||||
tag_repository_requests.append( ( POST, 'mappings', POST_DATA ) )
|
||||
|
||||
message_depot_requests = list( restricted_requests )
|
||||
message_depot_requests.append( ( GET, 'message', GET_DATA ) )
|
||||
|
@ -476,6 +488,10 @@ DEFAULT_OPTIONS[ MESSAGE_DEPOT ][ 'message' ] = 'hydrus message depot'
|
|||
EVT_PUBSUB = HydrusPubSub.EVT_PUBSUB
|
||||
pubsub = HydrusPubSub.HydrusPubSub()
|
||||
|
||||
def default_dict_list(): return collections.defaultdict( list )
|
||||
|
||||
def default_dict_set(): return collections.defaultdict( set )
|
||||
|
||||
def BuildKeyToListDict( pairs ):
|
||||
|
||||
d = collections.defaultdict( list )
|
||||
|
@ -633,6 +649,14 @@ def ConvertShortcutToPrettyShortcut( modifier, key, action ):
|
|||
|
||||
return ( modifier, key, action )
|
||||
|
||||
def ConvertStatusToPrefix( status ):
|
||||
|
||||
if status == CURRENT: return ''
|
||||
elif status == PENDING: return '(+)'
|
||||
elif status == PETITIONED: return '(-)'
|
||||
elif status == DELETED: return '(X)'
|
||||
elif status == DELETED_PENDING: return '(X+)'
|
||||
|
||||
def ConvertTimestampToPrettyAge( timestamp ):
|
||||
|
||||
if timestamp == 0 or timestamp is None: return 'unknown age'
|
||||
|
@ -895,6 +919,12 @@ def ConvertZoomToPercentage( zoom ):
|
|||
|
||||
return pretty_zoom
|
||||
|
||||
def GetEmptyDataDict():
|
||||
|
||||
data = collections.defaultdict( default_dict_list )
|
||||
|
||||
return data
|
||||
|
||||
def GetMimeFromPath( filename ):
|
||||
|
||||
f = open( filename, 'rb' )
|
||||
|
@ -943,21 +973,6 @@ def GetShortcutFromEvent( event ):
|
|||
|
||||
return ( modifier, key )
|
||||
|
||||
def IntelligentMassUnion( iterables_to_reduce ):
|
||||
|
||||
# while I might usually go |= here (for style), it is quicker to use the ugly .update when we want to be quick
|
||||
# set.update also converts the second argument to a set, if appropriate!
|
||||
|
||||
#return reduce( set.union, iterables_to_reduce, set() )
|
||||
|
||||
# also: reduce is slower, I think, cause of union rather than update!
|
||||
|
||||
answer = set()
|
||||
|
||||
for i in iterables_to_reduce: answer.update( i )
|
||||
|
||||
return answer
|
||||
|
||||
def IntelligentMassIntersect( sets_to_reduce ):
|
||||
|
||||
answer = None
|
||||
|
@ -986,6 +1001,17 @@ def IsCollection( mime ): return mime in ( APPLICATION_HYDRUS_CLIENT_COLLECTION,
|
|||
|
||||
def IsImage( mime ): return mime in ( IMAGE_JPEG, IMAGE_GIF, IMAGE_PNG, IMAGE_BMP )
|
||||
|
||||
def MergeKeyToListDicts( key_to_list_dicts ):
|
||||
|
||||
result = collections.defaultdict( list )
|
||||
|
||||
for key_to_list_dict in key_to_list_dicts:
|
||||
|
||||
for ( key, value ) in key_to_list_dict.items(): result[ key ].extend( value )
|
||||
|
||||
|
||||
return result
|
||||
|
||||
def SearchEntryMatchesPredicate( search_entry, predicate ):
|
||||
|
||||
( predicate_type, info ) = predicate.GetInfo()
|
||||
|
@ -1194,7 +1220,7 @@ class AdvancedHTTPConnection():
|
|||
|
||||
if server_header is None or service_string not in server_header:
|
||||
|
||||
pubsub.pub( 'service_update_db', ServiceUpdate( SERVICE_UPDATE_ACCOUNT, self._service_identifier, GetUnknownAccount() ) )
|
||||
wx.GetApp().Write( 'service_updates', { self._service_identifier : [ ServiceUpdate( SERVICE_UPDATE_ACCOUNT, GetUnknownAccount() ) ] })
|
||||
|
||||
raise WrongServiceTypeException( 'Target was not a ' + service_string + '!' )
|
||||
|
||||
|
@ -1206,9 +1232,9 @@ class AdvancedHTTPConnection():
|
|||
|
||||
if request_type == 'GET':
|
||||
|
||||
if ( service_type, GET, request_command ) in BANDWIDTH_CONSUMING_REQUESTS: pubsub.pub( 'service_update_db', ServiceUpdate( SERVICE_UPDATE_REQUEST_MADE, self._service_identifier, len( raw_response ) ) )
|
||||
if ( service_type, GET, request_command ) in BANDWIDTH_CONSUMING_REQUESTS: pubsub.pub( 'service_updates_delayed', { self._service_identifier : [ ServiceUpdate( SERVICE_UPDATE_REQUEST_MADE, len( raw_response ) ) ] } )
|
||||
|
||||
elif ( service_type, POST, request_command ) in BANDWIDTH_CONSUMING_REQUESTS: pubsub.pub( 'service_update_db', ServiceUpdate( SERVICE_UPDATE_REQUEST_MADE, self._service_identifier, len( body ) ) )
|
||||
elif ( service_type, POST, request_command ) in BANDWIDTH_CONSUMING_REQUESTS: pubsub.pub( 'service_updates_delayed', { self._service_identifier : [ ServiceUpdate( SERVICE_UPDATE_REQUEST_MADE, len( body ) ) ] } )
|
||||
|
||||
|
||||
if response.status == 200: return parsed_response
|
||||
|
@ -1264,9 +1290,9 @@ class AdvancedHTTPConnection():
|
|||
|
||||
if self._service_identifier is not None:
|
||||
|
||||
pubsub.pub( 'service_update_db', ServiceUpdate( SERVICE_UPDATE_ERROR, self._service_identifier, parsed_response ) )
|
||||
wx.GetApp().Write( 'service_updates', { self._service_identifier : [ ServiceUpdate( SERVICE_UPDATE_ERROR, parsed_response ) ] } )
|
||||
|
||||
if response.status in ( 401, 426 ): pubsub.pub( 'service_update_db', ServiceUpdate( SERVICE_UPDATE_ACCOUNT, self._service_identifier, GetUnknownAccount() ) )
|
||||
if response.status in ( 401, 426 ): wx.GetApp().Write( 'service_updates', { self._service_identifier : [ ServiceUpdate( SERVICE_UPDATE_ACCOUNT, GetUnknownAccount() ) ] } )
|
||||
|
||||
|
||||
if response.status == 401: raise PermissionsException( parsed_response )
|
||||
|
@ -1511,92 +1537,10 @@ class AccountType( HydrusYAMLBase ):
|
|||
|
||||
def HasPermission( self, permission ): return permission in self._permissions
|
||||
|
||||
class ClientFilePetitionDenial( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ClientFilePetitionDenial'
|
||||
|
||||
def __init__( self, hashes ):
|
||||
|
||||
HydrusYAMLBase.__init__( self )
|
||||
|
||||
self._hashes = hashes
|
||||
|
||||
|
||||
def GetInfo( self ): return self._hashes
|
||||
|
||||
class ClientFilePetitions( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ClientFilePetitions'
|
||||
|
||||
def __init__( self, petitions ):
|
||||
|
||||
HydrusYAMLBase.__init__( self )
|
||||
|
||||
self._petitions = petitions
|
||||
|
||||
|
||||
def __iter__( self ): return ( petition for petition in self._petitions )
|
||||
|
||||
def __len__( self ): return len( self._petitions )
|
||||
|
||||
def GetHashes( self ): return IntelligentMassUnion( [ hashes for ( reason, hashes ) in self._petitions ] )
|
||||
|
||||
class ClientMappingPetitionDenial( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ClientMappingPetitionDenial'
|
||||
|
||||
def __init__( self, tag, hashes ):
|
||||
|
||||
HydrusYAMLBase.__init__( self )
|
||||
|
||||
self._tag = tag
|
||||
self._hashes = hashes
|
||||
|
||||
|
||||
def GetInfo( self ): return ( self._tag, self._hashes )
|
||||
|
||||
class ClientMappingPetitions( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ClientMappingPetitions'
|
||||
|
||||
def __init__( self, petitions, hash_ids_to_hashes ):
|
||||
|
||||
HydrusYAMLBase.__init__( self )
|
||||
|
||||
self._petitions = petitions
|
||||
|
||||
self._hash_ids_to_hashes = hash_ids_to_hashes
|
||||
|
||||
|
||||
def __iter__( self ): return ( ( reason, tag, [ self._hash_ids_to_hashes[ hash_id ] for hash_id in hash_ids ] ) for ( reason, tag, hash_ids ) in self._petitions )
|
||||
|
||||
def __len__( self ): return len( self._petitions )
|
||||
|
||||
def GetHashes( self ): return self._hash_ids_to_hashes.values()
|
||||
|
||||
def GetTags( self ): return [ tag for ( reason, tag, hash_ids ) in self._petitions ]
|
||||
|
||||
class ClientMappings( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ClientMappings'
|
||||
|
||||
def __init__( self, mappings, hash_ids_to_hashes ):
|
||||
|
||||
HydrusYAMLBase.__init__( self )
|
||||
|
||||
self._mappings = mappings
|
||||
|
||||
self._hash_ids_to_hashes = hash_ids_to_hashes
|
||||
|
||||
|
||||
def __iter__( self ): return ( ( tag, [ self._hash_ids_to_hashes[ hash_id ] for hash_id in hash_ids ] ) for ( tag, hash_ids ) in self._mappings )
|
||||
|
||||
def __len__( self ): return len( self._mappings )
|
||||
|
||||
def GetHashes( self ): return self._hash_ids_to_hashes.values()
|
||||
|
||||
def GetTags( self ): return [ tag for ( tag, hash_ids ) in self._mappings ]
|
||||
|
||||
UNKNOWN_ACCOUNT_TYPE = AccountType( 'unknown account', [], ( None, None ) )
|
||||
|
||||
def GetUnknownAccount(): return Account( 0, UNKNOWN_ACCOUNT_TYPE, 0, None, ( 0, 0 ) )
|
||||
|
||||
class ClientServiceIdentifier( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ClientServiceIdentifier'
|
||||
|
@ -1630,23 +1574,147 @@ COMBINED_FILE_SERVICE_IDENTIFIER = ClientServiceIdentifier( 'all known files', C
|
|||
COMBINED_TAG_SERVICE_IDENTIFIER = ClientServiceIdentifier( 'all known tags', COMBINED_TAG, 'all known tags' )
|
||||
NULL_SERVICE_IDENTIFIER = ClientServiceIdentifier( '', NULL_SERVICE, 'no service' )
|
||||
|
||||
class ClientToServerUpdate( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ClientToServerUpdate'
|
||||
|
||||
def __init__( self, content_data, hash_ids_to_hashes ):
|
||||
|
||||
HydrusYAMLBase.__init__( self )
|
||||
|
||||
# we need to flatten it from a collections.defaultdict to just a normal dict so it can be YAMLised
|
||||
|
||||
self._content_data = {}
|
||||
|
||||
for data_type in content_data:
|
||||
|
||||
self._content_data[ data_type ] = {}
|
||||
|
||||
for action in content_data[ data_type ]: self._content_data[ data_type ][ action ] = content_data[ data_type ][ action ]
|
||||
|
||||
|
||||
self._hash_ids_to_hashes = hash_ids_to_hashes
|
||||
|
||||
|
||||
def GetContentUpdates( self, for_client = False ):
|
||||
|
||||
data_types = [ CONTENT_DATA_TYPE_FILES, CONTENT_DATA_TYPE_MAPPINGS, CONTENT_DATA_TYPE_TAG_SIBLINGS, CONTENT_DATA_TYPE_TAG_PARENTS ]
|
||||
actions = [ CONTENT_UPDATE_PENDING, CONTENT_UPDATE_PETITION, CONTENT_UPDATE_DENY_PEND, CONTENT_UPDATE_DENY_PETITION ]
|
||||
|
||||
content_updates = []
|
||||
|
||||
for ( data_type, action ) in itertools.product( data_types, actions ):
|
||||
|
||||
munge_row = lambda row: row
|
||||
|
||||
if for_client:
|
||||
|
||||
if action == CONTENT_UPDATE_PENDING: new_action = CONTENT_UPDATE_ADD
|
||||
elif action == CONTENT_UPDATE_PETITION: new_action = CONTENT_UPDATE_DELETE
|
||||
else: continue
|
||||
|
||||
if data_type in ( CONTENT_DATA_TYPE_TAG_SIBLINGS, CONTENT_DATA_TYPE_TAG_PARENTS ) and action in ( CONTENT_UPDATE_PENDING, CONTENT_UPDATE_PETITION ):
|
||||
|
||||
munge_row = lambda ( pair, reason ): pair
|
||||
|
||||
elif data_type == CONTENT_DATA_TYPE_FILES and action == CONTENT_UPDATE_PETITION:
|
||||
|
||||
munge_row = lambda ( hashes, reason ): hashes
|
||||
|
||||
elif data_type == CONTENT_DATA_TYPE_MAPPINGS and action == CONTENT_UPDATE_PETITION:
|
||||
|
||||
munge_row = lambda ( tag, hashes, reason ): ( tag, hashes )
|
||||
|
||||
|
||||
else: new_action = action
|
||||
|
||||
content_updates.extend( [ ContentUpdate( data_type, new_action, munge_row( row ) ) for row in self.GetContentDataIterator( data_type, action ) ] )
|
||||
|
||||
|
||||
return content_updates
|
||||
|
||||
|
||||
def GetHashes( self ): return self._hash_ids_to_hashes.values()
|
||||
|
||||
def GetContentDataIterator( self, data_type, action ):
|
||||
|
||||
if data_type not in self._content_data or action not in self._content_data[ data_type ]: return ()
|
||||
|
||||
data = self._content_data[ data_type ][ action ]
|
||||
|
||||
if data_type == CONTENT_DATA_TYPE_FILES:
|
||||
|
||||
if action == CONTENT_UPDATE_PETITION: return ( ( { self._hash_ids_to_hashes[ hash_id ] for hash_id in hash_ids }, reason ) for ( hash_ids, reason ) in data )
|
||||
else: return ( { self._hash_ids_to_hashes[ hash_id ] for hash_id in hash_ids } for hash_ids in ( data, ) )
|
||||
|
||||
if data_type == CONTENT_DATA_TYPE_MAPPINGS:
|
||||
|
||||
if action == CONTENT_UPDATE_PETITION: return ( ( tag, [ self._hash_ids_to_hashes[ hash_id ] for hash_id in hash_ids ], reason ) for ( tag, hash_ids, reason ) in data )
|
||||
else: return ( ( tag, [ self._hash_ids_to_hashes[ hash_id ] for hash_id in hash_ids ] ) for ( tag, hash_ids ) in data )
|
||||
|
||||
else: return data.__iter__()
|
||||
|
||||
|
||||
def GetTags( self ):
|
||||
|
||||
tags = set()
|
||||
|
||||
try: tags.update( ( tag for ( tag, hash_ids ) in self._content_data[ CONTENT_DATA_TYPE_MAPPINGS ][ CONTENT_UPDATE_PENDING ] ) )
|
||||
except: pass
|
||||
|
||||
try: tags.update( ( tag for ( tag, hash_ids, reason ) in self._content_data[ CONTENT_DATA_TYPE_MAPPINGS ][ CONTENT_UPDATE_PETITION ] ) )
|
||||
except: pass
|
||||
|
||||
return tags
|
||||
|
||||
|
||||
def IsEmpty( self ):
|
||||
|
||||
num_total = 0
|
||||
|
||||
for data_type in self._content_data:
|
||||
|
||||
for action in self._content_data[ data_type ]: num_total += len( self._content_data[ data_type ][ action ] )
|
||||
|
||||
|
||||
return num_total == 0
|
||||
|
||||
|
||||
class ContentUpdate():
|
||||
|
||||
def __init__( self, action, service_identifier, hashes, info = None ):
|
||||
def __init__( self, data_type, action, row ):
|
||||
|
||||
self._data_type = data_type
|
||||
self._action = action
|
||||
self._service_identifier = service_identifier
|
||||
self._hashes = set( hashes )
|
||||
self._info = info
|
||||
self._row = row
|
||||
|
||||
|
||||
def GetAction( self ): return self._action
|
||||
def GetHashes( self ):
|
||||
|
||||
if self._data_type == CONTENT_DATA_TYPE_FILES:
|
||||
|
||||
if self._action == CONTENT_UPDATE_ADD:
|
||||
|
||||
hash = self._row[0]
|
||||
|
||||
hashes = set( ( hash, ) )
|
||||
|
||||
elif self._action in ( CONTENT_UPDATE_ARCHIVE, CONTENT_UPDATE_DELETE, CONTENT_UPDATE_INBOX, CONTENT_UPDATE_PENDING, CONTENT_UPDATE_RESCIND_PENDING, CONTENT_UPDATE_RESCIND_PETITION ): hashes = self._row
|
||||
elif self._action == CONTENT_UPDATE_PETITION: ( hashes, reason ) = self._row
|
||||
|
||||
elif self._data_type == CONTENT_DATA_TYPE_MAPPINGS:
|
||||
|
||||
if self._action == CONTENT_UPDATE_PETITION: ( tag, hashes, reason ) = self._row
|
||||
else: ( tag, hashes ) = self._row
|
||||
|
||||
elif self._data_type in ( CONTENT_DATA_TYPE_TAG_PARENTS, CONTENT_DATA_TYPE_TAG_SIBLINGS ): hashes = set()
|
||||
|
||||
if type( hashes ) != set: hashes = set( hashes )
|
||||
|
||||
return hashes
|
||||
|
||||
|
||||
def GetHashes( self ): return self._hashes
|
||||
|
||||
def GetInfo( self ): return self._info
|
||||
|
||||
def GetServiceIdentifier( self ): return self._service_identifier
|
||||
def ToTuple( self ): return ( self._data_type, self._action, self._row )
|
||||
|
||||
class DAEMON( threading.Thread ):
|
||||
|
||||
|
@ -1739,103 +1807,6 @@ class DAEMONWorker( DAEMON ):
|
|||
|
||||
def set( self, *args, **kwargs ): self._event.set()
|
||||
|
||||
class HydrusUpdate( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!HydrusUpdate'
|
||||
|
||||
def __init__( self, news, begin, end ):
|
||||
|
||||
HydrusYAMLBase.__init__( self )
|
||||
|
||||
self._news = news
|
||||
|
||||
self._begin = begin
|
||||
self._end = end
|
||||
|
||||
|
||||
def GetBegin( self ): return self._begin
|
||||
|
||||
def GetEnd( self ): return self._end
|
||||
|
||||
def GetNextBegin( self ): return self._end + 1
|
||||
|
||||
def GetNews( self ): return [ ( news, timestamp ) for ( news, timestamp ) in self._news ]
|
||||
|
||||
def SplitIntoSubUpdates( self ): return [ self ]
|
||||
|
||||
class HydrusUpdateFileRepository( HydrusUpdate ):
|
||||
|
||||
yaml_tag = u'!HydrusUpdateFileRepository'
|
||||
|
||||
def __init__( self, files, deleted_hashes, news, begin, end ):
|
||||
|
||||
HydrusUpdate.__init__( self, news, begin, end )
|
||||
|
||||
self._files = files
|
||||
self._deleted_hashes = deleted_hashes
|
||||
|
||||
|
||||
def GetDeletedHashes( self ): return self._deleted_hashes
|
||||
|
||||
def GetFiles( self ): return self._files
|
||||
|
||||
def GetHashes( self ): return [ hash for ( hash, size, mime, timestamp, width, height, duration, num_frames, num_words ) in self._files ]
|
||||
|
||||
class HydrusUpdateTagRepository( HydrusUpdate ):
|
||||
|
||||
yaml_tag = u'!HydrusUpdateTagRepository'
|
||||
|
||||
def __init__( self, mappings, deleted_mappings, hash_ids_to_hashes, news, begin, end ):
|
||||
|
||||
HydrusUpdate.__init__( self, news, begin, end )
|
||||
|
||||
self._hash_ids_to_hashes = hash_ids_to_hashes
|
||||
|
||||
self._mappings = mappings
|
||||
self._deleted_mappings = deleted_mappings
|
||||
|
||||
|
||||
def GetDeletedMappings( self ): return ( ( tag, [ self._hash_ids_to_hashes[ hash_id ] for hash_id in hash_ids ] ) for ( tag, hash_ids ) in self._deleted_mappings )
|
||||
|
||||
def GetMappings( self ): return ( ( tag, [ self._hash_ids_to_hashes[ hash_id ] for hash_id in hash_ids ] ) for ( tag, hash_ids ) in self._mappings )
|
||||
|
||||
def GetTags( self ): return [ tag for ( tag, hash_ids ) in self._mappings ]
|
||||
|
||||
def SplitIntoSubUpdates( self ):
|
||||
|
||||
updates = [ HydrusUpdateTagRepository( [], [], {}, self._news, self._begin, None ) ]
|
||||
|
||||
total_mappings = sum( [ len( hashes ) for ( tag, hashes ) in self._mappings ] )
|
||||
|
||||
total_tags = len( self._mappings )
|
||||
|
||||
number_updates_to_make = total_mappings / 500
|
||||
|
||||
if number_updates_to_make == 0: number_updates_to_make = 1
|
||||
|
||||
int_to_split_by = total_tags / number_updates_to_make
|
||||
|
||||
if int_to_split_by == 0: int_to_split_by = 1
|
||||
|
||||
for i in range( 0, len( self._mappings ), int_to_split_by ):
|
||||
|
||||
mappings_subset = self._mappings[ i : i + int_to_split_by ]
|
||||
|
||||
updates.append( HydrusUpdateTagRepository( mappings_subset, [], self._hash_ids_to_hashes, [], self._begin, None ) )
|
||||
|
||||
|
||||
for i in range( 0, len( self._deleted_mappings ), int_to_split_by ):
|
||||
|
||||
deleted_mappings_subset = self._deleted_mappings[ i : i + int_to_split_by ]
|
||||
|
||||
updates.append( HydrusUpdateTagRepository( [], deleted_mappings_subset, self._hash_ids_to_hashes, [], self._begin, None ) )
|
||||
|
||||
|
||||
updates.append( HydrusUpdateTagRepository( [], [], {}, [], self._begin, self._end ) )
|
||||
|
||||
return updates
|
||||
|
||||
|
||||
class JobInternal():
|
||||
|
||||
yaml_tag = u'!JobInternal'
|
||||
|
@ -2157,74 +2128,7 @@ class ResponseContext():
|
|||
def HasBody( self ): return self._body != ''
|
||||
|
||||
def HasFilename( self ): return self._filename is not None
|
||||
|
||||
class ServerPetition( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ServerPetition'
|
||||
|
||||
def __init__( self, petitioner_identifier ):
|
||||
|
||||
HydrusYAMLBase.__init__( self )
|
||||
|
||||
self._petitioner_identifier = petitioner_identifier
|
||||
|
||||
|
||||
def GetPetitionerIdentifier( self ): return self._petitioner_identifier
|
||||
|
||||
class ServerFilePetition( ServerPetition ):
|
||||
|
||||
yaml_tag = u'!ServerFilePetition'
|
||||
|
||||
def __init__( self, petitioner_identifier, reason, hashes ):
|
||||
|
||||
ServerPetition.__init__( self, petitioner_identifier )
|
||||
|
||||
self._reason = reason
|
||||
self._hashes = hashes
|
||||
|
||||
|
||||
def GetClientPetition( self ): return ClientFilePetitions( [ ( self._reason, self._hashes ) ] )
|
||||
|
||||
def GetClientPetitionDenial( self ): return ClientFilePetitionDenial( self._hashes )
|
||||
|
||||
def GetPetitionHashes( self ): return self._hashes
|
||||
|
||||
def GetPetitionInfo( self ): return ( self._reason, self._hashes )
|
||||
|
||||
def GetPetitionInfoDenial( self ): return ( self._hashes, )
|
||||
|
||||
def GetPetitionString( self ): return 'For ' + ConvertIntToPrettyString( len( self._hashes ) ) + ' files:' + os.linesep + os.linesep + self._reason
|
||||
|
||||
class ServerMappingPetition( ServerPetition ):
|
||||
|
||||
yaml_tag = u'!ServerMappingPetition'
|
||||
|
||||
def __init__( self, petitioner_identifier, reason, tag, hashes ):
|
||||
|
||||
ServerPetition.__init__( self, petitioner_identifier )
|
||||
|
||||
self._reason = reason
|
||||
self._tag = tag
|
||||
self._hashes = hashes
|
||||
|
||||
|
||||
def GetClientPetition( self ):
|
||||
|
||||
hash_ids_to_hashes = { enum : hash for ( enum, hash ) in enumerate( self._hashes ) }
|
||||
|
||||
hash_ids = hash_ids_to_hashes.keys()
|
||||
|
||||
return ClientMappingPetitions( [ ( self._reason, self._tag, hash_ids ) ], hash_ids_to_hashes )
|
||||
|
||||
|
||||
def GetClientPetitionDenial( self ): return ClientMappingPetitionDenial( self._tag, self._hashes )
|
||||
|
||||
def GetPetitionHashes( self ): return self._hashes
|
||||
|
||||
def GetPetitionInfo( self ): return ( self._reason, self._tag, self._hashes )
|
||||
|
||||
def GetPetitionString( self ): return 'Tag: ' + self._tag + ' for ' + ConvertIntToPrettyString( len( self._hashes ) ) + ' files.' + os.linesep + os.linesep + 'Reason: ' + self._reason
|
||||
|
||||
|
||||
class ServerServiceIdentifier( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ServerServiceIdentifier'
|
||||
|
@ -2249,18 +2153,229 @@ class ServerServiceIdentifier( HydrusYAMLBase ):
|
|||
|
||||
class ServiceUpdate():
|
||||
|
||||
def __init__( self, action, service_identifier, info = None ):
|
||||
def __init__( self, action, row = None ):
|
||||
|
||||
self._action = action # make this an enumerated thing, yo
|
||||
self._service_identifier = service_identifier
|
||||
self._info = info
|
||||
self._action = action
|
||||
self._row = row
|
||||
|
||||
|
||||
def GetAction( self ): return self._action
|
||||
def ToTuple( self ): return ( self._action, self._row )
|
||||
|
||||
class ServerToClientPetition( HydrusYAMLBase ):
|
||||
|
||||
def GetInfo( self ): return self._info
|
||||
yaml_tag = u'!ServerToClientPetition'
|
||||
|
||||
def GetServiceIdentifier( self ): return self._service_identifier
|
||||
def __init__( self, petition_type, action, petitioner_account_identifier, petition_data, reason ):
|
||||
|
||||
HydrusYAMLBase.__init__( self )
|
||||
|
||||
self._petition_type = petition_type
|
||||
self._action = action
|
||||
self._petitioner_account_identifier = petitioner_account_identifier
|
||||
self._petition_data = petition_data
|
||||
self._reason = reason
|
||||
|
||||
|
||||
def GetApproval( self, reason = None ):
|
||||
|
||||
if reason is None: reason = self._reason
|
||||
|
||||
if self._petition_type == CONTENT_DATA_TYPE_FILES: hashes = self._petition_data
|
||||
elif self._petition_type == CONTENT_DATA_TYPE_MAPPINGS: ( tag, hashes ) = self._petition_data
|
||||
else: hashes = set()
|
||||
|
||||
hash_ids_to_hashes = dict( enumerate( hashes ) )
|
||||
|
||||
hash_ids = hash_ids_to_hashes.keys()
|
||||
|
||||
content_data = GetEmptyDataDict()
|
||||
|
||||
if self._petition_type == CONTENT_DATA_TYPE_FILES: row = ( hash_ids, reason )
|
||||
elif self._petition_type == CONTENT_DATA_TYPE_MAPPINGS: row = ( tag, hash_ids, reason )
|
||||
else:
|
||||
|
||||
( old, new ) = self._petition_data
|
||||
|
||||
row = ( ( old, new ), reason )
|
||||
|
||||
|
||||
content_data[ self._petition_type ][ self._action ].append( row )
|
||||
|
||||
return ClientToServerUpdate( content_data, hash_ids_to_hashes )
|
||||
|
||||
|
||||
def GetDenial( self ):
|
||||
|
||||
if self._petition_type == CONTENT_DATA_TYPE_FILES: hashes = self._petition_data
|
||||
elif self._petition_type == CONTENT_DATA_TYPE_MAPPINGS: ( tag, hashes ) = self._petition_data
|
||||
else: hashes = set()
|
||||
|
||||
hash_ids_to_hashes = dict( enumerate( hashes ) )
|
||||
|
||||
hash_ids = hash_ids_to_hashes.keys()
|
||||
|
||||
if self._petition_type == CONTENT_DATA_TYPE_FILES: row_list = hash_ids
|
||||
elif self._petition_type == CONTENT_DATA_TYPE_MAPPINGS: row_list = [ ( tag, hash_ids ) ]
|
||||
else: row_list = [ self._petition_data ]
|
||||
|
||||
content_data = GetEmptyDataDict()
|
||||
|
||||
if self._action == CONTENT_UPDATE_PENDING: denial_action = CONTENT_UPDATE_DENY_PEND
|
||||
elif self._action == CONTENT_UPDATE_PETITION: denial_action = CONTENT_UPDATE_DENY_PETITION
|
||||
|
||||
content_data[ self._petition_type ][ denial_action ] = row_list
|
||||
|
||||
return ClientToServerUpdate( content_data, hash_ids_to_hashes )
|
||||
|
||||
|
||||
def GetHashes( self ):
|
||||
|
||||
if self._petition_type == CONTENT_DATA_TYPE_FILES: hashes = self._petition_data
|
||||
elif self._petition_type == CONTENT_DATA_TYPE_MAPPINGS: ( tag, hashes ) = self._petition_data
|
||||
else: hashes = set()
|
||||
|
||||
return hashes
|
||||
|
||||
|
||||
def GetPetitioner( self ): return self._petitioner_account_identifier
|
||||
|
||||
def GetPetitionString( self ):
|
||||
|
||||
if self._action == CONTENT_UPDATE_PENDING: action_word = 'Add '
|
||||
elif self._action == CONTENT_UPDATE_PETITION: action_word = 'Remove '
|
||||
|
||||
if self._petition_type == CONTENT_DATA_TYPE_FILES:
|
||||
|
||||
hashes = self._petition_data
|
||||
|
||||
content_phrase = ConvertIntToPrettyString( len( hashes ) ) + ' files'
|
||||
|
||||
elif self._petition_type == CONTENT_DATA_TYPE_MAPPINGS:
|
||||
|
||||
( tag, hashes ) = self._petition_data
|
||||
|
||||
content_phrase = tag + ' for ' + ConvertIntToPrettyString( len( hashes ) ) + ' files'
|
||||
|
||||
elif self._petition_type == CONTENT_DATA_TYPE_TAG_SIBLINGS:
|
||||
|
||||
( old_tag, new_tag ) = self._petition_data
|
||||
|
||||
content_phrase = ' sibling ' + old_tag + '->' + new_tag
|
||||
|
||||
elif self._petition_type == CONTENT_DATA_TYPE_TAG_PARENTS:
|
||||
|
||||
( old_tag, new_tag ) = self._petition_data
|
||||
|
||||
content_phrase = ' parent ' + old_tag + '->' + new_tag
|
||||
|
||||
|
||||
return action_word + content_phrase + os.linesep + os.linesep + self._reason
|
||||
|
||||
|
||||
class ServerToClientUpdate( HydrusYAMLBase ):
|
||||
|
||||
yaml_tag = u'!ServerToClientUpdate'
|
||||
|
||||
def __init__( self, service_data, content_data, hash_ids_to_hashes ):
|
||||
|
||||
HydrusYAMLBase.__init__( self )
|
||||
|
||||
self._service_data = service_data
|
||||
|
||||
self._content_data = {}
|
||||
|
||||
for data_type in content_data:
|
||||
|
||||
self._content_data[ data_type ] = {}
|
||||
|
||||
for action in content_data[ data_type ]: self._content_data[ data_type ][ action ] = content_data[ data_type ][ action ]
|
||||
|
||||
|
||||
self._hash_ids_to_hashes = hash_ids_to_hashes
|
||||
|
||||
|
||||
def _GetContentData( data_type, action ):
|
||||
|
||||
if data_type in self._content_data and action in self._content_data[ data_type ]: return self._content_data[ data_type ][ action ]
|
||||
else: return []
|
||||
|
||||
|
||||
def GetContentDataIterator( self, data_type, action ):
|
||||
|
||||
if data_type not in self._content_data or action not in self._content_data[ data_type ]: return ()
|
||||
|
||||
data = self._content_data[ data_type ][ action ]
|
||||
|
||||
if data_type == CONTENT_DATA_TYPE_FILES:
|
||||
|
||||
if action == CONTENT_UPDATE_ADD: return ( ( self._hash_ids_to_hashes[ hash_id ], size, mime, timestamp, width, height, duration, num_frames, num_words ) for ( hash_id, size, mime, timestamp, width, height, duration, num_frames, num_words ) in data )
|
||||
else: return ( { self._hash_ids_to_hashes[ hash_id ] for hash_id in hash_ids } for hash_ids in ( data, ) )
|
||||
|
||||
elif data_type == CONTENT_DATA_TYPE_MAPPINGS: return ( ( tag, [ self._hash_ids_to_hashes[ hash_id ] for hash_id in hash_ids ] ) for ( tag, hash_ids ) in data )
|
||||
else: return data.__iter__()
|
||||
|
||||
|
||||
def GetNumContentUpdates( self ):
|
||||
|
||||
num = 0
|
||||
|
||||
data_types = [ CONTENT_DATA_TYPE_FILES, CONTENT_DATA_TYPE_MAPPINGS, CONTENT_DATA_TYPE_TAG_SIBLINGS, CONTENT_DATA_TYPE_TAG_PARENTS ]
|
||||
actions = [ CONTENT_UPDATE_ADD, CONTENT_UPDATE_DELETE ]
|
||||
|
||||
for ( data_type, action ) in itertools.product( data_types, actions ):
|
||||
|
||||
for row in self.GetContentDataIterator( data_type, action ): num += 1
|
||||
|
||||
|
||||
return num
|
||||
|
||||
|
||||
# this needs work!
|
||||
# we need a universal content_update for both client and server
|
||||
def IterateContentUpdates( self ):
|
||||
|
||||
data_types = [ CONTENT_DATA_TYPE_FILES, CONTENT_DATA_TYPE_MAPPINGS, CONTENT_DATA_TYPE_TAG_SIBLINGS, CONTENT_DATA_TYPE_TAG_PARENTS ]
|
||||
actions = [ CONTENT_UPDATE_ADD, CONTENT_UPDATE_DELETE ]
|
||||
|
||||
for ( data_type, action ) in itertools.product( data_types, actions ):
|
||||
|
||||
for row in self.GetContentDataIterator( data_type, action ): yield ContentUpdate( data_type, action, row )
|
||||
|
||||
|
||||
|
||||
def IterateServiceUpdates( self ):
|
||||
|
||||
service_types = [ SERVICE_UPDATE_NEWS, SERVICE_UPDATE_NEXT_BEGIN ]
|
||||
|
||||
for service_type in service_types:
|
||||
|
||||
if service_type in self._service_data:
|
||||
|
||||
data = self._service_data[ service_type ]
|
||||
|
||||
yield ServiceUpdate( service_type, data )
|
||||
|
||||
|
||||
|
||||
|
||||
def GetHashes( self ): return set( hash_ids_to_hashes.values() )
|
||||
|
||||
def GetTags( self ):
|
||||
|
||||
tags = set()
|
||||
|
||||
tags.update( ( tag for ( tag, hash_ids ) in self.GetContentDataIterator( CONTENT_DATA_TYPE_MAPPINGS, CURRENT ) ) )
|
||||
tags.update( ( tag for ( tag, hash_ids ) in self.GetContentDataIterator( CONTENT_DATA_TYPE_MAPPINGS, DELETED ) ) )
|
||||
|
||||
tags.update( ( old_tag for ( old_tag, new_tag ) in self.GetContentDataIterator( CONTENT_DATA_TYPE_TAG_SIBLINGS, CURRENT ) ) )
|
||||
tags.update( ( new_tag for ( old_tag, new_tag ) in self.GetContentDataIterator( CONTENT_DATA_TYPE_TAG_SIBLINGS, CURRENT ) ) )
|
||||
tags.update( ( old_tag for ( old_tag, new_tag ) in self.GetContentDataIterator( CONTENT_DATA_TYPE_TAG_SIBLINGS, DELETED ) ) )
|
||||
tags.update( ( new_tag for ( old_tag, new_tag ) in self.GetContentDataIterator( CONTENT_DATA_TYPE_TAG_SIBLINGS, DELETED ) ) )
|
||||
|
||||
return tags
|
||||
|
||||
|
||||
def GetServiceData( self, service_type ): return self._service_data[ service_type ]
|
||||
|
||||
# sqlite mod
|
||||
|
||||
|
@ -2280,8 +2395,7 @@ sqlite3.register_adapter( bool, int )
|
|||
sqlite3.register_converter( 'INTEGER_BOOLEAN', integer_boolean_to_bool )
|
||||
|
||||
# no converters in this case, since we always want to send the dumped string, not the object, to the network
|
||||
sqlite3.register_adapter( HydrusUpdateFileRepository, yaml.safe_dump )
|
||||
sqlite3.register_adapter( HydrusUpdateTagRepository, yaml.safe_dump )
|
||||
sqlite3.register_adapter( ServerToClientUpdate, yaml.safe_dump )
|
||||
|
||||
# Custom Exceptions
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import bs4
|
||||
import collections
|
||||
import HydrusConstants as HC
|
||||
import json
|
||||
import lxml
|
||||
|
@ -7,24 +8,23 @@ import urllib
|
|||
import urlparse
|
||||
import wx
|
||||
|
||||
def ConvertServiceIdentifiersToTagsToContentUpdates( hash, service_identifiers_to_tags ):
|
||||
def ConvertServiceIdentifiersToTagsToServiceIdentifiersToContentUpdates( hash, service_identifiers_to_tags ):
|
||||
|
||||
content_updates = []
|
||||
hashes = set( ( hash, ) )
|
||||
|
||||
service_identifiers_to_content_updates = {}
|
||||
|
||||
for ( service_identifier, tags ) in service_identifiers_to_tags.items():
|
||||
|
||||
if len( tags ) > 0:
|
||||
|
||||
if service_identifier == HC.LOCAL_TAG_SERVICE_IDENTIFIER: action = HC.CONTENT_UPDATE_ADD
|
||||
else: action = HC.CONTENT_UPDATE_PENDING
|
||||
|
||||
edit_log = [ ( action, tag ) for tag in tags ]
|
||||
|
||||
content_updates.append( HC.ContentUpdate( HC.CONTENT_UPDATE_EDIT_LOG, service_identifier, ( hash, ), info = edit_log ) )
|
||||
|
||||
if service_identifier == HC.LOCAL_TAG_SERVICE_IDENTIFIER: action = HC.CONTENT_UPDATE_ADD
|
||||
else: action = HC.CONTENT_UPDATE_PENDING
|
||||
|
||||
content_updates = [ HC.ContentUpdate( HC.CONTENT_DATA_TYPE_MAPPINGS, action, ( tag, hashes ) ) for tag in tags ]
|
||||
|
||||
service_identifiers_to_content_updates[ service_identifier ] = content_updates
|
||||
|
||||
|
||||
return content_updates
|
||||
return service_identifiers_to_content_updates
|
||||
|
||||
def GetDownloader( site_download_type, *args ):
|
||||
|
||||
|
|
1058
include/ServerDB.py
1058
include/ServerDB.py
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue