Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 42 additions & 16 deletions tools/generate_open_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from pathlib import Path
from textwrap import shorten
from typing import TypedDict
import html

from jinja2 import Environment, FileSystemLoader

Expand All @@ -37,7 +38,10 @@
# anchor on the corresponding "About …" page on docs.flipper.net/one.
SECTIONS: list[_Section] = [
{
"slug": "flipperdevices/flipperone-hardware",
"slug": [

@NickVolynkin NickVolynkin Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename it so it better reflects the content. slugs or even repos

"flipperdevices/flipperone-hardware",
"flipperdevices/flipperone-debug-probe",
],
"title": "Hardware",
"emoji": "🔌",
"description": "Electrical hardware development: printed circuit boards (PCBs), antennas, and everything related to the electrical design.",
Expand All @@ -46,7 +50,7 @@
"github_repo": "https://github.com/flipperdevices/flipperone-hardware",
},
{
"slug": "flipperdevices/flipperone-mechanics",
"slug": ["flipperdevices/flipperone-mechanics"],
"title": "Mechanics",
"emoji": "⚙️",
"description": "Mechanical design: enclosures, buttons, connectors, and everything related to the physical construction.",
Expand All @@ -55,7 +59,14 @@
"github_repo": "https://github.com/flipperdevices/flipperone-mechanics",
},
{
"slug": "flipperdevices/flipperone-linux-build-scripts",
"slug": [
"flipperdevices/flipperone-linux-build-scripts",
"flipperdevices/flipper-linux-kernel",
"flipperdevices/u-boot",
"flipperdevices/rkbin",
"flipperdevices/rockchip-linux",

@NickVolynkin NickVolynkin Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mirror repository that can't have issues or PRs. Let's remove it.

Suggested change
"flipperdevices/rockchip-linux",

"flipperdevices/bsb-protobuf",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a part of Flipper One development.

Suggested change
"flipperdevices/bsb-protobuf",

],
"title": "Linux (CPU Software)",
"emoji": "🐧",
"description": "Build system for the Linux firmware: U-Boot, kernel, root filesystem, and bootable images for the RK3576.",
Expand All @@ -64,7 +75,7 @@
"github_repo": "https://github.com/flipperdevices/flipperone-linux-build-scripts",
},
{
"slug": "flipperdevices/flipperone-mcu-firmware",
"slug": ["flipperdevices/flipperone-mcu-firmware"],
"title": "MCU Firmware",
"emoji": "🕹️",
"description": "Firmware for the RP2350 co-processor: FreeRTOS, display, buttons, touchpad, LEDs, and power management.",
Expand All @@ -73,7 +84,7 @@
"github_repo": "https://github.com/flipperdevices/flipperone-mcu-firmware",
},
{
"slug": "flipperdevices/flipperone-ui",
"slug": ["flipperdevices/flipperone-ui"],
"title": "User Interface",
"emoji": "🎨",
"description": "User interface design: operating modes, on-screen graphics, device prints, and FlipCTL.",
Expand All @@ -82,7 +93,7 @@
"github_repo": "https://github.com/flipperdevices/flipperone-ui",
},
{
"slug": "flipperdevices/flipperone-testing",
"slug": ["flipperdevices/flipperone-testing"],
"title": "Testing",
"emoji": "🧪",
"description": "Hardware validation and test scripts: temperature monitoring, power, CPU, GPU, network, and disk tests.",
Expand All @@ -91,14 +102,23 @@
"github_repo": "https://github.com/flipperdevices/flipperone-testing",
},
{
"slug": "flipperdevices/flipperone-docs",
"slug": ["flipperdevices/flipperone-docs"],
"title": "Docs",
"emoji": "📚",
"description": "Developer documentation published at docs.flipper.net/one.",
"task_tracker": "https://github.com/orgs/flipperdevices/projects/10",
"contribution_guide": "https://docs.flipper.net/one/resources/about-docs#how-to-contribute",
"github_repo": "https://github.com/flipperdevices/flipperone-docs",
},
{
"slug": ["flipperdevices/flipctl", "flipperdevices/flipctl-fonts"],
"title": "FlipCTL",
"emoji": "🎛️",
"description": "Command-line tool and companion fonts for managing and configuring Flipper One.",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite. FlipCTL is a UI framework for building Flipper-native applications.

Suggested change
"description": "Command-line tool and companion fonts for managing and configuring Flipper One.",
"description": "UI framework for embedded Linux systems"

"task_tracker": "https://github.com/orgs/flipperdevices/projects/12",
"contribution_guide": "https://docs.flipper.net/one/user-interface/about#how-to-contribute",
Comment on lines +118 to +119

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"task_tracker": "https://github.com/orgs/flipperdevices/projects/12",
"contribution_guide": "https://docs.flipper.net/one/user-interface/about#how-to-contribute",
"task_tracker": "TBD",
"contribution_guide": "https://blog.flipper.net/flipctl-our-gui-framework-for-embedded-linux-systems/#how-you-can-join",

"github_repo": "https://github.com/flipperdevices/flipctl",
},
]

