version-0.2.0

This commit is contained in:
2024-01-06 14:25:35 +03:00
parent bc05b93c47
commit 908529b5bb
26 changed files with 185 additions and 153 deletions

79
utils/graph.py Normal file
View File

@@ -0,0 +1,79 @@
import logging
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
# Define SVG code generation function with member_id parameter
def generate_chart(members, member_id=None):
if not member_id:
member_id = members[0]["id"]
# Define some constants for layout
node_radius = 30
node_spacing = 80
node_y = 100
parent_y_offset = 50
child_y_offset = 150
# Find the specified member and its descendants
member = None
descendants = set()
for m in members:
if m["id"] == member_id:
member = m
descendants.add(member_id)
break
# calculate only if links are founded
if member:
stack = member["children"].copy()
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:
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
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
for child_id in m["children"]:
if child_id in descendants:
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
# Finish the SVG code
svg_code += "</svg>"
return svg_code.encode("utf-8")
else:
logger.error(f"no connections in graph for {member_id}")
logger.debug(members)
return ""

21
utils/mention.py Normal file
View File

@@ -0,0 +1,21 @@
def escape_username(username):
# Replace any non-ASCII and non-alphanumeric characters with underscores
return "".join(c if c.isalnum() or c.isspace() else "-" for c in username)
# generates a mention from standard telegram web json 'from' field
# using HTML markup
def mention(user):
uid, identity, username = userdata_extract(user)
identity = escape_username(identity)
return f'<a href="tg://user?id={uid}">{identity} {username}</a>'
def userdata_extract(user):
ln = " " + user.get('last_name', "") if user.get('last_name', "") else ""
identity = f"{user['first_name']}{ln}"
uid = user["id"]
username = user.get("username", "")
if username:
username = f"(@{username})"
return uid, identity, username