fix-graph

This commit is contained in:
2023-09-18 14:26:42 +03:00
parent 19d0984466
commit 9bb5282307
5 changed files with 69 additions and 50 deletions

View File

@@ -1,10 +1,13 @@
## [0.0.12] ## [0.0.12]
- множество исправлений в роутинге сообщений
- исправления в коммандах /ask и /my - исправления в коммандах /ask и /my
- исправление обработки случая без фото - исправление обработки случая без фото
- добавлен автомат состояний - добавлен автомат состояний
- добавлена возможность высказаться "на кругу" без одобрения заявки - добавлена возможность высказаться "на кругу" без одобрения заявки
- асинхронное api - асинхронное api
## [0.0.11] ## [0.0.11]
- отображение одобренности заявки на кнопке - отображение одобренности заявки на кнопке
@@ -25,6 +28,7 @@
- исправлены ошибки - исправлены ошибки
- добавлена сервисная команда для показа потерянных заявок - добавлена сервисная команда для показа потерянных заявок
## [0.0.9] ## [0.0.9]
- исправление логики show_request_msg - исправление логики show_request_msg
@@ -33,7 +37,8 @@
- kick для тех, от кого отказались поручители - kick для тех, от кого отказались поручители
- bugfix: нестандартные символы в имени - bugfix: нестандартные символы в имени
## [0.0.8]
## [0.0.8]
- генерация древовидного графа, с опорой на одного участника - генерация древовидного графа, с опорой на одного участника
- /my для просмотра и изменения связей - /my для просмотра и изменения связей
@@ -55,7 +60,7 @@
- убраны кнопки ответов - убраны кнопки ответов
## [0.0.5] ## [0.0.5]
- добавлена возможность поручиться - добавлена возможность поручиться
- обычные сообщения в общем чате больше никак не обрабатываются - обычные сообщения в общем чате больше никак не обрабатываются
@@ -82,7 +87,7 @@
## [0.0.2] ## [0.0.2]
- добавлена функция для обратной связи - добавлена функция для обратной связи
- исправлена ошибка повторной регистрации хука - исправлена ошибка повторной регистрации хука
## [0.0.1] ## [0.0.1]
@@ -91,4 +96,4 @@
- настройки на основе переменных среды - настройки на основе переменных среды
- функция приветственного сообщения с кнопками - функция приветственного сообщения с кнопками
- ограничения для новоприбывших и неверно отвечающих - ограничения для новоприбывших и неверно отвечающих
- распознание приветствия в тексте - распознание приветствия в тексте

View File

@@ -42,6 +42,6 @@ async def handle_left(msg):
# удаление сообщения с кнопкой в этом чате # удаление сообщения с кнопкой в этом чате
prev_msg = storage.get(f"btn-{chat_id}-{member_id}") prev_msg = storage.get(f"btn-{chat_id}-{member_id}")
if prev_msg: if prev_msg:
r = await delete_message(chat_id, prev_msg["id"]) r = await delete_message(chat_id, prev_msg["message_id"])
logger.debug(r) logger.debug(r)
storage.remove(f"btn-{chat_id}-{member_id}") storage.remove(f"btn-{chat_id}-{member_id}")

View File

@@ -1,4 +1,4 @@
from bot.config import FEEDBACK_CHAT_ID from config import FEEDBACK_CHAT_ID
from storage import scan, Profile from storage import scan, Profile
from api import approve_chat_join_request, kick_member, send_message from api import approve_chat_join_request, kick_member, send_message
from handlers.callback_vouch import update_button from handlers.callback_vouch import update_button

View File

@@ -5,7 +5,8 @@ import signal # Import the signal module
from aiogram import Bot, Dispatcher, Router from aiogram import Bot, Dispatcher, Router
from aiogram.enums import ParseMode from aiogram.enums import ParseMode
from aiogram.filters import CommandStart, Command from aiogram.filters import CommandStart, Command
from aiogram.types import Message, ChatJoinRequest, CallbackQuery, ChatMemberUpdated, ChatMemberLeft from aiogram.types import Message, ChatJoinRequest, CallbackQuery, ChatMemberUpdated, ChatMemberLeft, ChatMemberBanned
from aiogram.enums import ChatMemberStatus
from config import BOT_TOKEN from config import BOT_TOKEN
from handlers.routing import handle_routing from handlers.routing import handle_routing
from handlers.callback_unlink import handle_unlink from handlers.callback_unlink import handle_unlink
@@ -66,15 +67,16 @@ async def chat_members_change(update: ChatMemberUpdated):
msg["chat"] = vars(update.chat) msg["chat"] = vars(update.chat)
msg["from"] = vars(update.from_user) msg["from"] = vars(update.from_user)
logger.debug(msg) logger.debug(msg)
if update.old_chat_member == ChatMemberLeft: if update.old_chat_member.status == ChatMemberStatus.KICKED:
# был забанен, удаляем все поручения
await handle_left(msg) await handle_left(msg)
else: else:
await handle_join(msg) await handle_join(msg)
async def main() -> None: async def main() -> None:
# connect router
dp.include_router(router) dp.include_router(router)
# storage revalidation # storage revalidation
await handle_startup() await handle_startup()
# Start event dispatching # Start event dispatching