LABEL = "help wanted"
Expand All @@ -112,7 +132,7 @@ class _Repository(TypedDict):
nameWithOwner: str

class _Section(TypedDict):
slug: str
slug: str | list[str]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you've replaced them all with lists, so there is no need for plain str here

title: str
emoji: str
description: str
Expand Down Expand Up @@ -147,7 +167,7 @@ def fetch_issues() -> list[_Issue]:
"--owner", ORG,
"--label", LABEL,
"--state", "open",
"--limit", "200",
"--limit", "1000",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's some AI leftover. In the PR description, it says

The original --limit 200 was not the problem — only 18 total "help wanted" issues exist across the entire flipperdevices org. The real issue was that SECTIONS was missing multiple repos:

which also looks like AI's reply to an iteration of debugging.

Your contribution is reviewed by humans. Please read and check the PR yourself, even when you use AI.

"--json", "repository,title,number,url,body,commentsCount",
],
capture_output=True, text=True, check=True,
Expand Down Expand Up @@ -191,12 +211,7 @@ def make_summary(body: str, max_len: int = 120) -> str:


def html_escape(text: str) -> str:
return (
text.replace("&", "&")
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace('"', "&quot;")
)
return html.escape(text, quote=True)

@NickVolynkin NickVolynkin Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is likely a good change, but it's out of scope for this PR. Could you please extract it to another PR? A separate commit in #403 would be fine too.



def archbee_timestamp(dt: datetime) -> str:
Expand All @@ -223,6 +238,13 @@ def _content_equal_ignoring_updated_at(a: str, b: str) -> bool:
return pattern.sub("updatedAt: -", a) == pattern.sub("updatedAt: -", b)


def _match_section_slug(slug: str | list[str], repo_full: str) -> bool:

@NickVolynkin NickVolynkin Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have full control over the project data, so there's no real need to add this str | list[str] flexibility. Let's leave just list[str]. And rename slug, repo_full to repos, repo.

"""Check if a repo name matches a section slug (single name or list)."""
if isinstance(slug, list):
return repo_full in slug
return repo_full == slug


def _build_template_sections(issues: list[_Issue]) -> list[_DisplaySection]:
"""Prepare section and issue data for the Open Tasks Jinja template."""
by_repo: dict[str, list[_Issue]] = {}
Expand All @@ -232,6 +254,10 @@ def _build_template_sections(issues: list[_Issue]) -> list[_DisplaySection]:

sections: list[_DisplaySection] = []
for section in SECTIONS:
matched_issues: list[_Issue] = []
for repo_full, repo_issues in by_repo.items():
if _match_section_slug(section["slug"], repo_full):
matched_issues.extend(repo_issues)
rendered_issues: list[_DisplayIssue] = [
{
"number": issue["number"],
Expand All @@ -240,7 +266,7 @@ def _build_template_sections(issues: list[_Issue]) -> list[_DisplaySection]:
"summary": html_escape(make_summary(issue.get("body", ""))),
"commentsCount": issue.get("commentsCount", 0),
}
for issue in by_repo.get(section["slug"], [])
for issue in matched_issues
]
rendered_issues.sort(key=lambda i: i["number"], reverse=True)
sections.append({**section, "issues": rendered_issues})
Expand Down