This is an automated email from the ASF dual-hosted git repository.

tn pushed a commit to branch add-project-model
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git


The following commit(s) were added to refs/heads/add-project-model by this push:
     new 5840fc7  small improvements
5840fc7 is described below

commit 5840fc7e0b69671682a2efe6cbf4d027add58625
Author: Thomas Neidhart <[email protected]>
AuthorDate: Tue Mar 11 14:06:57 2025 +0100

    small improvements
---
 atr/blueprints/admin/admin.py   | 35 ++++++++++++++++++++---------------
 atr/datasources/apache.py       |  4 ++--
 atr/db/models.py                | 17 ++++++++++++-----
 atr/server.py                   |  2 +-
 atr/templates/pmc-view.html     |  7 ++++++-
 atr/templates/project-view.html | 18 ++++--------------
 6 files changed, 45 insertions(+), 38 deletions(-)

diff --git a/atr/blueprints/admin/admin.py b/atr/blueprints/admin/admin.py
index ac42f68..3f3d716 100644
--- a/atr/blueprints/admin/admin.py
+++ b/atr/blueprints/admin/admin.py
@@ -30,6 +30,7 @@ from werkzeug.wrappers.response import Response
 from asfquart.base import ASFQuartException
 from asfquart.session import read as session_read
 from atr.datasources.apache import (
+    get_active_committee_data,
     get_current_podlings_data,
     get_groups_data,
     get_ldap_projects_data,
@@ -48,7 +49,7 @@ from atr.db.models import (
     Task,
     VotePolicy,
 )
-from atr.db.service import get_pmc_by_name
+from atr.db.service import get_pmc_by_name, get_project_by_name
 
 from . import blueprint
 
@@ -208,6 +209,7 @@ async def admin_projects_update() -> str | Response | 
tuple[Mapping[str, Any], i
 
 
 async def _update_pmcs() -> int:
+    committee_data = await get_active_committee_data()
     ldap_projects = await get_ldap_projects_data()
     podlings_data = await get_current_podlings_data()
     groups_data = await get_groups_data()
@@ -218,10 +220,10 @@ async def _update_pmcs() -> int:
     async with create_async_db_session() as db_session:
         async with db_session.begin():
             # First update PMCs
-            for project in ldap_projects.projects:
-                name = project.name
+            for committee in committee_data.committees:
+                name = committee.name
                 # Skip non-PMC committees
-                if not project.pmc:
+                if not committee.pmc:
                     continue
 
                 # Get or create PMC
@@ -235,6 +237,8 @@ async def _update_pmcs() -> int:
                 committers = groups_data.get(name)
                 pmc.pmc_members = pmc_members if pmc_members is not None else 
[]
                 pmc.committers = committers if committers is not None else []
+                pmc.full_name = committee.display_name
+                pmc.description = committee.description
                 # Ensure this is set for PMCs
                 pmc.is_podling = False
 
@@ -249,20 +253,22 @@ async def _update_pmcs() -> int:
             # Then add PPMCs (podlings)
             for podling_name, podling_data in podlings_data:
                 # Get or create PPMC
-                statement = select(PMC).where(PMC.name == podling_name)
-                ppmc = (await 
db_session.execute(statement)).scalar_one_or_none()
+                ppmc = await get_pmc_by_name(podling_name, db_session)
                 if not ppmc:
                     ppmc = PMC(name=podling_name)
                     db_session.add(ppmc)
 
                 # Update PPMC data from groups.json
-                ppmc.is_podling = True
                 pmc_members = groups_data.get(f"{podling_name}-pmc")
                 committers = groups_data.get(podling_name)
                 ppmc.pmc_members = pmc_members if pmc_members is not None else 
[]
                 ppmc.committers = committers if committers is not None else []
                 # Use PPMC members as release managers
                 ppmc.release_managers = ppmc.pmc_members
+                ppmc.full_name = podling_data.name
+                ppmc.description = podling_data.description
+                ppmc.parent_pmc = await get_pmc_by_name(podling_data.pmc, 
db_session)  # type: ignore
+                ppmc.is_podling = True
 
                 updated_count += 1
 
@@ -284,19 +290,18 @@ async def _update_pmcs() -> int:
 
             for project_name, project_status in projects_data:
                 # Get or create Project
-                my_statement = select(Project).where(Project.name == 
project_name)
-                aproject = (await 
db_session.execute(my_statement)).scalar_one_or_none()
-                if not aproject:
-                    aproject = Project(name=project_name)
-                    db_session.add(aproject)
+                project = await get_project_by_name(project_name, db_session)
+                if not project:
+                    project = Project(name=project_name)
+                    db_session.add(project)
 
-                pmc = await get_pmc_by_name(project_status.pmc)
+                pmc = await get_pmc_by_name(project_status.pmc, db_session)
                 if pmc is None:
                     _LOGGER.error(f"project {project_name} has unknown PMC 
{project_status.pmc}")
                     continue
                 else:
-                    aproject.pmc = pmc
-                    aproject.full_name = project_status.name
+                    project.pmc = pmc  # type: ignore
+                    project.full_name = project_status.name
 
     return updated_count
 
diff --git a/atr/datasources/apache.py b/atr/datasources/apache.py
index 7466d4e..797227a 100644
--- a/atr/datasources/apache.py
+++ b/atr/datasources/apache.py
@@ -78,10 +78,10 @@ class RetiredCommitteeData(BaseModel):
 class Committee(BaseModel):
     name: str
     display_name: str
-    site: str
+    site: str | None
     description: str
     mail_list: str
-    established: str
+    established: str | None
     report: list[str]
     chair: Annotated[list[User], DictToList(key="id")]
     roster_count: int
diff --git a/atr/db/models.py b/atr/db/models.py
index fdea586..fa05a9c 100644
--- a/atr/db/models.py
+++ b/atr/db/models.py
@@ -92,15 +92,24 @@ class PMC(ATRSQLModel, table=True):
     full_name: str | None = sqlmodel.Field(default=None)
     # True if this a podling PPMC
     is_podling: bool = sqlmodel.Field(default=False)
+    description: str | None = sqlmodel.Field(default=None)
 
     # One-to-many: A PMC can have parent PMC, e.g. in the case of a PPMC
     child_pmcs: list["PMC"] = sqlmodel.Relationship(
         sa_relationship_kwargs=dict(
-            backref=sqlalchemy.orm.backref("parent_pmc", remote_side="PMC.id"),
+            backref=sqlalchemy.orm.backref("_parent_pmc", 
remote_side="PMC.id"),
         ),
     )
     parent_pmc_id: int | None = sqlmodel.Field(default=None, 
foreign_key="pmc.id")
 
+    @property
+    async def parent_pmc(self) -> Optional["PMC"]:
+        return await self.awaitable_attrs._parent_pmc  # type: ignore
+
+    @parent_pmc.setter
+    def parent_pmc(self, value: Optional["PMC"]) -> None:
+        self._parent_pmc = value
+
     # One-to-many: A PMC can have multiple projects, each project belongs to 
one PMC
     _projects: list["Project"] = sqlmodel.Relationship(back_populates="_pmc")
 
@@ -126,8 +135,7 @@ class PMC(ATRSQLModel, table=True):
     @property
     def display_name(self) -> str:
         """Get the display name for the PMC/PPMC."""
-        name = self.name if self.full_name is None else self.full_name
-        return f"{name} (PPMC)" if self.is_podling else name
+        return self.name if self.full_name is None else self.full_name
 
 
 class Project(ATRSQLModel, table=True):
@@ -164,8 +172,7 @@ class Project(ATRSQLModel, table=True):
     @property
     def display_name(self) -> str:
         """Get the display name for the Project."""
-        name = self.name if self.full_name is None else self.full_name
-        return f"{name} (podling)" if self.is_podling else name
+        return self.name if self.full_name is None else self.full_name
 
 
 class ProductLine(ATRSQLModel, table=True):
diff --git a/atr/server.py b/atr/server.py
index 1b7adec..14b21fd 100644
--- a/atr/server.py
+++ b/atr/server.py
@@ -30,7 +30,7 @@ from werkzeug.routing import Rule
 import asfquart
 import asfquart.generics
 import asfquart.session
-from asfquart.base import QuartApp, ASFQuartException
+from asfquart.base import ASFQuartException, QuartApp
 from atr.blueprints import register_blueprints
 from atr.config import AppConfig, ConfigMode, get_config, get_config_mode
 from atr.db import create_database
diff --git a/atr/templates/pmc-view.html b/atr/templates/pmc-view.html
index 867d05e..f0ee969 100644
--- a/atr/templates/pmc-view.html
+++ b/atr/templates/pmc-view.html
@@ -165,7 +165,12 @@
     <h3>Projects</h3>
     <div class="card-meta"></div>
     <div class="card-body"></div>
-    {% for project in pmc.projects %}<div class="key-card">{{ 
project.display_name }}</div>{% endfor %}
+    {% for project in pmc.projects %}
+    <div class="key-card">
+      <a href="{{ url_for('root_project_view', name=project.name) }}">
+        {{ project.display_name }}
+      </a>
+    </div>{% endfor %}
   </div>
 
 {% endblock content %}
diff --git a/atr/templates/project-view.html b/atr/templates/project-view.html
index fd3523c..8d09a61 100644
--- a/atr/templates/project-view.html
+++ b/atr/templates/project-view.html
@@ -82,22 +82,12 @@
   <h1>{{ project.display_name | capitalize }}</h1>
 
   <div class="card-header">
-    <h3>PMC members</h3>
+    <h3>PMC</h3>
     <div class="card-meta"></div>
     <div class="card-body">
-      <p>
-        {% for user in project.pmc_members %}{{ user }},{% endfor %}
-      </p>
-    </div>
-  </div>
-
-  <div class="card-header">
-    <h3>Committers</h3>
-    <div class="card-meta"></div>
-    <div class="card-body">
-      <p>
-        {% for user in project.committers %}{{ user }},{% endfor %}
-      </p>
+      <a href="{{ url_for('root_pmc_view', name=project.pmc.name) }}">
+        {{ project.pmc.display_name }}
+      </a>
     </div>
   </div>
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to