View File

@@ -1,3 +1,8 @@
import logging
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
# Define SVG code generation function with member_id parameter # Define SVG code generation function with member_id parameter
def generate_chart(members, member_id=None): def generate_chart(members, member_id=None):
if not member_id: if not member_id:
@@ -18,50 +23,57 @@ def generate_chart(members, member_id=None):
descendants.add(member_id) descendants.add(member_id)
break break
stack = member["children"].copy() # calculate only if links are founded
while stack: if member:
child_id = stack.pop() stack = member["children"].copy()
descendants.add(child_id) while stack:
child_id = stack.pop()
descendants.add(child_id)
for m in members:
if m["id"] == child_id:
stack.extend(m["children"])
break
# Define the x position for each member
x_positions = {}
x_positions[member_id] = 0
for i, m in enumerate(members):
if m["id"] in descendants:
x_positions[m["id"]] = (i * node_spacing) + node_radius
# Start building the SVG code
svg_width = (len(descendants) * node_spacing) + (2 * node_radius)
svg_height = 200
svg_code = f'<svg width="{svg_width}" height="{svg_height}">'
# Generate nodes and names for each descendant
for m in members: for m in members:
if m["id"] == child_id: if m["id"] in descendants:
stack.extend(m["children"]) node_x = x_positions[m["id"]]
break node_code = f'<circle cx="{node_x}" cy="{node_y}" r="{node_radius}" stroke="black" stroke-width="2" fill="white"/>'
name_code = f'<text x="{node_x}" y="{node_y}" font-size="16" text-anchor="middle">{m["name"]}</text>'
svg_code += node_code + name_code
# Define the x position for each member # Generate links to parent nodes
x_positions = {} for parent_id in m["parents"]:
x_positions[member_id] = 0 if parent_id in descendants:
for i, m in enumerate(members): parent_x = x_positions[parent_id]
if m["id"] in descendants: link_code = f'<line x1="{node_x}" y1="{node_y - parent_y_offset}" x2="{parent_x}" y2="{node_y}" stroke="black" stroke-width="2"/>'
x_positions[m["id"]] = (i * node_spacing) + node_radius svg_code += link_code
# Start building the SVG code # Generate links to child nodes
svg_width = (len(descendants) * node_spacing) + (2 * node_radius) for child_id in m["children"]:
svg_height = 200 if child_id in descendants:
svg_code = f'<svg width="{svg_width}" height="{svg_height}">' child_x = x_positions[child_id]
link_code = f'<line x1="{node_x}" y1="{node_y + child_y_offset}" x2="{child_x}" y2="{node_y}" stroke="black" stroke-width="2"/>'
svg_code += link_code
# Generate nodes and names for each descendant # Finish the SVG code
for m in members: svg_code += "</svg>"
if m["id"] in descendants:
node_x = x_positions[m["id"]]
node_code = f'<circle cx="{node_x}" cy="{node_y}" r="{node_radius}" stroke="black" stroke-width="2" fill="white"/>'
name_code = f'<text x="{node_x}" y="{node_y}" font-size="16" text-anchor="middle">{m["name"]}</text>'
svg_code += node_code + name_code
# Generate links to parent nodes return svg_code.encode("utf-8")
for parent_id in m["parents"]:
if parent_id in descendants:
parent_x = x_positions[parent_id]
link_code = f'<line x1="{node_x}" y1="{node_y - parent_y_offset}" x2="{parent_x}" y2="{node_y}" stroke="black" stroke-width="2"/>'
svg_code += link_code
# Generate links to child nodes else:
for child_id in m["children"]: logger.error(f"no connections in graph for {member_id}")
if child_id in descendants: logger.debug(members)
child_x = x_positions[child_id] return ""
link_code = f'<line x1="{node_x}" y1="{node_y + child_y_offset}" x2="{child_x}" y2="{node_y}" stroke="black" stroke-width="2"/>'
svg_code += link_code
# Finish the SVG code
svg_code += "</svg>"
return svg_code.encode("utf-8")