Skip to content

Commit

Permalink
feat: reorganize sidebar, add organization page, integrate codemirror…
Browse files Browse the repository at this point in the history
… plugin
  • Loading branch information
netomi committed Feb 15, 2024
1 parent f58f689 commit 8b03af7
Show file tree
Hide file tree
Showing 17 changed files with 11,487 additions and 87 deletions.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ repos:
hooks:
- id: pyupgrade
args: ["--py310-plus"]
exclude: 'models.py'
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.9.0.6
hooks:
Expand Down
4 changes: 4 additions & 0 deletions otterdog/webapp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ def status_color(status):
case _:
return "info"

@app.template_filter("is_dict")
def is_dict(value):
return isinstance(value, dict)


def create_app(app_config: AppConfig):
app = Quart(app_config.QUART_APP)
Expand Down
8 changes: 4 additions & 4 deletions otterdog/webapp/api/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@
from otterdog.webapp.db.service import (
get_configuration_by_github_id,
get_configuration_by_project_name,
get_organizations,
get_installations,
)

from . import blueprint


@blueprint.route("/organizations")
async def organizations():
orgs = await get_organizations()
result = list(map(lambda x: x.model_dump_json(include={"github_id", "project_name"}), orgs))
return result
installations = await get_installations()
result = list(map(lambda x: x.model_dump(include={"github_id", "project_name"}), installations))
return jsonify(result)


@blueprint.route("/organizations/<github_id>")
Expand Down
15 changes: 8 additions & 7 deletions otterdog/webapp/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from datetime import datetime
from enum import Enum
from typing import Optional

from odmantic import Field, Index, Model

Expand All @@ -27,11 +28,11 @@ def __str__(self) -> str:

class InstallationModel(Model):
github_id: str = Field(primary_field=True)
project_name: str | None = Field(unique=True, index=True)
project_name: Optional[str] = Field(unique=True, index=True)
installation_id: int = Field(index=True, default=0)
installation_status: InstallationStatus
config_repo: str | None = None
base_template: str | None = None
config_repo: Optional[str] = None
base_template: Optional[str] = None


class TaskStatus(str, Enum):
Expand All @@ -49,14 +50,14 @@ class TaskModel(Model):
repo_name: str
pull_request: int = 0
status: TaskStatus = TaskStatus.CREATED
log: str | None = None
log: Optional[str] = None
created_at: datetime = Field(index=True, default_factory=current_utc_time)
updated_at: datetime = Field(default_factory=current_utc_time)


class ConfigurationModel(Model):
github_id: str = Field(primary_field=True)
project_name: str | None = Field(unique=True, index=True)
project_name: Optional[str] = Field(unique=True, index=True)
config: dict
sha: str

Expand Down Expand Up @@ -86,8 +87,8 @@ class PullRequestModel(Model):
pull_request: int
status: PullRequestStatus = Field(index=True)

valid: bool | None = None
in_sync: bool | None = None
valid: Optional[bool] = None
in_sync: Optional[bool] = None
requires_manual_apply: bool = False
apply_status: ApplyStatus = Field(index=True, default=ApplyStatus.NOT_APPLIED)

Expand Down
8 changes: 4 additions & 4 deletions otterdog/webapp/db/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ async def update_installations() -> None:

await mongo.odm.save(model)

