
    IiB              
       V   d Z ddlZddlZddlZddlmZ ddlmZ ddlmZm	Z	m
Z
mZmZ ddlZej                  j                  d e ee      j$                  j$                               ddlmZmZmZ deded	ed
efdZdeded
efdZdeded
ee
e   e
e   f   fdZdeded
efdZdeded
efdZdeded
efdZdededede d
ef
dZ!ded
efdZ"ded
ee   fd Z#de d
efd!Z$ddl%Z%d"d#l&m'Z' dd$l(m)Z)  G d% d&e%jT                        Z+ G d' d(e%jT                  e'jX                        Z-y))a  Config sharing dialog for importing and exporting server profiles.

Provides a single dialog that handles both import and export operations,
plus pure data helper functions for building export data, matching servers,
detecting account changes, and managing notes.
    N)datetime)Path)AnyDictListOptionalTuple)ExportedIdentitiesOptionsProfileServerserver_dictinclude_accountsinclude_optionsreturnc                     t        j                  |       }|si |d<   |st               j                         |d<   d|d<   d|d<   |S )zBuild an export-ready copy of a server dict.

    Deep-copies the server, clears accounts/options if not included,
    and always clears trusted_certificate and last_account_id.
    Server IDs and account IDs are kept.
    accountsoptions_profileNtrusted_certificatelast_account_id)copydeepcopyr   
model_dump)r   r   r   results       @C:\Users\dbart\PlayPalace11\clients\desktop\ui\config_sharing.pybuild_export_serverr      sT     ]];'Fz$2$4$?$?$A !$(F ! $FM    imported_serversexisting_serversc                    i }|j                         D ]-  \  }}|j                  dd      j                         }|s)|||<   / i }t        |       D ]9  \  }}|j                  dd      j                         }	|j                  |	      ||<   ; |S )a?  Map imported server index to existing server_id by matching host.

    Args:
        imported_servers: List of imported server dicts.
        existing_servers: Dict mapping server_id to server dict (from config manager).

    Returns:
        Dict mapping imported list index to existing server_id, or None if new.
    host )itemsgetlower	enumerate)
r   r   
host_to_id	server_idserver
host_lowerr   i
imp_serverimp_hosts
             r   match_serversr-   (   s     J-335	6ZZ+113
%.Jz" 6
 F"#34:>>&"-335NN8,q	 5 Mr   imported_accountsexisting_accountsc                    i }|j                         D ]/  \  }}|j                  dd      j                         }|s)||f||<   1 g }g }d}| j                         D ]  \  }	}
|
j                  dd      j                         }|j                  |      }||j                  |
       K|\  }}g }|D ]9  }|
j                  |d      |j                  |d      k7  s)|j                  |       ; |s|j                  |
|||d        ||fS )a  Find new and changed accounts by matching username.

    Notes are excluded from comparison. Returns changed field names.

    Args:
        imported_accounts: Dict mapping account_id to account dict (from import).
        existing_accounts: Dict mapping account_id to account dict (from config).

    Returns:
        Tuple of (new_accounts, changed_accounts) where:
        - new_accounts: list of imported account dicts with no username match
        - changed_accounts: list of dicts with keys: imported, existing, changed_fields
    usernamer!   )passwordemail)importedexistingexisting_idchanged_fields)r"   r#   r$   append)r.   r/   existing_by_usernameacct_idacctusername_lowernew_accountschanged_accountscompare_fieldsimp_idimp_acctimp_usernamematchr6   existing_acctr7   fields                    r   find_changed_accountsrF   @   s+   " *002*b17794;T? 0 3
 L*N-335||J399;$((6=)).&KN'<<r*m.?.?r.JJ"))%0 (  ''$,$1'2*8	 6* )))r   imported_serverexisting_serverc                     t        | |      ryt        |       ryt        | j                  di       |j                  di             \  }}|s|ryy)zCheck if an imported server has anything meaningful to import for an existing server.

    True if there are new/changed accounts, non-default options, or name/port differs.
    Tr   F)server_info_differshas_options_profile_datarF   r#   )rG   rH   	new_acctschanged_acctss       r   has_meaningful_changesrN   s   sX    
 ?O<04J+J+ I} Mr   r4   r5   c                     | j                  dd      |j                  dd      k7  ry| j                  dd      |j                  dd      k7  ryy)z@Compare name and port only between imported and existing server.namer!   Tport@  Fr#   )r4   r5   s     r   rJ   rJ      sG    ||FB8<<#;;||FD!X\\&$%??r   c                 (   g }| j                  dd      }|j                  dd      }||k7  r|j                  d| d|        | j                  dd      }|j                  dd      }||k7  r|j                  d| d|        dj                  |      S )	z<Build multiline comparison text for server info differences.rP   r!   zName: z -> rQ   rR   zPort: 
)r#   r8   join)r4   r5   linesimp_nameext_nameimp_portext_ports          r   build_server_info_displayr\      s    E||FB'H||FB'H8vhZtH:67||FD)H||FD)H8vhZtH:6799Ur   existing_notesimported_notesdescription	timestampc                     |s| S t        |      }d| d| d}g }| r|j                  |        |j                  | d|        dj                  |      S )zlAppend imported notes with a header.

    If imported_notes is empty, returns existing_notes unchanged.
    zImported Notes From Export (, z):rU   z

)format_export_timestampr8   rV   )r]   r^   r_   r`   date_strheaderpartss          r   append_imported_notesrg      sf     &y1H+K=8*BGFE^$	LLF82n-./;;ur   c                 `    t               j                         }| j                  d|      }||k7  S )z;True if the server's options_profile differs from defaults.r   )r   r   r#   )r   defaultscurrents      r   rK   rK      s/    **,Hoo/:Ghr   pathc                     	 t        | d      5 }t        j                  |      }ddd       t        j                         |S # 1 sw Y    xY w# t
        $ r Y yw xY w)zhLoad and validate an export JSON file.

    Returns:
        Parsed dict if valid, None if invalid.
    rN)openjsonloadr
   model_validate	Exception)rk   fdatas      r   try_load_export_fileru      sR    $_99Q<D ))$/ _  s'   A AA AA 	AAc                     	 t        j                  |       }|j                  d      S # t        t        t
        f$ r Y yw xY w)z8Format a unix timestamp as a human-readable date string.z%B %d, %Y at %I:%M %pzUnknown date)r   fromtimestampstrftimeOSError
