import ClientConstants as CC import ClientData import ClientDefaults import ClientGUICommon import ClientGUIDialogs import ClientGUIMenus import ClientGUIControls import ClientGUIListBoxes import ClientGUIListCtrl import ClientGUIParsing import ClientGUIScrolledPanels import ClientGUIScrolledPanelsEdit import ClientGUISerialisable import ClientGUITopLevelWindows import ClientImporting import ClientNetworking import ClientNetworkingBandwidth import ClientNetworkingContexts import ClientNetworkingDomain import ClientNetworkingLogin import ClientNetworkingJobs import ClientNetworkingSessions import ClientParsing import ClientPaths import ClientSerialisable import ClientThreading import HydrusConstants as HC import HydrusData import HydrusExceptions import HydrusGlobals as HG import HydrusSerialisable import HydrusTags import HydrusText import itertools import os import re import threading import traceback import time import wx class EditLoginCredentialsPanel( ClientGUIScrolledPanels.EditPanel ): def __init__( self, parent, credential_definitions, credentials ): ClientGUIScrolledPanels.EditPanel.__init__( self, parent ) # self._control_data = [] rows = [] credential_definitions = list( credential_definitions ) credential_definitions.sort( key = lambda cd: cd.ShouldHide() ) for credential_definition in credential_definitions: if credential_definition.ShouldHide(): style = wx.TE_PASSWORD else: style = 0 control = wx.TextCtrl( self, style = style ) name = credential_definition.GetName() if name in credentials: control.SetValue( credentials[ name ] ) control.Bind( wx.EVT_TEXT, self.EventKey ) control_st = ClientGUICommon.BetterStaticText( self ) self._control_data.append( ( credential_definition, control, control_st ) ) hbox = wx.BoxSizer( wx.HORIZONTAL ) hbox.Add( control, CC.FLAGS_EXPAND_BOTH_WAYS ) hbox.Add( control_st, CC.FLAGS_EXPAND_BOTH_WAYS ) rows.append( ( credential_definition.GetName() + ': ', hbox ) ) gridbox = ClientGUICommon.WrapInGrid( self, rows ) self.SetSizer( gridbox ) self._UpdateSts() def _UpdateSts( self ): for ( credential_definition, control, control_st ) in self._control_data: value = control.GetValue() colour = ( 127, 0, 0 ) if value == '': string_match = credential_definition.GetStringMatch() if string_match is None: st_label = '' else: st_label = string_match.ToUnicode() else: try: credential_definition.Test( value ) st_label = u'looks good \u2713' colour = ( 0, 127, 0 ) except Exception as e: st_label = HydrusData.ToUnicode( e ) control_st.SetLabelText( st_label ) control_st.SetForegroundColour( colour ) def EventKey( self, event ): self._UpdateSts() event.Skip() def GetValue( self ): # error on invalid credentials = {} for ( credential_definition, control, control_st ) in self._control_data: name = credential_definition.GetName() value = control.GetValue() if value == '': raise HydrusExceptions.VetoException( 'Please enter a value for ' + name + '!' ) else: try: credential_definition.Test( value ) except Exception as e: raise HydrusExceptions.VetoException( 'For ' + name + ': ' + HydrusData.ToUnicode( e ) ) credentials[ name ] = value return credentials class EditLoginCredentialDefinitionPanel( ClientGUIScrolledPanels.EditPanel ): def __init__( self, parent, credential_definition ): ClientGUIScrolledPanels.EditPanel.__init__( self, parent ) # self._name = wx.TextCtrl( self ) self._credential_type = ClientGUICommon.BetterChoice( self ) for credential_type in [ ClientNetworkingLogin.CREDENTIAL_TYPE_TEXT, ClientNetworkingLogin.CREDENTIAL_TYPE_PASS ]: self._credential_type.Append( ClientNetworkingLogin.credential_type_str_lookup[ credential_type ], credential_type ) string_match = credential_definition.GetStringMatch() self._string_match = ClientGUIControls.StringMatchButton( self, string_match ) # self._name.SetValue( credential_definition.GetName() ) self._credential_type.SelectClientData( credential_definition.GetType() ) # rows = [] rows.append( ( 'name: ', self._name ) ) rows.append( ( 'input type: ', self._credential_type ) ) rows.append( ( 'permitted input: ', self._string_match ) ) gridbox = ClientGUICommon.WrapInGrid( self, rows ) self.SetSizer( gridbox ) def GetValue( self ): name = self._name.GetValue() credential_type = self._credential_type.GetChoice() string_match = self._string_match.GetValue() credential_definition = ClientNetworkingLogin.LoginCredentialDefinition( name = name, credential_type = credential_type, string_match = string_match ) return credential_definition class EditLoginsPanel( ClientGUIScrolledPanels.EditPanel ): def __init__( self, parent, engine, login_scripts, domains_to_login_info ): ClientGUIScrolledPanels.EditPanel.__init__( self, parent ) self._engine = engine self._login_scripts = login_scripts domains_and_login_info_panel = ClientGUIListCtrl.BetterListCtrlPanel( self ) columns = [ ( 'domain', 20 ), ( 'login script', -1 ), ( 'access given', 48 ), ( 'active?', 8 ), ( 'logged in now?', 16 ), ( 'validity', 24 ), ( 'recent error/delay?', 24 ) ] self._domains_and_login_info = ClientGUIListCtrl.BetterListCtrl( domains_and_login_info_panel, 'domains_to_login_info', 8, 36, columns, self._ConvertDomainAndLoginInfoListCtrlTuples, use_simple_delete = True, activation_callback = self._EditCredentials ) domains_and_login_info_panel.SetListCtrl( self._domains_and_login_info ) domains_and_login_info_panel.AddButton( 'add', self._Add ) domains_and_login_info_panel.AddDeleteButton() domains_and_login_info_panel.AddSeparator() domains_and_login_info_panel.AddButton( 'change login script', self._EditLoginScript, enabled_only_on_selection = True ) domains_and_login_info_panel.AddButton( 'edit credentials', self._EditCredentials, enabled_check_func = self._CanEditCreds ) domains_and_login_info_panel.AddButton( 'flip active', self._FlipActive, enabled_only_on_selection = True ) domains_and_login_info_panel.AddSeparator() domains_and_login_info_panel.AddButton( 'scrub delays', self._ScrubDelays, enabled_only_on_selection = True ) domains_and_login_info_panel.NewButtonRow() domains_and_login_info_panel.AddButton( 'reset login (delete cookies)', self._ClearSessions, enabled_only_on_selection = True ) # listctrl_data = [] for ( login_domain, ( login_script_key_and_name, credentials, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) ) in domains_to_login_info.items(): credentials_tuple = tuple( credentials.items() ) domain_and_login_info = ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) listctrl_data.append( domain_and_login_info ) self._domains_and_login_info.AddDatas( listctrl_data ) self._domains_and_login_info.Sort( 0 ) # vbox = wx.BoxSizer( wx.VERTICAL ) warning = 'WARNING: Your credentials are stored in plaintext! For this and other reasons, I recommend you use throwaway accounts with hydrus!' warning_st = ClientGUICommon.BetterStaticText( self, warning ) warning_st.SetForegroundColour( ( 128, 0, 0 ) ) vbox.Add( warning_st, CC.FLAGS_CENTER ) vbox.Add( domains_and_login_info_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) self.SetSizer( vbox ) def _Add( self ): if len( self._login_scripts ) == 0: wx.MessageBox( 'You have no login scripts, so you cannot add a new login!' ) return choice_tuples = [ ( login_script.GetName(), login_script ) for login_script in self._login_scripts ] with ClientGUIDialogs.DialogSelectFromList( self, 'select the login script to use', choice_tuples ) as dlg: if dlg.ShowModal() == wx.ID_OK: login_script = dlg.GetChoice() else: return example_domains = set( login_script.GetExampleDomains() ) domains_in_use = { login_domain for ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) in self._domains_and_login_info.GetData() } available_examples = list( example_domains.difference( domains_in_use ) ) available_examples.sort() if len( available_examples ) > 0: choice_tuples = [ ( login_domain, login_domain ) for login_domain in available_examples ] choice_tuples.append( ( 'use other domain', None ) ) with ClientGUIDialogs.DialogSelectFromList( self, 'select the domain to use', choice_tuples, sort_tuples = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: login_domain = dlg.GetChoice() if login_domain is not None: ( login_access_type, login_access_text ) = login_script.GetExampleDomainInfo( login_domain ) else: return else: login_domain = None if login_domain is None: with ClientGUIDialogs.DialogTextEntry( self, 'enter the domain', default = 'example.com', allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: login_domain = dlg.GetValue() if login_domain in domains_in_use: wx.MessageBox( 'That domain is already in use!' ) return a_types = [ ClientNetworkingLogin.LOGIN_ACCESS_TYPE_EVERYTHING, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_NSFW, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_SPECIAL, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_USER_PREFS_ONLY ] choice_tuples = [ ( ClientNetworkingLogin.login_access_type_str_lookup[ a_type ], a_type ) for a_type in a_types ] with ClientGUIDialogs.DialogSelectFromList( self, 'select what type of access the login gives to this domain', choice_tuples, sort_tuples = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: login_access_type = dlg.GetChoice() else: return login_access_text = ClientNetworkingLogin.login_access_type_default_description_lookup[ login_access_type ] with ClientGUIDialogs.DialogTextEntry( self, 'edit the access description, if needed', default = login_access_text, allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: login_access_text = dlg.GetValue() else: return else: return credential_definitions = login_script.GetCredentialDefinitions() credentials = {} if len( credential_definitions ) > 0: with ClientGUITopLevelWindows.DialogEdit( self, 'edit login' ) as dlg: panel = EditLoginCredentialsPanel( dlg, credential_definitions, credentials ) dlg.SetPanel( panel ) if dlg.ShowModal() == wx.ID_OK: credentials = panel.GetValue() else: return message = 'Activate this login script for this domain?' with ClientGUIDialogs.DialogYesNo( self, message, title = message ) as dlg: if dlg.ShowModal() == wx.ID_YES: active = True else: active = False login_script_key_and_name = login_script.GetLoginScriptKeyAndName() credentials_tuple = tuple( credentials.items() ) active = True validity = ClientNetworkingLogin.VALIDITY_UNTESTED validity_error_text = '' no_work_until = 0 no_work_until_reason = '' domain_and_login_info = ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) self._domains_and_login_info.AddDatas( ( domain_and_login_info, ) ) self._domains_and_login_info.Sort() def _CanEditCreds( self ): domain_and_login_infos = self._domains_and_login_info.GetData( only_selected = True ) for domain_and_login_info in domain_and_login_infos: ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) = domain_and_login_info try: login_script = self._GetLoginScript( login_script_key_and_name ) if len( login_script.GetCredentialDefinitions() ) > 0: return True except HydrusExceptions.DataMissing: continue return False def _ClearSessions( self ): domain_and_login_infos = self._domains_and_login_info.GetData( only_selected = True ) if len( domain_and_login_infos ) > 0: message = 'Are you sure you want to clear these domains\' sessions? This will delete all their existing cookies and cannot be undone.' with ClientGUIDialogs.DialogYesNo( self, message ) as dlg: if dlg.ShowModal() != wx.ID_YES: return for domain_and_login_info in domain_and_login_infos: ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) = domain_and_login_info network_context = ClientNetworkingContexts.NetworkContext( context_type = CC.NETWORK_CONTEXT_DOMAIN, context_data = login_domain ) self._engine.session_manager.ClearSession( network_context ) self._domains_and_login_info.UpdateDatas() def _ConvertDomainAndLoginInfoListCtrlTuples( self, domain_and_login_info ): ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) = domain_and_login_info try: login_script = self._GetLoginScript( login_script_key_and_name ) sort_login_script = login_script.GetName() network_context = ClientNetworkingContexts.NetworkContext( context_type = CC.NETWORK_CONTEXT_DOMAIN, context_data = login_domain ) logged_in = login_script.IsLoggedIn( self._engine, network_context ) except HydrusExceptions.DataMissing: sort_login_script = 'login script not found' logged_in = False access = ClientNetworkingLogin.login_access_type_str_lookup[ login_access_type ] + ' - ' + login_access_text if active: sort_active = 'yes' else: sort_active = 'no' sort_validity = ClientNetworkingLogin.validity_str_lookup[ validity ] if len( validity_error_text ) > 0: sort_validity += ' - ' + validity_error_text if logged_in: sort_logged_in = 'yes' else: sort_logged_in = 'no' if HydrusData.TimeHasPassed( no_work_until ): pretty_no_work_until = '' else: pretty_no_work_until = HydrusData.ConvertTimestampToPrettyExpires( no_work_until ) + ' - ' + no_work_until_reason pretty_login_domain = login_domain pretty_login_script = sort_login_script pretty_access = access pretty_active = sort_active pretty_validity = sort_validity pretty_logged_in = sort_logged_in display_tuple = ( pretty_login_domain, pretty_login_script, pretty_access, pretty_active, pretty_logged_in, pretty_validity, pretty_no_work_until ) sort_tuple = ( login_domain, sort_login_script, access, sort_active, sort_logged_in, sort_validity, no_work_until ) return ( display_tuple, sort_tuple ) def _EditCredentials( self ): domain_and_login_infos = self._domains_and_login_info.GetData( only_selected = True ) for domain_and_login_info in domain_and_login_infos: ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) = domain_and_login_info try: login_script = self._GetLoginScript( login_script_key_and_name ) except HydrusExceptions.DataMissing: wx.MessageBox( 'Could not find a login script for "' + login_domain + '"! Please re-add the login script in the other dialog or update the entry here to a new one!' ) return credential_definitions = login_script.GetCredentialDefinitions() if len( credential_definitions ) > 0: with ClientGUITopLevelWindows.DialogEdit( self, 'edit login' ) as dlg: credentials = dict( credentials_tuple ) panel = EditLoginCredentialsPanel( dlg, credential_definitions, credentials ) dlg.SetPanel( panel ) if dlg.ShowModal() == wx.ID_OK: credentials = panel.GetValue() else: return else: continue credentials_tuple = tuple( credentials.items() ) if not active: message = 'Activate this login script for this domain?' with ClientGUIDialogs.DialogYesNo( self, message, title = message ) as dlg: if dlg.ShowModal() == wx.ID_YES: active = True validity = ClientNetworkingLogin.VALIDITY_UNTESTED validity_error_text = '' no_work_until = 0 no_work_until_reason = '' edited_domain_and_login_info = ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) self._domains_and_login_info.DeleteDatas( ( domain_and_login_info, ) ) self._domains_and_login_info.AddDatas( ( edited_domain_and_login_info, ) ) self._domains_and_login_info.Sort() def _EditLoginScript( self ): domain_and_login_infos = self._domains_and_login_info.GetData( only_selected = True ) for domain_and_login_info in domain_and_login_infos: ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) = domain_and_login_info try: login_script = self._GetLoginScript( login_script_key_and_name ) except HydrusExceptions.DataMissing: login_script = None choice_tuples = [ ( login_script.GetName(), login_script ) for login_script in self._login_scripts ] with ClientGUIDialogs.DialogSelectFromList( self, 'select the login script to use', choice_tuples, value_to_select = login_script ) as dlg: if dlg.ShowModal() == wx.ID_OK: login_script = dlg.GetChoice() login_script_key_and_name = login_script.GetLoginScriptKeyAndName() else: return try: ( login_access_type, login_access_text ) = login_script.GetExampleDomainInfo( login_domain ) except HydrusExceptions.DataMissing: a_types = [ ClientNetworkingLogin.LOGIN_ACCESS_TYPE_EVERYTHING, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_NSFW, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_SPECIAL, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_USER_PREFS_ONLY ] choice_tuples = [ ( ClientNetworkingLogin.login_access_type_str_lookup[ a_type ], a_type ) for a_type in a_types ] with ClientGUIDialogs.DialogSelectFromList( self, 'select what type of access the login gives to this domain', choice_tuples, sort_tuples = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: login_access_type = dlg.GetChoice() else: return login_access_text = ClientNetworkingLogin.login_access_type_default_description_lookup[ login_access_type ] with ClientGUIDialogs.DialogTextEntry( self, 'edit the access description, if needed', default = login_access_text, allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: login_access_text = dlg.GetValue() else: return validity = ClientNetworkingLogin.VALIDITY_UNTESTED validity_error_text = 'unknown: restart dialog to refresh validity' no_work_until = 0 no_work_until_reason = '' edited_domain_and_login_info = ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) self._domains_and_login_info.DeleteDatas( ( domain_and_login_info, ) ) self._domains_and_login_info.AddDatas( ( edited_domain_and_login_info, ) ) self._domains_and_login_info.Sort() def _FlipActive( self ): domain_and_login_infos = self._domains_and_login_info.GetData( only_selected = True ) for domain_and_login_info in domain_and_login_infos: ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) = domain_and_login_info active = not active flipped_domain_and_login_info = ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) self._domains_and_login_info.DeleteDatas( ( domain_and_login_info, ) ) self._domains_and_login_info.AddDatas( ( flipped_domain_and_login_info, ) ) self._domains_and_login_info.Sort() def _GetLoginScript( self, login_script_key_and_name ): ( login_script_key, login_script_name ) = login_script_key_and_name for login_script in self._login_scripts: if login_script.GetLoginScriptKey() == login_script_key: return login_script for login_script in self._login_scripts: if login_script.GetName() == login_script_name: return login_script raise HydrusExceptions.DataMissing( 'No login script found!' ) def _ScrubDelays( self ): domain_and_login_infos = self._domains_and_login_info.GetData( only_selected = True ) for domain_and_login_info in domain_and_login_infos: ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) = domain_and_login_info no_work_until = 0 no_work_until_reason = '' scrubbed_domain_and_login_info = ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) self._domains_and_login_info.DeleteDatas( ( domain_and_login_info, ) ) self._domains_and_login_info.AddDatas( ( scrubbed_domain_and_login_info, ) ) self._domains_and_login_info.Sort() def GetValue( self ): domains_to_login_info = dict() for ( login_domain, login_script_key_and_name, credentials_tuple, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) in self._domains_and_login_info.GetData(): credentials = dict( credentials_tuple ) domains_to_login_info[ login_domain ] = ( login_script_key_and_name, credentials, login_access_type, login_access_text, active, validity, validity_error_text, no_work_until, no_work_until_reason ) return domains_to_login_info def GenerateTestNetworkJobPresentationContextFactory( window, network_job_control ): def network_job_presentation_context_factory( network_job ): def wx_set_it( nj ): if not window: return network_job_control.SetNetworkJob( nj ) def enter_call(): wx.CallAfter( wx_set_it, network_job ) def exit_call(): wx.CallAfter( wx_set_it, None ) return ClientImporting.NetworkJobPresentationContext( enter_call, exit_call ) return network_job_presentation_context_factory class ReviewTestResultPanel( ClientGUIScrolledPanels.ReviewPanel ): def __init__( self, parent, test_result ): ClientGUIScrolledPanels.ReviewPanel.__init__( self, parent ) ( name, url, body, self._downloaded_data, new_temp_strings, new_cookie_strings, result ) = test_result self._name = ClientGUICommon.BetterStaticText( self, label = name ) self._url = wx.TextCtrl( self ) self._body = wx.TextCtrl( self, style = wx.TE_MULTILINE ) self._body.SetEditable( False ) min_size = ClientGUICommon.ConvertTextToPixels( self._body, ( 64, 3 ) ) self._body.SetMinClientSize( min_size ) self._data_preview = wx.TextCtrl( self, style = wx.TE_MULTILINE ) self._data_preview.SetEditable( False ) min_size = ClientGUICommon.ConvertTextToPixels( self._data_preview, ( 64, 8 ) ) self._data_preview.SetMinClientSize( min_size ) self._data_copy_button = ClientGUICommon.BetterBitmapButton( self, CC.GlobalBMPs.copy, self._CopyData ) self._data_copy_button.SetToolTip( 'Copy the current example data to the clipboard.' ) self._temp_variables = wx.TextCtrl( self, style = wx.TE_MULTILINE ) self._temp_variables.SetEditable( False ) min_size = ClientGUICommon.ConvertTextToPixels( self._temp_variables, ( 64, 6 ) ) self._temp_variables.SetMinClientSize( min_size ) self._cookies = wx.TextCtrl( self, style = wx.TE_MULTILINE ) self._cookies.SetEditable( False ) min_size = ClientGUICommon.ConvertTextToPixels( self._cookies, ( 64, 6 ) ) self._cookies.SetMinClientSize( min_size ) self._result = ClientGUICommon.BetterStaticText( self, label = result ) # self._url.SetValue( url ) if body is not None: try: self._body.SetValue( body ) except: self._body.SetValue( HydrusData.ToUnicode( body ) ) self._data_preview.SetValue( HydrusData.ToUnicode( self._downloaded_data[:1024] ) ) self._temp_variables.SetValue( os.linesep.join( new_temp_strings ) ) self._cookies.SetValue( os.linesep.join( new_cookie_strings ) ) # rows = [] rows.append( ( 'name: ', self._name ) ) rows.append( ( 'url: ', self._url ) ) rows.append( ( 'body (if set): ', self._body ) ) rows.append( ( 'data: ', self._data_preview ) ) rows.append( ( 'copy data: ', self._data_copy_button ) ) rows.append( ( 'new temp vars: ', self._temp_variables ) ) rows.append( ( 'new cookies: ', self._cookies ) ) rows.append( ( 'result: ', self._result ) ) gridbox = ClientGUICommon.WrapInGrid( self, rows ) self.SetSizer( gridbox ) def _CopyData( self ): HG.client_controller.pub( 'clipboard', 'text', self._downloaded_data ) class EditLoginScriptPanel( ClientGUIScrolledPanels.EditPanel ): def __init__( self, parent, login_script ): ClientGUIScrolledPanels.EditPanel.__init__( self, parent ) self._original_login_script = login_script self._currently_testing = False self._test_domain = '' self._test_credentials = {} # menu_items = [] page_func = HydrusData.Call( ClientPaths.LaunchPathInWebBrowser, os.path.join( HC.HELP_DIR, 'downloader_login.html' ) ) menu_items.append( ( 'normal', 'open the login scripts help', 'Open the help page for login scripts in your web browser.', page_func ) ) help_button = ClientGUICommon.MenuBitmapButton( self, CC.GlobalBMPs.help, menu_items ) help_hbox = ClientGUICommon.WrapInText( help_button, self, 'help for this panel -->', wx.Colour( 0, 0, 255 ) ) # self._name = wx.TextCtrl( self ) # credential_definitions_box_panel = ClientGUICommon.StaticBox( self, 'credential definitions' ) credential_definitions_panel = ClientGUIListCtrl.BetterListCtrlPanel( credential_definitions_box_panel ) columns = [ ( 'name', -1 ), ( 'type', 10 ), ( 'value', 16 ) ] self._credential_definitions = ClientGUIListCtrl.BetterListCtrl( credential_definitions_panel, 'credential_definitions', 4, 16, columns, self._ConvertCredentialDefinitionToListCtrlTuples, use_simple_delete = True, activation_callback = self._EditCredentialDefinitions ) credential_definitions_panel.SetListCtrl( self._credential_definitions ) credential_definitions_panel.AddButton( 'add', self._AddCredentialDefinition ) credential_definitions_panel.AddButton( 'edit', self._EditCredentialDefinitions, enabled_only_on_selection = True ) credential_definitions_panel.AddDeleteButton() # login_steps_box_panel = ClientGUICommon.StaticBox( self, 'login steps' ) columns = [ ( 'name', -1 ), ( 'url', 56 ) ] self._login_steps = ClientGUIListBoxes.QueueListBox( login_steps_box_panel, 5, self._ConvertLoginStepToListBoxString, add_callable = self._AddLoginStep, edit_callable = self._EditLoginStep ) # required_cookies_info_box_panel = ClientGUICommon.StaticBox( self, 'cookies required to consider session logged in' ) self._required_cookies_info = ClientGUIControls.StringToStringMatchDictControl( required_cookies_info_box_panel, login_script.GetRequiredCookiesInfo(), min_height = 4, key_name = 'cookie name' ) # example_domains_info_box_panel = ClientGUICommon.StaticBox( self, 'example domains' ) example_domains_info_panel = ClientGUIListCtrl.BetterListCtrlPanel( example_domains_info_box_panel ) columns = [ ( 'domain', -1 ), ( 'access type', 14 ), ( 'description', 40 ) ] self._example_domains_info = ClientGUIListCtrl.BetterListCtrl( example_domains_info_panel, 'example_domains_info', 6, 16, columns, self._ConvertExampleDomainInfoToListCtrlTuples, use_simple_delete = True, activation_callback = self._EditExampleDomainsInfo ) example_domains_info_panel.SetListCtrl( self._example_domains_info ) example_domains_info_panel.AddButton( 'add', self._AddExampleDomainsInfo ) example_domains_info_panel.AddButton( 'edit', self._EditExampleDomainsInfo, enabled_only_on_selection = True ) example_domains_info_panel.AddDeleteButton() # test_panel = ClientGUICommon.StaticBox( self, 'testing' ) self._test_button = ClientGUICommon.BetterButton( test_panel, 'run test', self._DoTest ) self._test_network_job_control = ClientGUIControls.NetworkJobControl( test_panel ) test_listctrl_panel = ClientGUIListCtrl.BetterListCtrlPanel( test_panel ) columns = [ ( 'step', -1 ), ( 'url', 36 ), ( 'result', 14 ) ] self._test_listctrl = ClientGUIListCtrl.BetterListCtrl( test_listctrl_panel, 'test_login_script_results', 6, 20, columns, self._ConvertTestResultToListCtrlTuples, activation_callback = self._ReviewTestResult ) test_listctrl_panel.SetListCtrl( self._test_listctrl ) test_listctrl_panel.AddButton( 'review', self._ReviewTestResult, enabled_only_on_selection = True ) self._final_test_result = ClientGUICommon.BetterStaticText( test_panel ) # self._name.SetValue( login_script.GetName() ) self._credential_definitions.SetData( login_script.GetCredentialDefinitions() ) self._login_steps.AddDatas( login_script.GetLoginSteps() ) self._example_domains_info.SetData( login_script.GetExampleDomainsInfo() ) # credential_definitions_box_panel.Add( credential_definitions_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) login_steps_box_panel.Add( self._login_steps, CC.FLAGS_EXPAND_BOTH_WAYS ) required_cookies_info_box_panel.Add( self._required_cookies_info, CC.FLAGS_EXPAND_BOTH_WAYS ) example_domains_info_box_panel.Add( example_domains_info_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) test_panel.Add( self._test_button, CC.FLAGS_EXPAND_PERPENDICULAR ) test_panel.Add( self._test_network_job_control, CC.FLAGS_EXPAND_PERPENDICULAR ) test_panel.Add( test_listctrl_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) test_panel.Add( self._final_test_result, CC.FLAGS_EXPAND_PERPENDICULAR ) # rows = [] rows.append( ( 'name: ', self._name ) ) gridbox = ClientGUICommon.WrapInGrid( self, rows ) vbox = ClientGUICommon.BetterBoxSizer( wx.VERTICAL ) vbox.Add( help_hbox, CC.FLAGS_BUTTON_SIZER ) vbox.Add( gridbox, CC.FLAGS_EXPAND_SIZER_PERPENDICULAR ) vbox.Add( credential_definitions_box_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) vbox.Add( login_steps_box_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) vbox.Add( required_cookies_info_box_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) vbox.Add( example_domains_info_box_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) hbox = ClientGUICommon.BetterBoxSizer( wx.HORIZONTAL ) hbox.Add( vbox, CC.FLAGS_EXPAND_SIZER_BOTH_WAYS ) hbox.Add( test_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) self.SetSizer( hbox ) def _AddCredentialDefinition( self ): new_credential_definition = ClientNetworkingLogin.LoginCredentialDefinition() with ClientGUITopLevelWindows.DialogEdit( self, 'edit parser', frame_key = 'deeply_nested_dialog' ) as dlg_edit: panel = EditLoginCredentialDefinitionPanel( dlg_edit, new_credential_definition ) dlg_edit.SetPanel( panel ) if dlg_edit.ShowModal() == wx.ID_OK: new_credential_definition = panel.GetValue() HydrusSerialisable.SetNonDupeName( new_credential_definition, self._GetExistingCredentialDefinitionNames() ) self._credential_definitions.AddDatas( ( new_credential_definition, ) ) self._credential_definitions.Sort() def _AddExampleDomainsInfo( self ): ( domain, access_type, access_text ) = ( 'example.com', ClientNetworkingLogin.LOGIN_ACCESS_TYPE_NSFW, ClientNetworkingLogin.login_access_type_default_description_lookup[ ClientNetworkingLogin.LOGIN_ACCESS_TYPE_NSFW ] ) with ClientGUIDialogs.DialogTextEntry( self, 'edit the domain', default = domain, allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: domain = dlg.GetValue() else: return existing_domains = self._GetExistingDomains() if domain in existing_domains: wx.MessageBox( 'That domain already exists!' ) return a_types = [ ClientNetworkingLogin.LOGIN_ACCESS_TYPE_EVERYTHING, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_NSFW, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_SPECIAL, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_USER_PREFS_ONLY ] choice_tuples = [ ( ClientNetworkingLogin.login_access_type_str_lookup[ a_type ], a_type ) for a_type in a_types ] with ClientGUIDialogs.DialogSelectFromList( self, 'select what type of access the login gives to this domain', choice_tuples, value_to_select = access_type, sort_tuples = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: new_access_type = dlg.GetChoice() else: return if new_access_type != access_type: access_type = new_access_type access_text = ClientNetworkingLogin.login_access_type_default_description_lookup[ access_type ] with ClientGUIDialogs.DialogTextEntry( self, 'edit the access description, if needed', default = access_text, allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: access_text = dlg.GetValue() else: return example_domain_info = ( domain, access_type, access_text ) self._example_domains_info.AddDatas( ( example_domain_info, ) ) self._example_domains_info.Sort() def _AddLoginStep( self ): login_step = ClientNetworkingLogin.LoginStep() return self._EditLoginStep( login_step ) def _ConvertCredentialDefinitionToListCtrlTuples( self, credential_definition ): name = credential_definition.GetName() credential_type = credential_definition.GetType() type_string = ClientNetworkingLogin.credential_type_str_lookup[ credential_type ] string_match = credential_definition.GetStringMatch() value = string_match.ToUnicode() pretty_name = name pretty_type_string = type_string pretty_value = value display_tuple = ( pretty_name, pretty_type_string, pretty_value ) sort_tuple = ( name, type_string, value ) return ( display_tuple, sort_tuple ) def _ConvertExampleDomainInfoToListCtrlTuples( self, example_domain_info ): ( domain, access_type, access_text ) = example_domain_info pretty_domain = domain pretty_access_type = ClientNetworkingLogin.login_access_type_str_lookup[ access_type ] pretty_access_text = access_text display_tuple = ( pretty_domain, pretty_access_type, pretty_access_text ) sort_tuple = ( domain, pretty_access_type, access_text ) return ( display_tuple, sort_tuple ) def _ConvertLoginStepToListBoxString( self, login_step ): name = login_step.GetName() return name def _ConvertTestResultToListCtrlTuples( self, test_result ): ( name, url, body, downloaded_data, new_temp_strings, new_cookie_strings, result ) = test_result pretty_name = name pretty_url = url pretty_result = result display_tuple = ( pretty_name, pretty_url, pretty_result ) sort_tuple = ( name, url, result ) return ( display_tuple, sort_tuple ) def _EditCredentialDefinitions( self ): credential_definitions = self._credential_definitions.GetData( only_selected = True ) for credential_definition in credential_definitions: with ClientGUITopLevelWindows.DialogEdit( self, 'edit login script', frame_key = 'deeply_nested_dialog' ) as dlg: panel = EditLoginCredentialDefinitionPanel( dlg, credential_definition ) dlg.SetPanel( panel ) if dlg.ShowModal() == wx.ID_OK: edited_credential_definition = panel.GetValue() self._credential_definitions.DeleteDatas( ( credential_definition, ) ) HydrusSerialisable.SetNonDupeName( edited_credential_definition, self._GetExistingCredentialDefinitionNames() ) self._credential_definitions.AddDatas( ( edited_credential_definition, ) ) else: break self._credential_definitions.Sort() def _DoTest( self ): def wx_add_result( test_result ): if not self: return self._test_listctrl.AddDatas( ( test_result, ) ) def receive_result( test_result ): wx.CallAfter( wx_add_result, test_result ) def clean_up( final_result ): if not self: return wx.MessageBox( final_result ) self._final_test_result.SetLabelText( final_result ) self._test_button.Enable() self._currently_testing = False def do_it( login_script, domain, credentials, network_job_presentation_context_factory ): try: login_result = 'login did not finish' # a potential here is to properly inform the login manager of the domain map and hence read back the invalidation text # but I am catching the info in the raised exception, so nbd really, I think bandwidth_manager = ClientNetworkingBandwidth.NetworkBandwidthManager() session_manager = ClientNetworkingSessions.NetworkSessionManager() domain_manager = ClientNetworkingDomain.NetworkDomainManager() login_manager = ClientNetworkingLogin.NetworkLoginManager() network_engine = ClientNetworking.NetworkEngine( HG.client_controller, bandwidth_manager, session_manager, domain_manager, login_manager ) HG.client_controller.CallToThreadLongRunning( network_engine.MainLoop ) network_context = ClientNetworkingContexts.NetworkContext.STATICGenerateForDomain( domain ) login_result = login_script.Start( network_engine, network_context, credentials, network_job_presentation_context_factory = network_job_presentation_context_factory, test_result_callable = wx_add_result ) except Exception as e: login_result = HydrusData.ToUnicode( e ) HydrusData.ShowException( e ) finally: network_engine.Shutdown() wx.CallAfter( clean_up, login_result ) if self._currently_testing: wx.MessageBox( 'Currently testing already! Please cancel current job!' ) return try: login_script = self.GetValue() except HydrusExceptions.VetoException: return if self._test_domain == '': example_domains = list( login_script.GetExampleDomains() ) example_domains.sort() if len( example_domains ) > 0: self._test_domain = example_domains[0] with ClientGUIDialogs.DialogTextEntry( self, 'edit the domain', default = self._test_domain, allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: self._test_domain = dlg.GetValue() else: return credential_definitions = login_script.GetCredentialDefinitions() if len( credential_definitions ) > 0: with ClientGUITopLevelWindows.DialogEdit( self, 'edit login' ) as dlg: panel = EditLoginCredentialsPanel( dlg, credential_definitions, self._test_credentials ) dlg.SetPanel( panel ) if dlg.ShowModal() == wx.ID_OK: self._test_credentials = panel.GetValue() else: return else: self._test_credentials = {} self._test_listctrl.DeleteDatas( self._test_listctrl.GetData() ) self._test_button.Disable() network_job_presentation_context_factory = GenerateTestNetworkJobPresentationContextFactory( self, self._test_network_job_control ) self._currently_testing = True HG.client_controller.CallToThread( do_it, login_script, self._test_domain, self._test_credentials, network_job_presentation_context_factory ) def _EditExampleDomainsInfo( self ): selected_example_domains_info = self._example_domains_info.GetData( only_selected = True ) for example_domain_info in selected_example_domains_info: ( original_domain, access_type, access_text ) = example_domain_info with ClientGUIDialogs.DialogTextEntry( self, 'edit the domain', default = original_domain, allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: domain = dlg.GetValue() else: break existing_domains = self._GetExistingDomains() if domain != original_domain and domain in existing_domains: wx.MessageBox( 'That domain already exists!' ) break a_types = [ ClientNetworkingLogin.LOGIN_ACCESS_TYPE_EVERYTHING, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_NSFW, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_SPECIAL, ClientNetworkingLogin.LOGIN_ACCESS_TYPE_USER_PREFS_ONLY ] choice_tuples = [ ( ClientNetworkingLogin.login_access_type_str_lookup[ a_type ], a_type ) for a_type in a_types ] with ClientGUIDialogs.DialogSelectFromList( self, 'select what type of access the login gives to this domain', choice_tuples, value_to_select = access_type, sort_tuples = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: new_access_type = dlg.GetChoice() else: break if new_access_type != access_type: access_type = new_access_type access_text = ClientNetworkingLogin.login_access_type_default_description_lookup[ access_type ] with ClientGUIDialogs.DialogTextEntry( self, 'edit the access description, if needed', default = access_text, allow_blank = False ) as dlg: if dlg.ShowModal() == wx.ID_OK: access_text = dlg.GetValue() else: break self._example_domains_info.DeleteDatas( ( example_domain_info, ) ) edited_example_domain_info = ( domain, access_type, access_text ) self._example_domains_info.AddDatas( ( edited_example_domain_info, ) ) self._example_domains_info.Sort() def _EditLoginStep( self, login_step ): with ClientGUITopLevelWindows.DialogEdit( self, 'edit login step' ) as dlg: panel = EditLoginStepPanel( dlg, login_step ) dlg.SetPanel( panel ) if dlg.ShowModal() == wx.ID_OK: login_step = panel.GetValue() return login_step else: raise HydrusExceptions.VetoException() def _GetExistingCredentialDefinitionNames( self ): return { credential_definition.GetName() for credential_definition in self._credential_definitions.GetData() } def _GetExistingDomains( self ): return { domain for ( domain, access_type, access_text ) in self._example_domains_info.GetData() } def _ReviewTestResult( self ): for test_result in self._test_listctrl.GetData( only_selected = True ): frame = ClientGUITopLevelWindows.FrameThatTakesScrollablePanel( self, 'login test result' ) panel = ReviewTestResultPanel( frame, test_result ) frame.SetPanel( panel ) def GetValue( self ): if self._currently_testing: raise HydrusExceptions.VetoException( 'Currently testing! Please cancel it first!' ) name = self._name.GetValue() login_script_key = self._original_login_script.GetLoginScriptKey() required_cookies_info = self._required_cookies_info.GetValue() credential_definitions = self._credential_definitions.GetData() login_steps = self._login_steps.GetData() example_domains_info = self._example_domains_info.GetData() credential_names = { credential_definition.GetName() for credential_definition in credential_definitions } login_script = ClientNetworkingLogin.LoginScriptDomain( name = name, login_script_key = login_script_key, required_cookies_info = required_cookies_info, credential_definitions = credential_definitions, login_steps = login_steps, example_domains_info = example_domains_info ) login_script.SetLoginScriptKey( login_script_key ) try: login_script.CheckIsValid() except HydrusExceptions.ValidationException as e: message = 'There is a problem with this script. The reason is:' message += os.linesep * 2 message += HydrusData.ToUnicode( e ) message += os.linesep * 2 message += 'Do you want to proceed with this invalid script, or go back and fix it?' with ClientGUIDialogs.DialogYesNo( self, message, yes_label = 'ok as invalid', no_label = 'go back' ) as dlg: if dlg.ShowModal() != wx.ID_YES: raise HydrusExceptions.VetoException( 'The ok event has been cancelled!' ) return login_script class EditLoginScriptsPanel( ClientGUIScrolledPanels.EditPanel ): def __init__( self, parent, login_scripts ): ClientGUIScrolledPanels.EditPanel.__init__( self, parent ) login_scripts_panel = ClientGUIListCtrl.BetterListCtrlPanel( self ) columns = [ ( 'name', -1 ), ( 'example domains', 40 ) ] self._login_scripts = ClientGUIListCtrl.BetterListCtrl( login_scripts_panel, 'login_scripts', 20, 24, columns, self._ConvertLoginScriptToListCtrlTuples, use_simple_delete = True, activation_callback = self._Edit ) login_scripts_panel.SetListCtrl( self._login_scripts ) login_scripts_panel.AddButton( 'add', self._Add ) login_scripts_panel.AddButton( 'edit', self._Edit, enabled_only_on_selection = True ) login_scripts_panel.AddDeleteButton() login_scripts_panel.AddSeparator() login_scripts_panel.AddImportExportButtons( ( ClientNetworkingLogin.LoginScriptDomain, ), self._AddLoginScript ) login_scripts_panel.AddSeparator() login_scripts_panel.AddDefaultsButton( ClientDefaults.GetDefaultLoginScripts, self._AddLoginScript ) # self._login_scripts.AddDatas( login_scripts ) # vbox = wx.BoxSizer( wx.VERTICAL ) vbox.Add( login_scripts_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) self.SetSizer( vbox ) def _Add( self ): new_login_script = ClientNetworkingLogin.LoginScriptDomain() with ClientGUITopLevelWindows.DialogEdit( self, 'edit login script', frame_key = 'deeply_nested_dialog' ) as dlg_edit: panel = EditLoginScriptPanel( dlg_edit, new_login_script ) dlg_edit.SetPanel( panel ) if dlg_edit.ShowModal() == wx.ID_OK: new_login_script = panel.GetValue() self._AddLoginScript( new_login_script ) self._login_scripts.Sort() def _AddLoginScript( self, login_script ): HydrusSerialisable.SetNonDupeName( login_script, self._GetExistingNames() ) login_script.RegenerateLoginScriptKey() self._login_scripts.AddDatas( ( login_script, ) ) def _ConvertLoginScriptToListCtrlTuples( self, login_script ): name = login_script.GetName() example_domains = list( login_script.GetExampleDomains() ) example_domains.sort() pretty_name = name pretty_example_domains = ', '.join( example_domains ) display_tuple = ( pretty_name, pretty_example_domains ) sort_tuple = ( name, example_domains ) return ( display_tuple, sort_tuple ) def _Edit( self ): login_scripts = self._login_scripts.GetData( only_selected = True ) for login_script in login_scripts: with ClientGUITopLevelWindows.DialogEdit( self, 'edit login script', frame_key = 'deeply_nested_dialog' ) as dlg: panel = EditLoginScriptPanel( dlg, login_script ) dlg.SetPanel( panel ) if dlg.ShowModal() == wx.ID_OK: edited_login_script = panel.GetValue() self._login_scripts.DeleteDatas( ( login_script, ) ) HydrusSerialisable.SetNonDupeName( edited_login_script, self._GetExistingNames() ) self._login_scripts.AddDatas( ( edited_login_script, ) ) else: break self._login_scripts.Sort() def _GetExistingNames( self ): names = { login_script.GetName() for login_script in self._login_scripts.GetData() } return names def GetValue( self ): return self._login_scripts.GetData() class EditLoginStepPanel( ClientGUIScrolledPanels.EditPanel ): def __init__( self, parent, login_step ): ClientGUIScrolledPanels.EditPanel.__init__( self, parent ) # name = login_step.GetName() ( scheme, method, subdomain, path, required_credentials, static_args, temp_args, required_cookies_info, content_parsers ) = login_step.ToTuple() # self._name = wx.TextCtrl( self ) self._method = ClientGUICommon.BetterChoice( self ) self._method.Append( 'GET', 'GET' ) self._method.Append( 'POST', 'POST' ) self._scheme = ClientGUICommon.BetterChoice( self ) self._scheme.Append( 'http', 'http' ) self._scheme.Append( 'https', 'https' ) self._subdomain = ClientGUICommon.NoneableTextCtrl( self, none_phrase = 'none' ) self._path = wx.TextCtrl( self ) required_credentials_panel = ClientGUICommon.StaticBox( self, 'credentials to send' ) self._required_credentials = ClientGUIControls.StringToStringDictControl( required_credentials_panel, required_credentials, min_height = 4, key_name = 'credential name', value_name = 'parameter name' ) # static_args_panel = ClientGUICommon.StaticBox( self, 'static variables to send' ) self._static_args = ClientGUIControls.StringToStringDictControl( static_args_panel, static_args, min_height = 4, key_name = 'parameter name', value_name = 'value' ) # temp_args_panel = ClientGUICommon.StaticBox( self, 'temporary variables to send' ) self._temp_args = ClientGUIControls.StringToStringDictControl( temp_args_panel, temp_args, min_height = 4, key_name = 'temp variable name', value_name = 'parameter name' ) # required_cookies_info_box_panel = ClientGUICommon.StaticBox( self, 'cookies required to consider step successful' ) self._required_cookies_info = ClientGUIControls.StringToStringMatchDictControl( required_cookies_info_box_panel, required_cookies_info, min_height = 4, key_name = 'cookie name' ) # content_parsers_panel = ClientGUICommon.StaticBox( self, 'content parsers' ) test_context_callable = lambda: ( {}, '' ) permitted_content_types = [ HC.CONTENT_TYPE_VARIABLE, HC.CONTENT_TYPE_VETO ] self._content_parsers = ClientGUIParsing.EditContentParsersPanel( content_parsers_panel, test_context_callable, permitted_content_types ) # a test panel a la pageparsers # self._name.SetValue( name ) self._scheme.SelectClientData( scheme ) self._method.SelectClientData( method ) self._subdomain.SetValue( subdomain ) self._path.SetValue( path ) self._content_parsers.AddDatas( content_parsers ) # required_credentials_panel.Add( self._required_credentials, CC.FLAGS_EXPAND_BOTH_WAYS ) static_args_panel.Add( self._static_args, CC.FLAGS_EXPAND_BOTH_WAYS ) temp_args_panel.Add( self._temp_args, CC.FLAGS_EXPAND_BOTH_WAYS ) required_cookies_info_box_panel.Add( self._required_cookies_info, CC.FLAGS_EXPAND_BOTH_WAYS ) content_parsers_panel.Add( self._content_parsers, CC.FLAGS_EXPAND_BOTH_WAYS ) # rows = [] rows.append( ( 'name: ', self._name ) ) rows.append( ( 'scheme: ', self._scheme ) ) rows.append( ( 'method: ', self._method ) ) rows.append( ( 'subdomain (replaces www, if present): ', self._subdomain ) ) rows.append( ( 'path: ', self._path ) ) gridbox = ClientGUICommon.WrapInGrid( self, rows ) vbox = ClientGUICommon.BetterBoxSizer( wx.VERTICAL ) vbox.Add( gridbox, CC.FLAGS_EXPAND_PERPENDICULAR ) vbox.Add( required_credentials_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) vbox.Add( static_args_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) vbox.Add( temp_args_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) vbox.Add( required_cookies_info_box_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) vbox.Add( content_parsers_panel, CC.FLAGS_EXPAND_BOTH_WAYS ) self.SetSizer( vbox ) def GetValue( self ): name = self._name.GetValue() scheme = self._scheme.GetChoice() method = self._method.GetChoice() subdomain = self._subdomain.GetValue() path = self._path.GetValue() required_credentials = self._required_credentials.GetValue() static_args = self._static_args.GetValue() temp_args = self._temp_args.GetValue() required_cookies_info = self._required_cookies_info.GetValue() content_parsers = self._content_parsers.GetData() if subdomain == '': subdomain = None login_step = ClientNetworkingLogin.LoginStep( name = name, scheme = scheme, method = method, subdomain = subdomain, path = path ) login_step.SetComplicatedVariables( required_credentials, static_args, temp_args, required_cookies_info, content_parsers ) return login_step