def Edit( self ): for i in self._listctrl.GetAllSelected(): ( key, value ) = self._listctrl.GetClientData( i ) import ClientGUIDialogs with ClientGUIDialogs.DialogTextEntry( self, 'edit the key', default = key, allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: key = dlg.GetValue() else: return with ClientGUIDialogs.DialogTextEntry( self, 'edit the value', default = value, allow_blank = True ) as dlg: if dlg.ShowModal() == wx.ID_OK: value = dlg.GetValue() else: return display_tuple = ( key, value ) self._listctrl.UpdateRow( i, display_tuple, display_tuple )
def test_dialog_choose_new_service_method(self): with ClientGUIDialogs.DialogChooseNewServiceMethod(None) as dlg: HitButton(dlg._register) result = dlg.ShowModal() self.assertEqual(result, wx.ID_OK) register = dlg.GetRegister() self.assertEqual(register, True) with ClientGUIDialogs.DialogChooseNewServiceMethod(None) as dlg: HitButton(dlg._setup) result = dlg.ShowModal() self.assertEqual(result, wx.ID_OK) register = dlg.GetRegister() self.assertEqual(register, False) with ClientGUIDialogs.DialogChooseNewServiceMethod(None) as dlg: HitCancelButton(dlg) result = dlg.ShowModal() self.assertEqual(result, wx.ID_CANCEL)
def test_dialog_finish_rating_filtering( self ): with ClientGUIDialogs.DialogFinishRatingFiltering( None, 3, 5 ) as dlg: HitButton( dlg._back ) result = dlg.ShowModal() self.assertEqual( result, wx.ID_CANCEL ) with ClientGUIDialogs.DialogFinishRatingFiltering( None, 3, 5 ) as dlg: HitButton( dlg._commit ) result = dlg.ShowModal() self.assertEqual( result, wx.ID_YES ) with ClientGUIDialogs.DialogFinishRatingFiltering( None, 3, 5 ) as dlg: HitButton( dlg._forget ) result = dlg.ShowModal() self.assertEqual( result, wx.ID_NO )
def test_dialog_finish_filtering(self): with ClientGUIDialogs.DialogFinishFiltering( None, 'keep 3 files and delete 5 files?') as dlg: HitButton(dlg._back) result = dlg.ShowModal() self.assertEqual(result, wx.ID_CANCEL) with ClientGUIDialogs.DialogFinishFiltering( None, 'keep 3 files and delete 5 files?') as dlg: HitButton(dlg._commit) result = dlg.ShowModal() self.assertEqual(result, wx.ID_YES) with ClientGUIDialogs.DialogFinishFiltering( None, 'keep 3 files and delete 5 files?') as dlg: HitButton(dlg._forget) result = dlg.ShowModal() self.assertEqual(result, wx.ID_NO)
def ExportToHTA(parent, service_key, hashes): with wx.FileDialog(parent, style=wx.FD_SAVE, defaultFile='archive.db') as dlg: if dlg.ShowModal() == wx.ID_OK: path = HydrusData.ToUnicode(dlg.GetPath()) else: return message = 'Would you like to use hydrus\'s normal hash type, or an alternative?' message += os.linesep * 2 message += 'Hydrus uses SHA256 to identify files, but other services use different standards. MD5, SHA1 and SHA512 are available, but only for local files, which may limit your export.' message += os.linesep * 2 message += 'If you do not know what this stuff means, click \'normal\'.' with ClientGUIDialogs.DialogYesNo(parent, message, title='Choose which hash type.', yes_label='normal', no_label='alternative') as dlg: result = dlg.ShowModal() if result in (wx.ID_YES, wx.ID_NO): if result == wx.ID_YES: hash_type = HydrusTagArchive.HASH_TYPE_SHA256 else: list_of_tuples = [] list_of_tuples.append(('md5', HydrusTagArchive.HASH_TYPE_MD5)) list_of_tuples.append( ('sha1', HydrusTagArchive.HASH_TYPE_SHA1)) list_of_tuples.append( ('sha512', HydrusTagArchive.HASH_TYPE_SHA512)) with ClientGUIDialogs.DialogSelectFromList( parent, 'Select the hash type', list_of_tuples) as hash_dlg: if hash_dlg.ShowModal() == wx.ID_OK: hash_type = hash_dlg.GetChoice() else: return if hash_type is not None: HG.client_controller.Write('export_mappings', path, service_key, hash_type, hashes)
def EditMappings(self): do_refresh = False for index in self._mappings_list_ctrl.GetAllSelected(): (description, internal_ip, internal_port, external_ip, external_port, protocol, duration) = self._mappings_list_ctrl.GetClientData(index) with ClientGUIDialogs.DialogInputUPnPMapping( self, external_port, protocol, internal_port, description, duration) as dlg: if dlg.ShowModal() == wx.ID_OK: (external_port, protocol, internal_port, description, duration) = dlg.GetInfo() HydrusNATPunch.RemoveUPnPMapping(external_port, protocol) internal_client = HydrusNATPunch.GetLocalIP() HydrusNATPunch.AddUPnPMapping(internal_client, internal_port, external_port, protocol, description, duration=duration) do_refresh = True if do_refresh: self._RefreshMappings()
def EventExplicitTags(self, event): button_id = event.GetId() service_key = self._button_ids_to_service_keys[button_id] (explicit_tags, explicit_button ) = self._service_keys_to_explicit_button_info[service_key] with ClientGUIDialogs.DialogInputTags(self, service_key, explicit_tags) as dlg: if dlg.ShowModal() == wx.ID_OK: explicit_tags = dlg.GetTags() button_label = HydrusData.ConvertIntToPrettyString( len(explicit_tags)) + ' explicit tags' explicit_button.SetLabelText(button_label) self._service_keys_to_explicit_button_info[service_key] = ( explicit_tags, explicit_button) wx.PostEvent( self, wx.CommandEvent(commandType=wx.wxEVT_COMMAND_MENU_SELECTED, winid=ClientCaches.MENU_EVENT_ID_TO_ACTION_CACHE. GetTemporaryId('import_tag_options_changed')))
def EventDeleteLocalDeleted(self, event): message = 'This will clear the client\'s memory of which files it has locally deleted, which affects \'exclude previously deleted files\' import tests.' message += os.linesep * 2 message += 'It will freeze the gui while it works.' message += os.linesep * 2 message += 'If you do not know what this does, click \'forget it\'.' with ClientGUIDialogs.DialogYesNo(self, message, yes_label='do it', no_label='forget it') as dlg_add: result = dlg_add.ShowModal() if result == wx.ID_YES: content_update = HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ADVANCED, ('delete_deleted', None)) service_keys_to_content_updates = { self._service_key: [content_update] } HydrusGlobals.client_controller.Write( 'content_updates', service_keys_to_content_updates) self._DisplayService()
def EditIPFSNotes(self): for (multihash, num_files, total_size, note) in self._ipfs_shares.GetSelectedClientData(): with ClientGUIDialogs.DialogTextEntry( self, 'Set a note for ' + multihash + '.') as dlg: if dlg.ShowModal() == wx.ID_OK: hashes = self._controller.Read('service_directory', self._service_key, multihash) note = dlg.GetValue() content_update_row = (hashes, multihash, note) content_updates = [ HydrusData.ContentUpdate(HC.CONTENT_TYPE_DIRECTORIES, HC.CONTENT_UPDATE_ADD, content_update_row) ] HydrusGlobals.client_controller.WriteSynchronous( 'content_updates', {self._service_key: content_updates}) self._DisplayService()
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 == 'copy_seed_notes': self._CopySelectedNotes() elif command == 'copy_seeds': self._CopySelectedSeeds() elif command == 'delete_seeds': message = 'Are you sure you want to delete all the selected entries?' with ClientGUIDialogs.DialogYesNo( self, message ) as dlg: if dlg.ShowModal() == wx.ID_YES: self._DeleteSelected() elif command == 'set_seed_unknown': self._SetSelected( CC.STATUS_UNKNOWN ) elif command == 'set_seed_skipped': self._SetSelected( CC.STATUS_SKIPPED ) else: event.Skip()
def InitDB(self): try: def make_temp_files_deletable(function_called, path, traceback_gumpf): os.chmod(path, stat.S_IWRITE) try: function_called(path) # try again except: pass if os.path.exists(HC.TEMP_DIR): shutil.rmtree(HC.TEMP_DIR, onerror=make_temp_files_deletable) except: pass try: if not os.path.exists(HC.TEMP_DIR): os.mkdir(HC.TEMP_DIR) except: pass db_initialised = False while not db_initialised: try: self._db = ClientDB.DB() db_initialised = True except HydrusExceptions.DBAccessException as e: try: print(HC.u(e)) except: print(repr(HC.u(e))) 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 * 2 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, 'There was a problem connecting to the database.', yes_label='wait a bit, then try again', no_label='forget it') as dlg: if dlg.ShowModal() == wx.ID_YES: time.sleep(3) else: raise HydrusExceptions.PermissionException() threading.Thread(target=self._db.MainLoop, name='Database Main Loop').start()
def TryToClose( self ): if self._job_key.IsDone(): self._ReleaseMessage() else: if self._job_key.IsCancellable(): with ClientGUIDialogs.DialogYesNo( self, 'Cancel/stop job?' ) as dlg: if dlg.ShowModal() == wx.ID_YES: self._job_key.Cancel() self._ReleaseMessage() else: raise HydrusExceptions.VetoException() else: raise HydrusExceptions.VetoException( 'Unfortunately, this job cannot be cancelled. If it really is taking too long, please kill the client through task manager.' )
def EditQuickNamespaces(self): data_to_edit = self._quick_namespaces_list.GetData( only_selected=True) for old_data in data_to_edit: (namespace, regex) = old_data import ClientGUIDialogs with ClientGUIDialogs.DialogInputNamespaceRegex( self, namespace=namespace, regex=regex) as dlg: if dlg.ShowModal() == wx.ID_OK: (new_namespace, new_regex) = dlg.GetInfo() new_data = (new_namespace, new_regex) if new_data != old_data: self._quick_namespaces_list.DeleteDatas( (old_data, )) self._quick_namespaces_list.AddDatas((new_data, )) self._refresh_callable()
def _OpenSelectedSeedData(self): seeds = self._list_ctrl.GetData(only_selected=True) if len(seeds) > 0: if len(seeds) > 10: message = 'You have many objects selected--are you sure you want to open them all?' with ClientGUIDialogs.DialogYesNo(self, message) as dlg: if dlg.ShowModal() != wx.ID_YES: return if seeds[0].seed_data.startswith('http'): for seed in seeds: webbrowser.open(seed.seed_data) else: try: for seed in seeds: HydrusPaths.OpenFileLocation(seed.seed_data) except Exception as e: wx.MessageBox(HydrusData.ToUnicode(e))
def FetchTags( self ): script = self._script_choice.GetChoice() if script.UsesUserInput(): message = 'Enter the custom input for the file lookup script.' with ClientGUIDialogs.DialogTextEntry( self, message ) as dlg: if dlg.ShowModal() != wx.ID_OK: return file_identifier = dlg.GetValue() else: ( m, ) = self._media file_identifier = script.ConvertMediaToFileIdentifier( m ) stop_time = HydrusData.GetNow() + 30 job_key = ClientThreading.JobKey( cancellable = True, stop_time = stop_time ) self._script_management.SetJobKey( job_key ) HG.client_controller.CallToThread( self.THREADFetchTags, script, job_key, file_identifier )
def RestoreDatabase(self): with wx.DirDialog(self._gui, 'Select backup location.') as dlg: if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() text = 'Are you sure you want to restore a backup from "' + path + '"?' text += os.linesep * 2 text += 'Everything in your current database will be deleted!' text += os.linesep * 2 text += 'The gui will shut down, and then it will take a while to complete the restore. Once it is done, the client will restart.' with ClientGUIDialogs.DialogYesNo(self._gui, text) as dlg_yn: if dlg_yn.ShowModal() == wx.ID_YES: self._gui.Hide() self._gui.Close() self._db.Shutdown() while not self._db.LoopIsFinished(): time.sleep(0.1) self._db.RestoreBackup(path) call_stuff = [sys.executable] call_stuff.extend(sys.argv) subprocess.Popen(call_stuff, shell=True)
def _Delete( self ): with ClientGUIDialogs.DialogYesNo( self, 'Remove all selected?' ) as dlg: if dlg.ShowModal() == wx.ID_YES: self._listctrl.RemoveAllSelected()
def EditBoorus(self): writes = [] for (name, text, timeout, (num_hashes, hashes, share_key)) in self._booru_shares.GetSelectedClientData(): with ClientGUIDialogs.DialogInputLocalBooruShare( self, share_key, name, text, timeout, hashes, new_share=False) as dlg: if dlg.ShowModal() == wx.ID_OK: (share_key, name, text, timeout, hashes) = dlg.GetInfo() info = {} info['name'] = name info['text'] = text info['timeout'] = timeout info['hashes'] = hashes writes.append((share_key, info)) for (share_key, info) in writes: self._controller.Write('local_booru_share', share_key, info)
def Exit(self): if HydrusGlobals.emergency_exit: self.ShutdownView() self.ShutdownModel() else: try: self.CreateSplash() idle_shutdown_action = self._options['idle_shutdown'] if idle_shutdown_action in (CC.IDLE_ON_SHUTDOWN, CC.IDLE_ON_SHUTDOWN_ASK_FIRST): idle_shutdown_max_minutes = self._options[ 'idle_shutdown_max_minutes'] time_to_stop = HydrusData.GetNow() + ( idle_shutdown_max_minutes * 60) if self.ThereIsIdleShutdownWorkDue(time_to_stop): if idle_shutdown_action == CC.IDLE_ON_SHUTDOWN_ASK_FIRST: text = 'Is now a good time for the client to do up to ' + HydrusData.ConvertIntToPrettyString( idle_shutdown_max_minutes ) + ' minutes\' maintenance work?' with ClientGUIDialogs.DialogYesNo( self._splash, text, title='Maintenance is due') as dlg_yn: if dlg_yn.ShowModal() == wx.ID_YES: HydrusGlobals.do_idle_shutdown_work = True else: HydrusGlobals.do_idle_shutdown_work = True exit_thread = threading.Thread( target=self.THREADExitEverything, name='Application Exit Thread') exit_thread.start() except: self.pub('splash_destroy') HydrusData.DebugPrint(traceback.format_exc()) HydrusGlobals.emergency_exit = True self.Exit()
def _Add( self ): with ClientGUIDialogs.DialogTextEntry( self, 'enter the key', allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: key = dlg.GetValue() with ClientGUIDialogs.DialogTextEntry( self, 'enter the value', allow_blank = True ) as dlg: if dlg.ShowModal() == wx.ID_OK: value = dlg.GetValue() data = ( key, value ) self._listctrl.AddDatas( ( data, ) )
def test_dialog_yes_no(self): with ClientGUIDialogs.DialogYesNo(None, 'hello') as dlg: HitButton(dlg._yes) result = dlg.ShowModal() self.assertEqual(result, wx.ID_YES) with ClientGUIDialogs.DialogYesNo(None, 'hello') as dlg: HitButton(dlg._no) result = dlg.ShowModal() self.assertEqual(result, wx.ID_NO)
def _Reset(self): name = self._service.GetName() message = 'This will remove all the processed information for ' + name + ' from the database, setting the \'processed\' gauge back to 0.' + os.linesep * 2 + 'Once the service is reset, you will have to reprocess everything that has been downloaded over again. The client will naturally do this in its idle time as before, just starting over from the beginning.' + os.linesep * 2 + 'If you do not understand what this does, click no!' with ClientGUIDialogs.DialogYesNo(self, message) as dlg: if dlg.ShowModal() == wx.ID_YES: message = 'Seriously, are you absolutely sure?' with ClientGUIDialogs.DialogYesNo(self, message) as dlg2: if dlg2.ShowModal() == wx.ID_YES: self._service.Reset()
def Add( self ): with ClientGUIDialogs.DialogTextEntry( self, 'enter the key', allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: key = dlg.GetValue() with ClientGUIDialogs.DialogTextEntry( self, 'enter the value', allow_blank = True ) as dlg: if dlg.ShowModal() == wx.ID_OK: value = dlg.GetValue() display_tuple = ( key, value ) self._listctrl.Append( display_tuple, display_tuple )
def test_dialog_first_start( self ): with ClientGUIDialogs.DialogFirstStart( None ) as dlg: HitCancelButton( dlg ) result = dlg.ShowModal() self.assertEqual( result, wx.ID_CANCEL ) with ClientGUIDialogs.DialogFirstStart( None ) as dlg: HitButton( dlg._ok ) result = dlg.ShowModal() self.assertEqual( result, wx.ID_OK )
def Exit( self ): if HG.emergency_exit: self.ShutdownView() self.ShutdownModel() else: try: self._CreateSplash() idle_shutdown_action = self.options[ 'idle_shutdown' ] if idle_shutdown_action in ( CC.IDLE_ON_SHUTDOWN, CC.IDLE_ON_SHUTDOWN_ASK_FIRST ): idle_shutdown_max_minutes = self.options[ 'idle_shutdown_max_minutes' ] time_to_stop = HydrusData.GetNow() + ( idle_shutdown_max_minutes * 60 ) if self.ThereIsIdleShutdownWorkDue( time_to_stop ): if idle_shutdown_action == CC.IDLE_ON_SHUTDOWN_ASK_FIRST: text = 'Is now a good time for the client to do up to ' + HydrusData.ConvertIntToPrettyString( idle_shutdown_max_minutes ) + ' minutes\' maintenance work? (Will auto-no in 15 seconds)' with ClientGUIDialogs.DialogYesNo( self._splash, text, title = 'Maintenance is due' ) as dlg_yn: call_later = wx.CallLater( 15000, dlg_yn.EndModal, wx.ID_NO ) if dlg_yn.ShowModal() == wx.ID_YES: HG.do_idle_shutdown_work = True call_later.Stop() else: HG.do_idle_shutdown_work = True self.CallToThreadLongRunning( self.THREADExitEverything ) except: self._DestroySplash() HydrusData.DebugPrint( traceback.format_exc() ) HG.emergency_exit = True self.Exit()
def ShowDeleteSelectedDialog(self): import ClientGUIDialogs with ClientGUIDialogs.DialogYesNo(self, 'Remove all selected?') as dlg: if dlg.ShowModal() == wx.ID_YES: self.DeleteSelected()
def _RetryFailures(self): message = 'Are you sure you want to retry all the failed files?' with ClientGUIDialogs.DialogYesNo(self, message) as dlg: if dlg.ShowModal() == wx.ID_YES: seed_cache = self._seed_cache_get_callable() seed_cache.RetryFailures()
def wx_code(): message = 'It looks like another instance of this client is already running, so this instance cannot start.' message += os.linesep * 2 message += 'If the old instance is closing and does not quit for a _very_ long time, it is usually safe to force-close it from task manager.' with ClientGUIDialogs.DialogYesNo( self._splash, message, 'The client is already running.', yes_label = 'wait a bit, then try again', no_label = 'forget it' ) as dlg: if dlg.ShowModal() != wx.ID_YES: raise HydrusExceptions.PermissionException()
def _ClearProcessed(self): message = 'Are you sure you want to delete all the processed (i.e. anything with a non-blank status in the larger window) files? This is useful for cleaning up and de-laggifying a very large list, but not much else.' with ClientGUIDialogs.DialogYesNo(self, message) as dlg: if dlg.ShowModal() == wx.ID_YES: seed_cache = self._seed_cache_get_callable() seed_cache.RemoveProcessedSeeds()
def test_dialog_select_booru( self ): HC.app.SetRead( 'remote_boorus', CC.DEFAULT_BOORUS ) with ClientGUIDialogs.DialogSelectBooru( None ) as dlg: HitCancelButton( dlg ) result = dlg.ShowModal() self.assertEqual( result, wx.ID_CANCEL )