@ -3,6 +3,7 @@
A mobile first interface for the standard unix password manager written in python
"""
import os
from typing import Union
import wx
import wx . lib . scrolledpanel as scrolled
@ -28,6 +29,7 @@ class PassUi(wx.Frame):
"""
self . sizer . Clear ( delete_windows = True )
func ( self , * wrapper_args )
self . pnl . SetupScrolling ( )
self . sizer . Layout ( )
return wrapper
@ -39,12 +41,12 @@ class PassUi(wx.Frame):
: param kw :
"""
super ( ) . __init__ ( * args , * * kw )
self . pass_handler = Pass ( )
self . pass_handler : Pass = Pass ( )
# create a panel in the frame
self . pnl = scrolled . ScrolledPanel ( self , - 1 , style = wx . VSCROLL )
self . pnl : wx . lib . scrolledpanel . ScrolledPanel = scrolled . ScrolledPanel ( self , - 1 , style = wx . VSCROLL )
self . pnl . SetupScrolling ( )
# and create a sizer to manage the layout of child widgets
self . sizer = wx . BoxSizer ( wx . VERTICAL )
self . sizer : wx . BoxSizer = wx . BoxSizer ( wx . VERTICAL )
self . pnl . SetSizer ( self . sizer )
self . add_buttons ( )
@ -53,57 +55,56 @@ class PassUi(wx.Frame):
""" add_buttons. """
self . add_tools ( )
if self . pass_handler . cur_dir != self . pass_handler . top_dir :
btn = self . make_back_button ( )
btn : wx . Button = self . make_back_button ( )
self . sizer . Add ( btn , 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON ,
lambda event : self . path_button_clicked ( ) , btn )
index = 0
for c path in self . pass_handler . cur_paths :
if c path != self . pass_handler . cur_dir :
label = ' 🗀 ' + os . path . basename ( os . path . normpath ( c path) )
btn = wx . Button ( self . pnl , label = label )
index : int = 0
for c _ path in self . pass_handler . cur_paths :
if c _ path != self . pass_handler . cur_dir :
label : str = ' 🗀 ' + os . path . basename ( os . path . normpath ( c _ path) )
btn : wx . Button = wx . Button ( self . pnl , label = label )
self . sizer . Add ( btn , 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON ,
lambda event , path = c path: self . path_button_clicked (
lambda event , path = c _ path: self . path_button_clicked (
path ) ,
btn )
index = index + 1
index = 0
for password in self . pass_handler . cur_passwords :
label = ' 🗝 ' + os . path . splitext (
label : str = ' 🗝 ' + os . path . splitext (
os . path . basename ( os . path . normpath ( password ) ) ) [ 0 ]
btn = wx . Button ( self . pnl , label = label )
btn : wx . Button = wx . Button ( self . pnl , label = label )
self . sizer . Add ( btn , 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON ,
lambda event , m index= index : self . password_button_clicked (
m index) ,
lambda event , m _ index= index : self . password_button_clicked (
m _ index) ,
btn )
index = index + 1
self . pnl . SetupScrolling ( )
def add_push_pull ( self ) :
""" add_push_pull. """
push btn = wx . Button ( self . pnl , label = " Push to remote " )
self . sizer . Add ( push btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON , lambda event : pass_push ( ) , push btn)
pull btn = wx . Button ( self . pnl , label = " Pull from remote " )
self . sizer . Add ( pull btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON , lambda event : pass_pull ( ) , pull btn)
def add_tools ( self , index = None ) :
push _ btn: wx . Butto n = wx . Button ( self . pnl , label = " Push to remote " )
self . sizer . Add ( push _ btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON , lambda event : pass_push ( ) , push _ btn)
pull _ btn: wx . Butto n = wx . Button ( self . pnl , label = " Pull from remote " )
self . sizer . Add ( pull _ btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON , lambda event : pass_pull ( ) , pull _ btn)
def add_tools ( self , index : Union [ None , int ] = None ) :
""" add_tools.
: param index :
"""
btn = wx . Button ( self . pnl , label = " Show tools " )
font = btn . GetFont ( ) . MakeBold ( )
btn : wx . Button = wx . Button ( self . pnl , label = " Show tools " )
font : wx . Font = btn . GetFont ( ) . MakeBold ( )
btn . SetFont ( font )
self . sizer . Add ( btn , 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON ,
lambda event , m index= index : self . show_tools ( m index) ,
lambda event , m _ index= index : self . show_tools ( m _ index) ,
btn )
def back_button_clicked ( self , index = None ) :
def back_button_clicked ( self , index : Union [ None , int ] = None ) :
""" back_button_clicked.
: param index :
@ -113,45 +114,45 @@ class PassUi(wx.Frame):
else :
self . add_buttons ( )
def delete_password ( self , index ):
def delete_password ( self , index : int ):
""" delete_password.
: param index :
"""
path = self . pass_handler . get_pass_path_from_index ( index , " password " )
dlg = wx . MessageDialog ( self . pnl ,
" Delete " + path + " ? " ,
" Are you sure? " ,
style = wx . CANCEL | wx . CANCEL_DEFAULT | wx . OK )
path : str = self . pass_handler . get_pass_path_from_index ( index , " password " )
dlg : wx . MessageDialog = wx . MessageDialog ( self . pnl ,
" Delete " + path + " ? " ,
" Are you sure? " ,
style = wx . CANCEL | wx . CANCEL_DEFAULT | wx . OK )
dlg . SetOKCancelLabels ( " &Yes " , " &Don ' t delete " )
reply = dlg . ShowModal ( )
reply : int = dlg . ShowModal ( )
if reply == wx . ID_CANCEL :
return
self . pass_handler . delete_password ( path )
self . back_button_clicked ( )
def make_back_button ( self , index = None ) :
def make_back_button ( self , index : Union [ None , int ] = None ) - > wx . Button :
""" make_back_button.
: param index :
"""
if index is not None :
label = self . pass_handler . get_pass_path_from_index ( index , " password " )
label : str = self . pass_handler . get_pass_path_from_index ( index , " password " )
else :
label = self . pass_handler . cur_dir . replace ( self . pass_handler . top_dir , ' ' )
btn = wx . Button ( self . pnl , label = label + ' ⤴ ' )
font = btn . GetFont ( ) . MakeItalic ( ) . MakeBold ( )
label : str = self . pass_handler . cur_dir . replace ( self . pass_handler . top_dir , ' ' )
btn : wx . Button = wx . Button ( self . pnl , label = label + ' ⤴ ' )
font : wx . Font = btn . GetFont ( ) . MakeItalic ( ) . MakeBold ( )
btn . SetFont ( font )
return btn
def password_button_clicked ( self , index ):
def password_button_clicked ( self , index : int ):
""" password_button_clicked.
: param index :
"""
self . show_password_dialog ( index )
def path_button_clicked ( self , path = None ) :
def path_button_clicked ( self , path : Union [ None , str ] = None ) :
""" path_button_clicked.
: param path :
@ -163,42 +164,42 @@ class PassUi(wx.Frame):
self . pass_handler . cur_passwords = self . pass_handler . get_pass_passwords ( )
self . add_buttons ( )
def save_to_pass ( self , path , text , name = None ) :
def save_to_pass ( self , path : str , text : wx . TextCtrl , name : Union [ None , wx . TextCtrl ] = None ) :
""" save_to_pass.
: param path :
: param text :
: param name :
"""
full path = os . path . dirname ( self . pass_handler . top_dir + ' / ' + path . lstrip ( ' / ' ) )
full _ path: str = os . path . dirname ( self . pass_handler . top_dir + ' / ' + path . lstrip ( ' / ' ) )
if name is not None :
path = name . GetLineText ( 0 )
full path = os . path . dirname ( self . pass_handler . top_dir + ' / ' + path . lstrip ( ' / ' ) )
filename = full path + ' .gpg '
if os . path . exists ( full path) or os . path . exists ( filename ) :
dlg = wx . MessageDialog (
path : str = name . GetLineText ( 0 )
full _ path: str = os . path . dirname ( self . pass_handler . top_dir + ' / ' + path . lstrip ( ' / ' ) )
filename : str = full _ path + ' .gpg '
if os . path . exists ( full _ path) or os . path . exists ( filename ) :
dlg : wx . MessageDialog = wx . MessageDialog (
self . pnl ,
" Path: " + path +
" al l ready exists! Please update password path" ,
" al ready exists! Please update password path" ,
" Error " ,
style = wx . OK )
dlg . ShowModal ( )
reply = wx . ID_CANCEL
reply : int = wx . ID_CANCEL
else :
dlg = wx . MessageDialog ( self . pnl ,
" Save to " + path + " ? " ,
" Are you sure? " ,
style = wx . CANCEL | wx . CANCEL_DEFAULT | wx . OK )
dlg : wx . MessageDialog = wx . MessageDialog ( self . pnl ,
" Save to " + path + " ? " ,
" Are you sure? " ,
style = wx . CANCEL | wx . CANCEL_DEFAULT | wx . OK )
dlg . SetOKCancelLabels ( " &Yes " , " &Don ' t save " )
reply = dlg . ShowModal ( )
reply : int = dlg . ShowModal ( )
if reply == wx . ID_CANCEL :
return
password = str ( )
for line no in range ( text . GetNumberOfLines ( ) ) :
password + = text . GetLineText ( line no)
password + = ' \n '
password : str = str ( )
for line _ no in range ( text . GetNumberOfLines ( ) ) :
password + = text . GetLineText ( line _ no)
password + = ' \n ' # FIXME: Is this right? Maybe we break stuff with the trailing newline?
self . pass_handler . save_to_pass ( password , path , full path)
self . pass_handler . save_to_pass ( password , path , full _ path)
self . back_button_clicked ( )
@redraw
@ -206,134 +207,130 @@ class PassUi(wx.Frame):
""" show_new_dialog.
"""
pass path = self . pass_handler . cur_dir . replace ( self . pass_handler . top_dir , ' ' )
btn = self . make_back_button ( )
pass _ path: str = self . pass_handler . cur_dir . replace ( self . pass_handler . top_dir , ' ' )
btn : wx . Button = self . make_back_button ( )
self . sizer . Add ( btn , 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON ,
lambda event , path = self . pass_handler . cur_dir : self . path_button_clicked (
path ) ,
btn )
name_sizer = wx . BoxSizer ( orient = wx . VERTICAL ) # pylint: disable=no-member
name_sizer : wx . BoxSizer = wx . BoxSizer ( orient = wx . VERTICAL ) # pylint: disable=no-member
name_sizer . Add ( wx . StaticText ( self . pnl , - 1 , " Password path: " ) , 0 ,
wx . EXPAND ) # pylint: disable=no-member
pw_sizer = wx . BoxSizer ( orient = wx . VERTICAL ) # pylint: disable=no-member
pw_sizer : wx . BoxSizer = wx . BoxSizer ( orient = wx . VERTICAL ) # pylint: disable=no-member
pw_sizer . Add ( wx . StaticText ( self . pnl , - 1 , " Password: " ) , 0 , wx . EXPAND ) # pylint: disable=no-member
name = wx . TextCtrl ( self . pnl , value = pass path, style = wx . TE_DONTWRAP )
text = wx . TextCtrl ( self . pnl , style = wx . TE_MULTILINE | wx . TE_DONTWRAP )
s btn = wx . Button ( self . pnl , label = " Save password " )
name : wx . TextCtrl = wx . TextCtrl ( self . pnl , value = pass _ path, style = wx . TE_DONTWRAP )
text : wx . TextCtrl = wx . TextCtrl ( self . pnl , style = wx . TE_MULTILINE | wx . TE_DONTWRAP )
s _ btn: wx . Butto n = wx . Button ( self . pnl , label = " Save password " )
name_sizer . Add ( name , 0 , wx . EXPAND ) # pylint: disable=no-member
pw_sizer . Add ( text , 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( name_sizer , 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( pw_sizer , 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( s btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( s _ btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON ,
lambda event , path = passpath , mtext = text , mname = name : self .
save_to_pass ( path , mtext , mname ) ,
sbtn )
self . pnl . SetupScrolling ( )
lambda event , path = pass_path , m_text = text , m_name = name : self .
save_to_pass ( path , m_text , m_name ) ,
s_btn )
name . SetFocus ( )
@redraw
def show_password_dialog ( self , index ):
def show_password_dialog ( self , index : int ):
""" show_password_dialog.
: param index :
"""
self . add_tools ( index )
pass path = self . pass_handler . get_pass_path_from_index ( index , " password " )
c path = self . pass_handler . top_dir + os . path . dirname ( pass path)
password = get_password_from_path ( pass path)
pass _ path: str = self . pass_handler . get_pass_path_from_index ( index , " password " )
c _ path: str = self . pass_handler . top_dir + os . path . dirname ( pass _ path)
password : str = get_password_from_path ( pass _ path)
btn = self . make_back_button ( index )
btn : wx . Button = self . make_back_button ( index )
self . sizer . Add ( btn , 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind (
wx . EVT_BUTTON ,
lambda event , path = c path: self . path_button_clicked ( path ) ,
lambda event , path = c _ path: self . path_button_clicked ( path ) ,
btn )
s btn = wx . Button ( self . pnl , label = " Show/edit password " )
c btn = wx . Button ( self . pnl , label = " Copy password " )
d btn = wx . Button ( self . pnl , label = " Delete password " )
self . sizer . Add ( s btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( c btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( d btn, 0 , wx . EXPAND ) # pylint: disable=no-member
s _ btn: wx . Butto n = wx . Button ( self . pnl , label = " Show/edit password " )
c _ btn: wx . Butto n = wx . Button ( self . pnl , label = " Copy password " )
d _ btn: wx . Butto n = wx . Button ( self . pnl , label = " Delete password " )
self . sizer . Add ( s _ btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( c _ btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( d _ btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON ,
lambda event , text = password : copy_to_clipboard ( text ) ,
c btn)
c _ btn)
self . Bind (
wx . EVT_BUTTON ,
lambda event , m index= index : self . show_password ( m index) ,
s btn)
lambda event , m _ index= index : self . show_password ( m _ index) ,
s _ btn)
self . Bind (
wx . EVT_BUTTON ,
lambda event , mindex = index : self . delete_password ( mindex ) ,
dbtn )
self . pnl . SetupScrolling ( )
lambda event , m_index = index : self . delete_password ( m_index ) ,
d_btn )
@redraw
def show_password ( self , index ):
def show_password ( self , index : int ):
""" show_password.
: param index :
"""
self . add_tools ( index )
pass path = self . pass_handler . get_pass_path_from_index ( index , " password " )
c path = self . pass_handler . top_dir + os . path . dirname ( pass path)
password = get_password_from_path ( pass path)
btn = self . make_back_button ( index )
pass _ path: str = self . pass_handler . get_pass_path_from_index ( index , " password " )
c _ path: str = self . pass_handler . top_dir + os . path . dirname ( pass _ path)
password : str = get_password_from_path ( pass _ path)
btn : wx . Button = self . make_back_button ( index )
self . sizer . Add ( btn , 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind (
wx . EVT_BUTTON ,
lambda event , path = c path: self . path_button_clicked ( path ) ,
lambda event , path = c _ path: self . path_button_clicked ( path ) ,
btn )
text = wx . TextCtrl ( self . pnl ,
value = password ,
style = wx . TE_MULTILINE | wx . TE_DONTWRAP )
c btn = wx . Button ( self . pnl , label = " Copy password " )
s btn = wx . Button ( self . pnl , label = " Save password " )
text : wx . TextCtrl = wx . TextCtrl ( self . pnl ,
value = password ,
style = wx . TE_MULTILINE | wx . TE_DONTWRAP )
c _ btn: wx . Butto n = wx . Button ( self . pnl , label = " Copy password " )
s _ btn: wx . Butto n = wx . Button ( self . pnl , label = " Save password " )
self . sizer . Add ( text , 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( c btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( s btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( c _ btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . sizer . Add ( s _ btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON ,
lambda event , m text= password : copy_to_clipboard ( m text) ,
c btn)
lambda event , m _ text= password : copy_to_clipboard ( m _ text) ,
c _ btn)
self . Bind ( wx . EVT_BUTTON ,
lambda event , path = passpath , mtext = text : self . save_to_pass (
path , mtext ) ,
sbtn )
self . pnl . SetupScrolling ( )
lambda event , path = pass_path , m_text = text : self . save_to_pass (
path , m_text ) ,
s_btn )
@redraw
def show_tools ( self , index = None ) :
def show_tools ( self , index : Union [ None , int ] = None ) :
""" show_tools.
: param index :
"""
btn = wx . Button ( self . pnl , label = " Go back " )
font = btn . GetFont ( ) . MakeBold ( )
btn : wx . Button = wx . Button ( self . pnl , label = " Go back " )
font : wx . Font = btn . GetFont ( ) . MakeBold ( )
btn . SetFont ( font )
self . sizer . Add ( btn , 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind (
wx . EVT_BUTTON ,
lambda event , m index= index : self . back_button_clicked ( m index) ,
lambda event , m _ index= index : self . back_button_clicked ( m _ index) ,
btn )
n btn = wx . Button ( self . pnl , label = " Add new password " )
font = n btn. GetFont ( ) . MakeBold ( )
n btn. SetFont ( font )
self . sizer . Add ( n btn, 0 , wx . EXPAND ) # pylint: disable=no-member
n _ btn: wx . Butto n = wx . Button ( self . pnl , label = " Add new password " )
font : wx . Font = n _ btn. GetFont ( ) . MakeBold ( )
n _ btn. SetFont ( font )
self . sizer . Add ( n _ btn, 0 , wx . EXPAND ) # pylint: disable=no-member
self . Bind ( wx . EVT_BUTTON , lambda event : self . show_new_dialog ( ) ,
n btn)
n _ btn)
self . add_push_pull ( )
self . pnl . SetupScrolling ( )
if __name__ == ' __main__ ' :
# When this module is run (not imported) then create the app, the
# frame, show it, and start the event loop.
app = wx . App ( )
frm = PassUi ( None , title = ' PassUi ' )
app : wx . App = wx . App ( )
frm : PassUi = PassUi ( None , title = ' PassUi ' )
frm . Show ( )
app . MainLoop ( )