hydrus/include/ClientGUIFileSeedCache.py

726 lines
25 KiB
Python
Raw Normal View History

2017-07-27 00:47:13 +00:00
import ClientConstants as CC
import ClientGUICommon
import ClientGUIDialogs
2017-08-02 21:32:54 +00:00
import ClientGUIListCtrl
2017-07-27 00:47:13 +00:00
import ClientGUIMenus
2017-12-20 22:55:48 +00:00
import ClientGUISerialisable
2017-07-27 00:47:13 +00:00
import ClientGUIScrolledPanels
import ClientGUITopLevelWindows
2018-06-27 19:27:05 +00:00
import ClientImportFileSeeds
2018-05-09 20:23:00 +00:00
import ClientPaths
2017-12-20 22:55:48 +00:00
import ClientSerialisable
2018-01-03 22:37:30 +00:00
import ClientThreading
2017-07-27 00:47:13 +00:00
import HydrusConstants as HC
import HydrusData
import HydrusGlobals as HG
2017-12-13 22:33:07 +00:00
import HydrusPaths
2017-12-20 22:55:48 +00:00
import HydrusText
2017-07-27 00:47:13 +00:00
import os
import wx
2018-06-27 19:27:05 +00:00
class EditFileSeedCachePanel( ClientGUIScrolledPanels.EditPanel ):
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
def __init__( self, parent, controller, file_seed_cache ):
2017-07-27 00:47:13 +00:00
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
self._controller = controller
2018-06-27 19:27:05 +00:00
self._file_seed_cache = file_seed_cache
2017-07-27 00:47:13 +00:00
self._text = ClientGUICommon.BetterStaticText( self, 'initialising' )
2018-06-27 19:27:05 +00:00
# add index control row here, hide it if needed and hook into showing/hiding and postsizechangedevent on file_seed add/remove
2017-07-27 00:47:13 +00:00
2017-09-27 21:52:54 +00:00
columns = [ ( '#', 3 ), ( 'source', -1 ), ( 'status', 12 ), ( 'added', 23 ), ( 'last modified', 23 ), ( 'source time', 23 ), ( 'note', 20 ) ]
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
self._list_ctrl = ClientGUIListCtrl.BetterListCtrl( self, 'file_seed_cache', 30, 30, columns, self._ConvertFileSeedToListCtrlTuples, delete_key_callback = self._DeleteSelected )
2017-07-27 00:47:13 +00:00
#
2018-06-27 19:27:05 +00:00
self._list_ctrl.AddDatas( self._file_seed_cache.GetFileSeeds() )
2017-07-27 00:47:13 +00:00
2017-08-30 20:27:47 +00:00
self._list_ctrl.Sort( 0 )
2017-07-27 00:47:13 +00:00
#
vbox = wx.BoxSizer( wx.VERTICAL )
2018-01-03 22:37:30 +00:00
vbox.Add( self._text, CC.FLAGS_EXPAND_PERPENDICULAR )
vbox.Add( self._list_ctrl, CC.FLAGS_EXPAND_BOTH_WAYS )
2017-07-27 00:47:13 +00:00
self.SetSizer( vbox )
self._list_ctrl.Bind( wx.EVT_RIGHT_DOWN, self.EventShowMenu )
2018-06-27 19:27:05 +00:00
self._controller.sub( self, 'NotifyFileSeedsUpdated', 'file_seed_cache_file_seeds_updated' )
2017-07-27 00:47:13 +00:00
wx.CallAfter( self._UpdateText )
2018-06-27 19:27:05 +00:00
def _ConvertFileSeedToListCtrlTuples( self, file_seed ):
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
try:
file_seed_index = self._file_seed_cache.GetFileSeedIndex( file_seed )
except:
file_seed_index = '--'
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
file_seed_data = file_seed.file_seed_data
status = file_seed.status
added = file_seed.created
modified = file_seed.modified
source_time = file_seed.source_time
note = file_seed.note
2017-07-27 00:47:13 +00:00
2018-07-04 20:48:28 +00:00
pretty_file_seed_index = HydrusData.ToHumanInt( file_seed_index )
2018-06-27 19:27:05 +00:00
pretty_file_seed_data = HydrusData.ToUnicode( file_seed_data )
2017-07-27 00:47:13 +00:00
pretty_status = CC.status_string_lookup[ status ]
2018-07-04 20:48:28 +00:00
pretty_added = HydrusData.TimestampToPrettyTimeDelta( added )
pretty_modified = HydrusData.TimestampToPrettyTimeDelta( modified )
2017-09-27 21:52:54 +00:00
2017-11-29 21:48:23 +00:00
if source_time is None:
2017-09-27 21:52:54 +00:00
pretty_source_time = 'unknown'
else:
2018-07-04 20:48:28 +00:00
pretty_source_time = HydrusData.TimestampToPrettyTimeDelta( source_time )
2017-09-27 21:52:54 +00:00
2017-07-27 00:47:13 +00:00
pretty_note = note.split( os.linesep )[0]
2018-06-27 19:27:05 +00:00
display_tuple = ( pretty_file_seed_index, pretty_file_seed_data, pretty_status, pretty_added, pretty_modified, pretty_source_time, pretty_note )
sort_tuple = ( file_seed_index, file_seed_data, status, added, modified, source_time, note )
2017-07-27 00:47:13 +00:00
return ( display_tuple, sort_tuple )
def _CopySelectedNotes( self ):
notes = []
2018-06-27 19:27:05 +00:00
for file_seed in self._list_ctrl.GetData( only_selected = True ):
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
note = file_seed.note
2017-07-27 00:47:13 +00:00
if note != '':
notes.append( note )
if len( notes ) > 0:
separator = os.linesep * 2
text = separator.join( notes )
HG.client_controller.pub( 'clipboard', 'text', text )
2018-06-27 19:27:05 +00:00
def _CopySelectedFileSeedData( self ):
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
file_seeds = self._list_ctrl.GetData( only_selected = True )
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
if len( file_seeds ) > 0:
2017-07-27 00:47:13 +00:00
separator = os.linesep * 2
2018-06-27 19:27:05 +00:00
text = separator.join( ( file_seed.file_seed_data for file_seed in file_seeds ) )
2017-07-27 00:47:13 +00:00
HG.client_controller.pub( 'clipboard', 'text', text )
def _DeleteSelected( self ):
2018-06-27 19:27:05 +00:00
file_seeds_to_delete = self._list_ctrl.GetData( only_selected = True )
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
if len( file_seeds_to_delete ) > 0:
2017-07-27 00:47:13 +00:00
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:
2018-06-27 19:27:05 +00:00
self._file_seed_cache.RemoveFileSeeds( file_seeds_to_delete )
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
def _OpenSelectedFileSeedData( self ):
2017-12-13 22:33:07 +00:00
2018-06-27 19:27:05 +00:00
file_seeds = self._list_ctrl.GetData( only_selected = True )
2017-12-13 22:33:07 +00:00
2018-06-27 19:27:05 +00:00
if len( file_seeds ) > 0:
2017-12-13 22:33:07 +00:00
2018-06-27 19:27:05 +00:00
if len( file_seeds ) > 10:
2017-12-13 22:33:07 +00:00
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
2018-06-27 19:27:05 +00:00
if file_seeds[0].file_seed_data.startswith( 'http' ):
2017-12-13 22:33:07 +00:00
2018-06-27 19:27:05 +00:00
for file_seed in file_seeds:
2017-12-13 22:33:07 +00:00
2018-06-27 19:27:05 +00:00
ClientPaths.LaunchURLInWebBrowser( file_seed.file_seed_data )
2017-12-13 22:33:07 +00:00
else:
try:
2018-06-27 19:27:05 +00:00
for file_seed in file_seeds:
2017-12-13 22:33:07 +00:00
2018-06-27 19:27:05 +00:00
HydrusPaths.OpenFileLocation( file_seed.file_seed_data )
2017-12-13 22:33:07 +00:00
except Exception as e:
2018-03-14 21:01:02 +00:00
wx.MessageBox( HydrusData.ToUnicode( e ) )
2017-12-13 22:33:07 +00:00
2017-07-27 00:47:13 +00:00
def _SetSelected( self, status_to_set ):
2018-06-27 19:27:05 +00:00
file_seeds = self._list_ctrl.GetData( only_selected = True )
2017-11-29 21:48:23 +00:00
2018-06-27 19:27:05 +00:00
for file_seed in file_seeds:
2017-11-29 21:48:23 +00:00
2018-06-27 19:27:05 +00:00
file_seed.SetStatus( status_to_set )
2017-11-29 21:48:23 +00:00
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
self._file_seed_cache.NotifyFileSeedsUpdated( file_seeds )
2017-07-27 00:47:13 +00:00
def _ShowMenuIfNeeded( self ):
2018-06-27 19:27:05 +00:00
selected_file_seeds = self._list_ctrl.GetData( only_selected = True )
2018-05-09 20:23:00 +00:00
2018-06-27 19:27:05 +00:00
if len( selected_file_seeds ) > 0:
2017-07-27 00:47:13 +00:00
menu = wx.Menu()
2018-06-27 19:27:05 +00:00
can_show_files_in_new_page = True in ( file_seed.HasHash() for file_seed in selected_file_seeds )
2018-05-09 20:23:00 +00:00
if can_show_files_in_new_page:
ClientGUIMenus.AppendMenuItem( self, menu, 'open selected import files in a new page', 'Show all the known selected files in a new thumbnail page. This is complicated, so cannot always be guaranteed, even if the import says \'success\'.', self._ShowSelectionInNewPage )
ClientGUIMenus.AppendSeparator( menu )
2018-06-27 19:27:05 +00:00
ClientGUIMenus.AppendMenuItem( self, menu, 'copy sources', 'Copy all the selected sources to clipboard.', self._CopySelectedFileSeedData )
2017-07-27 00:47:13 +00:00
ClientGUIMenus.AppendMenuItem( self, menu, 'copy notes', 'Copy all the selected notes to clipboard.', self._CopySelectedNotes )
ClientGUIMenus.AppendSeparator( menu )
2017-12-13 22:33:07 +00:00
2018-06-27 19:27:05 +00:00
ClientGUIMenus.AppendMenuItem( self, menu, 'open sources', 'Open all the selected sources in your file explorer or web browser.', self._OpenSelectedFileSeedData )
2017-12-13 22:33:07 +00:00
ClientGUIMenus.AppendSeparator( menu )
2017-07-27 00:47:13 +00:00
ClientGUIMenus.AppendMenuItem( self, menu, 'try again', 'Reset the progress of all the selected imports.', HydrusData.Call( self._SetSelected, CC.STATUS_UNKNOWN ) )
ClientGUIMenus.AppendMenuItem( self, menu, 'skip', 'Skip all the selected imports.', HydrusData.Call( self._SetSelected, CC.STATUS_SKIPPED ) )
2018-01-10 22:41:51 +00:00
ClientGUIMenus.AppendMenuItem( self, menu, 'delete from list', 'Remove all the selected imports.', self._DeleteSelected )
2017-07-27 00:47:13 +00:00
HG.client_controller.PopupMenu( self, menu )
2018-05-09 20:23:00 +00:00
def _ShowSelectionInNewPage( self ):
hashes = []
2018-06-27 19:27:05 +00:00
for file_seed in self._list_ctrl.GetData( only_selected = True ):
2018-05-09 20:23:00 +00:00
2018-06-27 19:27:05 +00:00
if file_seed.HasHash():
2018-05-09 20:23:00 +00:00
2018-06-27 19:27:05 +00:00
hashes.append( file_seed.GetHash() )
2018-05-09 20:23:00 +00:00
if len( hashes ) > 0:
HG.client_controller.pub( 'new_page_query', CC.LOCAL_FILE_SERVICE_KEY, initial_hashes = hashes )
2018-06-27 19:27:05 +00:00
def _UpdateListCtrl( self, file_seeds ):
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
file_seeds_to_add = []
file_seeds_to_update = []
file_seeds_to_delete = []
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
for file_seed in file_seeds:
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
if self._file_seed_cache.HasFileSeed( file_seed ):
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
if self._list_ctrl.HasData( file_seed ):
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
file_seeds_to_update.append( file_seed )
2017-07-27 00:47:13 +00:00
else:
2018-06-27 19:27:05 +00:00
file_seeds_to_add.append( file_seed )
2017-07-27 00:47:13 +00:00
else:
2018-06-27 19:27:05 +00:00
if self._list_ctrl.HasData( file_seed ):
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
file_seeds_to_delete.append( file_seed )
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
self._list_ctrl.DeleteDatas( file_seeds_to_delete )
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
if len( file_seeds_to_add ) > 0:
2018-06-20 20:20:22 +00:00
2018-06-27 19:27:05 +00:00
self._list_ctrl.AddDatas( file_seeds_to_add )
2018-06-20 20:20:22 +00:00
2018-06-27 19:27:05 +00:00
# if file_seeds are inserted, then all subsequent indices need to be shuffled up, hence just update all here
2018-06-20 20:20:22 +00:00
self._list_ctrl.UpdateDatas()
else:
2018-06-27 19:27:05 +00:00
self._list_ctrl.UpdateDatas( file_seeds_to_update )
2018-06-20 20:20:22 +00:00
2017-07-27 00:47:13 +00:00
def _UpdateText( self ):
2018-07-04 20:48:28 +00:00
( status, simple_status, ( total_processed, total ) ) = self._file_seed_cache.GetStatus()
2017-07-27 00:47:13 +00:00
self._text.SetLabelText( status )
self.Layout()
def EventShowMenu( self, event ):
wx.CallAfter( self._ShowMenuIfNeeded )
event.Skip() # let the right click event go through before doing menu, in case selection should happen
def GetValue( self ):
2018-06-27 19:27:05 +00:00
return self._file_seed_cache
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
def NotifyFileSeedsUpdated( self, file_seed_cache_key, file_seeds ):
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
if file_seed_cache_key == self._file_seed_cache.GetFileSeedCacheKey():
2017-07-27 00:47:13 +00:00
self._UpdateText()
2018-06-27 19:27:05 +00:00
self._UpdateListCtrl( file_seeds )
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
class FileSeedCacheButton( ClientGUICommon.BetterBitmapButton ):
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
def __init__( self, parent, controller, file_seed_cache_get_callable, file_seed_cache_set_callable = None ):
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
ClientGUICommon.BetterBitmapButton.__init__( self, parent, CC.GlobalBMPs.listctrl, self._ShowFileSeedCacheFrame )
2017-10-18 19:41:25 +00:00
self._controller = controller
2018-06-27 19:27:05 +00:00
self._file_seed_cache_get_callable = file_seed_cache_get_callable
self._file_seed_cache_set_callable = file_seed_cache_set_callable
2017-10-18 19:41:25 +00:00
2018-01-03 22:37:30 +00:00
self.SetToolTip( 'open detailed file import status--right-click for quick actions, if applicable' )
2017-10-18 19:41:25 +00:00
self.Bind( wx.EVT_RIGHT_DOWN, self.EventShowMenu )
2018-06-27 19:27:05 +00:00
def _ClearFileSeeds( self, statuses_to_remove ):
2017-10-18 19:41:25 +00:00
2018-05-09 20:23:00 +00:00
message = 'Are you sure you want to delete all the ' + '/'.join( ( CC.status_string_lookup[ status ] for status in statuses_to_remove ) ) + ' file import items? This is useful for cleaning up and de-laggifying a very large list, but be careful you aren\'t removing something you would want to revisit or what watcher/subscription may be using for future check time calculations.'
2017-10-18 19:41:25 +00:00
with ClientGUIDialogs.DialogYesNo( self, message ) as dlg:
if dlg.ShowModal() == wx.ID_YES:
2018-06-27 19:27:05 +00:00
file_seed_cache = self._file_seed_cache_get_callable()
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
file_seed_cache.RemoveFileSeedsByStatus( statuses_to_remove )
2018-01-10 22:41:51 +00:00
2017-12-20 22:55:48 +00:00
def _GetExportableSourcesString( self ):
2018-06-27 19:27:05 +00:00
file_seed_cache = self._file_seed_cache_get_callable()
2017-12-20 22:55:48 +00:00
2018-06-27 19:27:05 +00:00
file_seeds = file_seed_cache.GetFileSeeds()
2017-12-20 22:55:48 +00:00
2018-06-27 19:27:05 +00:00
sources = [ file_seed.file_seed_data for file_seed in file_seeds ]
2017-12-20 22:55:48 +00:00
return os.linesep.join( sources )
def _GetSourcesFromSourcesString( self, sources_string ):
sources_string = HydrusData.ToUnicode( sources_string )
sources = HydrusText.DeserialiseNewlinedTexts( sources_string )
return sources
def _ImportFromClipboard( self ):
raw_text = HG.client_controller.GetClipboardText()
sources = self._GetSourcesFromSourcesString( raw_text )
try:
self._ImportSources( sources )
except:
wx.MessageBox( 'Could not import!' )
raise
def _ImportFromPng( self ):
with wx.FileDialog( self, 'select the png with the sources', wildcard = 'PNG (*.png)|*.png' ) as dlg:
if dlg.ShowModal() == wx.ID_OK:
path = HydrusData.ToUnicode( dlg.GetPath() )
payload = ClientSerialisable.LoadFromPng( path )
try:
sources = self._GetSourcesFromSourcesString( payload )
self._ImportSources( sources )
except:
wx.MessageBox( 'Could not import!' )
raise
def _ImportSources( self, sources ):
2018-06-27 19:27:05 +00:00
file_seed_cache = self._file_seed_cache_get_callable()
2017-12-20 22:55:48 +00:00
if sources[0].startswith( 'http' ):
2018-06-27 19:27:05 +00:00
file_seed_type = ClientImportFileSeeds.FILE_SEED_TYPE_URL
2017-12-20 22:55:48 +00:00
else:
2018-06-27 19:27:05 +00:00
file_seed_type = ClientImportFileSeeds.FILE_SEED_TYPE_HDD
2017-12-20 22:55:48 +00:00
2018-06-27 19:27:05 +00:00
file_seeds = [ ClientImportFileSeeds.FileSeed( file_seed_type, source ) for source in sources ]
2018-03-14 21:01:02 +00:00
2018-06-27 19:27:05 +00:00
file_seed_cache.AddFileSeeds( file_seeds )
2018-03-14 21:01:02 +00:00
2017-12-20 22:55:48 +00:00
def _ExportToPng( self ):
payload = self._GetExportableSourcesString()
with ClientGUITopLevelWindows.DialogNullipotent( self, 'export to png' ) as dlg:
panel = ClientGUISerialisable.PngExportPanel( dlg, payload )
dlg.SetPanel( panel )
dlg.ShowModal()
def _ExportToClipboard( self ):
payload = self._GetExportableSourcesString()
HG.client_controller.pub( 'clipboard', 'text', payload )
2018-04-25 22:07:52 +00:00
def _RetryErrors( self ):
2017-10-18 19:41:25 +00:00
2018-04-25 22:07:52 +00:00
message = 'Are you sure you want to retry all the files that encountered errors?'
2017-10-18 19:41:25 +00:00
with ClientGUIDialogs.DialogYesNo( self, message ) as dlg:
if dlg.ShowModal() == wx.ID_YES:
2018-06-27 19:27:05 +00:00
file_seed_cache = self._file_seed_cache_get_callable()
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
file_seed_cache.RetryFailures()
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
def _ShowFileSeedCacheFrame( self ):
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
file_seed_cache = self._file_seed_cache_get_callable()
2017-10-18 19:41:25 +00:00
tlp = ClientGUICommon.GetTLP( self )
if isinstance( tlp, wx.Dialog ):
2018-06-27 19:27:05 +00:00
if self._file_seed_cache_set_callable is None: # throw up a dialog that edits the file_seed cache in place
2017-10-18 19:41:25 +00:00
with ClientGUITopLevelWindows.DialogNullipotent( self, 'file import status' ) as dlg:
2018-06-27 19:27:05 +00:00
panel = EditFileSeedCachePanel( dlg, self._controller, file_seed_cache )
2017-10-18 19:41:25 +00:00
dlg.SetPanel( panel )
dlg.ShowModal()
2018-06-27 19:27:05 +00:00
else: # throw up a dialog that edits the file_seed cache but can be cancelled
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
dupe_file_seed_cache = file_seed_cache.Duplicate()
2017-10-18 19:41:25 +00:00
with ClientGUITopLevelWindows.DialogEdit( self, 'file import status' ) as dlg:
2018-06-27 19:27:05 +00:00
panel = EditFileSeedCachePanel( dlg, self._controller, dupe_file_seed_cache )
2017-10-18 19:41:25 +00:00
dlg.SetPanel( panel )
if dlg.ShowModal() == wx.ID_OK:
2018-06-27 19:27:05 +00:00
self._file_seed_cache_set_callable( dupe_file_seed_cache )
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
else: # throw up a frame that edits the file_seed cache in place
2017-10-18 19:41:25 +00:00
title = 'file import status'
frame_key = 'file_import_status'
frame = ClientGUITopLevelWindows.FrameThatTakesScrollablePanel( self, title, frame_key )
2018-06-27 19:27:05 +00:00
panel = EditFileSeedCachePanel( frame, self._controller, file_seed_cache )
2017-10-18 19:41:25 +00:00
frame.SetPanel( panel )
def EventShowMenu( self, event ):
2017-12-20 22:55:48 +00:00
menu = wx.Menu()
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
file_seed_cache = self._file_seed_cache_get_callable()
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
num_file_seeds = len( file_seed_cache )
num_successful = file_seed_cache.GetFileSeedCount( CC.STATUS_SUCCESSFUL_AND_NEW ) + file_seed_cache.GetFileSeedCount( CC.STATUS_SUCCESSFUL_BUT_REDUNDANT )
2018-07-04 20:48:28 +00:00
num_vetoed = file_seed_cache.GetFileSeedCount( CC.STATUS_VETOED )
num_deleted_and_vetoed = file_seed_cache.GetFileSeedCount( CC.STATUS_DELETED ) + num_vetoed
2018-06-27 19:27:05 +00:00
num_errors = file_seed_cache.GetFileSeedCount( CC.STATUS_ERROR )
num_skipped = file_seed_cache.GetFileSeedCount( CC.STATUS_SKIPPED )
2017-10-18 19:41:25 +00:00
2018-04-25 22:07:52 +00:00
if num_errors > 0:
2017-10-18 19:41:25 +00:00
2018-07-04 20:48:28 +00:00
ClientGUIMenus.AppendMenuItem( self, menu, 'retry ' + HydrusData.ToHumanInt( num_errors ) + ' error failures', 'Tell this cache to reattempt all its error failures.', self._RetryErrors )
2017-10-18 19:41:25 +00:00
2018-07-04 20:48:28 +00:00
if num_vetoed > 0:
ClientGUIMenus.AppendMenuItem( self, menu, 'retry ' + HydrusData.ToHumanInt( num_errors ) + ' ignored', 'Tell this cache to reattempt all its ignored/vetoed results.', self._RetryIgnored )
ClientGUIMenus.AppendSeparator( menu )
2018-01-10 22:41:51 +00:00
if num_successful > 0:
2018-05-09 20:23:00 +00:00
num_deletees = num_successful
2018-07-04 20:48:28 +00:00
ClientGUIMenus.AppendMenuItem( self, menu, 'delete ' + HydrusData.ToHumanInt( num_deletees ) + ' successful file import items from the queue', 'Tell this cache to clear out successful files, reducing the size of the queue.', self._ClearFileSeeds, ( CC.STATUS_SUCCESSFUL_AND_NEW, CC.STATUS_SUCCESSFUL_BUT_REDUNDANT ) )
2018-01-10 22:41:51 +00:00
2018-05-09 20:23:00 +00:00
if num_deleted_and_vetoed > 0:
num_deletees = num_deleted_and_vetoed
2018-07-04 20:48:28 +00:00
ClientGUIMenus.AppendMenuItem( self, menu, 'delete ' + HydrusData.ToHumanInt( num_deletees ) + ' deleted/ignored file import items from the queue', 'Tell this cache to clear out deleted and ignored files, reducing the size of the queue.', self._ClearFileSeeds, ( CC.STATUS_DELETED, CC.STATUS_VETOED ) )
2018-05-09 20:23:00 +00:00
2017-10-18 19:41:25 +00:00
2018-05-09 20:23:00 +00:00
if num_errors + num_skipped > 0:
num_deletees = num_errors + num_skipped
2017-10-18 19:41:25 +00:00
2018-07-04 20:48:28 +00:00
ClientGUIMenus.AppendMenuItem( self, menu, 'delete ' + HydrusData.ToHumanInt( num_deletees ) + ' error/skipped file import items from the queue', 'Tell this cache to clear out errored and skipped files, reducing the size of the queue.', self._ClearFileSeeds, ( CC.STATUS_ERROR, CC.STATUS_SKIPPED ) )
2017-10-18 19:41:25 +00:00
2017-12-20 22:55:48 +00:00
ClientGUIMenus.AppendSeparator( menu )
2018-06-27 19:27:05 +00:00
if len( file_seed_cache ) > 0:
2017-10-18 19:41:25 +00:00
2017-12-20 22:55:48 +00:00
submenu = wx.Menu()
2017-10-18 19:41:25 +00:00
2017-12-20 22:55:48 +00:00
ClientGUIMenus.AppendMenuItem( self, submenu, 'to clipboard', 'Copy all the sources in this list to the clipboard.', self._ExportToClipboard )
ClientGUIMenus.AppendMenuItem( self, submenu, 'to png', 'Export all the sources in this list to a png file.', self._ExportToPng )
2017-10-18 19:41:25 +00:00
2017-12-20 22:55:48 +00:00
ClientGUIMenus.AppendMenu( menu, submenu, 'export all sources' )
2017-10-18 19:41:25 +00:00
2017-12-20 22:55:48 +00:00
submenu = wx.Menu()
ClientGUIMenus.AppendMenuItem( self, submenu, 'from clipboard', 'Import new urls or paths to this list from the clipboard.', self._ImportFromClipboard )
ClientGUIMenus.AppendMenuItem( self, submenu, 'from png', 'Import new urls or paths to this list from a png file.', self._ImportFromPng )
ClientGUIMenus.AppendMenu( menu, submenu, 'import new sources' )
HG.client_controller.PopupMenu( self, menu )
2017-10-18 19:41:25 +00:00
2018-06-27 19:27:05 +00:00
class FileSeedCacheStatusControl( wx.Panel ):
2017-07-27 00:47:13 +00:00
2018-05-09 20:23:00 +00:00
def __init__( self, parent, controller, page_key = None ):
2017-07-27 00:47:13 +00:00
wx.Panel.__init__( self, parent, style = wx.BORDER_DOUBLE )
self._controller = controller
2018-05-09 20:23:00 +00:00
self._page_key = page_key
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
self._file_seed_cache = None
2017-07-27 00:47:13 +00:00
self._import_summary_st = ClientGUICommon.BetterStaticText( self )
self._progress_st = ClientGUICommon.BetterStaticText( self )
2018-06-27 19:27:05 +00:00
self._file_seed_cache_button = FileSeedCacheButton( self, self._controller, self._GetFileSeedCache )
2017-07-27 00:47:13 +00:00
self._progress_gauge = ClientGUICommon.Gauge( self )
#
self._Update()
#
hbox = wx.BoxSizer( wx.HORIZONTAL )
2018-01-03 22:37:30 +00:00
hbox.Add( self._progress_st, CC.FLAGS_VCENTER_EXPAND_DEPTH_ONLY )
2018-06-27 19:27:05 +00:00
hbox.Add( self._file_seed_cache_button, CC.FLAGS_VCENTER )
2017-07-27 00:47:13 +00:00
vbox = wx.BoxSizer( wx.VERTICAL )
2018-01-03 22:37:30 +00:00
vbox.Add( self._import_summary_st, CC.FLAGS_EXPAND_PERPENDICULAR )
vbox.Add( hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
vbox.Add( self._progress_gauge, CC.FLAGS_EXPAND_PERPENDICULAR )
2017-07-27 00:47:13 +00:00
self.SetSizer( vbox )
#
2018-02-14 21:47:18 +00:00
HG.client_controller.gui.RegisterUIUpdateWindow( self )
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
def _GetFileSeedCache( self ):
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
return self._file_seed_cache
2017-07-27 00:47:13 +00:00
def _Update( self ):
2018-06-27 19:27:05 +00:00
if self._file_seed_cache is None:
2017-07-27 00:47:13 +00:00
self._import_summary_st.SetLabelText( '' )
self._progress_st.SetLabelText( '' )
self._progress_gauge.SetRange( 1 )
self._progress_gauge.SetValue( 0 )
2018-06-27 19:27:05 +00:00
if self._file_seed_cache_button.IsEnabled():
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
self._file_seed_cache_button.Disable()
2017-07-27 00:47:13 +00:00
else:
2018-07-04 20:48:28 +00:00
( import_summary, simple_status, ( num_done, num_to_do ) ) = self._file_seed_cache.GetStatus()
2017-07-27 00:47:13 +00:00
self._import_summary_st.SetLabelText( import_summary )
if num_to_do == 0:
self._progress_st.SetLabelText( '' )
else:
self._progress_st.SetLabelText( HydrusData.ConvertValueRangeToPrettyString( num_done, num_to_do ) )
self._progress_gauge.SetRange( num_to_do )
self._progress_gauge.SetValue( num_done )
2018-06-27 19:27:05 +00:00
if not self._file_seed_cache_button.IsEnabled():
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
self._file_seed_cache_button.Enable()
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
def SetFileSeedCache( self, file_seed_cache ):
2017-07-27 00:47:13 +00:00
2018-02-14 21:47:18 +00:00
if not self:
2017-07-27 00:47:13 +00:00
2018-02-14 21:47:18 +00:00
return
2017-07-27 00:47:13 +00:00
2018-06-27 19:27:05 +00:00
self._file_seed_cache = file_seed_cache
2018-02-14 21:47:18 +00:00
2017-07-27 00:47:13 +00:00
2018-02-14 21:47:18 +00:00
def TIMERUIUpdate( self ):
2017-07-27 00:47:13 +00:00
2018-05-09 20:23:00 +00:00
do_it_anyway = False
2018-06-27 19:27:05 +00:00
if self._file_seed_cache is not None:
2018-05-09 20:23:00 +00:00
2018-07-04 20:48:28 +00:00
( import_summary, simple_status, ( num_done, num_to_do ) ) = self._file_seed_cache.GetStatus()
2018-05-09 20:23:00 +00:00
( old_num_done, old_num_to_do ) = self._progress_gauge.GetValueRange()
if old_num_done != num_done or old_num_to_do != num_to_do:
if self._page_key is not None:
do_it_anyway = True # to update the gauge
HG.client_controller.pub( 'refresh_page_name', self._page_key )
if self._controller.gui.IShouldRegularlyUpdate( self ) or do_it_anyway:
2017-07-27 00:47:13 +00:00
self._Update()