dynamic html load (#63)

* dynamic html load
* split by classes
This commit is contained in:
2022-05-20 22:29:36 +03:00
committed by GitHub
parent 375f9fcfb7
commit b1dfafe275
72 changed files with 720 additions and 706 deletions

View File

@@ -101,7 +101,7 @@ class BaseView(View):
Returns:
UserAccess: extracted permission
"""
permission: UserAccess = getattr(cls, f"{request.method.upper()}_PERMISSION", UserAccess.Write)
permission: UserAccess = getattr(cls, f"{request.method.upper()}_PERMISSION", UserAccess.Full)
return permission
async def extract_data(self, list_keys: Optional[List[str]] = None) -> Dict[str, Any]:

View File

@@ -21,9 +21,7 @@ import aiohttp_jinja2
from typing import Any, Dict
from ahriman import version
from ahriman.core.auth.helpers import authorized_userid
from ahriman.core.util import pretty_datetime
from ahriman.models.user_access import UserAccess
from ahriman.web.views.base import BaseView
@@ -34,37 +32,19 @@ class IndexView(BaseView):
It uses jinja2 templates for report generation, the following variables are allowed:
* architecture - repository architecture, string, required
* auth - authorization descriptor, required
* authenticated - alias to check if user can see the page, boolean, required
* control - HTML to insert for login control, HTML string, required
* enabled - whether authorization is enabled by configuration or not, boolean, required
* username - authenticated username if any, string, null means not authenticated
* index_url - url to the repository index, string, optional
* packages - sorted list of packages properties, required
* base, string
* depends, sorted list of strings
* groups, sorted list of strings
* licenses, sorted list of strings
* packages, sorted list of strings
* status, string based on enum value
* status_color, string based on enum value
* timestamp, pretty printed datetime, string
* version, string
* web_url, string
* repository - repository name, string, required
* service - service status properties, required
* status, string based on enum value
* status_color, string based on enum value
* timestamp, pretty printed datetime, string
* version - ahriman version, string, required
Attributes:
GET_PERMISSION(UserAccess): (class attribute) get permissions of self
HEAD_PERMISSION(UserAccess): (class attribute) head permissions of self
"""
GET_PERMISSION = HEAD_PERMISSION = UserAccess.Safe
GET_PERMISSION = HEAD_PERMISSION = UserAccess.Unauthorized
@aiohttp_jinja2.template("build-status.jinja2")
async def get(self) -> Dict[str, Any]:
@@ -74,43 +54,15 @@ class IndexView(BaseView):
Returns:
Dict[str, Any]: parameters for jinja template
"""
# some magic to make it jinja-friendly
packages = [
{
"base": package.base,
"depends": package.depends,
"groups": package.groups,
"licenses": package.licenses,
"packages": list(sorted(package.packages)),
"status": status.status.value,
"status_color": status.status.bootstrap_color(),
"timestamp": pretty_datetime(status.timestamp),
"version": package.version,
"web_url": package.remote.web_url if package.remote is not None else None,
} for package, status in sorted(self.service.packages, key=lambda item: item[0].base)
]
service = {
"status": self.service.status.status.value,
"status_color": self.service.status.status.badges_color(),
"timestamp": pretty_datetime(self.service.status.timestamp),
}
# auth block
auth_username = await authorized_userid(self.request)
authenticated = not self.validator.enabled or self.validator.safe_build_status or auth_username is not None
auth = {
"authenticated": authenticated,
"control": self.validator.auth_control,
"enabled": self.validator.enabled,
"username": auth_username,
}
return {
"architecture": self.service.architecture,
"auth": auth,
"index_url": self.configuration.get("web", "index_url", fallback=None),
"packages": packages,
"repository": self.service.repository.name,
"service": service,
"version": version.__version__,
}

View File

@@ -31,7 +31,7 @@ class AddView(BaseView):
POST_PERMISSION(UserAccess): (class attribute) post permissions of self
"""
POST_PERMISSION = UserAccess.Write
POST_PERMISSION = UserAccess.Full
async def post(self) -> None:
"""

View File

@@ -31,7 +31,7 @@ class RemoveView(BaseView):
POST_PERMISSION(UserAccess): (class attribute) post permissions of self
"""
POST_PERMISSION = UserAccess.Write
POST_PERMISSION = UserAccess.Full
async def post(self) -> None:
"""

View File

@@ -31,7 +31,7 @@ class RequestView(BaseView):
POST_PERMISSION(UserAccess): (class attribute) post permissions of self
"""
POST_PERMISSION = UserAccess.Read
POST_PERMISSION = UserAccess.Reporter
async def post(self) -> None:
"""

View File

@@ -35,7 +35,7 @@ class SearchView(BaseView):
HEAD_PERMISSION(UserAccess): (class attribute) head permissions of self
"""
GET_PERMISSION = HEAD_PERMISSION = UserAccess.Read
GET_PERMISSION = HEAD_PERMISSION = UserAccess.Reporter
async def get(self) -> Response:
"""

View File

@@ -1,71 +0,0 @@
#
# Copyright (c) 2021-2022 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response
from ahriman.models.build_status import BuildStatusEnum
from ahriman.models.user_access import UserAccess
from ahriman.web.views.base import BaseView
class AhrimanView(BaseView):
"""
service status web view
Attributes:
GET_PERMISSION(UserAccess): (class attribute) get permissions of self
HEAD_PERMISSION(UserAccess): (class attribute) head permissions of self
POST_PERMISSION(UserAccess): (class attribute) post permissions of self
"""
GET_PERMISSION = HEAD_PERMISSION = UserAccess.Read
POST_PERMISSION = UserAccess.Write
async def get(self) -> Response:
"""
get current service status
Returns:
Response: 200 with service status object
"""
return json_response(self.service.status.view())
async def post(self) -> None:
"""
update service status
JSON body must be supplied, the following model is used::
{
"status": "unknown", # service status string, must be valid ``BuildStatusEnum``
}
Raises:
HTTPBadRequest: if bad data is supplied
HTTPNoContent: in case of success response
"""
try:
data = await self.extract_data()
status = BuildStatusEnum(data["status"])
except Exception as e:
raise HTTPBadRequest(reason=str(e))
self.service.update_self(status)
raise HTTPNoContent()

View File

@@ -37,7 +37,7 @@ class PackageView(BaseView):
POST_PERMISSION(UserAccess): (class attribute) post permissions of self
"""
DELETE_PERMISSION = POST_PERMISSION = UserAccess.Write
DELETE_PERMISSION = POST_PERMISSION = UserAccess.Full
GET_PERMISSION = HEAD_PERMISSION = UserAccess.Read
async def get(self) -> Response:

View File

@@ -34,7 +34,7 @@ class PackagesView(BaseView):
"""
GET_PERMISSION = HEAD_PERMISSION = UserAccess.Read
POST_PERMISSION = UserAccess.Write
POST_PERMISSION = UserAccess.Full
async def get(self) -> Response:
"""

View File

@@ -17,9 +17,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from aiohttp.web import Response, json_response
from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response
from ahriman import version
from ahriman.models.build_status import BuildStatusEnum
from ahriman.models.counters import Counters
from ahriman.models.internal_status import InternalStatus
from ahriman.models.user_access import UserAccess
@@ -33,9 +34,11 @@ class StatusView(BaseView):
Attributes:
GET_PERMISSION(UserAccess): (class attribute) get permissions of self
HEAD_PERMISSION(UserAccess): (class attribute) head permissions of self
POST_PERMISSION(UserAccess): (class attribute) post permissions of self
"""
GET_PERMISSION = HEAD_PERMISSION = UserAccess.Read
POST_PERMISSION = UserAccess.Full
async def get(self) -> Response:
"""
@@ -46,9 +49,34 @@ class StatusView(BaseView):
"""
counters = Counters.from_packages(self.service.packages)
status = InternalStatus(
status=self.service.status,
architecture=self.service.architecture,
packages=counters,
repository=self.service.repository.name,
version=version.__version__)
return json_response(status.view())
async def post(self) -> None:
"""
update service status
JSON body must be supplied, the following model is used::
{
"status": "unknown", # service status string, must be valid ``BuildStatusEnum``
}
Raises:
HTTPBadRequest: if bad data is supplied
HTTPNoContent: in case of success response
"""
try:
data = await self.extract_data()
status = BuildStatusEnum(data["status"])
except Exception as e:
raise HTTPBadRequest(reason=str(e))
self.service.update_self(status)
raise HTTPNoContent()

View File

@@ -34,7 +34,7 @@ class LoginView(BaseView):
POST_PERMISSION(UserAccess): (class attribute) post permissions of self
"""
GET_PERMISSION = POST_PERMISSION = UserAccess.Safe
GET_PERMISSION = POST_PERMISSION = UserAccess.Unauthorized
async def get(self) -> None:
"""

View File

@@ -32,7 +32,7 @@ class LogoutView(BaseView):
POST_PERMISSION(UserAccess): (class attribute) post permissions of self
"""
POST_PERMISSION = UserAccess.Safe
POST_PERMISSION = UserAccess.Unauthorized
async def post(self) -> None:
"""