#!/usr/bin/python3 # ==================================================================== # passworld vault 04 - utilities # ==================================================================== import time msg0 = 'Welcome to my Password Vault program.' msg1 = 'v0.1' msg2 = 'Password Vault ' + msg1 msg3 = '''\ Searches are case-insensitive substring matches. All entries that match are returned as a list of entries.''' msg4 = '''\ My password vault is a dictionary. It is stored on disk as an ecrypted JSON data structure. Encryption and decryption use a symmetrical key (the same key). This key is generated from a password you create and enter. DO NOT FORGET THIS PASSWORD. If you do, the data can not be recoved. My Password Vault allows you to have multiple vaults. Each can vault is a different file and can have the same or different password. The program start with a default vault. You then select which vault to access. While the program is running you can switch to a different vault. I would suggest you keep the entries to less than 60 to 80 entries per vault. You may also dump a vault to a CVS file which is not encrypted. Each entry is given a unique (integer) ID. This can speed up processing because it eliminates duplicate matching entries. Deleted entry IDs are never reused.''' # -------------------------------------------------------------------- # ----- display each line is a multi-line string # -------------------------------------------------------------------- def _display_message_indented(msg,indent=''): lines = msg.split('\n') for line in lines: print(indent + line) # -------------------------------------------------------------------- # ---- display message # -------------------------------------------------------------------- def display_message(i,indent=None): msg = None if i == 0: msg = msg0 elif i == 1: msg = msg1 elif i == 2: msg = msg2 elif i == 3: msg = msg3 elif i == 4: msg = msg4 if msg is None: return None if indent is not None: _display_message_indented(msg,indent) return i print(msg) return i # -------------------------------------------------------------------- # ---- return message # -------------------------------------------------------------------- def return_message(i): msg = '' if i == 0: msg = msg0 elif i == 1: msg = msg1 elif i == 2: msg = msg2 elif i == 3: msg = msg3 elif i == 4: msg = msg4 return msg # -------------------------------------------------------------------- # ---- current date (string) # -------------------------------------------------------------------- def current_date(): t = time.time() return time.strftime('%B %d, %Y',time.localtime(t)) # ------------------------------------------------------------------- # ---- renumber entry IDs # ---- this function can be used to eliminate gaps in the range # ---- of IDs if you feel there are to many. # ------------------------------------------------------------------- def renumber_vault_ids(vault): id_count = 0 for e in vault["entries"]: id_count += 1 e["id"] = id_count return id_count # ------------------------------------------------------------------- # ---- return entries that match an id # ---- test if an entry's id matches # ------------------------------------------------------------------- def search_for_id(vault,id): lst = [] for e in vault["entries"]: if id == e["id"]: lst.append(ee) return lst # ------------------------------------------------------------------- # ---- return entries that have 'name' match pat (string) # ---- (case insensitive search for a substring) # ---- # ---- for each entry # ---- test if there is a substring match in 'name' # ------------------------------------------------------------------- def search_for_name(vault,pat): lst = [] if not pat: return lst lpat = pat.lower() for e in vault["entries"]: lnam = e["name"].lower() idx = lnam.find(lpat) if idx >= 0: lst.append(e) return lst # ------------------------------------------------------------------- # ---- return entries that have 'note' matchs pat (string) # ---- (case insensitive search for a substring) # ---- # ---- (notes are optional) # ---- for each entry # ---- test if the dictionary key 'note' exists in vault # ---- test if there is a note (not '' or None) # ---- test if there is a substring match in 'note' # ------------------------------------------------------------------- def search_for_note(vault,pat): lst = [] if not pat: return lst lpat = pat.lower() for e in vault["entries"]: if "note" in e: if e["note"]: lnot = e["note"].lower() idx = lnot.find(lpat) if idx >= 0: lst.append(e) return lst # ------------------------------------------------------------------- # ---- main (test utilities) # ------------------------------------------------------------------- if __name__ == '__main__': import password_vault_01_db as db vault = db.test_vault_1 print('----display messages----------------------------') print() display_message(0) display_message(1) display_message(3) print() print('----current date---------------------------------') print(current_date()) print('----name match \'A\'-------------------------------') lst = search_for_name(vault,'A') print(f'lst-len = {len(lst)}') for e in lst: print(f'entry = {e["name"]}') print('----name match \'zon\'-----------------------------') lst = search_for_name(vault,'zon') print(f'lst-len = {len(lst)}') for e in lst: print(f'entry = {e["name"]}') print('----note match \'fur\'-----------------------------') lst = search_for_note(vault,'fur') print(f'lst-len = {len(lst)}') for e in lst: print(f'entry = {e["note"]}')