Skip to content

Commit 5f4323b

Browse files
committed
adding functionality with graphing
1 parent b5c0bb8 commit 5f4323b

File tree

15 files changed

+155
-42
lines changed

15 files changed

+155
-42
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ qodana.yaml
1212
**/develop
1313
**/docs
1414
**/csv_tables
15+
**/graphs
1516

1617
# Databases
1718
*.sqlite3

budget_graph/bot.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
from os import getenv, path
88
from secrets import compare_digest
99
from datetime import datetime, UTC
10+
from uuid import UUID, uuid4
1011
from dotenv import load_dotenv
1112
from telebot import TeleBot
1213
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton, ReplyKeyboardMarkup, KeyboardButton
1314

1415
sys_path.append('../')
1516
from budget_graph.logger import setup_logger
17+
from budget_graph.plot_builder import build_diagram
1618
from budget_graph.global_config import GlobalConfig
1719
from budget_graph.registration_service import user_registration
1820
from budget_graph.dictionary import Stickers, receive_translation
@@ -305,15 +307,24 @@ def get_diagram(db_connection, message, user_language: str) -> None:
305307

306308

307309
@bot.callback_query_handler(func=lambda call: call.data.startswith('get_diagram'))
308-
@connect_defer_close_db
309-
def callback_query_get_diagram(db_connection, call):
310+
def callback_query_get_diagram(call):
311+
# TODO - логи по всей операции
310312
telegram_id: int = call.from_user.id
311313
user_language: str = check_user_language(telegram_id)
312-
group_id: int = db_connection.get_group_id_by_telegram_id(telegram_id)
313314
diagram_type: int = int(call.data[-1])
314-
build_diagram(diagram_type, call.message.chat.id, telegram_id, group_id)
315-
bot.answer_callback_query(call.id, f'{receive_translation(user_language, "wait_diagram")}')
316-
bot.delete_message(call.message.chat.id, call.message.message_id)
315+
uuid: UUID = uuid4()
316+
# TODO - поддержать 3 тип диаграммы
317+
status: bool | None = build_diagram(call.message.chat.id, telegram_id, uuid, diagram_type)
318+
if status:
319+
bot.answer_callback_query(call.id, f'{receive_translation(user_language, "wait_diagram")}')
320+
bot.send_message(call.message.chat.id, f"{receive_translation(user_language, "feature_uuid_filename")}: {uuid}")
321+
bot.delete_message(call.message.chat.id, call.message.message_id)
322+
elif status is None:
323+
bot.send_message(call.message.chat.id, f"{receive_translation(user_language, "table_is_empty")}")
324+
bot.delete_message(call.message.chat.id, call.message.message_id)
325+
else:
326+
bot.send_message(call.message.chat.id, f"{receive_translation(user_language, "csv_not_found_error")}")
327+
bot.delete_message(call.message.chat.id, call.message.message_id)
317328

318329

319330
@connect_defer_close_db
@@ -864,19 +875,6 @@ def get_str_with_group_users(db_connection, telegram_id: int, with_owner: bool)
864875
return res
865876

866877