for installation in await get_active_organizations():
for installation in await get_active_installations():
configuration_model = await get_configuration_by_github_id(installation.github_id)
if configuration_model is None:
from otterdog.webapp.tasks.fetch_all_pull_requests import (
Expand Down Expand Up @@ -169,15 +169,15 @@ async def get_installation(installation_id: int) -> InstallationModel | None:
return await mongo.odm.find_one(InstallationModel, InstallationModel.installation_id == installation_id)


async def get_all_organization_count() -> int:
async def get_all_installations_count() -> int:
return await mongo.odm.count(InstallationModel)


async def get_organizations() -> list[InstallationModel]:
async def get_installations() -> list[InstallationModel]:
return await mongo.odm.find(InstallationModel, sort=InstallationModel.project_name)


async def get_active_organizations() -> list[InstallationModel]:
async def get_active_installations() -> list[InstallationModel]:
return await mongo.odm.find(
InstallationModel, InstallationModel.installation_status == InstallationStatus.INSTALLED
)
Expand Down
109 changes: 83 additions & 26 deletions otterdog/webapp/home/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@
# SPDX-License-Identifier: EPL-2.0
# *******************************************************************************

import json
from typing import Any

from quart import current_app, redirect, render_template, request, url_for
from werkzeug.routing import BuildError

from otterdog.utils import associate_by_key
from otterdog.webapp.db.service import (
get_active_organizations,
get_active_installations,
get_configuration_by_project_name,
get_configurations,
get_installations,
get_merged_pull_requests,
get_open_or_incomplete_pull_requests,
get_open_or_incomplete_pull_requests_count,
get_organizations,
get_tasks,
)
from otterdog.webapp.tasks.fetch_all_pull_requests import FetchAllPullRequestsTask
Expand All @@ -32,26 +36,42 @@ def route_default():

@blueprint.route("/index")
async def index():
orgs = await get_organizations()
configs = await get_configurations()
configs_by_key = associate_by_key(configs, lambda x: x.github_id)
return await render_template(
"home/index.html",
segments=get_segments(request),
org_count=len(orgs),
installations = await get_installations()
configurations = await get_configurations()
configurations_by_key = associate_by_key(configurations, lambda x: x.github_id)
return await render_home_template(
"index.html",
pull_request_count=await get_open_or_incomplete_pull_requests_count(),
organizations=orgs,
configurations=configs_by_key,
installations=installations,
configurations=configurations_by_key,
)


@blueprint.route("/projects/<project_name>")
async def project(project_name: str):
config = await get_configuration_by_project_name(project_name)

if config is None:
return await render_template("home/page-404.html"), 404

from otterdog.models.github_organization import GitHubOrganization

github_organization = GitHubOrganization.from_model_data(config.config)

return await render_home_template(
"organization.html",
project_name=project_name,
github_id=config.github_id,
config=config,
org_settings=json.dumps(github_organization.settings.to_model_dict(False, False), indent=2, ensure_ascii=False),
)


@blueprint.route("/organizations")
@blueprint.route("/admin/organizations")
async def organizations():
orgs = await get_organizations()
return await render_template(
"home/organizations.html",
segments=get_segments(request),
organizations=orgs,
return await render_home_template(
"organizations.html",
installations=await get_installations(),
)


Expand All @@ -60,9 +80,8 @@ async def pullrequests():
open_pull_requests = await get_open_or_incomplete_pull_requests()
merged_pull_requests = await get_merged_pull_requests(100)

return await render_template(
"home/pullrequests.html",
segments=get_segments(request),
return await render_home_template(
"pullrequests.html",
open_pull_requests=open_pull_requests,
merged_pull_requests=merged_pull_requests,
)
Expand All @@ -71,9 +90,8 @@ async def pullrequests():
@blueprint.route("/admin/tasks")
async def tasks():
latest_tasks = await get_tasks(100)
return await render_template(
"home/tasks.html",
segments=get_segments(request),
return await render_home_template(
"tasks.html",
tasks=latest_tasks,
)

Expand All @@ -89,9 +107,21 @@ async def init():

await update_installations()

for org in await get_active_organizations():
current_app.add_background_task(FetchConfigTask(org.installation_id, org.github_id, org.config_repo))
current_app.add_background_task(FetchAllPullRequestsTask(org.installation_id, org.github_id, org.config_repo))
for installation in await get_active_installations():
current_app.add_background_task(
FetchConfigTask(
installation.installation_id,
installation.github_id,
installation.config_repo,
)
)
current_app.add_background_task(
FetchAllPullRequestsTask(
installation.installation_id,
installation.github_id,
installation.config_repo,
)
)

return {}, 200

Expand Down Expand Up @@ -119,7 +149,34 @@ def get_segments(request):
if len(segments) == 1 and segments[0] == "":
segments = ["index"]

segments = list(filter(lambda x: x, segments))
return segments

except: # noqa: E722
return None


async def get_project_navigation():
installations = await get_active_installations()

navigation = {}

for installation in installations:
levels = installation.project_name.split(".", 2)
if len(levels) == 1:
navigation[levels[0]] = installation
else:
curr = navigation.get(levels[0], {})
curr.update({levels[1]: installation})
navigation[levels[0]] = curr

return navigation


async def render_home_template(template_name: str, **context: Any) -> str:
return await render_template(
f"home/{template_name}",
segments=get_segments(request),
projects=await get_project_navigation(),
**context,
)
Loading

0 comments on commit 8b03af7

Please sign in to comment.