ValueErrorOverflowError)r`   dts     r   rc   rc      s@    ##I.{{233Z/ s   %( ??   )audio_events)ConfigManagerc                   X     e Zd ZdZdZdZdZdZdedede	f fd	Z
d
efdZdefdZ xZS )AccountConflictDialogz7Prompt for resolving an account conflict during import.updateskip
update_allskip_allr1   server_namer7   c                 T    t            |dd        j                   _        t	        j
                         }t	        j                  t        j                        }dj                  |      }d| d| d| d}t	        j                  ||	      }	|	j                  d
       |j                  |	dt        j                  d       t	        j                  |d	      }
|
j                  t        j                   fd       |j                  |
dt        j                   t        j"                  z  t        j$                  z  d       t	        j                  |d	      }|j                  t        j                   fd       |j                  |dt        j                   t        j"                  z  t        j$                  z  t        j&                  z  d       t	        j                  |d| d	      }|j                  t        j                   fd       |j                  |dt        j                   t        j"                  z  t        j$                  z  t        j&                  z  d       t	        j                  |d| d	      }|j                  t        j                   fd       |j                  |dt        j                   t        j"                  z  t        j$                  z  t        j&                  z  d       |j)                  |        j+                          |
j-                          y )NzAccount Conflict)i     titlesizerb   zThe account 'z' on server 'z' has different values for: z.

What would you like to do?labelir  r   
   z&Updatec                 :    j                  j                        S N)_finishRESULT_UPDATEeselfs    r   <lambda>z0AccountConflictDialog.__init__.<locals>.<lambda>   s    d>P>P1Qr   z&Skipc                 :    j                  j                        S r   )r   RESULT_SKIPr   s    r   r   z0AccountConflictDialog.__init__.<locals>.<lambda>   s    t||D<L<L/Mr   zUpdate &all for server ""c                 :    j                  j                        S r   )r   RESULT_UPDATE_ALLr   s    r   r   z0AccountConflictDialog.__init__.<locals>.<lambda>   s    T\\$BXBX5Yr   zS&kip all for server "c                 :    j                  j                        S r   )r   RESULT_SKIP_ALLr   s    r   r   z0AccountConflictDialog.__init__.<locals>.<lambda>   s    4<<@T@T3Ur   )super__init__r   r   wxPanelBoxSizerVERTICALrV   
StaticTextWrapAddALLButtonBind
EVT_BUTTONEXPANDLEFTRIGHTTOPSetSizerCenterOnParentSetFocus)r   parentr1   r   r7   panelsizer
fields_strmsgr   
update_btnskip_btnupdate_all_btnskip_all_btn	__class__s   `             r   r   zAccountConflictDialog.__init__   s1   '9
K&&BKK(YY~.
H:];- @))3 5)* 	
 e3/

