adds login generator as OOP and MVC
This commit is contained in:
parent
b4b40f1790
commit
1b48d3f0e0
|
@ -2760,7 +2760,339 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
### Improve the login generator
|
### Improve the login generator
|
||||||
|
|
||||||
TODO convert the login generator to a class
|
First the library...
|
||||||
|
|
||||||
|
```python
|
||||||
|
Oimport string
|
||||||
|
import random
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def load_file(filepath):
|
||||||
|
words = []
|
||||||
|
with open(filepath, "r") as fp:
|
||||||
|
data = fp.readlines()
|
||||||
|
for line in data:
|
||||||
|
word = line.strip()
|
||||||
|
words.append(word)
|
||||||
|
return words
|
||||||
|
|
||||||
|
|
||||||
|
class Login(object):
|
||||||
|
ADJECTIVES = load_file("adjectives.txt")
|
||||||
|
ANIMALS = load_file("subjects.txt")
|
||||||
|
|
||||||
|
def __init__(self, site=None):
|
||||||
|
self.site = site
|
||||||
|
self.generate_password()
|
||||||
|
self.generate_username()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
msg = "site: {} - username: {} with password: {}".format(self.site, self.username, self.password)
|
||||||
|
return msg
|
||||||
|
|
||||||
|
def generate_password(self, length=16, complex=False):
|
||||||
|
if complex:
|
||||||
|
db = list(string.ascii_letters + string.digits + string.punctuation)
|
||||||
|
else:
|
||||||
|
db = list(string.ascii_letters)
|
||||||
|
password = []
|
||||||
|
for i in range(0, length):
|
||||||
|
char = random.choice(db)
|
||||||
|
password.append(char)
|
||||||
|
password = "".join(password)
|
||||||
|
self.password = password
|
||||||
|
|
||||||
|
def generate_username(self):
|
||||||
|
"""generates a random username from a list of animals and adjectives"""
|
||||||
|
adj = random.choice(self.__class__.ADJECTIVES)
|
||||||
|
sbj = random.choice(self.__class__.ANIMALS)
|
||||||
|
username = f"{adj.capitalize()}{sbj.capitalize()}"
|
||||||
|
self.username = username
|
||||||
|
|
||||||
|
def set_password(self, password):
|
||||||
|
self.password = password
|
||||||
|
|
||||||
|
def set_username(self, username):
|
||||||
|
self.username = username
|
||||||
|
|
||||||
|
def verify_password(self, password):
|
||||||
|
if password == self.password:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def verify_username(self, username):
|
||||||
|
if username == self.username:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def verify_login(self, username, password):
|
||||||
|
# if password == self.password and username == self.username:
|
||||||
|
if self.verify_password(password) and self.verify_username(username):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class Database(object):
|
||||||
|
def __init__(self, path="db.json"):
|
||||||
|
self.path = path
|
||||||
|
self.data = []
|
||||||
|
|
||||||
|
def add(self, login):
|
||||||
|
if isinstance(login, Login):
|
||||||
|
self.data.append(login)
|
||||||
|
|
||||||
|
def get_all(self):
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
def get_by_index(self, index):
|
||||||
|
if index in range(0, len(self.data)):
|
||||||
|
return self.data[index]
|
||||||
|
|
||||||
|
def save_to_disk(self):
|
||||||
|
with open(self.path, "w") as fp:
|
||||||
|
json.dump(self.data, fp , default=vars)
|
||||||
|
|
||||||
|
def load_from_disk(self):
|
||||||
|
with open(self.path, "r") as fp:
|
||||||
|
data = json.load(fp)
|
||||||
|
for item in data:
|
||||||
|
l = Login(item["site"])
|
||||||
|
l.set_password(item["password"])
|
||||||
|
l.set_username(item["username"])
|
||||||
|
self.data.append(l)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
db = Database()
|
||||||
|
db.load_from_disk()
|
||||||
|
for login in db.data:
|
||||||
|
print(login)
|
||||||
|
login.generate_password()
|
||||||
|
db.save_to_disk()
|
||||||
|
```
|
||||||
|
|
||||||
|
Now the command line interface with a **bad** separation of responsibilities.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from login_lib_OOP import Login, Database
|
||||||
|
|
||||||
|
|
||||||
|
class CommandLineInterface(object):
|
||||||
|
def __init__(self, db):
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
def ask_for_int(self, msg):
|
||||||
|
while True:
|
||||||
|
result = input(msg)
|
||||||
|
if result.isdigit():
|
||||||
|
number = int(result)
|
||||||
|
break
|
||||||
|
print("only intergers please...")
|
||||||
|
return number
|
||||||
|
|
||||||
|
def ask_for_bool(self, msg):
|
||||||
|
while True:
|
||||||
|
result = input(msg).lower()
|
||||||
|
if result.startswith("y"):
|
||||||
|
status = True
|
||||||
|
break
|
||||||
|
elif result.startswith("n"):
|
||||||
|
status = False
|
||||||
|
break
|
||||||
|
print("answer with y(es)/n(o) please...")
|
||||||
|
return status
|
||||||
|
|
||||||
|
def ask_for_view(self):
|
||||||
|
msg = "do you want to view your logins?"
|
||||||
|
status = self.ask_for_bool(msg)
|
||||||
|
|
||||||
|
def ask_for_add_logins(self):
|
||||||
|
msg = "how many logins do you want to add?"
|
||||||
|
number = self.ask_for_int(msg)
|
||||||
|
for i in range(0, number):
|
||||||
|
l = Login("undefined")
|
||||||
|
self.db.add(l)
|
||||||
|
|
||||||
|
def view_logins(self):
|
||||||
|
for login in self.db.data:
|
||||||
|
print("\t{}: {}".format(self.db.data.index(login), login))
|
||||||
|
|
||||||
|
def main_menu(self):
|
||||||
|
actions = ["show logins", "add logins", "save to disk","load from disk", "quit"]
|
||||||
|
for action in actions:
|
||||||
|
print("{}: {}".format(actions.index(action), action))
|
||||||
|
msg = "what do you want to do?"
|
||||||
|
action = self.ask_for_int(msg)
|
||||||
|
if action == 0:
|
||||||
|
self.view_logins()
|
||||||
|
elif action == 1:
|
||||||
|
self.ask_for_add_logins()
|
||||||
|
elif action == 2:
|
||||||
|
self.db.save_to_disk()
|
||||||
|
elif action == 3:
|
||||||
|
self.db.load_from_disk()
|
||||||
|
elif action == 4:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
status = self.main_menu()
|
||||||
|
if not status:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
db = Database()
|
||||||
|
app = CommandLineInterface(db)
|
||||||
|
app.run()
|
||||||
|
```
|
||||||
|
|
||||||
|
Now a minimal **MVC** version...
|
||||||
|
|
||||||
|
```python
|
||||||
|
from login_lib_OOP import Login, Database
|
||||||
|
|
||||||
|
|
||||||
|
class Controller(object):
|
||||||
|
def __init__(self, model):
|
||||||
|
self.model = model
|
||||||
|
|
||||||
|
def set_view(self, view):
|
||||||
|
self.view = view
|
||||||
|
|
||||||
|
def add_multiple_logins(self, number):
|
||||||
|
for i in range(0, number):
|
||||||
|
l = Login()
|
||||||
|
self.model.add(l)
|
||||||
|
self.view.show_message("added {}".format(l))
|
||||||
|
|
||||||
|
def get_all_logins(self):
|
||||||
|
data = self.model.get_all()
|
||||||
|
self.view.show_message("there are {} logins in your database".format(len(data)))
|
||||||
|
for login in data:
|
||||||
|
msg = "{}: {}".format(data.index(login), login)
|
||||||
|
self.view.show_data(msg)
|
||||||
|
|
||||||
|
def get_one_login(self, index):
|
||||||
|
login = self.model.get_all()[index]
|
||||||
|
return login
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
self.model.load_from_disk()
|
||||||
|
number = len(self.model.get_all())
|
||||||
|
self.view.show_message("loaded {} logins from disk".format(number))
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
self.model.save_to_disk()
|
||||||
|
number = len(self.model.get_all())
|
||||||
|
self.view.show_message("saved {} logins to disk".format(number))
|
||||||
|
|
||||||
|
|
||||||
|
class CommandLineInterface(object):
|
||||||
|
def __init__(self, controller):
|
||||||
|
self.controller = controller
|
||||||
|
|
||||||
|
def ask_for_int(self, msg):
|
||||||
|
while True:
|
||||||
|
result = input(msg)
|
||||||
|
if result.isdigit():
|
||||||
|
number = int(result)
|
||||||
|
break
|
||||||
|
print("only intergers please...")
|
||||||
|
return number
|
||||||
|
|
||||||
|
def ask_for_bool(self, msg):
|
||||||
|
while True:
|
||||||
|
result = input(msg).lower()
|
||||||
|
if result.startswith("y"):
|
||||||
|
status = True
|
||||||
|
break
|
||||||
|
elif result.startswith("n"):
|
||||||
|
status = False
|
||||||
|
break
|
||||||
|
print("answer with y(es)/n(o) please...")
|
||||||
|
return status
|
||||||
|
|
||||||
|
def ask_for_login_index(self):
|
||||||
|
msg = "which login do you want to modify?"
|
||||||
|
number = self.ask_for_int(msg)
|
||||||
|
return number
|
||||||
|
|
||||||
|
def show_data(self, msg):
|
||||||
|
print("\t{}".format(msg))
|
||||||
|
|
||||||
|
def show_message(self, msg):
|
||||||
|
print("MSG: {}".format(msg))
|
||||||
|
|
||||||
|
def show_header(self, msg):
|
||||||
|
print(msg)
|
||||||
|
print(len(msg) * "-")
|
||||||
|
|
||||||
|
def main_menu(self):
|
||||||
|
self.show_header("main menu:")
|
||||||
|
actions = ["show logins", "add logins", "save to disk", "load from disk", "modify a login", "quit"]
|
||||||
|
for action in actions:
|
||||||
|
print("{}: {}".format(actions.index(action), action))
|
||||||
|
msg = "what do you want to do?"
|
||||||
|
action = self.ask_for_int(msg)
|
||||||
|
if action == 0:
|
||||||
|
self.controller.get_all_logins()
|
||||||
|
elif action == 1:
|
||||||
|
msg = "how many logins do you want?"
|
||||||
|
number = self.ask_for_int(msg)
|
||||||
|
self.controller.add_multiple_logins(number)
|
||||||
|
elif action == 2:
|
||||||
|
self.controller.save()
|
||||||
|
elif action == 3:
|
||||||
|
self.controller.load()
|
||||||
|
elif action == 4:
|
||||||
|
self.sub_menu_modify()
|
||||||
|
elif action == 5:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def sub_menu_modify(self):
|
||||||
|
self.show_header("modify entry:")
|
||||||
|
msg = "which login do you want to modify?"
|
||||||
|
number = self.ask_for_int(msg)
|
||||||
|
login = self.controller.get_one_login(number)
|
||||||
|
msg = "do you want to change the site name?"
|
||||||
|
status = self.ask_for_bool(msg)
|
||||||
|
if status:
|
||||||
|
login.site = input("for which site is this login?")
|
||||||
|
self.show_message("set site to: {}".format(login.site))
|
||||||
|
msg = "do you want to renew the username?"
|
||||||
|
status = self.ask_for_bool(msg)
|
||||||
|
if status:
|
||||||
|
login.generate_username()
|
||||||
|
self.show_message("set username to: {}".format(login.username))
|
||||||
|
msg = "do you want to renew the password?"
|
||||||
|
status = self.ask_for_bool(msg)
|
||||||
|
if status:
|
||||||
|
login.generate_password()
|
||||||
|
self.show_message("set password to: {}".format(login.password))
|
||||||
|
msg = "save changes?"
|
||||||
|
status = self.ask_for_bool(msg)
|
||||||
|
if status:
|
||||||
|
self.controller.save()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
status = self.main_menu()
|
||||||
|
if not status:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
model = Database()
|
||||||
|
controller = Controller(model)
|
||||||
|
view = CommandLineInterface(controller)
|
||||||
|
controller.set_view(view)
|
||||||
|
view.run()
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
### Improve the task manager
|
### Improve the task manager
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue