From 277f1e1aff5927b2d4030291ac4e94237d200f85 Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 27 Apr 2021 19:59:31 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5/=D0=B2=D0=BE=D1=81=D1=81=D1=82=D0=B0=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=82=D0=BE=D0=BA=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/backend/urls.py | 16 +++++++-------- frontend/api.py | 17 ++++++++++++++-- frontend/api_demo.py | 1 + frontend/login.py | 20 ++++++++++++++++++ frontend/todo_tk.py | 9 +++++++++ frontend/user.py | 45 +++++++++++++++++++++++++++++++++++++++-- frontend/workspace.py | 12 +++++++++++ 7 files changed, 108 insertions(+), 12 deletions(-) diff --git a/backend/backend/urls.py b/backend/backend/urls.py index d123db5..cdcbc7f 100644 --- a/backend/backend/urls.py +++ b/backend/backend/urls.py @@ -13,13 +13,13 @@ from drf_yasg import openapi from .api import router schema_view = get_schema_view( - openapi.Info( - title="ToDo List", - default_version='v1', - description="Swagger Interface for ToDo List", - ), - public=True, - permission_classes=(permissions.AllowAny,), + openapi.Info( + title="ToDo List", + default_version="v1", + description="Swagger Interface for ToDo List", + ), + public=True, + permission_classes=(permissions.AllowAny,), ) urlpatterns = [ @@ -28,5 +28,5 @@ urlpatterns = [ path("api/token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), path("api/", include(router.urls)), path("api-auth/", include("rest_framework.urls", namespace="rest_framework")), - path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), + path("swagger/", schema_view.with_ui("swagger", cache_timeout=0), name="schema-swagger-ui"), ] diff --git a/frontend/api.py b/frontend/api.py index ad54387..458c0d8 100644 --- a/frontend/api.py +++ b/frontend/api.py @@ -18,7 +18,8 @@ API_LISTS_UPDATE = "api/lists/{0}/" API_LISTS_PARTIAL_UPDATE = "api/lists/{0}/" API_LISTS_DELETE = "api/lists/{0}/" -API_TOKEN = "api/token/" +API_TOKEN_CREATE = "api/token/" +API_TOKEN_REFRESH = "api/token/refresh/" class UserApi(object): @@ -61,11 +62,23 @@ class UserApi(object): """ token = UserApi._raise_or_return_( - requests.post(url=self.get_api(API_TOKEN), json={"username": user, "password": passwd}) + requests.post( + url=self.get_api(API_TOKEN_CREATE), json={"username": user, "password": passwd} + ) ) self.token = SimpleNamespace(**token) return self.token + def refresh(self): + """ + Refresh existing token + """ + token = UserApi._raise_or_return_( + requests.post(url=self.get_api(API_TOKEN_REFRESH), json={"refresh": self.token.refresh}) + ) + self.token.access = token["access"] + return self.token + def lists_list(self, **argv): """ List all the exsiting to-do lists. diff --git a/frontend/api_demo.py b/frontend/api_demo.py index e3ec5f9..329297c 100644 --- a/frontend/api_demo.py +++ b/frontend/api_demo.py @@ -13,6 +13,7 @@ DEFAULT_URL = "http://127.0.0.1:8000" user = User(url=DEFAULT_URL) user.auth("root", "root") +user.refresh() # Fetch existing lists: print_lists(user.fetchUserLists()) diff --git a/frontend/login.py b/frontend/login.py index 64ba0e3..0efd7f9 100644 --- a/frontend/login.py +++ b/frontend/login.py @@ -38,6 +38,13 @@ class LoginFrame(tk.Frame): print(ex) message.invalid_login() + # Если захочется реализовать в логине + """ + @property + def remember(self): + return self.rbtn_var.get() + """ + def initAUTH(self) -> None: """ Создает окно авторизации программы @@ -66,3 +73,16 @@ class LoginFrame(tk.Frame): # Кнопка авториазции btn = tk.Button(self, text="Войти", command=self.login_clicked) btn.grid(row=14, column=12, columnspan=3, rowspan=1, sticky="nsew") + + # Если захочется реализовать в логине + """ + # Запомнить пользователя + self.rbtn_var = tk.IntVar(value=0) + rbtn = tk.Checkbutton( + self, + text="Запомнить меня", + variable=self.rbtn_var, + command=None + ) + rbtn.grid(row=15, column=12, columnspan=3, rowspan=1, sticky="nsew") + """ diff --git a/frontend/todo_tk.py b/frontend/todo_tk.py index 831ac6c..e97c352 100644 --- a/frontend/todo_tk.py +++ b/frontend/todo_tk.py @@ -4,6 +4,7 @@ import sys import tkinter as tk from login import LoginFrame from workspace import WorkSpaceFrame +from user import User if "win" in sys.platform.lower(): DEFAULT_URL = "http://localhost:8000" @@ -24,11 +25,19 @@ class Application(tk.Tk): def login(self): """Возвращает пользователя - его можно потом сериализовать""" + # Пользователь сохранен! Авторизация не нужна! + user = User.load() + if user is not None: + return user + # Не удалось - нужен логин self.frame = LoginFrame(master=self, url=DEFAULT_URL) while not self.frame.loggedIn: self.update_idletasks() self.update() self.frame.destroy() + # Нужно запомнить пользователя + # if self.frame.remember: + # self.frame.user.save() return self.frame.user def main(self, user): diff --git a/frontend/user.py b/frontend/user.py index ed264df..e5e6baf 100644 --- a/frontend/user.py +++ b/frontend/user.py @@ -1,8 +1,11 @@ import os import random - from datetime import datetime +from types import SimpleNamespace +from pathlib import Path + +import json from api import UserApi @@ -12,6 +15,8 @@ UPDATE_ERROR = "Failed to update property: {0}" DATETIME_STR = "%Y-%m-%dT%H:%M:%S.%fZ" +USER_TOKEN_PATH = os.path.join(Path.home(), ".todo_config.json") + def bad_arguments(x, d): return list((set(x) - set(d))) @@ -150,7 +155,43 @@ class User(UserApi): """ if "DEBUG" in os.environ: return - UserApi.auth(self, user, passwd) + return UserApi.auth(self, user, passwd) + + def remove(self): + """ + Remove the login file from homedir + """ + if not os.path.exists(USER_TOKEN_PATH): + return + try: + os.remove(USER_TOKEN_PATH) + except Exception as e: + raise RuntimeError("Failed to remove tokens:", e) + + def save(self): + """ + Store user token in homedir + """ + try: + with open(USER_TOKEN_PATH, "w") as handler: + json.dump(self.token.__dict__, handler) + except Exception as e: + raise RuntimeError("Failed to store tokens:", e) + + @staticmethod + def load(): + """ + Restore user token from the file in homedir + """ + if os.path.exists(USER_TOKEN_PATH): + try: + with open(USER_TOKEN_PATH, "r") as handler: + user = User(token=SimpleNamespace(**json.load(handler))) + user.refresh() + return user + except Exception as e: + raise RuntimeError("Failed to restore tokens:", e) + return None # Storing lists - mostly for debug purposes lists_ = make_debug_lists() diff --git a/frontend/workspace.py b/frontend/workspace.py index c82d2fd..8a488bc 100644 --- a/frontend/workspace.py +++ b/frontend/workspace.py @@ -118,8 +118,20 @@ class WorkSpaceFrame(tk.Frame): self.pack(fill=tk.BOTH, expand=1) self.initLayout(user) + def destroy(self): + tk.Tk.destroy(self) + if self.rbtn_var.get() > 0: + self.user.save() + else: + self.user.remove() + def initLayout(self, user): + # Запомнить пользователя + self.rbtn_var = tk.IntVar(value=1) + rbtn = tk.Checkbutton(self, text="Запомнить меня", variable=self.rbtn_var, command=None) + rbtn.pack(anchor="n") + # data self.lists = user.fetchUserLists()