diff --git a/include/ClientDB.py b/include/ClientDB.py index 4f8d36d..a1a5c2d 100755 --- a/include/ClientDB.py +++ b/include/ClientDB.py @@ -2611,7 +2611,7 @@ class DB( HydrusDB.HydrusDB ): counts_iterable = self._c.execute( nonzero_counts_query ) - query_hash_ids = { id for ( id, count ) in counts_iterable if False not in ( pred( count ) for pred in tag_predicates ) } + query_hash_ids = { id for ( id, count ) in counts_iterable if False not in (lambda count:( pred( count ) for pred in tag_predicates ))(count) } # diff --git a/include/ClientGUICanvas.py b/include/ClientGUICanvas.py index a459170..7ec0a30 100755 --- a/include/ClientGUICanvas.py +++ b/include/ClientGUICanvas.py @@ -48,7 +48,8 @@ NON_ZOOMABLE_MIMES = list( HC.AUDIO ) + [ HC.APPLICATION_PDF ] EMBED_BUTTON_MIMES = [ HC.VIDEO_FLV, HC.APPLICATION_FLASH ] -def CalculateCanvasZoom( media, ( canvas_width, canvas_height ) ): +def CalculateCanvasZoom( media, canvas_dims ): + ( canvas_width, canvas_height ) = canvas_dims ( media_width, media_height ) = media.GetResolution() diff --git a/include/ClientGUIDialogs.py b/include/ClientGUIDialogs.py index b73c6ef..f1ea71c 100755 --- a/include/ClientGUIDialogs.py +++ b/include/ClientGUIDialogs.py @@ -242,7 +242,8 @@ class Dialog( wx.Dialog ): def EventDialogButton( self, event ): self.EndModal( event.GetId() ) - def SetInitialSize( self, ( width, height ) ): + def SetInitialSize( self, dims ): + ( width, height ) = dims wx.Dialog.SetInitialSize( self, ( width, height ) ) diff --git a/include/ClientGUIManagement.py b/include/ClientGUIManagement.py index 2fa9574..ae5a9cb 100755 --- a/include/ClientGUIManagement.py +++ b/include/ClientGUIManagement.py @@ -64,26 +64,6 @@ def CreateManagementController( management_type, file_service_key = None ): return management_controller -def CreateManagementControllerDumper( imageboard, media_results ): - - # this stuff doesn't work yet because media_results and imageboard are still yaml things - - management_controller = CreateManagementController( MANAGEMENT_TYPE_DUMPER ) - - management_controller.SetVariable( 'imageboard', imageboard ) - management_controller.SetVariable( 'media_results', media_results ) - - self._current_hash = None - - self._dumping = False - self._actually_dumping = False - self._num_dumped = 0 - self._next_dump_index = 0 - self._next_dump_time = 0 - - self._file_post_name = 'upfile' - - return management_controller def CreateManagementControllerImportGallery( site_type, gallery_type ): @@ -667,734 +647,6 @@ class ManagementPanel( wx.lib.scrolledpanel.ScrolledPanel ): def TestAbleToClose( self ): pass -class ManagementPanelDumper( ManagementPanel ): - - def __init__( self, parent, page, management_controller ): - - ManagementPanel.__init__( self, parent, page, management_controller ) - - ( self._4chan_token, pin, timeout ) = wx.GetApp().Read( '4chan_pass' ) - - self._have_4chan_pass = timeout > HydrusData.GetNow() - - self._timer = wx.Timer( self, ID_TIMER_DUMP ) - self.Bind( wx.EVT_TIMER, self.TIMEREvent, id = ID_TIMER_DUMP ) - - ( self._post_url, self._flood_time, self._form_fields, self._restrictions ) = self._imageboard.GetBoardInfo() - - # progress - - self._import_queue_panel = ClientGUICommon.StaticBox( self, 'import queue' ) - - self._progress_info = wx.StaticText( self._import_queue_panel ) - - self._progress_gauge = ClientGUICommon.Gauge( self._import_queue_panel ) - self._progress_gauge.SetRange( len( media_results ) ) - - self._start_button = wx.Button( self._import_queue_panel, label = 'start' ) - self._start_button.Bind( wx.EVT_BUTTON, self.EventStartButton ) - - self._import_queue_panel.AddF( self._progress_info, CC.FLAGS_EXPAND_PERPENDICULAR ) - self._import_queue_panel.AddF( self._progress_gauge, CC.FLAGS_EXPAND_PERPENDICULAR ) - self._import_queue_panel.AddF( self._start_button, CC.FLAGS_EXPAND_PERPENDICULAR ) - - # thread options - - self._thread_panel = ClientGUICommon.StaticBox( self, 'thread options' ) - - self._thread_fields = {} - - gridbox = wx.FlexGridSizer( 0, 2 ) - - gridbox.AddGrowableCol( 1, 1 ) - - for ( name, field_type, default, editable ) in self._form_fields: - - if field_type in ( CC.FIELD_TEXT, CC.FIELD_THREAD_ID ): field = wx.TextCtrl( self._thread_panel, value = default ) - elif field_type == CC.FIELD_PASSWORD: field = wx.TextCtrl( self._thread_panel, value = default, style = wx.TE_PASSWORD ) - else: continue - - self._thread_fields[ name ] = ( field_type, field ) - - if editable: - - gridbox.AddF( wx.StaticText( self._thread_panel, label = name + ':' ), CC.FLAGS_MIXED ) - gridbox.AddF( field, CC.FLAGS_EXPAND_BOTH_WAYS ) - - else: field.Hide() - - - self._thread_panel.AddF( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR ) - - # post options - - self._post_panel = ClientGUICommon.StaticBox( self, 'post options' ) - - self._post_fields = {} - - postbox = wx.BoxSizer( wx.VERTICAL ) - - self._post_info = wx.StaticText( self._post_panel, label = 'no file selected', style = wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE ) - - for ( name, field_type, default, editable ) in self._form_fields: - - if field_type == CC.FIELD_VERIFICATION_RECAPTCHA: - - if self._have_4chan_pass: continue - - field = CaptchaControl( self._post_panel, field_type, default ) - field.Bind( CAPTCHA_FETCH_EVENT, self.EventCaptchaRefresh ) - - elif field_type == CC.FIELD_COMMENT: field = Comment( self._post_panel ) - else: continue - - self._post_fields[ name ] = ( field_type, field, default ) - - postbox.AddF( field, CC.FLAGS_EXPAND_PERPENDICULAR ) - - - gridbox = wx.FlexGridSizer( 0, 2 ) - - gridbox.AddGrowableCol( 1, 1 ) - - for ( name, field_type, default, editable ) in self._form_fields: - - if field_type == CC.FIELD_CHECKBOX: - - field = wx.CheckBox( self._post_panel ) - - field.SetValue( default == 'True' ) - - else: continue - - self._post_fields[ name ] = ( field_type, field, default ) - - gridbox.AddF( wx.StaticText( self._post_panel, label = name + ':' ), CC.FLAGS_MIXED ) - gridbox.AddF( field, CC.FLAGS_EXPAND_BOTH_WAYS ) - - - for ( name, field_type, default, editable ) in self._form_fields: - - if field_type == CC.FIELD_FILE: self._file_post_name = name - - - self._post_panel.AddF( self._post_info, CC.FLAGS_EXPAND_PERPENDICULAR ) - self._post_panel.AddF( postbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR ) - self._post_panel.AddF( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR ) - - # misc - - self._advanced_tag_options = ClientGUICollapsible.CollapsibleOptionsTags( self, namespaces = [ 'creator', 'series', 'title', 'volume', 'chapter', 'page', 'character', 'person', 'all others' ] ) - - # arrange stuff - - vbox = wx.BoxSizer( wx.VERTICAL ) - - self._MakeSort( vbox ) - - vbox.AddF( self._import_queue_panel, CC.FLAGS_EXPAND_PERPENDICULAR ) - vbox.AddF( self._thread_panel, CC.FLAGS_EXPAND_PERPENDICULAR ) - vbox.AddF( self._post_panel, CC.FLAGS_EXPAND_PERPENDICULAR ) - vbox.AddF( self._advanced_tag_options, CC.FLAGS_EXPAND_PERPENDICULAR ) - - self._MakeCurrentSelectionTagsBox( vbox ) - - self.SetSizer( vbox ) - - HydrusGlobals.pubsub.sub( self, 'FocusChanged', 'focus_changed' ) - HydrusGlobals.pubsub.sub( self, 'SortedMediaPulse', 'sorted_media_pulse' ) - - self._sorted_media_hashes = [ media_result.GetHash() for media_result in media_results ] - - self._hashes_to_media = { media_result.GetHash() : ClientMedia.MediaSingleton( media_result ) for media_result in media_results } - - self._hashes_to_dump_info = {} - - for ( hash, media ) in self._hashes_to_media.items(): - - dump_status_enum = CC.DUMPER_NOT_DUMPED - - dump_status_string = 'not yet dumped' - - post_field_info = [] - - for ( name, ( field_type, field, default ) ) in self._post_fields.items(): - - if field_type == CC.FIELD_COMMENT: - - post_field_info.append( ( name, field_type, ( self._GetInitialComment( media ), '' ) ) ) - - elif field_type == CC.FIELD_CHECKBOX: post_field_info.append( ( name, field_type, default == 'True' ) ) - elif field_type == CC.FIELD_VERIFICATION_RECAPTCHA: post_field_info.append( ( name, field_type, None ) ) - - - self._hashes_to_dump_info[ hash ] = ( dump_status_enum, dump_status_string, post_field_info ) - - - self.Bind( wx.EVT_MENU, self.EventMenu ) - - self._timer.Start( 1000, wx.TIMER_CONTINUOUS ) - - - def _THREADDoDump( self, hash, post_field_info, headers, body ): - - try: - - response = wx.GetApp().DoHTTP( HC.POST, self._post_url, request_headers = headers, body = body ) - - ( status, phrase ) = ClientDownloading.Parse4chanPostScreen( response ) - - except Exception as e: - - ( status, phrase ) = ( 'big error', HydrusData.ToString( e ) ) - - - wx.CallAfter( self.CALLBACKDoneDump, hash, post_field_info, status, phrase ) - - - def _FreezeCurrentMediaPostInfo( self ): - - ( dump_status_enum, dump_status_string, post_field_info ) = self._hashes_to_dump_info[ self._current_hash ] - - post_field_info = [] - - for ( name, ( field_type, field, default ) ) in self._post_fields.items(): - - if field_type == CC.FIELD_COMMENT: post_field_info.append( ( name, field_type, field.GetValues() ) ) - elif field_type == CC.FIELD_CHECKBOX: post_field_info.append( ( name, field_type, field.GetValue() ) ) - elif field_type == CC.FIELD_VERIFICATION_RECAPTCHA: post_field_info.append( ( name, field_type, field.GetValues() ) ) - - - self._hashes_to_dump_info[ self._current_hash ] = ( dump_status_enum, dump_status_string, post_field_info ) - - - def _GetInitialComment( self, media ): - - hash = media.GetHash() - - try: index = self._sorted_media_hashes.index( hash ) - except: return 'media removed' - - num_files = len( self._sorted_media_hashes ) - - if index == 0: - - total_size = sum( [ m.GetSize() for m in self._hashes_to_media.values() ] ) - - initial = 'Hydrus Network Client is starting a dump of ' + HydrusData.ToString( num_files ) + ' files, totalling ' + HydrusData.ConvertIntToBytes( total_size ) + ':' + os.linesep * 2 - - else: initial = '' - - initial += HydrusData.ConvertValueRangeToPrettyString( index + 1, num_files ) - - advanced_tag_options = self._advanced_tag_options.GetInfo() - - for ( service_key, namespaces ) in advanced_tag_options.items(): - - tags_manager = media.GetTagsManager() - - try: service = wx.GetApp().GetServicesManager().GetService( service_key ) - except HydrusExceptions.NotFoundException: continue - - service_key = service.GetServiceKey() - - current = tags_manager.GetCurrent( service_key ) - pending = tags_manager.GetPending( service_key ) - - tags = current.union( pending ) - - tags_to_include = [] - - for namespace in namespaces: - - if namespace == 'all others': tags_to_include.extend( [ tag for tag in tags if not True in ( tag.startswith( n ) for n in namespaces if n != 'all others' ) ] ) - else: tags_to_include.extend( [ tag for tag in tags if tag.startswith( namespace + ':' ) ] ) - - - initial += os.linesep * 2 + ', '.join( tags_to_include ) - - - return initial - - - def _ShowCurrentMedia( self ): - - if self._current_hash is None: - - self._post_info.SetLabel( 'no file selected' ) - - for ( name, ( field_type, field, default ) ) in self._post_fields.items(): - - if field_type == CC.FIELD_CHECKBOX: field.SetValue( False ) - - field.Disable() - - - else: - - num_files = len( self._sorted_media_hashes ) - - ( dump_status_enum, dump_status_string, post_field_info ) = self._hashes_to_dump_info[ self._current_hash ] - - index = self._sorted_media_hashes.index( self._current_hash ) - - self._post_info.SetLabel( HydrusData.ConvertValueRangeToPrettyString( index + 1, num_files ) + ': ' + dump_status_string ) - - for ( name, field_type, value ) in post_field_info: - - ( field_type, field, default ) = self._post_fields[ name ] - - if field_type == CC.FIELD_COMMENT: - - ( initial, append ) = value - - field.EnableWithValues( initial, append ) - - elif field_type == CC.FIELD_CHECKBOX: - - field.SetValue( value ) - field.Enable() - - elif field_type == CC.FIELD_VERIFICATION_RECAPTCHA: - - if value is None: field.Enable() - else: - - ( challenge, bitmap, captcha_runs_out, entry, ready ) = value - - field.EnableWithValues( challenge, bitmap, captcha_runs_out, entry, ready ) - - - - - if dump_status_enum in ( CC.DUMPER_DUMPED_OK, CC.DUMPER_UNRECOVERABLE_ERROR ): - - for ( name, ( field_type, field, default ) ) in self._post_fields.items(): - - if field_type == CC.FIELD_CHECKBOX: field.SetValue( False ) - - field.Disable() - - - - - - def _UpdatePendingInitialComments( self ): - - hashes_to_dump = self._sorted_media_hashes[ self._next_dump_index : ] - - for hash in hashes_to_dump: - - if hash == self._current_hash: self._FreezeCurrentMediaPostInfo() - - ( dump_status_enum, dump_status_string, post_field_info ) = self._hashes_to_dump_info[ hash ] - - new_post_field_info = [] - - for ( name, field_type, value ) in post_field_info: - - if field_type == CC.FIELD_COMMENT: - - ( initial, append ) = value - - media = self._hashes_to_media[ hash ] - - initial = self._GetInitialComment( media ) - - new_post_field_info.append( ( name, field_type, ( initial, append ) ) ) - - else: new_post_field_info.append( ( name, field_type, value ) ) - - - self._hashes_to_dump_info[ hash ] = ( dump_status_enum, dump_status_string, new_post_field_info ) - - if hash == self._current_hash: self._ShowCurrentMedia() - - - - def CALLBACKDoneDump( self, hash, post_field_info, status, phrase ): - - self._actually_dumping = False - - if HC.options[ 'play_dumper_noises' ]: - - if status == 'success': HydrusAudioHandling.PlayNoise( 'success' ) - else: HydrusAudioHandling.PlayNoise( 'error' ) - - - if status == 'success': - - dump_status_enum = CC.DUMPER_DUMPED_OK - dump_status_string = 'dumped ok' - - if hash == self._current_hash: HydrusGlobals.pubsub.pub( 'set_focus', self._page_key, None ) - - self._next_dump_time = HydrusData.GetNow() + self._flood_time - - self._num_dumped += 1 - - self._progress_gauge.SetValue( self._num_dumped ) - - self._next_dump_index += 1 - - elif status == 'captcha': - - dump_status_enum = CC.DUMPER_RECOVERABLE_ERROR - dump_status_string = 'captcha was incorrect' - - self._next_dump_time = HydrusData.GetNow() + 10 - - new_post_field_info = [] - - for ( name, field_type, value ) in post_field_info: - - if field_type == CC.FIELD_VERIFICATION_RECAPTCHA: new_post_field_info.append( ( name, field_type, None ) ) - else: new_post_field_info.append( ( name, field_type, value ) ) - - if hash == self._current_hash: - - ( field_type, field, default ) = self._post_fields[ name ] - - field.Enable() - - - - post_field_info = new_post_field_info - - elif status == 'too quick': - - dump_status_enum = CC.DUMPER_RECOVERABLE_ERROR - dump_status_string = '' - - self._progress_info.SetLabel( 'Flood limit hit, retrying.' ) - - self._next_dump_time = HydrusData.GetNow() + self._flood_time - - elif status == 'big error': - - dump_status_enum = CC.DUMPER_UNRECOVERABLE_ERROR - dump_status_string = '' - - HydrusData.ShowText( phrase ) - - self._progress_info.SetLabel( 'error: ' + phrase ) - - self._start_button.Disable() - - self._timer.Stop() - - elif 'Thread specified does not exist' in phrase: - - dump_status_enum = CC.DUMPER_UNRECOVERABLE_ERROR - dump_status_string = '' - - self._progress_info.SetLabel( 'thread specified does not exist!' ) - - self._start_button.Disable() - - self._timer.Stop() - - else: - - dump_status_enum = CC.DUMPER_UNRECOVERABLE_ERROR - dump_status_string = phrase - - if hash == self._current_hash: HydrusGlobals.pubsub.pub( 'set_focus', self._page_key, None ) - - self._next_dump_time = HydrusData.GetNow() + self._flood_time - - self._next_dump_index += 1 - - - self._hashes_to_dump_info[ hash ] = ( dump_status_enum, dump_status_string, post_field_info ) - - HydrusGlobals.pubsub.pub( 'file_dumped', self._page_key, hash, dump_status_enum ) - - if self._next_dump_index == len( self._sorted_media_hashes ): - - self._progress_info.SetLabel( 'done - ' + HydrusData.ToString( self._num_dumped ) + ' dumped' ) - - self._start_button.Disable() - - self._timer.Stop() - - self._dumping = False - - - - def EventCaptchaRefresh( self, event ): - - try: - - index = self._sorted_media_hashes.index( self._current_hash ) - - if ( ( index + 1 ) - self._next_dump_index ) * ( self._flood_time + 10 ) > 5 * 60: event.Veto() - - except: event.Veto() - - - def EventMenu( self, event ): - - action = ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE.GetAction( event.GetId() ) - - if action is not None: - - ( command, data ) = action - - if command == 'advanced_tag_options_changed': self._UpdatePendingInitialComments() - else: event.Skip() - - - - def EventStartButton( self, event ): - - if self._start_button.GetLabel() in ( 'start', 'continue' ): - - for ( name, ( field_type, field ) ) in self._thread_fields.items(): - - if field_type == CC.FIELD_THREAD_ID: - - try: int( field.GetValue() ) - except: - - # let's assume they put the url in - - value = field.GetValue() - - thread_id = value.split( '/' )[ -1 ] - - try: int( thread_id ) - except: - - self._progress_info.SetLabel( 'set thread_id field first' ) - - return - - - field.SetValue( thread_id ) - - - - - for ( field_type, field ) in self._thread_fields.values(): field.Disable() - - self._dumping = True - self._start_button.SetLabel( 'pause' ) - - if self._next_dump_time == 0: self._next_dump_time = HydrusData.GetNow() + 5 - - # disable thread fields here - - else: - - for ( field_type, field ) in self._thread_fields.values(): field.Enable() - - self._dumping = False - - if self._num_dumped == 0: self._start_button.SetLabel( 'start' ) - else: self._start_button.SetLabel( 'continue' ) - - - - def FocusChanged( self, page_key, media ): - - if page_key == self._page_key: - - if media is None: hash = None - else: hash = media.GetHash() - - if hash != self._current_hash: - - old_hash = self._current_hash - - if old_hash is not None: self._FreezeCurrentMediaPostInfo() - - self._current_hash = hash - - self._ShowCurrentMedia() - - - - - def SortedMediaPulse( self, page_key, sorted_media ): - - if page_key == self._page_key: - - self._sorted_media_hashes = [ media.GetHash() for media in sorted_media ] - - self._hashes_to_media = { hash : self._hashes_to_media[ hash ] for hash in self._sorted_media_hashes } - - new_hashes_to_dump_info = {} - - for ( hash, ( dump_status_enum, dump_status_string, post_field_info ) ) in self._hashes_to_dump_info.items(): - - if hash not in self._sorted_media_hashes: continue - - new_post_field_info = [] - - for ( name, field_type, value ) in post_field_info: - - if field_type == CC.FIELD_COMMENT: - - ( initial, append ) = value - - media = self._hashes_to_media[ hash ] - - initial = self._GetInitialComment( media ) - - value = ( initial, append ) - - - new_post_field_info.append( ( name, field_type, value ) ) - - - new_hashes_to_dump_info[ hash ] = ( dump_status_enum, dump_status_string, new_post_field_info ) - - - self._hashes_to_dump_info = new_hashes_to_dump_info - - self._ShowCurrentMedia() - - if self._current_hash is None and len( self._sorted_media_hashes ) > 0: - - hash_to_select = self._sorted_media_hashes[0] - - media_to_select = self._hashes_to_media[ hash_to_select ] - - HydrusGlobals.pubsub.pub( 'set_focus', self._page_key, media_to_select ) - - - - - def TestAbleToClose( self ): - - if self._dumping: - - with ClientGUIDialogs.DialogYesNo( self, 'This page is still dumping. Are you sure you want to close it?' ) as dlg: - - if dlg.ShowModal() == wx.ID_NO: raise Exception() - - - - - def TIMEREvent( self, event ): - - if self._controller.IsPaused(): return - - if self._actually_dumping: return - - if self._dumping: - - time_left = self._next_dump_time - HydrusData.GetNow() - - if time_left < 1: - - try: - - hash = self._sorted_media_hashes[ self._next_dump_index ] - - wait = False - - if hash == self._current_hash: self._FreezeCurrentMediaPostInfo() - - ( dump_status_enum, dump_status_string, post_field_info ) = self._hashes_to_dump_info[ hash ] - - for ( name, field_type, value ) in post_field_info: - - if field_type == CC.FIELD_VERIFICATION_RECAPTCHA: - - if value is None: - - wait = True - - break - - else: - - ( challenge, bitmap, captcha_runs_out, entry, ready ) = value - - if HydrusData.TimeHasPassed( captcha_runs_out ) or not ready: - - wait = True - - break - - - - - - if wait: self._progress_info.SetLabel( 'waiting for captcha' ) - else: - - self._progress_info.SetLabel( 'dumping' ) # 100% cpu time here - may or may not be desirable - - post_fields = [] - - for ( name, ( field_type, field ) ) in self._thread_fields.items(): - - post_fields.append( ( name, field_type, field.GetValue() ) ) - - - for ( name, field_type, value ) in post_field_info: - - if field_type == CC.FIELD_VERIFICATION_RECAPTCHA: - - ( challenge, bitmap, captcha_runs_out, entry, ready ) = value - - post_fields.append( ( 'recaptcha_challenge_field', field_type, challenge ) ) - post_fields.append( ( 'recaptcha_response_field', field_type, entry ) ) - - elif field_type == CC.FIELD_COMMENT: - - ( initial, append ) = value - - comment = initial - - if len( append ) > 0: comment += os.linesep * 2 + append - - post_fields.append( ( name, field_type, comment ) ) - - else: post_fields.append( ( name, field_type, value ) ) - - - media = self._hashes_to_media[ hash ] - - mime = media.GetMime() - - path = ClientFiles.GetFilePath( hash, mime ) - - with open( path, 'rb' ) as f: file = f.read() - - post_fields.append( ( self._file_post_name, CC.FIELD_FILE, ( hash, mime, file ) ) ) - - ( ct, body ) = HydrusNetworking.GenerateDumpMultipartFormDataCTAndBody( post_fields ) - - headers = {} - headers[ 'Content-Type' ] = ct - if self._have_4chan_pass: headers[ 'Cookie' ] = 'pass_enabled=1; pass_id=' + self._4chan_token - - self._actually_dumping = True - - HydrusThreading.CallToThread( self._THREADDoDump, hash, post_field_info, headers, body ) - - - except Exception as e: - - ( status, phrase ) = ( 'big error', HydrusData.ToString( e ) ) - - wx.CallAfter( self.CALLBACKDoneDump, hash, post_field_info, status, phrase ) - - - else: self._progress_info.SetLabel( 'dumping next file in ' + HydrusData.ToString( time_left ) + ' seconds' ) - - else: - - if self._num_dumped == 0: self._progress_info.SetLabel( 'will dump to ' + self._imageboard.GetName() ) - else: self._progress_info.SetLabel( 'paused after ' + HydrusData.ToString( self._num_dumped ) + ' files dumped' ) - - - -management_panel_types_to_classes[ MANAGEMENT_TYPE_DUMPER ] = ManagementPanelDumper class ManagementPanelImport( ManagementPanel ): diff --git a/include/ClientImporting.py b/include/ClientImporting.py index 6da6748..7cd6636 100644 --- a/include/ClientImporting.py +++ b/include/ClientImporting.py @@ -113,26 +113,6 @@ class ImportController( HydrusSerialisable.SerialisableBase ): - def _DAEMONProcessSearchSeeds( self ): - - while True: - - # if searcher paused - - with self._lock: - - result = import_seed_queue.GetNextUnknownSeed() - - - if result is not None: - - ( seed, seed_info ) = result - - self._ProcessSearchSeed( seed, seed_info ) - - - - def GetOptions( self, name ): with self._lock: diff --git a/include/HydrusData.py b/include/HydrusData.py index 3b644d5..b80b5e8 100644 --- a/include/HydrusData.py +++ b/include/HydrusData.py @@ -1003,15 +1003,15 @@ class ClientToServerContentUpdatePackage( HydrusYAMLBase ): if data_type in ( HC.CONTENT_DATA_TYPE_TAG_SIBLINGS, HC.CONTENT_DATA_TYPE_TAG_PARENTS ) and action in ( HC.CONTENT_UPDATE_PENDING, HC.CONTENT_UPDATE_PETITION ): - munge_row = lambda ( pair, reason ): pair + munge_row = lambda tup: tup[0] elif data_type == HC.CONTENT_DATA_TYPE_FILES and action == HC.CONTENT_UPDATE_PETITION: - munge_row = lambda ( hashes, reason ): hashes + munge_row = lambda tup: tup[0] elif data_type == HC.CONTENT_DATA_TYPE_MAPPINGS and action == HC.CONTENT_UPDATE_PETITION: - munge_row = lambda ( tag, hashes, reason ): ( tag, hashes ) + munge_row = lambda tup: tup[:-1] else: new_action = action diff --git a/include/HydrusImageHandling.py b/include/HydrusImageHandling.py index c037164..bb6c08e 100755 --- a/include/HydrusImageHandling.py +++ b/include/HydrusImageHandling.py @@ -50,7 +50,8 @@ def ConvertToPngIfBmp( path ): -def EfficientlyResizeNumpyImage( numpy_image, ( target_x, target_y ) ): +def EfficientlyResizeNumpyImage( numpy_image, target_dims ): + ( target_x, target_y ) = target_dims ( im_y, im_x, depth ) = numpy_image.shape @@ -63,7 +64,8 @@ def EfficientlyResizeNumpyImage( numpy_image, ( target_x, target_y ) ): return cv2.resize( result, ( target_x, target_y ), interpolation = cv2.INTER_LINEAR ) -def EfficientlyResizePILImage( pil_image, ( target_x, target_y ) ): +def EfficientlyResizePILImage( pil_image, target_dims ): + ( target_x, target_y ) = target_dims ( im_x, im_y ) = pil_image.size @@ -76,7 +78,8 @@ def EfficientlyResizePILImage( pil_image, ( target_x, target_y ) ): return pil_image.resize( ( target_x, target_y ), PILImage.ANTIALIAS ) -def EfficientlyThumbnailNumpyImage( numpy_image, ( target_x, target_y ) ): +def EfficientlyThumbnailNumpyImage( numpy_image, target_dims ): + ( target_x, target_y ) = target_dims ( im_y, im_x, depth ) = numpy_image.shape @@ -86,7 +89,8 @@ def EfficientlyThumbnailNumpyImage( numpy_image, ( target_x, target_y ) ): return cv2.resize( numpy_image, ( target_x, target_y ), interpolation = cv2.INTER_AREA ) -def EfficientlyThumbnailPILImage( pil_image, ( target_x, target_y ) ): +def EfficientlyThumbnailPILImage( pil_image, target_dims ): + ( target_x, target_y ) = target_dims ( im_x, im_y ) = pil_image.size @@ -350,7 +354,9 @@ def GetResolutionAndNumFrames( path ): return ( ( x, y ), num_frames ) -def GetThumbnailResolution( ( im_x, im_y ), ( target_x, target_y ) ): +def GetThumbnailResolution( im_dims, target_dims ): + ( im_x, im_y ) = im_dims + ( target_x, target_y ) = target_dims im_x = float( im_x ) im_y = float( im_y ) diff --git a/include/HydrusMessageHandling.py b/include/HydrusMessageHandling.py index dbd6c95..cbc017f 100755 --- a/include/HydrusMessageHandling.py +++ b/include/HydrusMessageHandling.py @@ -164,235 +164,3 @@ class Message( HydrusData.HydrusYAMLBase ): return verifier.verify( hash_object, self._signature ) -# here begins the new stuff, I'm pretty sure - -class Identity( object ): # should be a yamlable object - - def __init__( self ): - - # no name, right? we associate names and addresses with the identity, but the id only has keys - - # store key_type -> key - # hence need a key_type enum - - pass - - -class IMManager( object ): - - def __init__( self ): - - self._accounts = {} - self._contexts = {} - self._persistent_connections = {} - self._temporary_connections = {} - - # go fetch all accounts from the db - - # set up many pubsubs - - # start up some sort of daemon to keep our accounts logged in - - pass - - - def _GetContext( self, identifier_local, name_local, identifier_remote, name_remote ): - - if ( identifier_remote, name_remote ) not in self._contexts[ identifier_local ]: - - account = self._accounts[ ( identifier_local, name_local ) ] - - context = HydrusEncryption.HydrusOTRContext( account, identifier_remote, name_remote ) - - self._contexts[ ( identifier_local, name_local, identifier_remote, name_remote ) ] = context - - - context = self._contexts[ identifier_local ][ ( identifier_remote, name_remote ) ] - - return context - - - def LoginPersistentConnections( self ): - - # this is on a daemon thread, so move to twisted - - for ( identifier, name ) in self._accounts.keys(): - - if ( identifier, name ) not in self._persistent_connections: - - # get host, port for that identity - - creator = ClientCreator( reactor, HydrusServerAMP.MessagingClientProtocol ) - - deferred = creator.connectTCP( host, port ) - - # deferred is called with the connection, or an error - # callRemote to register with session key and whatnot - - self._persistent_connections[ ( identifier, name ) ] = connection - - - - - def ReceiveMessage( self, identifier_from, name_from, identifier_to, name_to, message ): - - # currently on wx loop - # move it to the twisted loop - - if ( identifier_from, name_from, identifier_to, name_to ) not in self._temporary_connections: - - self._temporary_connections[ ( identifier_from, name_from, identifier_to, name_to ) ] = self._persistent_connections[ ( identifier_to, name_to ) ] - # this should have a better error, if the _to doesn't exist - # we should really just disregard it, and any other weirdness - - - context = self._GetContext( identifier_to, name_to, identifier_from, name_from ) - - response = context.receiveMessage( message ) - - if response is not None: - - ( decrypted_message, gumpf ) = response - - message_object = yaml.safe_load( decrypted_message ) - - # do the pubsub - - - - def RemovePersistentConnection( self, identifier, name ): - - # if it is still alive, loseConnection or whatever. - # remove it - # pubsub the login daemon - - pass - - - def RemoveTemporaryConnection( self, identifier_from, name_from, identifier_to, name_to ): - - # if it is still alive, loseConnection or whatever. - # remove it - - pass - - - def SendMessage( self, identifier_from, name_from, identifier_to, name_to, message ): - - context = self._GetContext( identifier_from, name_from, identifier_to, name_to ) - - context.sendMessage( potr.context.FRAGMENT_SEND_ALL, message ) - - - def SendEncryptedMessage( self, identifier_from, name_from, identifier_to, name_to, message ): - - # currently on wx loop - # move it to the twisted loop - - connection = self._temporary_connections[ ( identifier_from, name_from, identifier_to, name_to ) ] - - connection.callRemote( HydrusServerAMP.IMMessageServer, identifier_to = identifier_to, name_to = name_to, message = message ) - - # if it breaks, we should pubsub that it broke - - - def StartTalking( self, identifier_from, name_from, identifier_to, name_to ): - - # currently on wx loop - # move it to the twisted loop - - # fetch host and port for that id - - creator = ClientCreator( reactor, HydrusServerAMP.MessagingClientProtocol ) - - deferred = creator.connectTCP( host, port ) - - # deferred is called with the connection, or an error - # callRemote to register identifier_from and name_from as temp login - # then add to temp_connections - - self._temporary_connections[ ( identifier_from, name_from, identifier_to, name_to ) ] = connection - - message = '' # this is just to get the OTR handshake going; it'll never be sent - - connection.callRemote( HydrusServerAMP.IMMessageServer, identifier_to = identifier_to, name_to = name_to, message = message ) - - # how do I detect when we are ready to do encrypted comms? - # I can check periodically context.status, but that is a _little_ bleh - # I can write a pubsub in the setStatus thing in context - # check that article again, or the code, on the exact name - - # do a pubsub to say we are ready to do encrypted comms - - # if it fails, we should pubsub that it broke - - - def StopTalking( self, identifier, name ): - - # close temp connection - # - - pass - - -class IMMessage( HydrusData.HydrusYAMLBase ): - - yaml_tag = u'!IMMessage' - -class IMMessageQuestion( IMMessage ): - - yaml_tag = u'!IMMessageQuestion' - - def __init__( self, job_key = None ): - - if job_key is None: job_key = HydrusData.GenerateKey() - - self._job_key = job_key - - - def GenerateAnswer( self, answer ): - - return IMMessageQuestionAnswer( self._job_key, answer ) - - - def GetJobKey( self ): return self._job_key - -class IMMessageQuestionAnswer( IMMessageQuestion ): - - yaml_tag = u'!IMMessageQuestionAnswer' - - def __init__( self, job_key, answer ): - - IMMessageQuestion.__init__( self, job_key ) - - self._answer = answer - - - def GetAnswer( self ): return self._answer - -class IMMessageQuestionFiles( IMMessageQuestion ): - - yaml_tag = u'!IMMessageFiles' - - def __init__( self, media_results ): - - IMMessageQuestion.__init__( self ) - - self._text = text - - -IM_MESSAGE_TYPE_CONVO = 0 -IM_MESSAGE_TYPE_STATUS = 1 - -class IMMessageText( IMMessage ): - - yaml_tag = u'!IMMessageText' - - def __init__( self, message_type, text ): - - self._type = message_type - self._text = text - - - def ToTuple( self ): return ( self._type, self._text ) - \ No newline at end of file diff --git a/include/HydrusTags.py b/include/HydrusTags.py index 710c20a..edd9bfd 100644 --- a/include/HydrusTags.py +++ b/include/HydrusTags.py @@ -352,7 +352,7 @@ class TagsManagerSimple( object ): combined_current = combined_statuses_to_tags[ HC.CURRENT ] combined_pending = combined_statuses_to_tags[ HC.PENDING ] - slice = { tag for tag in combined_current.union( combined_pending ) if True in ( tag.startswith( namespace + ':' ) for namespace in namespaces ) } + slice = { tag for tag in combined_current.union( combined_pending ) if True in (lambda tag:( tag.startswith( namespace + ':' ) for namespace in namespaces ))(tag) } if collapse_siblings: