11 Commits

Author SHA1 Message Date
moscap
d27066b15b Merge pull request #27 from AlekseyLobanov/fix
Исправлен баг потери локализации
2021-06-08 10:31:49 +03:00
Derinhelm
cac9d14d52 Исправлен баг потери локализации 2021-06-08 10:29:22 +03:00
Derinhelm
57f2f72856 Merge pull request #25 from AlekseyLobanov/add_wheels_to_project
Add wheels to project
2021-06-08 09:48:20 +03:00
moscap
f8bebe8115 add some automatization and localizatipon into wheels 2021-06-08 07:55:11 +03:00
moscap
f714f5ad1d Merge branch 'master' of https://github.com/AlekseyLobanov/django-todo into add_wheels_to_project 2021-06-08 06:57:43 +03:00
moscap
437b97b005 Merge pull request #26 from AlekseyLobanov/feat_11
Добавлена локализация
2021-06-08 06:51:03 +03:00
Derinhelm
16c151a1f3 Изменен интейрфейс 2021-06-07 20:47:42 +03:00
Derinhelm
bb8e1365bb Изменен путь к директории po 2021-06-07 16:36:01 +03:00
Derinhelm
fbd033e6ef Добавлена локализация
Перед запуском программы сгенерировать mo-файл
pybabel compile -D todo -i po/eng/LC_MESSAGES/todo.po -o po/eng/LC_MESSAGES/todo.mo
2021-06-07 00:38:53 +03:00
moscap
4fdd63b234 lint improvements 2021-06-02 14:16:35 +03:00
moscap
75e1d5c13e add deployment configs and tools 2021-06-02 14:11:10 +03:00
15 changed files with 265 additions and 61 deletions

5
.gitignore vendored
View File

@@ -67,3 +67,8 @@ target/
tmp* tmp*
.env* .env*
venv* venv*
# Doit
*.bak
*.dat
*.dir

View File

@@ -15,4 +15,4 @@ repos:
rev: 3.9.0 rev: 3.9.0
hooks: hooks:
- id: flake8 - id: flake8
args: ["--ignore=E203,W503,FI10,FI11,FI12,FI13,FI14,FI15,FI16,FI17,FI58,E501"] args: ["--ignore=E203,W503,FI10,FI11,FI12,FI13,FI14,FI15,FI16,FI17,FI58,E501", "--builtins=_"]

View File

@@ -32,8 +32,14 @@
## Как запустить проект ## Как запустить проект
### Frontend ### Frontend
Интерфейс на русском языке
```bash ```bash
python3 todo_tk.py python3 -m frontend
```
Интерфейс на английском языке
```bash
LANG=eng python3 -m frontend
``` ```
### backend ### backend

19
dodo.py Normal file
View File

@@ -0,0 +1,19 @@
#!usr/bin/env python3
"""
"""
def task_mo():
"""Create bynary wheel distribution"""
return {
"actions": [
"""pybabel compile -D todo -i frontend/po/eng/LC_MESSAGES/todo.po -o frontend/po/eng/LC_MESSAGES/todo.mo"""
],
"file_dep": ["frontend/po/eng/LC_MESSAGES/todo.po"],
"targets": ["frontend/po/eng/LC_MESSAGES/todo.mo"],
}
def task_wheel():
"""Create bynary wheel distribution"""
return {"actions": ["python3 -m build -w"], "task_dep": ["mo"]}

0
frontend/__init__.py Normal file
View File

8
frontend/__main__.py Normal file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/env python3
"""django-todo application launcher"""
from .todo_tk import Application
if __name__ == "__main__":
app = Application()
app.main(app.login())

View File

@@ -1,5 +1,5 @@
import random import random
from user import User from .user import User
def print_lists(lists): def print_lists(lists):

View File

@@ -1,6 +1,10 @@
import gettext
import os
import tkinter as tk import tkinter as tk
from user import User from .user import User
import message from . import message
gettext.install("todo", os.path.join(os.path.dirname(__file__), "po"))
class LoginFrame(tk.Frame): class LoginFrame(tk.Frame):
@@ -57,21 +61,22 @@ class LoginFrame(tk.Frame):
tk.Grid.columnconfigure(self, columns, weight=1) tk.Grid.columnconfigure(self, columns, weight=1)
# Подпись и поле ввода для логина # Подпись и поле ввода для логина
login_label = tk.Label(self, text="Введите логин") t = _("Введите логин")
login_label = tk.Label(self, text=t)
login_label.grid(row=9, column=12, columnspan=3, rowspan=1, sticky="nsew") login_label.grid(row=9, column=12, columnspan=3, rowspan=1, sticky="nsew")
self.login = tk.Entry(self) self.login = tk.Entry(self)
self.login.grid(row=10, column=12, columnspan=3, rowspan=1, sticky="nsew") self.login.grid(row=10, column=12, columnspan=3, rowspan=1, sticky="nsew")
# Подпись и поле ввода для пароля # Подпись и поле ввода для пароля
password_label = tk.Label(self, text="Введите пароль") password_label = tk.Label(self, text=_("Введите пароль"))
password_label.grid(row=11, column=12, columnspan=3, rowspan=1, sticky="nsew") password_label.grid(row=11, column=12, columnspan=3, rowspan=1, sticky="nsew")
self.password = tk.Entry(self, show="*") self.password = tk.Entry(self, show="*")
self.password.grid(row=12, column=12, columnspan=3, rowspan=1, sticky="nsew") self.password.grid(row=12, column=12, columnspan=3, rowspan=1, sticky="nsew")
# Кнопка авториазции # Кнопка авториазции
btn = tk.Button(self, text="Войти", command=self.login_clicked) btn = tk.Button(self, text=_("Войти"), command=self.login_clicked)
btn.grid(row=14, column=12, columnspan=3, rowspan=1, sticky="nsew") btn.grid(row=14, column=12, columnspan=3, rowspan=1, sticky="nsew")
# Если захочется реализовать в логине # Если захочется реализовать в логине

View File

@@ -1,8 +1,12 @@
import gettext
import os
from tkinter import messagebox as mb from tkinter import messagebox as mb
TITLE_INFO_BOX = "Сообщение!" gettext.install("todo", os.path.join(os.path.dirname(__file__), "po"))
MESSAGE_INVALID_LOGIN = "Неправильный логин или пароль"
MESSAGE_EMPTY = "Сдесь могло быть ваше сообщение" TITLE_INFO_BOX = _("Сообщение!")
MESSAGE_INVALID_LOGIN = _("Неправильный логин или пароль")
MESSAGE_EMPTY = _("Сдесь могло быть ваше сообщение")
def infobox(msg: str = None) -> None: def infobox(msg: str = None) -> None:

View File

@@ -0,0 +1,83 @@
# English (United States) translations for PROJECT.
# Copyright (C) 2021 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2021-06-06 23:42+0300\n"
"PO-Revision-Date: 2021-06-07 00:24+0300\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en_US\n"
"Language-Team: en_US <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.8.1\n"
#: todo_tk.py:20
msgid "Приложение для планирования"
msgstr "ToDo Application"
#: message.py:6
msgid "Сообщение!"
msgstr "Message!"
#: message.py:7
msgid "Неправильный логин или пароль"
msgstr "Wrong login or password"
#: message.py:8
msgid "Сдесь могло быть ваше сообщение"
msgstr "This could have been your message"
#: login.py:63
msgid "Введите логин"
msgstr "Enter your username"
#: login.py:71
msgid "Введите пароль"
msgstr "Enter your password"
#: login.py:78
msgid "Войти"
msgstr "Enter"
#: workspace.py:17
msgid "Не реализовано"
msgstr "Not implemented"
#: workspace.py:25
msgid "Текст"
msgstr "Text"
#: workspace.py:28
msgid "Выполнено"
msgstr "Done"
#: workspace.py:31
msgid "Создано"
msgstr "Created"
#: workspace.py:60
msgid "Удалить"
msgstr "Delete"
#: workspace.py:88
msgid "Добавить заметку"
msgstr "Add note"
#: workspace.py:91
msgid "Удалить лист"
msgstr "Delete list"
#: workspace.py:149
msgid "Запомнить меня"
msgstr "Remember me"
#: workspace.py:158
msgid "Добавить лист"
msgstr "Add list"

View File

@@ -1,20 +1,24 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import gettext
import os
import sys import sys
import tkinter as tk import tkinter as tk
from login import LoginFrame from .login import LoginFrame
from workspace import WorkSpaceFrame from .workspace import WorkSpaceFrame
from user import User from .user import User
gettext.install("todo", os.path.join(os.path.dirname(__file__), "po"))
if "win" in sys.platform.lower(): if "win" in sys.platform.lower():
DEFAULT_URL = "http://localhost:8000" DEFAULT_URL = "http://localhost:8000"
else: else:
DEFAULT_URL = "http://0.0.0.0:8000" DEFAULT_URL = "http://0.0.0.0:8000"
BASE_W = 600 BASE_W = 900
BASE_H = 400 BASE_H = 400
TITLE_APP = "ToDo Application" TITLE_APP = _("Приложение для планирования")
class Application(tk.Tk): class Application(tk.Tk):
@@ -50,7 +54,6 @@ class Application(tk.Tk):
def center_window(self, width: str = BASE_W, heigh: str = BASE_H) -> None: def center_window(self, width: str = BASE_W, heigh: str = BASE_H) -> None:
""" """
Центрирует приложение по центру экрана Центрирует приложение по центру экрана
:param width: ширина окна :param width: ширина окна
:param heigh: высота окна :param heigh: высота окна
""" """

View File

@@ -7,7 +7,7 @@ from pathlib import Path
import json import json
from api import UserApi from .api import UserApi
LIST_UPDATEBLE = ["title"] LIST_UPDATEBLE = ["title"]
TODO_ITEM_UPDATEBLE = ["text", "finished"] TODO_ITEM_UPDATEBLE = ["text", "finished"]

View File

