2017-03-08 23:23:12 +00:00
import ClientCaches
2017-03-02 02:14:56 +00:00
import ClientConstants as CC
2017-07-12 20:03:45 +00:00
import ClientData
2017-03-02 02:14:56 +00:00
import ClientGUICommon
2017-03-08 23:23:12 +00:00
import ClientGUIDialogs
2017-08-02 21:32:54 +00:00
import ClientGUIListCtrl
2017-03-15 20:13:04 +00:00
import ClientGUIMenus
2017-03-02 02:14:56 +00:00
import ClientGUIScrolledPanels
import ClientGUITopLevelWindows
import HydrusConstants as HC
import HydrusData
2017-05-10 21:33:58 +00:00
import HydrusGlobals as HG
2017-03-02 02:14:56 +00:00
import HydrusNetworking
2017-03-08 23:23:12 +00:00
import os
2017-03-02 02:14:56 +00:00
import wx
class BandwidthRulesCtrl ( ClientGUICommon . StaticBox ) :
def __init__ ( self , parent , bandwidth_rules ) :
ClientGUICommon . StaticBox . __init__ ( self , parent , ' bandwidth rules ' )
columns = [ ( ' type ' , - 1 ) , ( ' time delta ' , 120 ) , ( ' max allowed ' , 80 ) ]
2017-08-02 21:32:54 +00:00
listctrl_panel = ClientGUIListCtrl . SaneListCtrlPanel ( self )
2017-03-02 02:14:56 +00:00
2017-08-02 21:32:54 +00:00
self . _listctrl = ClientGUIListCtrl . SaneListCtrl ( listctrl_panel , 100 , columns , delete_key_callback = self . _Delete , activation_callback = self . _Edit )
2017-07-27 00:47:13 +00:00
listctrl_panel . SetListCtrl ( self . _listctrl )
listctrl_panel . AddButton ( ' add ' , self . _Add )
listctrl_panel . AddButton ( ' edit ' , self . _Edit , enabled_only_on_selection = True )
listctrl_panel . AddButton ( ' delete ' , self . _Delete , enabled_only_on_selection = True )
2017-03-02 02:14:56 +00:00
#
for rule in bandwidth_rules . GetRules ( ) :
sort_tuple = rule
display_tuple = self . _GetDisplayTuple ( sort_tuple )
self . _listctrl . Append ( display_tuple , sort_tuple )
#
2017-07-27 00:47:13 +00:00
self . AddF ( listctrl_panel , CC . FLAGS_EXPAND_PERPENDICULAR )
2017-03-02 02:14:56 +00:00
def _Add ( self ) :
rule = ( HC . BANDWIDTH_TYPE_DATA , None , 1024 * 1024 * 100 )
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit rule ' ) as dlg :
panel = self . _EditPanel ( dlg , rule )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
new_rule = panel . GetValue ( )
sort_tuple = new_rule
display_tuple = self . _GetDisplayTuple ( sort_tuple )
self . _listctrl . Append ( display_tuple , sort_tuple )
def _GetDisplayTuple ( self , rule ) :
( bandwidth_type , time_delta , max_allowed ) = rule
pretty_bandwidth_type = HC . bandwidth_type_string_lookup [ bandwidth_type ]
pretty_time_delta = HydrusData . ConvertTimeDeltaToPrettyString ( time_delta )
if bandwidth_type == HC . BANDWIDTH_TYPE_DATA :
pretty_max_allowed = HydrusData . ConvertIntToBytes ( max_allowed )
elif bandwidth_type == HC . BANDWIDTH_TYPE_REQUESTS :
pretty_max_allowed = HydrusData . ConvertIntToPrettyString ( max_allowed )
return ( pretty_bandwidth_type , pretty_time_delta , pretty_max_allowed )
def _Delete ( self ) :
2017-03-22 22:38:15 +00:00
with ClientGUIDialogs . DialogYesNo ( self , ' Remove all selected? ' ) as dlg :
if dlg . ShowModal ( ) == wx . ID_YES :
self . _listctrl . RemoveAllSelected ( )
2017-03-02 02:14:56 +00:00
def _Edit ( self ) :
all_selected = self . _listctrl . GetAllSelected ( )
for index in all_selected :
rule = self . _listctrl . GetClientData ( index )
with ClientGUITopLevelWindows . DialogEdit ( self , ' edit rule ' ) as dlg :
panel = self . _EditPanel ( dlg , rule )
dlg . SetPanel ( panel )
if dlg . ShowModal ( ) == wx . ID_OK :
edited_rule = panel . GetValue ( )
sort_tuple = edited_rule
display_tuple = self . _GetDisplayTuple ( sort_tuple )
self . _listctrl . UpdateRow ( index , display_tuple , sort_tuple )
else :
break
def GetValue ( self ) :
bandwidth_rules = HydrusNetworking . BandwidthRules ( )
for ( bandwidth_type , time_delta , max_allowed ) in self . _listctrl . GetClientData ( ) :
bandwidth_rules . AddRule ( bandwidth_type , time_delta , max_allowed )
return bandwidth_rules
class _EditPanel ( ClientGUIScrolledPanels . EditPanel ) :
def __init__ ( self , parent , rule ) :
ClientGUIScrolledPanels . EditPanel . __init__ ( self , parent )
self . _bandwidth_type = ClientGUICommon . BetterChoice ( self )
self . _bandwidth_type . Append ( ' data ' , HC . BANDWIDTH_TYPE_DATA )
self . _bandwidth_type . Append ( ' requests ' , HC . BANDWIDTH_TYPE_REQUESTS )
self . _bandwidth_type . Bind ( wx . EVT_CHOICE , self . EventBandwidth )
2017-06-21 21:15:59 +00:00
self . _time_delta = ClientGUICommon . TimeDeltaButton ( self , min = 1 , days = True , hours = True , minutes = True , seconds = True , monthly_allowed = True )
2017-03-02 02:14:56 +00:00
self . _max_allowed = wx . SpinCtrl ( self , min = 1 , max = 1024 * 1024 * 1024 )
2017-04-19 20:58:30 +00:00
self . _max_allowed_st = ClientGUICommon . BetterStaticText ( self )
2017-03-02 02:14:56 +00:00
#
( bandwidth_type , time_delta , max_allowed ) = rule
self . _bandwidth_type . SelectClientData ( bandwidth_type )
self . _time_delta . SetValue ( time_delta )
if bandwidth_type == HC . BANDWIDTH_TYPE_DATA :
max_allowed / = 1048576
self . _max_allowed . SetValue ( max_allowed )
self . _UpdateMaxAllowedSt ( )
#
hbox = wx . BoxSizer ( wx . HORIZONTAL )
hbox . AddF ( self . _bandwidth_type , CC . FLAGS_VCENTER )
hbox . AddF ( self . _time_delta , CC . FLAGS_VCENTER )
hbox . AddF ( self . _max_allowed , CC . FLAGS_VCENTER )
hbox . AddF ( self . _max_allowed_st , CC . FLAGS_VCENTER )
self . SetSizer ( hbox )
def _UpdateMaxAllowedSt ( self ) :
bandwidth_type = self . _bandwidth_type . GetChoice ( )
if bandwidth_type == HC . BANDWIDTH_TYPE_DATA :
self . _max_allowed_st . SetLabelText ( ' MB ' )
elif bandwidth_type == HC . BANDWIDTH_TYPE_REQUESTS :
self . _max_allowed_st . SetLabelText ( ' requests ' )
def EventBandwidth ( self , event ) :
self . _UpdateMaxAllowedSt ( )
def GetValue ( self ) :
bandwidth_type = self . _bandwidth_type . GetChoice ( )
time_delta = self . _time_delta . GetValue ( )
max_allowed = self . _max_allowed . GetValue ( )
if bandwidth_type == HC . BANDWIDTH_TYPE_DATA :
max_allowed * = 1048576
return ( bandwidth_type , time_delta , max_allowed )
2017-03-08 23:23:12 +00:00
2017-03-22 22:38:15 +00:00
class EditStringToStringDictControl ( wx . Panel ) :
def __init__ ( self , parent , initial_dict ) :
wx . Panel . __init__ ( self , parent )
2017-08-02 21:32:54 +00:00
listctrl_panel = ClientGUIListCtrl . SaneListCtrlPanel ( self )
2017-07-27 00:47:13 +00:00
2017-08-02 21:32:54 +00:00
self . _listctrl = ClientGUIListCtrl . SaneListCtrl ( listctrl_panel , 120 , [ ( ' key ' , 200 ) , ( ' value ' , - 1 ) ] , delete_key_callback = self . Delete , activation_callback = self . Edit )
2017-03-22 22:38:15 +00:00
2017-07-27 00:47:13 +00:00
listctrl_panel . SetListCtrl ( self . _listctrl )
listctrl_panel . AddButton ( ' add ' , self . Add )
listctrl_panel . AddButton ( ' edit ' , self . Edit , enabled_only_on_selection = True )
listctrl_panel . AddButton ( ' delete ' , self . Delete , enabled_only_on_selection = True )
2017-03-22 22:38:15 +00:00
#
for display_tuple in initial_dict . items ( ) :
self . _listctrl . Append ( display_tuple , display_tuple )
#
vbox = wx . BoxSizer ( wx . VERTICAL )
2017-07-27 00:47:13 +00:00
vbox . AddF ( listctrl_panel , CC . FLAGS_EXPAND_BOTH_WAYS )
2017-03-22 22:38:15 +00:00
self . SetSizer ( vbox )
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 Delete ( self ) :
with ClientGUIDialogs . DialogYesNo ( self , ' Remove all selected? ' ) as dlg :
if dlg . ShowModal ( ) == wx . ID_YES :
self . _listctrl . RemoveAllSelected ( )
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 GetValue ( self ) :
value_dict = { key : value for ( key , value ) in self . _listctrl . GetClientData ( ) }
return value_dict
2017-07-05 21:09:28 +00:00
class NetworkJobControl ( wx . Panel ) :
def __init__ ( self , parent ) :
2017-07-12 20:03:45 +00:00
wx . Panel . __init__ ( self , parent , style = wx . BORDER_DOUBLE )
2017-07-05 21:09:28 +00:00
self . _network_job = None
2017-07-12 20:03:45 +00:00
self . _download_started = False
2017-08-16 21:58:06 +00:00
self . _auto_override_bandwidth_rules = False
2017-07-12 20:03:45 +00:00
self . _left_text = ClientGUICommon . BetterStaticText ( self )
self . _right_text = ClientGUICommon . BetterStaticText ( self , style = wx . ALIGN_RIGHT )
# 512/768KB - 200KB/s
right_width = ClientData . ConvertTextToPixelWidth ( self . _right_text , 20 )
2017-07-05 21:09:28 +00:00
2017-07-12 20:03:45 +00:00
self . _right_text . SetMinSize ( ( right_width , - 1 ) )
self . _gauge = ClientGUICommon . Gauge ( self )
2017-07-05 21:09:28 +00:00
2017-08-16 21:58:06 +00:00
menu_items = [ ]
invert_call = self . FlipOverrideBandwidthForCurrentJob
value_call = self . CurrentJobOverridesBandwidth
check_manager = ClientGUICommon . CheckboxManagerCalls ( invert_call , value_call )
menu_items . append ( ( ' check ' , ' override bandwidth rules for this job ' , ' Tell the current job to ignore existing bandwidth rules and go ahead anyway. ' , check_manager ) )
menu_items . append ( ( ' separator ' , 0 , 0 , 0 ) )
invert_call = self . FlipAutoOverrideBandwidth
value_call = self . AutoOverrideBandwidth
check_manager = ClientGUICommon . CheckboxManagerCalls ( invert_call , value_call )
menu_items . append ( ( ' check ' , ' auto-override bandwidth rules for all jobs here after five seconds ' , ' Ignore existing bandwidth rules for all jobs under this control, instead waiting a flat five seconds. ' , check_manager ) )
self . _cog_button = ClientGUICommon . MenuBitmapButton ( self , CC . GlobalBMPs . cog , menu_items )
2017-07-05 21:09:28 +00:00
self . _cancel_button = ClientGUICommon . BetterBitmapButton ( self , CC . GlobalBMPs . stop , self . Cancel )
#
self . _Update ( )
#
2017-07-12 20:03:45 +00:00
st_hbox = wx . BoxSizer ( wx . HORIZONTAL )
st_hbox . AddF ( self . _left_text , CC . FLAGS_EXPAND_BOTH_WAYS )
st_hbox . AddF ( self . _right_text , CC . FLAGS_VCENTER )
left_vbox = wx . BoxSizer ( wx . VERTICAL )
left_vbox . AddF ( st_hbox , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
left_vbox . AddF ( self . _gauge , CC . FLAGS_EXPAND_PERPENDICULAR )
2017-07-05 21:09:28 +00:00
hbox = wx . BoxSizer ( wx . HORIZONTAL )
2017-07-12 20:03:45 +00:00
hbox . AddF ( left_vbox , CC . FLAGS_EXPAND_SIZER_BOTH_WAYS )
2017-08-16 21:58:06 +00:00
hbox . AddF ( self . _cog_button , CC . FLAGS_VCENTER )
2017-07-05 21:09:28 +00:00
hbox . AddF ( self . _cancel_button , CC . FLAGS_VCENTER )
self . SetSizer ( hbox )
#
2017-07-12 20:03:45 +00:00
self . Bind ( wx . EVT_TIMER , self . TIMEREventUpdate )
2017-07-05 21:09:28 +00:00
2017-07-27 00:47:13 +00:00
self . _update_timer = wx . Timer ( self )
2017-07-05 21:09:28 +00:00
2017-08-30 20:27:47 +00:00
def _OverrideBandwidthIfAppropriate ( self ) :
if self . _network_job is None or self . _network_job . NoEngineYet ( ) :
return
else :
if self . _auto_override_bandwidth_rules and HydrusData . TimeHasPassed ( self . _network_job . GetCreationTime ( ) + 5 ) :
self . _network_job . OverrideBandwidth ( )
2017-07-05 21:09:28 +00:00
def _Update ( self ) :
2017-07-27 00:47:13 +00:00
if self . _network_job is None or self . _network_job . NoEngineYet ( ) :
2017-07-05 21:09:28 +00:00
2017-07-12 20:03:45 +00:00
self . _left_text . SetLabelText ( ' ' )
self . _right_text . SetLabelText ( ' ' )
self . _gauge . SetRange ( 1 )
self . _gauge . SetValue ( 0 )
2017-07-05 21:09:28 +00:00
can_cancel = False
else :
if self . _network_job . IsDone ( ) :
can_cancel = False
else :
can_cancel = True
( status_text , current_speed , bytes_read , bytes_to_read ) = self . _network_job . GetStatus ( )
2017-07-12 20:03:45 +00:00
self . _left_text . SetLabelText ( status_text )
if not self . _download_started and current_speed > 0 :
2017-07-05 21:09:28 +00:00
2017-07-12 20:03:45 +00:00
self . _download_started = True
if self . _download_started and not self . _network_job . HasError ( ) :
speed_text = ' '
if bytes_read is not None :
if bytes_to_read is not None and bytes_read != bytes_to_read :
speed_text + = HydrusData . ConvertValueRangeToBytes ( bytes_read , bytes_to_read )
else :
speed_text + = HydrusData . ConvertIntToBytes ( bytes_read )
if current_speed != bytes_to_read : # if it is a real quick download, just say its size
speed_text + = ' ' + HydrusData . ConvertIntToBytes ( current_speed ) + ' /s '
self . _right_text . SetLabelText ( speed_text )
2017-07-05 21:09:28 +00:00
else :
2017-07-12 20:03:45 +00:00
self . _right_text . SetLabelText ( ' ' )
2017-07-05 21:09:28 +00:00
2017-07-12 20:03:45 +00:00
self . _gauge . SetRange ( bytes_to_read )
self . _gauge . SetValue ( bytes_read )
2017-07-05 21:09:28 +00:00
if can_cancel :
if not self . _cancel_button . IsEnabled ( ) :
self . _cancel_button . Enable ( )
else :
if self . _cancel_button . IsEnabled ( ) :
self . _cancel_button . Disable ( )
2017-08-16 21:58:06 +00:00
def AutoOverrideBandwidth ( self ) :
return self . _auto_override_bandwidth_rules
2017-07-05 21:09:28 +00:00
def Cancel ( self ) :
if self . _network_job is not None :
self . _network_job . Cancel ( )
def ClearNetworkJob ( self ) :
2017-08-02 21:32:54 +00:00
if self and self . _network_job is not None :
2017-07-19 21:21:41 +00:00
self . _network_job = None
2017-07-27 00:47:13 +00:00
self . _Update ( )
self . _update_timer . Stop ( )
2017-07-19 21:21:41 +00:00
2017-07-12 20:03:45 +00:00
2017-07-05 21:09:28 +00:00
2017-08-16 21:58:06 +00:00
def CurrentJobOverridesBandwidth ( self ) :
if self . _network_job is None :
return None
else :
return not self . _network_job . ObeysBandwidth ( )
def FlipAutoOverrideBandwidth ( self ) :
self . _auto_override_bandwidth_rules = not self . _auto_override_bandwidth_rules
def FlipOverrideBandwidthForCurrentJob ( self ) :
if self . _network_job is not None :
self . _network_job . OverrideBandwidth ( )
2017-07-05 21:09:28 +00:00
def SetNetworkJob ( self , network_job ) :
2017-08-02 21:32:54 +00:00
if self and self . _network_job != network_job :
2017-07-19 21:21:41 +00:00
self . _network_job = network_job
self . _download_started = False
2017-07-27 00:47:13 +00:00
self . _update_timer . Start ( 250 , wx . TIMER_CONTINUOUS )
2017-07-05 21:09:28 +00:00
def TIMEREventUpdate ( self , event ) :
2017-08-30 20:27:47 +00:00
self . _OverrideBandwidthIfAppropriate ( )
2017-08-02 21:32:54 +00:00
if HG . client_controller . gui . IShouldRegularlyUpdate ( self ) :
2017-07-05 21:09:28 +00:00
self . _Update ( )