1421 lines
52 KiB
Python
1421 lines
52 KiB
Python
import ClientConstants as CC
|
|
import ClientData
|
|
import ClientDefaults
|
|
import ClientDownloading
|
|
import ClientImporting
|
|
import ClientGUICollapsible
|
|
import ClientGUICommon
|
|
import ClientGUIControls
|
|
import ClientGUIDialogs
|
|
import ClientGUIScrolledPanels
|
|
import ClientGUITopLevelWindows
|
|
import HydrusConstants as HC
|
|
import HydrusData
|
|
import HydrusGlobals
|
|
import HydrusNetwork
|
|
import HydrusSerialisable
|
|
import wx
|
|
|
|
class EditAccountTypePanel( ClientGUIScrolledPanels.EditPanel ):
|
|
|
|
def __init__( self, parent, service_type, account_type ):
|
|
|
|
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
|
|
|
|
( self._account_type_key, title, permissions, bandwidth_rules ) = account_type.ToTuple()
|
|
|
|
self._title = wx.TextCtrl( self )
|
|
|
|
permission_choices = self._GeneratePermissionChoices( service_type )
|
|
|
|
self._permission_controls = []
|
|
|
|
self._permissions_panel = ClientGUICommon.StaticBox( self, 'permissions' )
|
|
|
|
gridbox_rows = []
|
|
|
|
for ( content_type, action_rows ) in permission_choices:
|
|
|
|
choice_control = ClientGUICommon.BetterChoice( self._permissions_panel )
|
|
|
|
for ( label, action ) in action_rows:
|
|
|
|
choice_control.Append( label, ( content_type, action ) )
|
|
|
|
|
|
if content_type in permissions:
|
|
|
|
selection_row = ( content_type, permissions[ content_type ] )
|
|
|
|
else:
|
|
|
|
selection_row = ( content_type, None )
|
|
|
|
|
|
try:
|
|
|
|
choice_control.SelectClientData( selection_row )
|
|
|
|
except:
|
|
|
|
choice_control.SelectClientData( ( content_type, None ) )
|
|
|
|
|
|
self._permission_controls.append( choice_control )
|
|
|
|
gridbox_label = HC.content_type_string_lookup[ content_type ]
|
|
|
|
gridbox_rows.append( ( gridbox_label, choice_control ) )
|
|
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self._permissions_panel, gridbox_rows )
|
|
|
|
self._bandwidth_rules_control = ClientGUIControls.BandwidthRulesCtrl( self, bandwidth_rules )
|
|
|
|
#
|
|
|
|
self._title.SetValue( title )
|
|
|
|
#
|
|
|
|
t_hbox = ClientGUICommon.WrapInText( self._title, self, 'title: ' )
|
|
|
|
self._permissions_panel.AddF( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
|
|
vbox = wx.BoxSizer( wx.VERTICAL )
|
|
|
|
vbox.AddF( t_hbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
vbox.AddF( self._permissions_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._bandwidth_rules_control, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
self.SetSizer( vbox )
|
|
|
|
|
|
def _GeneratePermissionChoices( self, service_type ):
|
|
|
|
possible_permissions = HydrusNetwork.GetPossiblePermissions( service_type )
|
|
|
|
permission_choices = []
|
|
|
|
for ( content_type, possible_actions ) in possible_permissions:
|
|
|
|
choices = []
|
|
|
|
for action in possible_actions:
|
|
|
|
choices.append( ( HC.permission_pair_string_lookup[ ( content_type, action ) ], action ) )
|
|
|
|
|
|
permission_choices.append( ( content_type, choices ) )
|
|
|
|
|
|
return permission_choices
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
title = self._title.GetValue()
|
|
|
|
permissions = {}
|
|
|
|
for permission_control in self._permission_controls:
|
|
|
|
( content_type, action ) = permission_control.GetChoice()
|
|
|
|
if action is not None:
|
|
|
|
permissions[ content_type ] = action
|
|
|
|
|
|
|
|
bandwidth_rules = self._bandwidth_rules_control.GetValue()
|
|
|
|
return HydrusNetwork.AccountType.GenerateAccountTypeFromParameters( self._account_type_key, title, permissions, bandwidth_rules )
|
|
|
|
|
|
class EditDuplicateActionOptionsPanel( ClientGUIScrolledPanels.EditPanel ):
|
|
|
|
def __init__( self, parent, duplicate_action, duplicate_action_options ):
|
|
|
|
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
|
|
|
|
self._duplicate_action = duplicate_action
|
|
|
|
self._service_actions = ClientGUICommon.SaneListCtrl( self, 120, [ ( 'service name', -1 ), ( 'action', 240 ) ], delete_key_callback = self._Delete, activation_callback = self._Edit )
|
|
|
|
self._service_actions.SetMinSize( ( 320, 120 ) )
|
|
|
|
add_button = ClientGUICommon.BetterButton( self, 'add', self._Add )
|
|
edit_button = ClientGUICommon.BetterButton( self, 'edit', self._Edit )
|
|
delete_button = ClientGUICommon.BetterButton( self, 'delete', self._Delete )
|
|
|
|
self._delete_second_file = wx.CheckBox( self, label = 'delete worse file' )
|
|
|
|
#
|
|
|
|
( service_actions, delete_second_file ) = duplicate_action_options.ToTuple()
|
|
|
|
services_manager = HydrusGlobals.client_controller.GetServicesManager()
|
|
|
|
for ( service_key, action ) in service_actions:
|
|
|
|
if services_manager.ServiceExists( service_key ):
|
|
|
|
sort_tuple = ( service_key, action )
|
|
|
|
display_tuple = self._GetDisplayTuple( sort_tuple )
|
|
|
|
self._service_actions.Append( display_tuple, sort_tuple )
|
|
|
|
|
|
|
|
self._delete_second_file.SetValue( delete_second_file )
|
|
|
|
#
|
|
|
|
if self._duplicate_action != HC.DUPLICATE_BETTER:
|
|
|
|
self._delete_second_file.Hide()
|
|
edit_button.Hide()
|
|
|
|
|
|
button_hbox = wx.BoxSizer( wx.HORIZONTAL )
|
|
|
|
button_hbox.AddF( add_button, CC.FLAGS_VCENTER )
|
|
button_hbox.AddF( edit_button, CC.FLAGS_VCENTER )
|
|
button_hbox.AddF( delete_button, CC.FLAGS_VCENTER )
|
|
|
|
vbox = wx.BoxSizer( wx.VERTICAL )
|
|
|
|
vbox.AddF( self._service_actions, CC.FLAGS_EXPAND_BOTH_WAYS )
|
|
vbox.AddF( button_hbox, CC.FLAGS_BUTTON_SIZER )
|
|
vbox.AddF( self._delete_second_file, CC.FLAGS_LONE_BUTTON )
|
|
|
|
self.SetSizer( vbox )
|
|
|
|
|
|
def _Add( self ):
|
|
|
|
existing_service_keys = set()
|
|
|
|
for ( service_key, action ) in self._service_actions.GetClientData():
|
|
|
|
existing_service_keys.add( service_key )
|
|
|
|
|
|
services_manager = HydrusGlobals.client_controller.GetServicesManager()
|
|
|
|
choice_tuples = []
|
|
|
|
for service in services_manager.GetServices( [ HC.LOCAL_TAG, HC.TAG_REPOSITORY, HC.LOCAL_RATING_LIKE, HC.LOCAL_RATING_NUMERICAL ] ):
|
|
|
|
service_key = service.GetServiceKey()
|
|
|
|
if service_key not in existing_service_keys:
|
|
|
|
name = service.GetName()
|
|
|
|
choice_tuples.append( ( name, service_key ) )
|
|
|
|
|
|
|
|
if len( choice_tuples ) == 0:
|
|
|
|
wx.MessageBox( 'You have no more tag or rating services to add! Try editing the existing ones instead!' )
|
|
|
|
else:
|
|
|
|
with ClientGUIDialogs.DialogSelectFromList( self, 'select service', choice_tuples ) as dlg_1:
|
|
|
|
if dlg_1.ShowModal() == wx.ID_OK:
|
|
|
|
service_key = dlg_1.GetChoice()
|
|
|
|
if self._duplicate_action == HC.DUPLICATE_BETTER:
|
|
|
|
service = services_manager.GetService( service_key )
|
|
|
|
if service.GetServiceType() == HC.TAG_REPOSITORY:
|
|
|
|
possible_actions = [ HC.CONTENT_MERGE_ACTION_COPY, HC.CONTENT_MERGE_ACTION_TWO_WAY_MERGE ]
|
|
|
|
else:
|
|
|
|
possible_actions = [ HC.CONTENT_MERGE_ACTION_COPY, HC.CONTENT_MERGE_ACTION_MOVE, HC.CONTENT_MERGE_ACTION_TWO_WAY_MERGE ]
|
|
|
|
|
|
choice_tuples = [ ( HC.content_merge_string_lookup[ action ], action ) for action in possible_actions ]
|
|
|
|
with ClientGUIDialogs.DialogSelectFromList( self, 'select action', choice_tuples ) as dlg_2:
|
|
|
|
if dlg_2.ShowModal() == wx.ID_OK:
|
|
|
|
action = dlg_2.GetChoice()
|
|
|
|
else:
|
|
|
|
return
|
|
|
|
|
|
|
|
else:
|
|
|
|
action = HC.CONTENT_MERGE_ACTION_TWO_WAY_MERGE
|
|
|
|
|
|
sort_tuple = ( service_key, action )
|
|
|
|
display_tuple = self._GetDisplayTuple( sort_tuple )
|
|
|
|
self._service_actions.Append( display_tuple, sort_tuple )
|
|
|
|
|
|
|
|
|
|
|
|
def _Delete( self ):
|
|
|
|
with ClientGUIDialogs.DialogYesNo( self, 'Remove all selected?' ) as dlg:
|
|
|
|
if dlg.ShowModal() == wx.ID_YES:
|
|
|
|
self._service_actions.RemoveAllSelected()
|
|
|
|
|
|
|
|
|
|
def _Edit( self ):
|
|
|
|
all_selected = self._service_actions.GetAllSelected()
|
|
|
|
for index in all_selected:
|
|
|
|
( service_key, action ) = self._service_actions.GetClientData( index )
|
|
|
|
if self._duplicate_action == HC.DUPLICATE_BETTER:
|
|
|
|
possible_actions = [ HC.CONTENT_MERGE_ACTION_COPY, HC.CONTENT_MERGE_ACTION_MOVE, HC.CONTENT_MERGE_ACTION_TWO_WAY_MERGE ]
|
|
|
|
choice_tuples = [ ( HC.content_merge_string_lookup[ action ], action ) for action in possible_actions ]
|
|
|
|
with ClientGUIDialogs.DialogSelectFromList( self, 'select action', choice_tuples ) as dlg_2:
|
|
|
|
if dlg_2.ShowModal() == wx.ID_OK:
|
|
|
|
action = dlg_2.GetChoice()
|
|
|
|
else:
|
|
|
|
break
|
|
|
|
|
|
|
|
else: # This shouldn't get fired because the edit button is hidden, but w/e
|
|
|
|
action = HC.CONTENT_MERGE_ACTION_TWO_WAY_MERGE
|
|
|
|
|
|
sort_tuple = ( service_key, action )
|
|
|
|
display_tuple = self._GetDisplayTuple( sort_tuple )
|
|
|
|
self._service_actions.UpdateRow( index, display_tuple, sort_tuple )
|
|
|
|
|
|
|
|
def _GetDisplayTuple( self, sort_tuple ):
|
|
|
|
( service_key, action ) = sort_tuple
|
|
|
|
services_manager = HydrusGlobals.client_controller.GetServicesManager()
|
|
|
|
service = services_manager.GetService( service_key )
|
|
|
|
name = service.GetName()
|
|
|
|
pretty_action = HC.content_merge_string_lookup[ action ]
|
|
|
|
return ( name, pretty_action )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
service_actions = self._service_actions.GetClientData()
|
|
delete_second_file = self._delete_second_file.GetValue()
|
|
|
|
duplicate_action_options = ClientData.DuplicateActionOptions( service_actions, delete_second_file )
|
|
|
|
return duplicate_action_options
|
|
|
|
|
|
class EditFrameLocationPanel( ClientGUIScrolledPanels.EditPanel ):
|
|
|
|
def __init__( self, parent, info ):
|
|
|
|
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
|
|
|
|
self._original_info = info
|
|
|
|
self._remember_size = wx.CheckBox( self, label = 'remember size' )
|
|
self._remember_position = wx.CheckBox( self, label = 'remember position' )
|
|
|
|
self._last_size = ClientGUICommon.NoneableSpinCtrl( self, 'last size', none_phrase = 'none set', min = 100, max = 1000000, unit = None, num_dimensions = 2 )
|
|
self._last_position = ClientGUICommon.NoneableSpinCtrl( self, 'last position', none_phrase = 'none set', min = -1000000, max = 1000000, unit = None, num_dimensions = 2 )
|
|
|
|
self._default_gravity_x = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._default_gravity_x.Append( 'by default, expand to width of parent', 1 )
|
|
self._default_gravity_x.Append( 'by default, expand width as much as needed', -1 )
|
|
|
|
self._default_gravity_y = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._default_gravity_y.Append( 'by default, expand to height of parent', 1 )
|
|
self._default_gravity_y.Append( 'by default, expand height as much as needed', -1 )
|
|
|
|
self._default_position = ClientGUICommon.BetterChoice( self )
|
|
|
|
self._default_position.Append( 'by default, position off the top-left corner of parent', 'topleft' )
|
|
self._default_position.Append( 'by default, position centered on the parent', 'center' )
|
|
|
|
self._maximised = wx.CheckBox( self, label = 'start maximised' )
|
|
self._fullscreen = wx.CheckBox( self, label = 'start fullscreen' )
|
|
|
|
#
|
|
|
|
( name, remember_size, remember_position, last_size, last_position, default_gravity, default_position, maximised, fullscreen ) = self._original_info
|
|
|
|
self._remember_size.SetValue( remember_size )
|
|
self._remember_position.SetValue( remember_position )
|
|
|
|
self._last_size.SetValue( last_size )
|
|
self._last_position.SetValue( last_position )
|
|
|
|
( x, y ) = default_gravity
|
|
|
|
self._default_gravity_x.SelectClientData( x )
|
|
self._default_gravity_y.SelectClientData( y )
|
|
|
|
self._default_position.SelectClientData( default_position )
|
|
|
|
self._maximised.SetValue( maximised )
|
|
self._fullscreen.SetValue( fullscreen )
|
|
|
|
#
|
|
|
|
vbox = wx.BoxSizer( wx.VERTICAL )
|
|
|
|
text = 'Setting frame location info for ' + name + '.'
|
|
|
|
vbox.AddF( ClientGUICommon.BetterStaticText( self, text ), CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._remember_size, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._remember_position, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._last_size, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._last_position, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._default_gravity_x, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._default_gravity_y, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._default_position, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._maximised, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._fullscreen, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
self.SetSizer( vbox )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
( name, remember_size, remember_position, last_size, last_position, default_gravity, default_position, maximised, fullscreen ) = self._original_info
|
|
|
|
remember_size = self._remember_size.GetValue()
|
|
remember_position = self._remember_position.GetValue()
|
|
|
|
last_size = self._last_size.GetValue()
|
|
last_position = self._last_position.GetValue()
|
|
|
|
x = self._default_gravity_x.GetChoice()
|
|
y = self._default_gravity_y.GetChoice()
|
|
|
|
default_gravity = [ x, y ]
|
|
|
|
default_position = self._default_position.GetChoice()
|
|
|
|
maximised = self._maximised.GetValue()
|
|
fullscreen = self._fullscreen.GetValue()
|
|
|
|
return ( name, remember_size, remember_position, last_size, last_position, default_gravity, default_position, maximised, fullscreen )
|
|
|
|
|
|
class EditMediaViewOptionsPanel( ClientGUIScrolledPanels.EditPanel ):
|
|
|
|
def __init__( self, parent, info ):
|
|
|
|
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
|
|
|
|
self._original_info = info
|
|
|
|
( self._mime, media_show_action, preview_show_action, ( media_scale_up, media_scale_down, preview_scale_up, preview_scale_down, exact_zooms_only, scale_up_quality, scale_down_quality ) ) = self._original_info
|
|
|
|
possible_actions = CC.media_viewer_capabilities[ self._mime ]
|
|
|
|
self._media_show_action = ClientGUICommon.BetterChoice( self )
|
|
self._preview_show_action = ClientGUICommon.BetterChoice( self )
|
|
|
|
for action in possible_actions:
|
|
|
|
self._media_show_action.Append( CC.media_viewer_action_string_lookup[ action ], action )
|
|
|
|
if action != CC.MEDIA_VIEWER_ACTION_DO_NOT_SHOW_ON_ACTIVATION_OPEN_EXTERNALLY:
|
|
|
|
self._preview_show_action.Append( CC.media_viewer_action_string_lookup[ action ], action )
|
|
|
|
|
|
|
|
self._media_show_action.Bind( wx.EVT_CHOICE, self.EventActionChange )
|
|
self._preview_show_action.Bind( wx.EVT_CHOICE, self.EventActionChange )
|
|
|
|
self._media_scale_up = ClientGUICommon.BetterChoice( self )
|
|
self._media_scale_down = ClientGUICommon.BetterChoice( self )
|
|
self._preview_scale_up = ClientGUICommon.BetterChoice( self )
|
|
self._preview_scale_down = ClientGUICommon.BetterChoice( self )
|
|
|
|
for scale_action in ( CC.MEDIA_VIEWER_SCALE_100, CC.MEDIA_VIEWER_SCALE_MAX_REGULAR, CC.MEDIA_VIEWER_SCALE_TO_CANVAS ):
|
|
|
|
text = CC.media_viewer_scale_string_lookup[ scale_action ]
|
|
|
|
self._media_scale_up.Append( text, scale_action )
|
|
self._preview_scale_up.Append( text, scale_action )
|
|
|
|
if scale_action != CC.MEDIA_VIEWER_SCALE_100:
|
|
|
|
self._media_scale_down.Append( text, scale_action )
|
|
self._preview_scale_down.Append( text, scale_action )
|
|
|
|
|
|
|
|
self._exact_zooms_only = wx.CheckBox( self, label = 'only permit half and double zooms' )
|
|
self._exact_zooms_only.SetToolTipString( 'This limits zooms to 25%, 50%, 100%, 200%, 400%, and so on. It makes for fast resize and is useful for files that often have flat colours and hard edges, which often scale badly otherwise. The \'canvas fit\' zoom will still be inserted.' )
|
|
|
|
self._scale_up_quality = ClientGUICommon.BetterChoice( self )
|
|
|
|
for zoom in ( CC.ZOOM_NEAREST, CC.ZOOM_LINEAR, CC.ZOOM_CUBIC, CC.ZOOM_LANCZOS4 ):
|
|
|
|
self._scale_up_quality.Append( CC.zoom_string_lookup[ zoom ], zoom )
|
|
|
|
|
|
self._scale_down_quality = ClientGUICommon.BetterChoice( self )
|
|
|
|
for zoom in ( CC.ZOOM_NEAREST, CC.ZOOM_LINEAR, CC.ZOOM_AREA ):
|
|
|
|
self._scale_down_quality.Append( CC.zoom_string_lookup[ zoom ], zoom )
|
|
|
|
|
|
#
|
|
|
|
self._media_show_action.SelectClientData( media_show_action )
|
|
self._preview_show_action.SelectClientData( preview_show_action )
|
|
|
|
self._media_scale_up.SelectClientData( media_scale_up )
|
|
self._media_scale_down.SelectClientData( media_scale_down )
|
|
self._preview_scale_up.SelectClientData( preview_scale_up )
|
|
self._preview_scale_down.SelectClientData( preview_scale_down )
|
|
|
|
self._exact_zooms_only.SetValue( exact_zooms_only )
|
|
|
|
self._scale_up_quality.SelectClientData( scale_up_quality )
|
|
self._scale_down_quality.SelectClientData( scale_down_quality )
|
|
|
|
#
|
|
|
|
vbox = wx.BoxSizer( wx.VERTICAL )
|
|
|
|
text = 'Setting media view options for ' + HC.mime_string_lookup[ self._mime ] + '.'
|
|
|
|
vbox.AddF( ClientGUICommon.BetterStaticText( self, text ), CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( ClientGUICommon.WrapInText( self._media_show_action, self, 'media viewer show action:' ), CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
vbox.AddF( ClientGUICommon.WrapInText( self._preview_show_action, self, 'preview show action:' ), CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
|
|
if possible_actions == CC.no_support:
|
|
|
|
self._media_scale_up.Hide()
|
|
self._media_scale_down.Hide()
|
|
self._preview_scale_up.Hide()
|
|
self._preview_scale_down.Hide()
|
|
|
|
self._exact_zooms_only.Hide()
|
|
|
|
self._scale_up_quality.Hide()
|
|
self._scale_down_quality.Hide()
|
|
|
|
else:
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'if the media is smaller than the media viewer canvas: ', self._media_scale_up ) )
|
|
rows.append( ( 'if the media is larger than the media viewer canvas: ', self._media_scale_down ) )
|
|
rows.append( ( 'if the media is smaller than the preview canvas: ', self._preview_scale_up) )
|
|
rows.append( ( 'if the media is larger than the preview canvas: ', self._preview_scale_down ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self, rows )
|
|
|
|
vbox.AddF( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
|
|
vbox.AddF( self._exact_zooms_only, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
vbox.AddF( ClientGUICommon.BetterStaticText( self, 'Nearest neighbour is fast and ugly, 8x8 lanczos and area resampling are slower but beautiful.' ), CC.FLAGS_VCENTER )
|
|
|
|
vbox.AddF( ClientGUICommon.WrapInText( self._scale_up_quality, self, '>100% (interpolation) quality:' ), CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
vbox.AddF( ClientGUICommon.WrapInText( self._scale_down_quality, self, '<100% (decimation) quality:' ), CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
|
|
|
|
if self._mime == HC.APPLICATION_FLASH:
|
|
|
|
self._scale_up_quality.Disable()
|
|
self._scale_down_quality.Disable()
|
|
|
|
|
|
self.SetSizer( vbox )
|
|
|
|
|
|
def EventActionChange( self, event ):
|
|
|
|
if self._media_show_action.GetChoice() in CC.no_support and self._preview_show_action.GetChoice() in CC.no_support:
|
|
|
|
self._media_scale_up.Disable()
|
|
self._media_scale_down.Disable()
|
|
self._preview_scale_up.Disable()
|
|
self._preview_scale_down.Disable()
|
|
|
|
self._exact_zooms_only.Disable()
|
|
|
|
self._scale_up_quality.Disable()
|
|
self._scale_down_quality.Disable()
|
|
|
|
else:
|
|
|
|
self._media_scale_up.Enable()
|
|
self._media_scale_down.Enable()
|
|
self._preview_scale_up.Enable()
|
|
self._preview_scale_down.Enable()
|
|
|
|
self._exact_zooms_only.Enable()
|
|
|
|
self._scale_up_quality.Enable()
|
|
self._scale_down_quality.Enable()
|
|
|
|
|
|
if self._mime == HC.APPLICATION_FLASH:
|
|
|
|
self._scale_up_quality.Disable()
|
|
self._scale_down_quality.Disable()
|
|
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
media_show_action = self._media_show_action.GetChoice()
|
|
preview_show_action = self._preview_show_action.GetChoice()
|
|
|
|
media_scale_up = self._media_scale_up.GetChoice()
|
|
media_scale_down = self._media_scale_down.GetChoice()
|
|
preview_scale_up = self._preview_scale_up.GetChoice()
|
|
preview_scale_down = self._preview_scale_down.GetChoice()
|
|
|
|
exact_zooms_only = self._exact_zooms_only.GetValue()
|
|
|
|
scale_up_quality = self._scale_up_quality.GetChoice()
|
|
scale_down_quality = self._scale_down_quality.GetChoice()
|
|
|
|
return ( self._mime, media_show_action, preview_show_action, ( media_scale_up, media_scale_down, preview_scale_up, preview_scale_down, exact_zooms_only, scale_up_quality, scale_down_quality ) )
|
|
|
|
|
|
class EditSeedCachePanel( ClientGUIScrolledPanels.EditPanel ):
|
|
|
|
def __init__( self, parent, controller, seed_cache ):
|
|
|
|
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
|
|
|
|
self._controller = controller
|
|
self._seed_cache = seed_cache
|
|
|
|
self._text = ClientGUICommon.BetterStaticText( self, 'initialising' )
|
|
self._seed_cache_control = ClientGUIControls.SeedCacheControl( self, self._seed_cache )
|
|
|
|
vbox = wx.BoxSizer( wx.VERTICAL )
|
|
|
|
vbox.AddF( self._text, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._seed_cache_control, CC.FLAGS_EXPAND_BOTH_WAYS )
|
|
|
|
self.SetSizer( vbox )
|
|
|
|
self._controller.sub( self, 'NotifySeedUpdated', 'seed_cache_seed_updated' )
|
|
|
|
wx.CallAfter( self._UpdateText )
|
|
|
|
|
|
def _UpdateText( self ):
|
|
|
|
( status, ( total_processed, total ) ) = self._seed_cache.GetStatus()
|
|
|
|
self._text.SetLabelText( status )
|
|
|
|
self.Layout()
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
return self._seed_cache
|
|
|
|
|
|
def NotifySeedUpdated( self, seed ):
|
|
|
|
self._UpdateText()
|
|
|
|
|
|
class EditServersideService( ClientGUIScrolledPanels.EditPanel ):
|
|
|
|
def __init__( self, parent, serverside_service ):
|
|
|
|
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
|
|
|
|
duplicate_serverside_service = serverside_service.Duplicate()
|
|
|
|
( self._service_key, self._service_type, name, port, self._dictionary ) = duplicate_serverside_service.ToTuple()
|
|
|
|
self._service_panel = self._ServicePanel( self, name, port, self._dictionary )
|
|
|
|
self._panels = []
|
|
|
|
if self._service_type in HC.RESTRICTED_SERVICES:
|
|
|
|
self._panels.append( self._ServiceRestrictedPanel( self, self._dictionary ) )
|
|
|
|
if self._service_type == HC.FILE_REPOSITORY:
|
|
|
|
self._panels.append( self._ServiceFileRepositoryPanel( self, self._dictionary ) )
|
|
|
|
|
|
if self._service_type == HC.SERVER_ADMIN:
|
|
|
|
self._panels.append( self._ServiceServerAdminPanel( self, self._dictionary ) )
|
|
|
|
|
|
|
|
#
|
|
|
|
vbox = wx.BoxSizer( wx.VERTICAL )
|
|
|
|
vbox.AddF( self._service_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
for panel in self._panels:
|
|
|
|
vbox.AddF( panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
|
|
self.SetSizer( vbox )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
( name, port, dictionary_part ) = self._service_panel.GetValue()
|
|
|
|
dictionary = self._dictionary.Duplicate()
|
|
|
|
dictionary.update( dictionary_part )
|
|
|
|
for panel in self._panels:
|
|
|
|
dictionary_part = panel.GetValue()
|
|
|
|
dictionary.update( dictionary_part )
|
|
|
|
|
|
return HydrusNetwork.GenerateService( self._service_key, self._service_type, name, port, dictionary )
|
|
|
|
|
|
class _ServicePanel( ClientGUICommon.StaticBox ):
|
|
|
|
def __init__( self, parent, name, port, dictionary ):
|
|
|
|
ClientGUICommon.StaticBox.__init__( self, parent, 'basic information' )
|
|
|
|
self._name = wx.TextCtrl( self )
|
|
self._port = wx.SpinCtrl( self, min = 1, max = 65535 )
|
|
self._upnp_port = ClientGUICommon.NoneableSpinCtrl( self, 'external upnp port', none_phrase = 'do not forward port', min = 1, max = 65535 )
|
|
|
|
self._bandwidth_tracker_st = ClientGUICommon.BetterStaticText( self )
|
|
|
|
#
|
|
|
|
self._name.SetValue( name )
|
|
self._port.SetValue( port )
|
|
|
|
upnp_port = dictionary[ 'upnp_port' ]
|
|
|
|
self._upnp_port.SetValue( upnp_port )
|
|
|
|
bandwidth_tracker = dictionary[ 'bandwidth_tracker' ]
|
|
|
|
bandwidth_text = bandwidth_tracker.GetCurrentMonthSummary()
|
|
|
|
self._bandwidth_tracker_st.SetLabelText( bandwidth_text )
|
|
|
|
#
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'name: ', self._name ) )
|
|
rows.append( ( 'port: ', self._port ) )
|
|
rows.append( ( 'upnp port: ', self._upnp_port ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self, rows )
|
|
|
|
self.AddF( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
self.AddF( self._bandwidth_tracker_st, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
dictionary_part = {}
|
|
|
|
name = self._name.GetValue()
|
|
port = self._port.GetValue()
|
|
|
|
upnp_port = self._upnp_port.GetValue()
|
|
|
|
dictionary_part[ 'upnp_port' ] = upnp_port
|
|
|
|
return ( name, port, dictionary_part )
|
|
|
|
|
|
|
|
class _ServiceRestrictedPanel( wx.Panel ):
|
|
|
|
def __init__( self, parent, dictionary ):
|
|
|
|
wx.Panel.__init__( self, parent )
|
|
|
|
bandwidth_rules = dictionary[ 'bandwidth_rules' ]
|
|
|
|
self._bandwidth_rules = ClientGUIControls.BandwidthRulesCtrl( self, bandwidth_rules )
|
|
|
|
#
|
|
|
|
vbox = wx.BoxSizer( wx.VERTICAL )
|
|
|
|
vbox.AddF( self._bandwidth_rules, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
|
|
self.SetSizer( vbox )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
dictionary_part = {}
|
|
|
|
dictionary_part[ 'bandwidth_rules' ] = self._bandwidth_rules.GetValue()
|
|
|
|
return dictionary_part
|
|
|
|
|
|
|
|
class _ServiceFileRepositoryPanel( ClientGUICommon.StaticBox ):
|
|
|
|
def __init__( self, parent, dictionary ):
|
|
|
|
ClientGUICommon.StaticBox.__init__( self, parent, 'file repository' )
|
|
|
|
self._log_uploader_ips = wx.CheckBox( self )
|
|
self._max_storage = ClientGUICommon.NoneableSpinCtrl( self, unit = 'MB', multiplier = 1024 * 1024 )
|
|
|
|
#
|
|
|
|
log_uploader_ips = dictionary[ 'log_uploader_ips' ]
|
|
max_storage = dictionary[ 'max_storage' ]
|
|
|
|
self._log_uploader_ips.SetValue( log_uploader_ips )
|
|
self._max_storage.SetValue( max_storage )
|
|
|
|
#
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'log file uploader IP addresses?: ', self._log_uploader_ips ) )
|
|
rows.append( ( 'max file storage: ', self._max_storage ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self, rows )
|
|
|
|
self.AddF( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
dictionary_part = {}
|
|
|
|
log_uploader_ips = self._log_uploader_ips.GetValue()
|
|
max_storage = self._max_storage.GetValue()
|
|
|
|
dictionary_part[ 'log_uploader_ips' ] = log_uploader_ips
|
|
dictionary_part[ 'max_storage' ] = max_storage
|
|
|
|
return dictionary_part
|
|
|
|
|
|
|
|
class _ServiceServerAdminPanel( ClientGUICommon.StaticBox ):
|
|
|
|
def __init__( self, parent, dictionary ):
|
|
|
|
ClientGUICommon.StaticBox.__init__( self, parent, 'server-wide bandwidth' )
|
|
|
|
self._bandwidth_tracker_st = ClientGUICommon.BetterStaticText( self )
|
|
|
|
bandwidth_rules = dictionary[ 'server_bandwidth_rules' ]
|
|
|
|
self._bandwidth_rules = ClientGUIControls.BandwidthRulesCtrl( self, bandwidth_rules )
|
|
|
|
#
|
|
|
|
bandwidth_tracker = dictionary[ 'server_bandwidth_tracker' ]
|
|
|
|
bandwidth_text = bandwidth_tracker.GetCurrentMonthSummary()
|
|
|
|
self._bandwidth_tracker_st.SetLabelText( bandwidth_text )
|
|
|
|
#
|
|
|
|
self.AddF( self._bandwidth_tracker_st, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
self.AddF( self._bandwidth_rules, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
dictionary_part = {}
|
|
|
|
bandwidth_rules = self._bandwidth_rules.GetValue()
|
|
|
|
dictionary_part[ 'server_bandwidth_rules' ] = bandwidth_rules
|
|
|
|
return dictionary_part
|
|
|
|
|
|
|
|
class EditChooseMultiple( ClientGUIScrolledPanels.EditPanel ):
|
|
|
|
def __init__( self, parent, choice_tuples ):
|
|
|
|
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
|
|
|
|
self._checkboxes = wx.CheckListBox( self )
|
|
|
|
self._checkboxes.SetMinSize( ( 320, 420 ) )
|
|
|
|
for ( i, ( label, data, selected ) ) in enumerate( choice_tuples ):
|
|
|
|
self._checkboxes.Append( label, data )
|
|
|
|
if selected:
|
|
|
|
self._checkboxes.Check( i )
|
|
|
|
|
|
|
|
#
|
|
|
|
vbox = wx.BoxSizer( wx.VERTICAL )
|
|
|
|
vbox.AddF( self._checkboxes, CC.FLAGS_EXPAND_BOTH_WAYS )
|
|
|
|
self.SetSizer( vbox )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
datas = []
|
|
|
|
for index in self._checkboxes.GetChecked():
|
|
|
|
datas.append( self._checkboxes.GetClientData( index ) )
|
|
|
|
|
|
return datas
|
|
|
|
|
|
class EditSubscriptionPanel( ClientGUIScrolledPanels.EditPanel ):
|
|
|
|
def __init__( self, parent, subscription ):
|
|
|
|
subscription = subscription.Duplicate()
|
|
|
|
ClientGUIScrolledPanels.EditPanel.__init__( self, parent )
|
|
|
|
self._original_subscription = subscription
|
|
|
|
#
|
|
|
|
self._name = wx.TextCtrl( self )
|
|
|
|
#
|
|
|
|
self._info_panel = ClientGUICommon.StaticBox( self, 'info' )
|
|
|
|
self._last_checked_st = wx.StaticText( self._info_panel )
|
|
self._next_check_st = wx.StaticText( self._info_panel )
|
|
self._seed_info_st = wx.StaticText( self._info_panel )
|
|
|
|
#
|
|
|
|
self._query_panel = ClientGUICommon.StaticBox( self, 'site and query' )
|
|
|
|
self._site_type = ClientGUICommon.BetterChoice( self._query_panel )
|
|
|
|
site_types = []
|
|
site_types.append( HC.SITE_TYPE_BOORU )
|
|
site_types.append( HC.SITE_TYPE_DEVIANT_ART )
|
|
site_types.append( HC.SITE_TYPE_HENTAI_FOUNDRY_ARTIST )
|
|
site_types.append( HC.SITE_TYPE_HENTAI_FOUNDRY_TAGS )
|
|
site_types.append( HC.SITE_TYPE_NEWGROUNDS )
|
|
site_types.append( HC.SITE_TYPE_PIXIV_ARTIST_ID )
|
|
site_types.append( HC.SITE_TYPE_PIXIV_TAG )
|
|
site_types.append( HC.SITE_TYPE_TUMBLR )
|
|
|
|
for site_type in site_types:
|
|
|
|
self._site_type.Append( HC.site_type_string_lookup[ site_type ], site_type )
|
|
|
|
|
|
self._site_type.Bind( wx.EVT_CHOICE, self.EventSiteChanged )
|
|
|
|
self._query = wx.TextCtrl( self._query_panel )
|
|
|
|
self._booru_selector = wx.ListBox( self._query_panel )
|
|
self._booru_selector.Bind( wx.EVT_LISTBOX, self.EventBooruSelected )
|
|
|
|
self._period = ClientGUICommon.TimeDeltaButton( self._query_panel, min = 3600 * 4, days = True, hours = True )
|
|
self._period.Bind( ClientGUICommon.EVT_TIME_DELTA, self.EventPeriodChanged )
|
|
|
|
#
|
|
|
|
self._options_panel = ClientGUICommon.StaticBox( self, 'options' )
|
|
|
|
menu_items = []
|
|
|
|
invert_call = self._InvertGetTagsIfURLKnownAndFileRedundant
|
|
value_call = self._GetTagsIfURLKnownAndFileRedundant
|
|
|
|
check_manager = ClientGUICommon.CheckboxManagerCalls( invert_call, value_call )
|
|
|
|
menu_items.append( ( 'check', 'get tags even if url is known and file is already in db (this downloader)', 'If this is selected, the client will fetch the tags from a file\'s page even if it has the file and already previously downloaded it from that location.', check_manager ) )
|
|
|
|
menu_items.append( ( 'separator', 0, 0, 0 ) )
|
|
|
|
check_manager = ClientGUICommon.CheckboxManagerOptions( 'get_tags_if_url_known_and_file_redundant' )
|
|
|
|
menu_items.append( ( 'check', 'get tags even if url is known and file is already in db (default)', 'Set the default for this value.', check_manager ) )
|
|
|
|
cog_button = ClientGUICommon.MenuBitmapButton( self._options_panel, CC.GlobalBMPs.cog, menu_items )
|
|
|
|
self._initial_file_limit = ClientGUICommon.NoneableSpinCtrl( self._options_panel, '', none_phrase = 'get everything', min = 1, max = 1000000 )
|
|
self._initial_file_limit.SetToolTipString( 'If set, the first sync will add no more than this many files. Otherwise, it will get everything the gallery has.' )
|
|
|
|
self._periodic_file_limit = ClientGUICommon.NoneableSpinCtrl( self._options_panel, '', none_phrase = 'get everything', min = 1, max = 1000000 )
|
|
self._periodic_file_limit.SetToolTipString( 'If set, normal syncs will add no more than this many files. Otherwise, they will get everything up until they find a file they have seen before.' )
|
|
|
|
#
|
|
|
|
self._control_panel = ClientGUICommon.StaticBox( self, 'control' )
|
|
|
|
self._paused = wx.CheckBox( self._control_panel )
|
|
|
|
self._seed_cache_button = ClientGUICommon.BetterBitmapButton( self._control_panel, CC.GlobalBMPs.seed_cache, self._SeedCache )
|
|
self._seed_cache_button.SetToolTipString( 'open detailed url cache status' )
|
|
|
|
self._retry_failed = ClientGUICommon.BetterButton( self._control_panel, 'retry failed', self.RetryFailed )
|
|
|
|
self._check_now_button = ClientGUICommon.BetterButton( self._control_panel, 'force check on dialog ok', self.CheckNow )
|
|
|
|
self._reset_cache_button = ClientGUICommon.BetterButton( self._control_panel, 'reset url cache', self.ResetCache )
|
|
|
|
#
|
|
|
|
self._import_tag_options = ClientGUICollapsible.CollapsibleOptionsTags( self )
|
|
|
|
self._import_file_options = ClientGUICollapsible.CollapsibleOptionsImportFiles( self )
|
|
|
|
#
|
|
|
|
( name, gallery_identifier, gallery_stream_identifiers, query, period, self._get_tags_if_url_known_and_file_redundant, initial_file_limit, periodic_file_limit, paused, import_file_options, import_tag_options, self._last_checked, self._last_error, self._check_now, self._seed_cache ) = subscription.ToTuple()
|
|
|
|
self._name.SetValue( name )
|
|
|
|
site_type = gallery_identifier.GetSiteType()
|
|
|
|
self._site_type.SelectClientData( site_type )
|
|
|
|
self._PresentForSiteType()
|
|
|
|
if site_type == HC.SITE_TYPE_BOORU:
|
|
|
|
booru_name = gallery_identifier.GetAdditionalInfo()
|
|
|
|
index = self._booru_selector.FindString( booru_name )
|
|
|
|
if index != wx.NOT_FOUND:
|
|
|
|
self._booru_selector.Select( index )
|
|
|
|
|
|
|
|
# set gallery_stream_identifiers selection here--some kind of list of checkboxes or whatever
|
|
|
|
self._query.SetValue( query )
|
|
|
|
self._period.SetValue( period )
|
|
|
|
self._initial_file_limit.SetValue( initial_file_limit )
|
|
self._periodic_file_limit.SetValue( periodic_file_limit )
|
|
|
|
self._paused.SetValue( paused )
|
|
|
|
self._import_file_options.SetOptions( import_file_options )
|
|
|
|
self._import_tag_options.SetOptions( import_tag_options )
|
|
|
|
if self._last_checked == 0:
|
|
|
|
self._reset_cache_button.Disable()
|
|
|
|
|
|
if self._check_now:
|
|
|
|
self._check_now_button.Disable()
|
|
|
|
|
|
self._UpdateCommandButtons()
|
|
self._UpdateLastNextCheck()
|
|
self._UpdateSeedInfo()
|
|
|
|
#
|
|
|
|
self._info_panel.AddF( self._last_checked_st, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
self._info_panel.AddF( self._next_check_st, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
self._info_panel.AddF( self._seed_info_st, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
#
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'search text: ', self._query ) )
|
|
rows.append( ( 'check for new files every: ', self._period ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self._query_panel, rows )
|
|
|
|
self._query_panel.AddF( self._site_type, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
self._query_panel.AddF( self._booru_selector, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
self._query_panel.AddF( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
|
|
#
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'on first check, get at most this many files: ', self._initial_file_limit ) )
|
|
rows.append( ( 'on normal checks, get at most this many newer files: ', self._periodic_file_limit ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self._options_panel, rows )
|
|
|
|
self._options_panel.AddF( cog_button, CC.FLAGS_LONE_BUTTON )
|
|
self._options_panel.AddF( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
|
|
#
|
|
|
|
self._control_panel.AddF( self._seed_cache_button, CC.FLAGS_LONE_BUTTON )
|
|
|
|
rows = []
|
|
|
|
rows.append( ( 'currently paused: ', self._paused ) )
|
|
|
|
gridbox = ClientGUICommon.WrapInGrid( self._control_panel, rows )
|
|
|
|
self._control_panel.AddF( gridbox, CC.FLAGS_LONE_BUTTON )
|
|
self._control_panel.AddF( self._retry_failed, CC.FLAGS_LONE_BUTTON )
|
|
self._control_panel.AddF( self._check_now_button, CC.FLAGS_LONE_BUTTON )
|
|
self._control_panel.AddF( self._reset_cache_button, CC.FLAGS_LONE_BUTTON )
|
|
|
|
#
|
|
|
|
vbox = wx.BoxSizer( wx.VERTICAL )
|
|
|
|
vbox.AddF( ClientGUICommon.WrapInText( self._name, self, 'name: ' ), CC.FLAGS_EXPAND_SIZER_PERPENDICULAR )
|
|
vbox.AddF( self._info_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._query_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._options_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._control_panel, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._import_tag_options, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
vbox.AddF( self._import_file_options, CC.FLAGS_EXPAND_PERPENDICULAR )
|
|
|
|
self.SetSizer( vbox )
|
|
|
|
|
|
def _ConfigureImportTagOptions( self ):
|
|
|
|
gallery_identifier = self._GetGalleryIdentifier()
|
|
|
|
( namespaces, search_value ) = ClientDefaults.GetDefaultNamespacesAndSearchValue( gallery_identifier )
|
|
|
|
new_options = HydrusGlobals.client_controller.GetNewOptions()
|
|
|
|
import_tag_options = new_options.GetDefaultImportTagOptions( gallery_identifier )
|
|
|
|
if gallery_identifier == self._original_subscription.GetGalleryIdentifier():
|
|
|
|
search_value = self._original_subscription.GetQuery()
|
|
import_tag_options = self._original_subscription.GetImportTagOptions()
|
|
|
|
|
|
self._query.SetValue( search_value )
|
|
self._import_tag_options.SetNamespaces( namespaces )
|
|
self._import_tag_options.SetOptions( import_tag_options )
|
|
|
|
|
|
def _GetGalleryIdentifier( self ):
|
|
|
|
site_type = self._site_type.GetChoice()
|
|
|
|
if site_type == HC.SITE_TYPE_BOORU:
|
|
|
|
booru_name = self._booru_selector.GetStringSelection()
|
|
|
|
gallery_identifier = ClientDownloading.GalleryIdentifier( site_type, additional_info = booru_name )
|
|
|
|
else:
|
|
|
|
gallery_identifier = ClientDownloading.GalleryIdentifier( site_type )
|
|
|
|
|
|
return gallery_identifier
|
|
|
|
|
|
def _GetTagsIfURLKnownAndFileRedundant( self ):
|
|
|
|
return self._get_tags_if_url_known_and_file_redundant
|
|
|
|
|
|
def _InvertGetTagsIfURLKnownAndFileRedundant( self ):
|
|
|
|
self._get_tags_if_url_known_and_file_redundant = not self._get_tags_if_url_known_and_file_redundant
|
|
|
|
|
|
def _UpdateCommandButtons( self ):
|
|
|
|
on_initial_sync = self._last_checked == 0
|
|
no_failures = self._seed_cache.GetSeedCount( CC.STATUS_FAILED ) == 0
|
|
|
|
can_check = not ( self._check_now or on_initial_sync )
|
|
|
|
if no_failures:
|
|
|
|
self._retry_failed.Disable()
|
|
|
|
else:
|
|
|
|
self._retry_failed.Enable()
|
|
|
|
|
|
if can_check:
|
|
|
|
self._check_now_button.Enable()
|
|
|
|
else:
|
|
|
|
self._check_now_button.Disable()
|
|
|
|
|
|
if on_initial_sync:
|
|
|
|
self._reset_cache_button.Disable()
|
|
|
|
else:
|
|
|
|
self._reset_cache_button.Enable()
|
|
|
|
|
|
|
|
def _UpdateLastNextCheck( self ):
|
|
|
|
if self._last_checked == 0:
|
|
|
|
last_checked_text = 'initial check has not yet occured'
|
|
|
|
else:
|
|
|
|
last_checked_text = 'last checked ' + HydrusData.ConvertTimestampToPrettySync( self._last_checked )
|
|
|
|
|
|
self._last_checked_st.SetLabelText( last_checked_text )
|
|
|
|
periodic_next_check_time = self._last_checked + self._period.GetValue()
|
|
error_next_check_time = self._last_error + HC.UPDATE_DURATION
|
|
|
|
if self._check_now:
|
|
|
|
next_check_text = 'next check as soon as manage subscriptions dialog is closed'
|
|
|
|
elif error_next_check_time > periodic_next_check_time:
|
|
|
|
next_check_text = 'due to an error, next check ' + HydrusData.ConvertTimestampToPrettyPending( error_next_check_time )
|
|
|
|
else:
|
|
|
|
next_check_text = 'next check ' + HydrusData.ConvertTimestampToPrettyPending( periodic_next_check_time )
|
|
|
|
|
|
self._next_check_st.SetLabelText( next_check_text )
|
|
|
|
|
|
def _UpdateSeedInfo( self ):
|
|
|
|
seed_cache_text = HydrusData.ConvertIntToPrettyString( self._seed_cache.GetSeedCount() ) + ' urls in cache'
|
|
|
|
num_failed = self._seed_cache.GetSeedCount( CC.STATUS_FAILED )
|
|
|
|
if num_failed > 0:
|
|
|
|
seed_cache_text += ', ' + HydrusData.ConvertIntToPrettyString( num_failed ) + ' failed'
|
|
|
|
|
|
self._seed_info_st.SetLabelText( seed_cache_text )
|
|
|
|
|
|
def _PresentForSiteType( self ):
|
|
|
|
site_type = self._site_type.GetChoice()
|
|
|
|
if site_type == HC.SITE_TYPE_BOORU:
|
|
|
|
if self._booru_selector.GetCount() == 0:
|
|
|
|
boorus = HydrusGlobals.client_controller.Read( 'remote_boorus' )
|
|
|
|
for ( name, booru ) in boorus.items(): self._booru_selector.Append( name, booru )
|
|
|
|
self._booru_selector.Select( 0 )
|
|
|
|
|
|
self._booru_selector.Show()
|
|
|
|
else:
|
|
|
|
self._booru_selector.Hide()
|
|
|
|
|
|
wx.CallAfter( self._ConfigureImportTagOptions )
|
|
|
|
event = CC.SizeChangedEvent( -1 )
|
|
|
|
wx.CallAfter( self.ProcessEvent, event )
|
|
|
|
|
|
def _SeedCache( self ):
|
|
|
|
dupe_seed_cache = self._seed_cache.Duplicate()
|
|
|
|
with ClientGUITopLevelWindows.DialogEdit( self, 'file import status' ) as dlg:
|
|
|
|
panel = EditSeedCachePanel( dlg, HydrusGlobals.client_controller, dupe_seed_cache )
|
|
|
|
dlg.SetPanel( panel )
|
|
|
|
if dlg.ShowModal() == wx.ID_OK:
|
|
|
|
self._seed_cache = panel.GetValue()
|
|
|
|
self._UpdateCommandButtons()
|
|
self._UpdateSeedInfo()
|
|
|
|
|
|
|
|
|
|
def CheckNow( self ):
|
|
|
|
self._check_now = True
|
|
|
|
self._UpdateCommandButtons()
|
|
self._UpdateLastNextCheck()
|
|
|
|
|
|
def EventBooruSelected( self, event ):
|
|
|
|
self._ConfigureImportTagOptions()
|
|
|
|
|
|
def EventPeriodChanged( self, event ):
|
|
|
|
self._UpdateLastNextCheck()
|
|
|
|
|
|
def EventSiteChanged( self, event ):
|
|
|
|
self._PresentForSiteType()
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
name = self._name.GetValue()
|
|
|
|
subscription = ClientImporting.Subscription( name )
|
|
|
|
gallery_identifier = self._GetGalleryIdentifier()
|
|
|
|
# in future, this can be harvested from some checkboxes or whatever for stream selection
|
|
gallery_stream_identifiers = ClientDownloading.GetGalleryStreamIdentifiers( gallery_identifier )
|
|
|
|
query = self._query.GetValue()
|
|
|
|
period = self._period.GetValue()
|
|
|
|
initial_file_limit = self._initial_file_limit.GetValue()
|
|
periodic_file_limit = self._periodic_file_limit.GetValue()
|
|
|
|
paused = self._paused.GetValue()
|
|
|
|
import_file_options = self._import_file_options.GetOptions()
|
|
|
|
import_tag_options = self._import_tag_options.GetOptions()
|
|
|
|
subscription.SetTuple( gallery_identifier, gallery_stream_identifiers, query, period, self._get_tags_if_url_known_and_file_redundant, initial_file_limit, periodic_file_limit, paused, import_file_options, import_tag_options, self._last_checked, self._last_error, self._check_now, self._seed_cache )
|
|
|
|
return subscription
|
|
|
|
|
|
def ResetCache( self ):
|
|
|
|
message = '''Resetting this subscription's cache will delete ''' + HydrusData.ConvertIntToPrettyString( self._original_subscription.GetSeedCache().GetSeedCount() ) + ''' remembered urls, meaning when the subscription next runs, it will try to download those all over again. This may be expensive in time and data. Only do it if you are willing to wait. Do you want to do it?'''
|
|
|
|
with ClientGUIDialogs.DialogYesNo( self, message ) as dlg:
|
|
|
|
if dlg.ShowModal() == wx.ID_YES:
|
|
|
|
self._last_checked = 0
|
|
self._last_error = 0
|
|
self._seed_cache = ClientImporting.SeedCache()
|
|
|
|
self._UpdateCommandButtons()
|
|
self._UpdateLastNextCheck()
|
|
self._UpdateSeedInfo()
|
|
|
|
|
|
|
|
|
|
def RetryFailed( self ):
|
|
|
|
failed_seeds = self._seed_cache.GetSeeds( CC.STATUS_FAILED )
|
|
|
|
for seed in failed_seeds:
|
|
|
|
self._seed_cache.UpdateSeedStatus( seed, CC.STATUS_UNKNOWN )
|
|
|
|
|
|
self._last_error = 0
|
|
|
|
self._UpdateCommandButtons()
|
|
self._UpdateLastNextCheck()
|
|
self._UpdateSeedInfo()
|
|
|
|
|