3		%BFFB'YYuI6
'QR		*aRWW!4rxx!?D99U'2bmm%MN		(Aryy2772RXX=FK52J;-WX0YZBMM+YZ		.!RYY%8288%Cbff%LbQyy0F{mST.UV"--)UV		,299rww#6#ABFF#JBOur   r   c                 P    || _         | j                  t        j                         y r   )r   EndModalr   ID_OK)r   r   s     r   r   zAccountConflictDialog._finish  s    bhhr   r   c                     | j                   S r   )r   )r   s    r   
get_resultz AccountConflictDialog.get_result  s    {{r   )__name__
__module____qualname____doc__r   r   r   r   strlistr   r   r   __classcell__r   s   @r   r   r      sO    AMK$ O# #3 #PT #J c  C r   r   c            
           e Zd ZdZdZdZdZdZdZ	 d3de	d	e
d
ee   f fdZd Zd Zd Zdee   fdZd Zd ZdefdZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z defdZ!d Z"d  Z#de$fd!Z%de$fd"Z&de$fd#Z'd$e
d%ed&eddfd'Z(d(e)ddfd)Z*d&eddfd*Z+d+ed,ed$e
d%ed&ef
d-Z,d.ed,ed$e
d%ed&ef
d/Z-d0e
d1ed$e
d%efd2Z. xZ/S )4ConfigSharingDialogz2Dialog for importing or exporting server profiles.exportimportuser_accountsoption_profilesserver_info_updatesNconfig_managermodeimported_datac                 f   || j                   k(  rdnd}t        | 	  ||d       || _        || _        || _        d| _        d| _        g | _        i | _	        | j                          | j                          | j                          | j                  t        j                  | j                          y )NzExport Server ProfileszImport Server Profiles)i  i  r   F)MODE_EXPORTr   r   r   r   r   _user_interacted_no_data_server_data_per_server_state_build_server_data
_create_uir   r   r   EVT_CHAR_HOOK_on_key)r   r   r   r   r   r   r   s         r   r   zConfigSharingDialog.__init__  s     -1D4D4D,D(Jbu:>,	* % !#!		"""DLL1r   c                 "   | j                   j                         }| j                  | j                  k(  rr|j	                         D ]]  \  }}|j                  di       }| j                  j                  |||j                  dd      t        |      t        |      dd|d       _ n| j                  j                  dg       }t        ||      }t        |      D ]  \  }}|j                  |      }	|	du }
|j                  di       }d}t        |      }|
sT||	   }t        ||      sNt        ||      }t        ||j                  di             \  }}t        |      t        |      z   }| j                  j                  |||j                  dd      |t        |      |
||	d        | j                  sd	| _        t#        t        | j                              D ]4  }ddd
}| j                  | j$                  k(  rd|d<   || j&                  |<   6 y)z<Build the list of servers and their metadata for the dialog.r   rP   UnknownF)r'   r   rP   account_counthas_optionsis_newinfo_differsr6   serversN)indexr   rP   r   r   r   r   r6   T)r   optionsupdate_info)r   get_all_serversr   r   r"   r#   r   r8   lenrK   r   r-   r%   rN   rJ   rF   r   rangeMODE_IMPORTr   )r   r   r'   r(   r   r   matchesr*   r+   r6   r   r   r   rH   rL   rM   states                    r   r   z&ConfigSharingDialog._build_server_data.  s   ..>>@99(((%5%;%;%=!	6!::j"5!!((%.'- &

69 =),X'?'G"'(-'0	 &>   $1155iD#$46FGG!*+;!<:%kk!n$,%>>*b9$ #H&6{&CO1*oN #6z?#SL/D '++J;0,I} %(	NS5G$GM!!((!"'1 *vy A)6'?
'K"((4'2	' "=@ $$ $ s4,,-.A!&59EyyD,,,',m$(-D""1%	 /r   c                    t        j                  |       }t        j                  t         j                        }| j                  | j
                  k(  rt        j                  |d      }t        j                  |t         j                        }t        j                  |dg ddt         j                        | _
        | j                  j                  t         j                  | j                         |j                  | j                  dt         j                  t         j                   z  d       n;t        j                  |d      }t        j                  |t         j                        }| j                  | j"                  k(  rd	nd
}g | _        g | _        t)        d | j*                  D              }t)        d | j*                  D              }t)        d | j*                  D              }|r@| j$                  j-                  d       | j&                  j-                  | j.                         |r@| j$                  j-                  d       | j&                  j-                  | j0                         | j                  | j
                  k(  rB|r@| j$                  j-                  d       | j&                  j-                  | j2                         t        j4                  ||      }	|j                  |	dt         j6                  t         j8                  z  d       t        j:                  || j$                        | _        t?        tA        | j$                              D ]  }