@@ -1,60 +1,65 @@
import gettext
import os
import tkinter as tk import tkinter as tk
gettext.install("todo", os.path.join(os.path.dirname(__file__), "po"))
def str_time(time): def str_time(time):
return time.strftime("%Y-%m-%d %H:%M:%S") return time.strftime("%Y-%m-%d %H:%M:%S")
TODO_ITEM_TABLE_TEXT_WIDTH = 15 TODO_ITEM_TABLE_TEXT_WIDTH = 25
TODO_ITEM_TABLE_FINISHED_WIDTH = 8 TODO_ITEM_TABLE_FINISHED_WIDTH = 20
TODO_ITEM_TABLE_CREATED_AT_WIDTH = 15
TODO_ITEM_TABLE_CREATED_AT_WIDTH = 25
def placeholder(): def placeholder():
print("Не реализовано") print(_("Не реализовано"))
class ToDoItemWidget(tk.Frame): class ToDoItemWidget(tk.Frame):
@staticmethod def __init__(self, *args, row_number, item, table, **argv):
def header(parent):
body = tk.Frame(parent)
text = tk.Label(body, text="Текст", width=TODO_ITEM_TABLE_TEXT_WIDTH)
text.pack(side="left")
text = tk.Label(body, text="Выполнено", width=TODO_ITEM_TABLE_FINISHED_WIDTH)
text.pack(side="left")
text = tk.Label(body, text="Создано", width=TODO_ITEM_TABLE_CREATED_AT_WIDTH)
text.pack(side="left")
return body
def __init__(self, *args, item, **argv):
super().__init__(*args, **argv) super().__init__(*args, **argv)
self.parent = self.master self.parent = self.master
self.item = item self.item = item
self.noteLabel = tk.Label(self, text=item.text, width=TODO_ITEM_TABLE_TEXT_WIDTH) self.noteLabel = tk.Label(
self.noteLabel.pack(side="left") table,
text=item.text,
width=TODO_ITEM_TABLE_TEXT_WIDTH,
justify="center",
font=("Arial", 8),
)
self.noteLabel.grid(row=row_number, column=0)
self.finished = tk.IntVar(value=int(item.finished)) self.finished = tk.IntVar(value=int(item.finished))
self.finishedButton = tk.Checkbutton( self.finishedButton = tk.Checkbutton(
self, table,
variable=self.finished, variable=self.finished,
command=self.finishedButton_command, command=self.finishedButton_command,
width=TODO_ITEM_TABLE_FINISHED_WIDTH, width=TODO_ITEM_TABLE_FINISHED_WIDTH,
justify="center",
) )
self.finishedButton.pack(side="left") self.finishedButton.grid(row=row_number, column=1)
self.createdAt = tk.Label( self.createdAt = tk.Label(
self, text=str_time(item.created_at), width=TODO_ITEM_TABLE_CREATED_AT_WIDTH table,
text=str_time(item.created_at),
width=TODO_ITEM_TABLE_CREATED_AT_WIDTH,
justify="center",
) )
self.createdAt.pack(side="left") self.createdAt.grid(row=row_number, column=2)
self.remove = tk.Button(self, text="Удалить", command=lambda: self.parent.remove(self.item)) self.remove = tk.Button(
self.remove.pack(side="left") table,
text=_("Удалить"),
command=lambda: self.parent.remove(self.item),
justify="center",
)
self.remove.grid(row=row_number, column=3)
def finishedButton_command(self): def finishedButton_command(self):
self.item.modify(finished=self.finished.get() > 0) self.item.modify(finished=self.finished.get() > 0)
@@ -65,26 +70,69 @@ class ToDoListWidget(tk.Frame):
super().__init__(*args, **argv) super().__init__(*args, **argv)
self.delete_list = delete_list self.delete_list = delete_list
def fill(self, itemList): def create_table_header(self, body):
header = ToDoItemWidget.header(self) header_font = ("Arial", "10", "bold")
header.pack(side="left") text = tk.Label(
header.pack(side="top", fill="y") body,
text=_("Текст"),
width=TODO_ITEM_TABLE_TEXT_WIDTH,
justify="center",
font=header_font,
)
text.grid(row=0, column=0)
done = tk.Label(
body,
text=_("Выполнено"),
width=TODO_ITEM_TABLE_FINISHED_WIDTH,
justify="center",
font=header_font,
)
done.grid(row=0, column=1)
created = tk.Label(
body,
text=_("Создано"),
width=TODO_ITEM_TABLE_CREATED_AT_WIDTH,
justify="center",
font=header_font,
)
created.grid(row=0, column=2)
def create_table(self, itemList):
table = tk.LabelFrame(self, relief=tk.GROOVE)
table.grid()
self.create_table_header(table)
self.itemList = itemList self.itemList = itemList
row_number = 1
for item in itemList: for item in itemList:
item = ToDoItemWidget(self, item=item) item = ToDoItemWidget(self, row_number=row_number, item=item, table=table)
item.pack(side="top", fill="y") row_number += 1
return table
self.itemToAdd = tk.Text(self, width=15, height=1) def create_new_item(self):
self.itemToAdd.pack(side="top") table = tk.LabelFrame(self, relief=tk.GROOVE)
table.grid()
self.itemToAdd = tk.Text(table, width=15, height=1)
self.itemToAdd.grid(row=0, column=0)
add = tk.Button(self, text="Добавить заметку", command=self.add_command) add = tk.Button(table, text=_("Добавить заметку"), command=self.add_command)
add.pack(side="top") add.grid(row=0, column=1)
return table
delete = tk.Button(self, text="Удалить лист", command=self.delete_list) def fill(self, itemList):
delete.pack(side="top") self.frame = tk.LabelFrame(self, relief=tk.GROOVE)
self.frame.grid(sticky="NEWS")
table = self.create_table(itemList)
table.grid(row=0, column=0)
new = self.create_new_item()
new.grid(row=2, column=0)
delete = tk.Button(self, text=_("Удалить лист"), command=self.delete_list)
delete.grid(row=4, column=0)
def update(self, itemList=None): def update(self, itemList=None):
self.clear() self.clear()
@@ -141,7 +189,7 @@ class WorkSpaceFrame(tk.Frame):
# Запомнить пользователя # Запомнить пользователя
self.rbtn_var = tk.IntVar(value=1) self.rbtn_var = tk.IntVar(value=1)
rbtn = tk.Checkbutton(self, text="Запомнить меня", variable=self.rbtn_var, command=None) rbtn = tk.Checkbutton(self, text=_("Запомнить меня"), variable=self.rbtn_var, command=None)
rbtn.pack(anchor="n") rbtn.pack(anchor="n")
# data # data
@@ -150,7 +198,7 @@ class WorkSpaceFrame(tk.Frame):
self.add_list_text = tk.Text(self, width=15, height=1) self.add_list_text = tk.Text(self, width=15, height=1)
self.add_list_text.pack(anchor="sw") self.add_list_text.pack(anchor="sw")
add = tk.Button(self, text="Добавить лист", command=self.add_list) add = tk.Button(self, text=_("Добавить лист"), command=self.add_list)
add.pack(anchor="sw") add.pack(anchor="sw")
# select list box # select list box

View File

@@ -21,3 +21,15 @@ exclude = '''
| profiling | profiling
)/ )/
''' '''
[build-system]
requires = [
"setuptools",
"wheel",
"requests",
"build",
"coverage",
"doit"
]
build-backend = "setuptools.build_meta"

11
setup.cfg Normal file
View File

@@ -0,0 +1,11 @@
[metadata]
name = django-todo
version = 0.0.1
[options]
packages = frontend
install_requires =
requests; python_version >= "3.6"
[options.package_data]
frontend = */*/*/todo.mo