867-
def build_diagram(diagram_type: int, chat_id: int, telegram_id: int | None, group_id: int | None):
868-
"""
869-
:param diagram_type:
870-
0 - по запросившему пользователю
871-
1 - по группе
872-
2 - по конкретному пользователю (доступно только владельцу группы)
873-
:param chat_id:
874-
:param telegram_id:
875-
:param group_id:
876-
"""
877-
pass
878-
879-
880878
@connect_defer_close_db
881879
def user_is_registered(db_connection, telegram_id: int) -> bool:
882880
"""

budget_graph/build_project.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def drop_tables_in_db() -> None:
2121
def create_directories() -> None:
2222
try:
2323
makedirs('csv_tables', exist_ok=True)
24+
makedirs('graphs', exist_ok=True)
2425
makedirs('logs', exist_ok=True)
2526
# pylint: disable=broad-exception-caught
2627
except Exception as err:

budget_graph/db_manager.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,28 @@ def get_group_owner_username_by_group_id(self, group_id: int) -> str:
381381
except (DatabaseError, TypeError) as err:
382382
logger_database.error(f"[DB_QUERY] {str(err)}, "
383383
f"group id: {group_id}")
384-
return ""
384+
return ''
385+
386+
def get_data_for_plot_builder(
387+
self,
388+
telegram_id: int,
389+
diagram_type: int,
390+
dates: list | tuple = tuple([None, None])
391+
) -> dict[str, tuple]:
392+
try:
393+
with self.__conn as conn:
394+
with conn.cursor() as cur:
395+
cur.execute(read_sql_file('get_data_for_plot_builder'), {
396+
'telegram_id': telegram_id, 'diagram_type': diagram_type,
397+
'start_date': dates[0], 'end_date': dates[1]
398+
})
399+
return {item[0]: (item[1], item[2]) for item in cur.fetchall()}
400+
401+
except (DatabaseError, TypeError) as err:
402+
logger_database.error(f"[DB_QUERY] {str(err)}, "
403+
f"telegram_id: {telegram_id}, diagram_type: {diagram_type}, "
404+
f"dates: {dates}, start_date: {dates[0]}, end_date: {dates[1]}")
405+
return {}
385406

386407
def get_group_owner_telegram_id_by_group_id(self, group_id: int) -> int:
387408
try:

budget_graph/localization/de.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,6 @@
139139
"budget_diagram_for_group": "Graph gruppieren",
140140
"specific_user_budget_diagram": "Diagramm nach bestimmtem Benutzer",
141141
"choose_diagram_type": "Wählen Sie einen verfügbaren Diagrammtyp aus:",
142-
"wait_diagram": "🛠 Wir erstellen bereits ein Diagramm. Bitte warten..."
142+
"wait_diagram": "🛠 Wir erstellen bereits ein Diagramm. Bitte warten...",
143+
"feature_uuid_filename": "Anwendungs-ID (Name der zukünftigen Datei)"
143144
}

budget_graph/localization/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,6 @@
139139
"budget_diagram_for_group": "Group graph",
140140
"specific_user_budget_diagram": "Graph by specific user",
141141
"choose_diagram_type": "Select an available graph type:",
142-
"wait_diagram": "🛠 We are already building a graph, please wait..."
142+
"wait_diagram": "🛠 We are already building a graph, please wait...",
143+
"feature_uuid_filename": "Application ID (name of future file)"
143144
}

budget_graph/localization/es.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,6 @@
139139
"budget_diagram_for_group": "Gráfico de grupo",
140140
"specific_user_budget_diagram": "Gráfico por usuario específico",
141141
"choose_diagram_type": "Seleccionar un tipo de gráfico disponible:",
142-
"wait_diagram": "🛠 Ya estamos creando un gráfico, por favor espere..."
142+
"wait_diagram": "🛠 Ya estamos creando un gráfico, por favor espere...",
143+
"feature_uuid_filename": "ID de la aplicación (nombre del archivo futuro)"
143144
}

budget_graph/localization/fr.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,6 @@
139139
"budget_diagram_for_group": "Graphique de groupe",
140140
"specific_user_budget_diagram": "Graphique par utilisateur spécifique",
141141
"choose_diagram_type": "Sélectionner un type de graphique disponible:",
142-
"wait_diagram": "🛠 Nous créons déjà un graphique, veuillez patienter..."
142+
"wait_diagram": "🛠 Nous créons déjà un graphique, veuillez patienter...",
143+
"feature_uuid_filename": "ID de l'application (nom du futur fichier)"
143144
}

budget_graph/localization/is.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,6 @@
139139
"budget_diagram_for_group": "Hópgraf",
140140
"specific_user_budget_diagram": "Línurit eftir tiltekinn notanda",
141141
"choose_diagram_type": "Veldu tiltæka línuritsgerð:",
142-
"wait_diagram": "🛠 Við erum nú þegar að smíða línurit, vinsamlegast bíðið..."
142+
"wait_diagram": "🛠 Við erum nú þegar að smíða línurit, vinsamlegast bíðið...",
143+
"feature_uuid_filename": "Auðkenni umsóknar (nafn framtíðarskráar)"
143144
}

budget_graph/localization/kk.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,6 @@
139139
"budget_diagram_for_group": "Топтық диаграмма",
140140
"specific_user_budget_diagram": "Нақты пайдаланушының графигі",
141141
"choose_diagram_type": "Қол жетімді график түрін таңдаңыз:",
142-
"wait_diagram": "🛠 Біз график құрастырып жатырмыз, күте тұрыңыз..."
142+
"wait_diagram": "🛠 Біз график құрастырып жатырмыз, күте тұрыңыз...",
143+
"feature_uuid_filename": "Қолданба идентификаторы (болашақ файлдың атауы)"
143144
}

budget_graph/localization/pt.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,6 @@
139139
"budget_diagram_for_group": "Gráfico de grupo",
140140
"specific_user_budget_diagram": "Gráfico por utilizador específico",
141141
"choose_diagram_type": "Selecione um tipo de gráfico disponível:",
142-
"wait_diagram": "🛠 Já estamos a construir um gráfico, aguarde..."
142+
"wait_diagram": "🛠 Já estamos a construir um gráfico, aguarde...",
143+
"feature_uuid_filename": "ID da aplicação (nome do ficheiro futuro)"
143144
}

budget_graph/localization/ru.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,6 @@
139139
"budget_diagram_for_group": "График группы",
140140
"specific_user_budget_diagram": "График по конкретному пользователю",
141141
"choose_diagram_type": "Выберите доступный тип диаграммы:",
142-
"wait_diagram": "🛠 Уже строим график, ожидайте..."
142+
"wait_diagram": "🛠 Уже строим график, ожидайте...",
143+
"feature_uuid_filename": "ID заявки (имя будущего файла)"
143144
}

budget_graph/plot_builder.py

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,56 @@
1+
from sys import path as sys_path
12
from os import getenv
23
from uuid import UUID
34
from requests import post
45
from dotenv import load_dotenv
56

7+
sys_path.append('../')
8+
from budget_graph.db_manager import connect_defer_close_db
9+
610
load_dotenv() # Load environment variables from .env file
711
host = getenv('PLOT_BUILDER_HOST')
812
port = getenv('PLOT_BUILDER_PORT')
913

1014

11-
def send_report_request(data: dict[str, tuple | list], uuid: UUID | str) -> bool | None:
15+
class Reports:
16+
"""
17+
TODO
18+
"""
19+
await_list = {}
20+
21+
@staticmethod
22+
def send_report_request(
23+
chat_id: int, data: dict[str, tuple | list], uuid: UUID | str
24+
) -> bool | None:
25+
"""
26+
:param chat_id:
27+
:param data: {"username_1": (float(income sum), float(expense sum)), "username_2": etc.}
28+
:param uuid: uuid4()
29+
Sending a request with data to the server deployed on the main application machine (local server)
30+
"""
31+
if not isinstance(uuid, (UUID, str)) or not data or not all(len(elem) == 2 for elem in data.values()):
32+
return False
33+
34+
json_data = {
35+
"data": data,
36+
"uuid": str(uuid)
37+
}
38+
status: bool = post(f'http://{host}:{port}/generate', json=json_data).status_code == 200
39+
40+
if status:
41+
Reports.await_list[uuid] = chat_id
42+
return True
43+
else:
44+
return False
45+
46+
47+
@connect_defer_close_db
48+
def build_diagram(db_connection, chat_id: int, telegram_id: int, uuid: UUID, diagram_type: int) -> bool:
49+
"""
50+
diagram_type:
51+
0 - по запросившему пользователю
52+
1 - по группе
53+
2 - по конкретному пользователю (доступно только владельцу группы)
1254
"""
13-
:param data: {"username_1": (float(income sum), float(expense sum)), "username_2": etc.}
14-
:param uuid: uuid4()
15-
Sending a request with data to the server deployed on the main application machine (local server) """
16-
if not isinstance(uuid, (UUID, str)) or not data or not all(len(elem) == 2 for elem in data.values()):
17-
return
18-
19-
json_data = {
20-
"data": data,
21-
"uuid": str(uuid)
22-
}
23-
return post(f'http://{host}:{port}/generate', json=json_data).status_code == 200
55+
data: dict[str, tuple] = db_connection.get_data_for_plot_builder(telegram_id, diagram_type)
56+
return Reports.send_report_request(chat_id, data, uuid) if data else None
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
WITH
2+
3+
usernames AS (
4+
SELECT
5+
users."username"
6+
FROM
7+
"budget_graph"."users_groups" users_groups
8+
JOIN "budget_graph"."users" users ON users."telegram_id" = users_groups."telegram_id"
9+
WHERE
10+
users_groups."group_id" = (SELECT "group_id" FROM "budget_graph"."users_groups" WHERE "telegram_id" = %(telegram_id)s::bigint)
11+
AND
12+
(
13+
%(diagram_type)s::smallint = 0 AND users."telegram_id" = %(telegram_id)s::bigint
14+
OR
15+
%(diagram_type)s::smallint = 1
16+
)
17+
)
18+
19+
SELECT
20+
"username",
21+
SUM(CASE WHEN "transfer" > 0 THEN "transfer" ELSE 0 END) "incomeSum",
22+
SUM(CASE WHEN "transfer" < 0 THEN "transfer" ELSE 0 END) "expenseSum"
23+
FROM
24+
"budget_graph"."monetary_transactions"
25+
WHERE
26+
"username" = ANY(SELECT "username" FROM usernames)
27+
AND
28+
(
29+
(
30+
%(start_date)s::date IS NULL AND %(end_date)s::date IS NULL
31+
)
32+
OR
33+
(
34+
%(start_date)s::date IS NOT NULL AND %(end_date)s::date IS NOT NULL
35+
AND
36+
"record_date" BETWEEN %(start_date)s::date AND %(end_date)s::date
37+
)
38+
OR
39+
(
40+
%(start_date)s::date IS NOT NULL AND %(end_date)s::date IS NULL
41+
AND
42+
"record_date" >= %(start_date)s::date
43+
)
44+
OR
45+
(
46+
%(start_date)s::date IS NULL AND %(end_date)s::date IS NOT NULL
47+
AND
48+
"record_date" <= %(end_date)s::date
49+
)
50+
)
51+
GROUP BY "username"

go-graph-server/builder.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ func createReport(data map[string][2]float32, uuid string, ch chan string) {
4242
bar.AddSeries("Income", compositionDataColumns(incomeElements)).
4343
AddSeries("Expense", compositionDataColumns(expenseElements))
4444

45-
fileName := fmt.Sprintf("%s.html", uuid)
46-
f, err := os.Create(fileName)
45+
PathFilename := fmt.Sprintf("../budget_graph/graphs/%s.html", uuid)
46+
f, err := os.Create(PathFilename)
4747
if err != nil {
4848
panic(err)
4949
}

0 commit comments

Comments
 (0)