| j<                  jC                  |
d         | j<                  j                  t         jD                  | jF                         | j<                  jI                         dkD  r| j<                  jK                  d       |j                  | j<                  dt         j                  t         j                   z  d       |j                  |dt         j                  t         j                   z  d       t        j                  |d      }t        j                  |t         j                        }t        j4                  |d      }|j                  |dt         j6                  t         j8                  z  d       t        j:                  |g d      | _&        | jL                  j                  t         jD                  | jN                         | jL                  j                  t         jP                  | jR                         |j                  | jL                  dt         j                  t         j                   z  d       t        jT                  |dt         jV                  t         jX                  z  d      | _-        | jZ                  j]                          |j                  | jZ                  dt         j                  t         j6                  z  t         j^                  z  d       t        j                  |      | _0        t        j                  t         j                        | _1        t        jT                  | j`                  dt         jV                  t         jX                  z  d      | _2        | jd                  jg                  d       t        jh                  | j`                  d      | _5        | jj                  j                  t         jl                  | jn                         t        jh                  | j`                  d      | _8        | jp                  j                  t         jl                  | jr                         | j                  | j
                  k(  rt        jT                  | j`                  t         jV                  t         jX                  z  d      | _:        | jt                  jg                  d       t        jh                  | j`                  d       | _;        | jv                  j                  t         jl                  | jx                         | jb                  j                  | jd                  dt         j                   d       | jb                  j                  | jj                  dt         j                   d       | jb                  j                  | jp                  dt         j                   d       | j                  | j
                  k(  r}| jb                  j                  | jt                  dt         j                  t         j                   z  d       | jb                  j                  | jv                  dt         j                   d       | j`                  j{                  | jb                         |j                  | j`                  dt         j                  t         j                   z  d       |j                  |dt         j                  t         j                   z  d       t        j                  |d!      }t        j                  |t         j|                        }| j                  | j"                  k(  rd"nd#}t        j~                  ||      | _@        | j                  j                  t         j                  | j                         |j                  | j                  dt         j                   d       t        j~                  |t         j                  d$      | _D        | j                  j                  t         j                  | j                         |j                  | j                  dt         j                   d       |j                  |dt         j                  t         j                   z  d       |j{                  |       | j                          | j                          | j                  d%&       | j                  | j<                  d       | j                  | jL                  d       | j                  | j
                  k(  r't        | d'      r| j                  j                          y(| j$                  r| j<                  j                          y(| jL                  j                          y())zCreate all UI components.Filtersr   z&Server filter)AllzExisting onlyzNew onlyr}   )r   choicesmajorDimensionstyler      zE&xport typeszI&mport typesc              3   ,   K   | ]  }|d    dkD    yw)r   r   N .0ss     r   	<genexpr>z1ConfigSharingDialog._create_ui.<locals>.<genexpr>  s     M;La1_-1;Ls   c              3   &   K   | ]	  }|d      yw)r   Nr   r   s     r   r   z1ConfigSharingDialog._create_ui.<locals>.<genexpr>  s     F4Eq!M*4Es   c              3   @   K   | ]  }|j                  d d        yw)r   FNrS   r   s     r   r   z1ConfigSharingDialog._create_ui.<locals>.<genexpr>  s     WEVquu^U;EVs   zUser accountszOption profileszServer info updates)r   TDetailsz&Available servers)x   )r   r   r!   )r      )valuer   r   Server not includedzAdd &user accountsAdd options &profile)r   2   )r   r   zServer info changeszUpdate server &info	OperationzStart &exportzStart &importz&Cancelr   )	recursion_server_filterN)Lr   r   r   r   r   r   	StaticBoxStaticBoxSizerRadioBoxRA_SPECIFY_ROWSr  r   EVT_RADIOBOX_on_server_filter_changedr   r   r   r   _type_items
_type_keysanyr   r8   TYPE_ACCOUNTSTYPE_OPTIONSTYPE_SERVER_INFOr   r   r   CheckListBox_types_listr   r   CheckEVT_CHECKLISTBOX_on_type_toggledGetCountSetSelection_servers_list_on_server_checkedEVT_LISTBOX_on_server_selection_changedTextCtrlTE_MULTILINETE_READONLY_empty_list_msgHider   _server_panel_panel_sizer_not_included_labelSetNameCheckBox_accounts_cbEVT_CHECKBOX_on_account_cb_changed_options_cb_on_options_cb_changed
_info_text_update_info_cb_on_update_info_cb_changedr   
HORIZONTALr   
_start_btnr   	_on_start	ID_CANCEL_cancel_btn
_on_cancel_populate_servers_list_refresh_server_panelbind_soundsbind_sfx_to_controlhasattrr   )r   r   
main_sizer
filter_boxfilter_sizer
type_labelany_accountsany_optionsany_info_differstypes_labelr*   details_boxdetails_sizerservers_labelop_boxop_sizerstart_labels                    r   r   zConfigSharingDialog._create_uip  s   [[-
 99(((e9=J,,ZEL"$++&< ((#D $$R__d6T6TUT00!RYY5GKe9=J,,ZEL )-		T5E5E(E_?
M4;L;LMMFD4E4EFFWTEVEVWW##O4OO""4#5#56##$56OO""4#4#4599(((-=##$9:OO""4#8#89mmE<a266)91=??5$:J:JKs4++,-A""1d+ .b1143H3HI$$&*))!,))1bii"&&.@!D|Q		BFF(:A> ll5	:))+r{{C e3GH-BGGbff,<a@__UBYO 3 3T5L5LM0Q0QR$,,aRVV1CQG  "{{//BNN2	 
 	!!#$..299rww3F3QSTU  XXe_KK4 $&;;'//BNN2	$
  	  (()>? KK(:(:BVWr0K0KL ;;t'9'9AWXboot/J/JK 99((( kk""oo6DO
 OO##$9:#%;;t/A/AI^#_D   %%boot7V7VWd662661Ed//BFFA>d..2661=99(((!!$//1bii"&&6H!L!!$"6"62661E##D$5$56$,,aRVV1CQG}aRVV);Q? e;7$$VR]];)-d6F6F)FoO))E=R]]DNN;T__a399UBLL)DbmmT__=T%%q"&&!4xBII$6:z" 	##%""$ 	2&  !1!148  !3!3T: 99(((WT;K-L((*%%''')r   c                    | j                   j                          g | _        d}| j                  | j                  k(  r&t        | d      r| j                  j                         }t        | j                        D ]  \  }}| j                  | j                  k(  r|dk(  r|d   r*|dk(  r|d   s5|d   }| j                  | j                  k(  r|dk(  r|d   rdnd}| d	| d
}| j                   j                  |       | j                  j                  |        | j                   j                         dk(  r| j                  | j                  k(  rc|dk(  rd}n
|dk(  rd}nd}| j                  j                  |       | j                  j                  |       | j                  j!                  d       | j                   j#                          | j                   j%                         j'                          y| j                   j!                  d       | j                  j#                          | j                   j)                  d       t        | j                        D ]@  \  }}| j*                  |   j-                  dd      }	| j                   j/                  ||	       B | j                   j                         dkD  r| j                   j1                  d       yy)zDPopulate the available servers checklistbox based on current filter.r   r  r}   r      rP   newr5   z ()z No existing servers with changeszNo new servers foundzNo servers availableTNserver_checkedF)r  Clear_visible_indicesr   r   r:  r  GetSelectionr%   r   Appendr8   r  r!  SetValuer&  Showr"  	GetParentLayoutEnabler   r#   r  r  )
r   
filter_valr*   sdatar   tagr   list_posdata_idxcheckeds
             r   r6  z*ConfigSharingDialog._populate_servers_list  sw     " "
99(((WT;K-L,,99;J!$"3"34HAuyyD,,,?uX?5?&MEyyD,,,q$XeJ 'C5*%%e,!!((+ 5  &&(A-yyD,,,?<C1_0C0C$$--c2$$,,S1$$))$/##%((*113%!!#!!$' #,D,A,A"BHh ,,X6::;KUSG$$Xw7	 #C &&(1,++A. -r   r   c                     | j                   j                         }|t        j                  k(  s|t	        | j
                        k\  ry| j
                  |   S )z;Get the server_data index for the currently focused server.N)r  rP  r   	NOT_FOUNDr   rO  )r   sels     r   _get_focused_data_indexz+ConfigSharingDialog._get_focused_data_indexC  sH      --/",,#T-B-B)C"C$$S))r   c                    | j                   j                  |       | j                   j                  |       | j                   j                  d       | j                  j                  d       | j
                  j                  d       | j                  | j                  k(  r6| j                  j                  d       | j                  j                  d       | j                  j                          y)z>Show a message in the server panel, hiding all other controls.TFN)r%  rR  r&  rS  r(  r+  r   r   r-  r.  r#  rU  )r   texts     r   _show_panel_messagez'ConfigSharingDialog._show_panel_messageJ  s      ))$/  ((.  %%d+u%e$99(((OO  '  %%e,!!#r   c                 :   | j                   sD| j                  j                  d       | j                  j                         j	                          y| j                  j                  d       | j                         }|| j                  d       y| j                  |   }| j                  |   }|j                  dd      }|s| j                  d       y| j                         }| j                  |v }| j                  |v }| j                  |v }|xs5 |xs1 | j                  | j                  k(  xr |xr |j                  dd      }	|	s| j                  d       y| j                   j                  d       |r|d   }
d	|
 d
|
dk7  rdnd }| j"                  j%                  |       | j"                  j'                  |d          | j"                  j)                  |
dkD         | j"                  j                  d       n| j"                  j                  d       |r|d   r7| j*                  j%                  d       | j*                  j)                  d       n6| j*                  j%                  d       | j*                  j)                  d       | j*                  j'                  |d          | j*                  j                  d       n| j*                  j                  d       | j                  | j                  k(  r|r|j                  dd      r| j,                  j/                         }|j                  |d   i       }t1        |d   |      }| j2                  j'                  |       | j2                  j                  d       | j4                  j'                  |j                  dd             | j4                  j                  d       n6| j2                  j                  d       | j4                  j                  d       | j                  j	                          y)z:Refresh the server panel for the currently focused server.FNTr  rM  r   z!No included types for this serverr   zAdd &user accounts, z accountr}   r   r!   r   r   r   r  z(Add options &profile (will use defaults)r   r6   r   r   )rO  r#  rS  rT  rU  r`  rc  r   r   r#   _get_visible_typesr  r  r  r   r   r%  r(  SetLabelrR  rV  r+  r   r   r\   r-  r.  )r   idxrX  r   
is_checkedvisible_typesshow_accountsshow_options	show_infoany_visiblecount
acct_labelr   rH   display_texts                  r   r7  z)ConfigSharingDialog._refresh_server_panelV  s    $$##E*((*113%**,;$$%:;!!#&&&s+YY/7
$$%:; //1**m;((M9))]:	  bb		T---`)`		.Z_@` 	
 $$%HI  %%e, /*E/wheqjsVX>YZJ&&z2&&uZ'89$$UQY/""4(""5) ]#  ))*@A  ''-  ))*TU  ''.%%eI&67!!$'!!%( 99(((UYY~u=#'#6#6#F#F#H "2"6"6u]7KR"P8}9M_((6$$T*$$--eiiu.MN$$))$/$$U+$$))%0!!#r   c                     g }t        t        | j                              D ]<  }| j                  j	                  |      s|j                  | j                  |          > |S )z,Get the list of currently visible type keys.)r   r   r  r  	IsCheckedr8   )r   r   r*   s      r   re  z&ConfigSharingDialog._get_visible_types  sO    s4??+,A))!,dooa01 - r   c                     |j                         t        j                  k(  r| j                  |       y |j	                          y r   )
GetKeyCoder   
WXK_ESCAPEr5  Skipr   events     r   r   zConfigSharingDialog._on_key  s,    .OOE"JJLr   c                 2    d| _         | j                          y )NT)r   r7  rw  s     r   r  z$ConfigSharingDialog._on_type_toggled  s     $""$r   c                 D    | j                          | j                          y r   )r6  r7  rw  s     r   r  z-ConfigSharingDialog._on_server_filter_changed  s    ##%""$r   c                     d| _         |j                         }|t        | j                        k  r:| j                  |   }| j                  j                  |      | j                  |   d<   | j                          y )NTrM  )r   GetIntr   rO  r  rr  r   r7  )r   rx  rZ  r[  s       r   r  z&ConfigSharingDialog._on_server_checked  sq     $<<>c$//00,,X6HAEASASA]A]BD""8,-=> 	""$r   c                 $    | j                          y r   )r7  rw  s     r   r  z0ConfigSharingDialog._on_server_selection_changed  s    ""$r   c                     d| _         | j                         }|+| j                  j                         | j                  |   d<   y y )NTr   )r   r`  r(  GetValuer   r   rx  rg  s      r   r*  z*ConfigSharingDialog._on_account_cb_changed  sF     $**,?6:6G6G6P6P6RD""3'
3 r   c                     d| _         | j                         }|+| j                  j                         | j                  |   d<   y y )NTr   )r   r`  r+  r  r   r  s      r   r,  z*ConfigSharingDialog._on_options_cb_changed  sF     $**,?595E5E5N5N5PD""3'	2 r   c                     d| _         | j                         }|+| j                  j                         | j                  |   d<   y y )NTr   )r   r`  r.  r  r   r  s      r   r/  z.ConfigSharingDialog._on_update_info_cb_changed  sF     $**,?9=9M9M9V9V9XD""3'6 r   c                    | j                   r\t        j                  ddt        j                  t        j                  z  t        j
                  z  |       }|t        j                  k7  ry | j                  t        j                         y )Nz>Are you sure you want to cancel? Your selections will be lost.zConfirm Cancel)	r   r   
MessageBoxYES_NO
NO_DEFAULTICON_WARNINGYESr   r3  )r   rx  r   s      r   r5  zConfigSharingDialog._on_cancel  s\      ]]P 		BMM)BOO;	F bll#r   c                 x    | j                   | j                  k(  r| j                          y | j                          y r   )r   r   _execute_export_execute_importrw  s     r   r2  zConfigSharingDialog._on_start  s,    99(((  "  "r   c                     g }t        | j                        D ]E  \  }}| j                  |   j                  dd      s&|j	                  || j
                  |   f       G |S )z>Get list of (data_index, server_data) for all checked servers.rM  F)r%   rO  r   r#   r8   r   )r   r   rZ  r[  s       r   _get_selected_serversz)ConfigSharingDialog._get_selected_servers  sa    "+D,A,A"BHh%%h/334DeLx):):8)DEF #C r   c           	           j                         }|s8t        j                  ddt        j                  t        j                  z          y t         fd|D              }|r\t        j                  ddt        j                  t        j                  z  t        j                  z         }|t        j                  k7  ry t        j                   dd      }	 |j                         t        j                  k7  r|j                          y |j                         j                         }|rn8t        j                  ddt        j                  t        j                  z          |j                          t!        t#        j"                               }g }|D ]<  \  }}	 j$                  |   }
t'        |	d	   |
d
   |
d         }|j)                  |       > |||d}	 t+        j,                  |       t        j2                   dt5        t7        j8                               ddt        j:                  t        j<                  z        }|j                         t        j                  k7  r|j                          y |j?                         }|j                          	 tA        |d      5 }tC        jD                  ||d       d d d        tG        |      }t        j                  d| d|dk7  rdnd ddt        j                  t        j                  z           jI                  t        j                         y # t.        $ rD}t        j                  d| dt        j                  t        j0                  z          Y d }~y d }~ww xY w# 1 sw Y   xY w# t.        $ rD}t        j                  d| dt        j                  t        j0                  z          Y d }~y d }~ww xY w)NNo servers selected.Exportc              3   H   K   | ]  \  }}j                   |   d      ywr   Nr   r   rg  _r   s      r   r   z6ConfigSharingDialog._execute_export.<locals>.<genexpr>  s(     ZQYvsA411#6zBQY   "zUser accounts are included in this export. Are you sure you want to proceed?

Some servers will ban the account owner and anyone else who attempts to access the same account.zExport Warningz$Enter a description for this export:zExport DescriptionzDescription cannot be empty.r   r   r   )r   r   )r_   r`   r   zExport data validation failed: zExport ErrorzSave Export Filezidentities-export.jsonzJSON files (*.json)|*.json)
defaultDirdefaultFilewildcardr   wrJ  )indentzFailed to save export file: zSuccessfully exported z serverr}   r   r!   .zExport Complete)%r  r   r  OKICON_INFORMATIONr  r  r  r  r  TextEntryDialog	ShowModalr   Destroyr  stripinttimer   r   r8   r
   rq   rr   
ICON_ERROR
FileDialogr   r   cwdFD_SAVEFD_OVERWRITE_PROMPTGetPathrn   ro   dumpr   r   )r   selectedr?  r   desc_dlgr_   r`   export_serversrg  rX  r   server_exportexport_datar   file_dlg	save_pathrs   server_counts   `                 r   r  z#ConfigSharingDialog._execute_export  sD   --/MM0(BEEBDWDW<WY]^ ZQYZZ]]s 		BMM)BOO;F  %%8:N
 !!#rxx/  ""++-335KMM8(BEEBOOD[]ab  	 		$	"JC**3/E/m$!&z!2 %i 0M
 !!-0 # '"%
		--k: ==488:01**r555
 288+$$&	
	i%		+q3 & >*
$\N'QRAR#XZ9[[\]EEB'''		
 	bhhY  	MM1!5%	 	4 &% 	MM.qc2%	 	sH   L2 N !N:N 2	M?;:M::M?NN 	O:OOc                 (   | j                         }| j                  |      sy t        j                  | j                  j
                        }| j                  j                  dd      }| j                  j                  dd      }dddddd}	 | j                  ||||       | j                  j                          | j                  |       | j                  t        j                         y # t        $ r}| j                  ||       Y d }~y d }~ww xY w)Nr_   r!   r`   r   )new_serversupdated_serversr=   updated_accountsskipped_accounts)r  _validate_import_selectionr   r   r   
identitiesr   r#   _run_importsave_identitiesrr   _rollback_import_show_import_summaryr   r   r   )r   r  snapshotr_   r`   statsr   s          r   r  z#ConfigSharingDialog._execute_import`  s    --/..x8==!4!4!?!?@((,,]B?&&**;:	  ! !
	X{IuE//1
 	!!%(bhh  	!!(A.	s   .C, ,	D5DDc                 ,   |s8t        j                  ddt         j                  t         j                  z  |        y| j	                  |      r\t        j                  ddt         j
                  t         j                  z  t         j                  z  |       }|t         j                  k7  ry| j                  |      r\t        j                  ddt         j
                  t         j                  z  t         j                  z  |       }|t         j                  k7  ryy)Nr  ImportFzUser accounts are included in this import. Are you sure you want to proceed?

Some servers will ban the account owner and anyone else who attempts to access the same account.zImport WarningzNOption profiles will overwrite your existing settings. Do you want to proceed?T)
r   r  r  r  _has_selected_accountsr  r  r  r  _has_selected_options)r   r  r   s      r   r  z.ConfigSharingDialog._validate_import_selectionz  s    MM0(BEEBDWDW<WY]^&&x0]]s 		BMM)BOO;F %%h/]]` 		BMM)BOO;	F r   c                 ,     t         fd|D              S )Nc              3   H   K   | ]  \  }}j                   |   d      ywr  r  r  s      r   r   z=ConfigSharingDialog._has_selected_accounts.<locals>.<genexpr>  s&     RvsA4))#.z:r  r  r   r  s   ` r   r  z*ConfigSharingDialog._has_selected_accounts  s    RRRRr   c                 ,     t         fd|D              S )Nc              3   H   K   | ]  \  }}j                   |   d      yw)r   Nr  r  s      r   r   z<ConfigSharingDialog._has_selected_options.<locals>.<genexpr>  s&     Qfc14))#.y9r  r  r  s   ` r   r  z)ConfigSharingDialog._has_selected_options  s    QQQQr   r_   r`   r  c                     |D ]K  \  }}| j                   |   }|d   }|d   }	|	r| j                  |||||       7| j                  |||||       M y )Nr   r   )r   _import_new_server_import_existing_server)
r   r  r_   r`   r  rg  rX  r   r+   r   s
             r   r  zConfigSharingDialog._run_import  sd    "JC**3/E}-J8_F''
E;	SXY,,UE;	SXY #r   errorc                     || j                   _        | j                   j                          t        j                  d| dt        j
                  t        j                  z  |        y )Nz,Import failed and changes were rolled back: zImport Error)r   r  r  r   r  r  r  )r   r  r  s      r   r  z$ConfigSharingDialog._rollback_import  sN    )1&++-
:5'BEEBMM!		
r   c                 <   g }|d   r#|j                  |d    d|d   dk7  rdnd        |d   r#|j                  |d    d|d   dk7  rdnd        |d   r#|j                  |d    d	|d   dk7  rdnd        |d
   r#|j                  |d
    d|d
   dk7  rdnd        |d   r#|j                  |d    d|d   dk7  rdnd        |rddj                  |      z   dz   nd}t        j                  |dt        j                  t        j
                  z  |        y )Nr  z new serverr}   r   r!   r  z updated serverr=   z new accountr  z updated accountr  z skipped accountz	Imported rb   r  zNo changes were made.zImport Complete)r8   rV   r   r  r  r  )r   r  rf   summarys       r   r  z(ConfigSharingDialog._show_import_summary  sy   LL'(5;OST;TCZ\3]^ "#LL*+,O5IZC[_`C`Cfh;ij  LL()U>=RVW=Wc]_5`a #$LL+,--=UK]E^bcEccik=lm #$LL+,--=UK]E^bcEccik=lm ;@+		% 0036E\
g0"%%":M:M2MtTr   r+   r   c                    |j                  dd      }| j                  j                  |j                  dd      |j                  dd      |j                  dd      |      }|dxx   d	z  cc<   |d
   r|j                  d
i       j                         D ]r  \  }}	| j                  j	                  ||	j                  dd      |	j                  dd      |	j                  dd      |	j                  dd             |dxx   d	z  cc<   t |d   rSt        |      rG| j                  j                  |      }
|
r)t        j                  |j                  di             |
d<   yyyy)zImport a completely new server.notesr!   rP   r    rQ   rR   )rP   r    rQ   r  r  r}   r   r1   r2   r3   r1   r2   r3   r  r=   r   r   N)	r#   r   
add_serverr"   add_accountrK   get_server_by_idr   r   )r   r+   r   r_   r`   r  r  r'   r:   r;   r(   s              r   r  z&ConfigSharingDialog._import_new_server  s[    w+''22++-	 3 
	 	m! !+
B!?!E!E!G##//!XXj"5!XXj"5((7B/((7B/ 0  n%*% "H  8 D((99)DF,0MM*..IZ\^:_,`()  !Er   rX  c                 <   |d   }|d   }| j                   j                  |      }|syd}	|j                  dd      r|j                  dd      rq|j                  d      }
|j                  d      }t        |j                  d	d
      |j                  d	d
      ||      }| j                   j	                  ||
||       d}	|d   r| j                   j                  |      }t        |j                  di       |      \  }}|D ]o  }| j                   j                  ||j                  dd
      |j                  dd
      |j                  dd
      |j                  d	d
             |dxx   dz  cc<   q |j                  dd      }d}d}|D ]=  }|r|dxx   dz  cc<   |r"| j                  ||||       |dxx   dz  cc<   8t        | |d   j                  dd
      ||d         }|j                          |j                         }|j                          |t        j                  k(  r"| j                  ||||       |dxx   dz  cc<   |t        j                  k(  r|dxx   dz  cc<   |t        j                  k(  r%d}| j                  ||||       |dxx   dz  cc<   |t        j                   k(  s/d}|dxx   dz  cc<   @ |s|rd}	|d   r5t#        |      r*t%        j&                  |j                  di             |d<   d}	|	r|dxx   dz  cc<   yy)z$Import data into an existing server.r   r6   NFr   r   rP   rQ   r  r!   )rP   rQ   r  Tr   r1   r2   r3   r  r=   r}   r   r  r  r4   r7   r   r   r  )r   r  r#   rg   update_serverget_server_accountsrF   r  _apply_account_updater   r  r   r  r   r   r   r   rK   r   r   )r   rX  r   r_   r`   r  r+   r6   rH   updatednew_namenew_port	new_notesr/   rL   rM   r;   r   r   r   changedlgr   s                          r   r  z+ConfigSharingDialog._import_existing_server  sR    =)
M*-->>{K 99]E*uyy/O!~~f-H!~~f-H-##GR0w+	I --	 .  G  $ 3 3 G G T'<z2.!($I} "##//!XXj"5!XXj"5((7B/((7B/ 0  n%*% " *--fi@KJH',-2-..{FKQZ[,-2- ,:&**:r:+,	 )2@@@..{FKQZ[,-2-4@@@,-2-4FFF!%J..{FKQZ[,-2-4DDD#H,-2-? (B M  8 D150"52O-. G#$)$ r   r'   r  c                    |d   }|d   }|d   }i }|d   D ]  }	|j                  |	d      ||	<    t        |j                  dd      |j                  dd      ||      }
|
|d<    | j                  j                  ||fi | y)z)Apply an account update from import data.r6   r4   r5   r7   r!   r  N)r#   rg   r   update_account)r   r'   r  r_   r`   r6   rA   rD   kwargsrE   r  s              r   r  z)ConfigSharingDialog._apply_account_updateK  s    ]+*%z* ,-E$LL3F5M . *gr*LL"%	
	 $w***9kLVLr   r   )0r   r   r   r   r   r   r  r  r  r   r   r   dictr   r   r   r6  r  r`  rc  r7  r   re  r   r  r  r  r  r*  r,  r/  r5  r2  r  r  r  boolr  r  r  r  rr   r  r  r  r  r  r   r   s   @r   r   r   
  s   <KK $M$L, )-2 &2 	2
  ~22@.D[*z4/l*# *
$O$bD %%%%SQY
$#t b L 4d 2S$ SR R	Z 	Z 	ZT 	ZVZ 	Z
	 
d 
U$ U4 U4aa'+a:=aJMaVZa>b*b*"&b*58b*EHb*QUb*HMs MD Ms M_b Mr   r   ).r   r   ro   r  r   pathlibr   typingr   r   r   r   r	   sysrk   insertr   __file__r   config_schemasr
   r   r   r  r  r   r   r-   rF   rN   rJ   r\   r  rg   rK   ru   rc   r   
enhance_wxr~   r   r   Dialogr   SoundBindingsMixinr   r   r   r   <module>r     s        3 3 
 3tH~,,334 5 E E
T T TX ]a "D D T 00*0*040*
4:tDz!"0*fD 4 D &$ $ 4    ),;>KN$$ 4 s x~ s s  
 $ (2BII 2jUM"))\%D%D UMr   