Compare commits

..

No commits in common. "2414686f3cb700b7d7700cbd29e93823e9023fc5" and "3016a919c5e3b52dd664474febc57d963be3c3e3" have entirely different histories.

168 changed files with 1558 additions and 1553 deletions

View File

@ -189,7 +189,8 @@ class Repository(Properties):
no_local(bool): do not check local packages for updates no_local(bool): do not check local packages for updates
no_manual(bool): do not check for manual updates no_manual(bool): do not check for manual updates
no_vcs(bool): do not check VCS packages no_vcs(bool): do not check VCS packages
log_fn(Callable[[str], None]): logger function to log updates log_fn(Callable[[str]): logger function to log updates
None]:
Returns: Returns:
List[Package]: list of out-of-dated packages List[Package]: list of out-of-dated packages

View File

@ -64,7 +64,7 @@ class Update(Handler):
dry_run(bool): do not perform update itself dry_run(bool): do not perform update itself
Returns: Returns:
Callable[[str], None]: in case if dry_run is set it will return print, logger otherwise Callable[[str],None]: in case if dry_run is set it will return print, logger otherwise
""" """
def inner(line: str) -> None: def inner(line: str) -> None:
return print(line) if dry_run else application.logger.info(line) return print(line) if dry_run else application.logger.info(line)

View File

@ -66,11 +66,11 @@ class Lock:
""" """
default workflow is the following: default workflow is the following:
1. Check user UID check user UID
2. Check if there is lock file check if there is lock file
3. Check web status watcher status check web status watcher status
4. Create lock file create lock file
5. Report to status page if enabled report to status page if enabled
""" """
self.check_user() self.check_user()
self.check_version() self.check_version()

View File

@ -36,8 +36,7 @@ class Configuration(configparser.RawConfigParser):
extension for built-in configuration parser extension for built-in configuration parser
Attributes: Attributes:
ARCHITECTURE_SPECIFIC_SECTIONS(List[str]): (class attribute) known sections which can be architecture specific. ARCHITECTURE_SPECIFIC_SECTIONS(List[str]): (class attribute) known sections which can be architecture specific (required by dump)
Required by dump and merging functions
DEFAULT_LOG_FORMAT(str): (class attribute) default log format (in case of fallback) DEFAULT_LOG_FORMAT(str): (class attribute) default log format (in case of fallback)
DEFAULT_LOG_LEVEL(int): (class attribute) default log level (in case of fallback) DEFAULT_LOG_LEVEL(int): (class attribute) default log level (in case of fallback)
SYSTEM_CONFIGURATION_PATH(Path): (class attribute) default system configuration path distributed by package SYSTEM_CONFIGURATION_PATH(Path): (class attribute) default system configuration path distributed by package
@ -128,7 +127,7 @@ class Configuration(configparser.RawConfigParser):
quote_mark = char quote_mark = char
elif char == quote_mark: # quoted part ended, reset quotation elif char == quote_mark: # quoted part ended, reset quotation
quote_mark = None quote_mark = None
elif char == " " and quote_mark is None: # found space outside the quotation, yield the word elif char == " " and quote_mark is None: # found space outside of the quotation, yield the word
yield word yield word
word = "" word = ""
else: # append character to the buffer else: # append character to the buffer

View File

@ -148,8 +148,7 @@ class Executor(Cleaner):
generate reports generate reports
Args: Args:
targets(Optional[Iterable[str]]): list of targets to generate reports. Configuration option will be used targets(Optional[Iterable[str]]): list of targets to generate reports. Configuration option will be used if it is not set
if it is not set
result(Result): build result result(Result): build result
""" """
if targets is None: if targets is None:
@ -163,8 +162,7 @@ class Executor(Cleaner):
process synchronization to remote servers process synchronization to remote servers
Args: Args:
targets(Optional[Iterable[str]]): list of targets to sync. Configuration option will be used targets(Optional[Iterable[str]]): list of targets to sync. Configuration option will be used if it is not set
if it is not set
built_packages(Iterable[Package]): list of packages which has just been built built_packages(Iterable[Package]): list of packages which has just been built
""" """
if targets is None: if targets is None:

View File

@ -34,8 +34,8 @@ class Github(HttpUpload):
upload files to github releases upload files to github releases
Attributes: Attributes:
github_owner(str): github repository owner gh_owner(str): github repository owner
github_repository(str): github repository name gh_repository(str): github repository name
""" """
def __init__(self, architecture: str, configuration: Configuration, section: str) -> None: def __init__(self, architecture: str, configuration: Configuration, section: str) -> None:
@ -48,8 +48,8 @@ class Github(HttpUpload):
section(str): settings section name section(str): settings section name
""" """
HttpUpload.__init__(self, architecture, configuration, section) HttpUpload.__init__(self, architecture, configuration, section)
self.github_owner = configuration.get(section, "owner") self.gh_owner = configuration.get(section, "owner")
self.github_repository = configuration.get(section, "repository") self.gh_repository = configuration.get(section, "repository")
def asset_remove(self, release: Dict[str, Any], name: str) -> None: def asset_remove(self, release: Dict[str, Any], name: str) -> None:
""" """
@ -133,8 +133,8 @@ class Github(HttpUpload):
Returns: Returns:
Dict[str, Any]: github API release object for the new release Dict[str, Any]: github API release object for the new release
""" """
url = f"https://api.github.com/repos/{self.github_owner}/{self.github_repository}/releases" response = self._request("POST", f"https://api.github.com/repos/{self.gh_owner}/{self.gh_repository}/releases",
response = self._request("POST", url, json={"tag_name": self.architecture, "name": self.architecture}) json={"tag_name": self.architecture, "name": self.architecture})
release: Dict[str, Any] = response.json() release: Dict[str, Any] = response.json()
return release return release
@ -145,9 +145,10 @@ class Github(HttpUpload):
Returns: Returns:
Optional[Dict[str, Any]]: github API release object if release found and None otherwise Optional[Dict[str, Any]]: github API release object if release found and None otherwise
""" """
url = f"https://api.github.com/repos/{self.github_owner}/{self.github_repository}/releases/tags/{self.architecture}"
try: try:
response = self._request("GET", url) response = self._request(
"GET",
f"https://api.github.com/repos/{self.gh_owner}/{self.gh_repository}/releases/tags/{self.architecture}")
release: Dict[str, Any] = response.json() release: Dict[str, Any] = response.json()
return release return release
except requests.HTTPError as e: except requests.HTTPError as e:

View File

@ -47,6 +47,9 @@ class SignSettings(Enum):
Returns: Returns:
SignSettings: parsed value SignSettings: parsed value
Raises:
InvalidOption: if unsupported option suppled
""" """
if value.lower() in ("package", "packages", "sign-package"): if value.lower() in ("package", "packages", "sign-package"):
return cls.Packages return cls.Packages

View File

@ -25,8 +25,7 @@ class UserAccess(Enum):
web user access enumeration web user access enumeration
Attributes: Attributes:
Safe(UserAccess): (class attribute) user can access the page without authorization, Safe(UserAccess): (class attribute) user can access the page without authorization, should not be user for user configuration
should not be used for user configuration
Read(UserAccess): (class attribute) user can read the page Read(UserAccess): (class attribute) user can read the page
Write(UserAccess): (class attribute) user can modify task and package list Write(UserAccess): (class attribute) user can modify task and package list
""" """

View File

@ -39,34 +39,34 @@ def setup_routes(application: Application, static_path: Path) -> None:
Available routes are: Available routes are:
* GET / get build status page GET / get build status page
* GET /index.html same as above GET /index.html same as above
* POST /service-api/v1/add add new packages to repository POST /service-api/v1/add add new packages to repository
* POST /service-api/v1/remove remove existing package from repository POST /service-api/v1/remove remove existing package from repository
* POST /service-api/v1/request request to add new packages to repository POST /service-api/v1/request request to add new packages to repository
* GET /service-api/v1/search search for substring in AUR GET /service-api/v1/search search for substring in AUR
* POST /service-api/v1/update update packages in repository, actually it is just alias for add POST /service-api/v1/update update packages in repository, actually it is just alias for add
* GET /status-api/v1/ahriman get current service status GET /status-api/v1/ahriman get current service status
* POST /status-api/v1/ahriman update service status POST /status-api/v1/ahriman update service status
* GET /status-api/v1/packages get all known packages GET /status-api/v1/packages get all known packages
* POST /status-api/v1/packages force update every package from repository POST /status-api/v1/packages force update every package from repository
* DELETE /status-api/v1/package/:base delete package base from status page DELETE /status-api/v1/package/:base delete package base from status page
* GET /status-api/v1/package/:base get package base status GET /status-api/v1/package/:base get package base status
* POST /status-api/v1/package/:base update package base status POST /status-api/v1/package/:base update package base status
* GET /status-api/v1/status get web service status itself GET /status-api/v1/status get web service status itself
* GET /user-api/v1/login OAuth2 handler for login GET /user-api/v1/login OAuth2 handler for login
* POST /user-api/v1/login login to service POST /user-api/v1/login login to service
* POST /user-api/v1/logout logout from service POST /user-api/v1/logout logout from service
Args: Args:
application(Application): web application instance application(Application): web application instance

View File

@ -99,8 +99,7 @@ class BaseView(View):
extract json data from either json or form data extract json data from either json or form data
Args: Args:
list_keys(Optional[List[str]], optional): optional list of keys which must be forced to list from form data list_keys(Optional[List[str]], optional): optional list of keys which must be forced to list from form data (Default value = None)
(Default value = None)
Returns: Returns:
Dict[str, Any]: raw json object or form data converted to json Dict[str, Any]: raw json object or form data converted to json
@ -119,8 +118,7 @@ class BaseView(View):
list_keys(List[str]): list of keys which must be forced to list from form data list_keys(List[str]): list of keys which must be forced to list from form data
Returns: Returns:
Dict[str, Any]: form data converted to json. In case if a key is found multiple times Dict[str, Any]: form data converted to json. In case if a key is found multiple times it will be returned as list
it will be returned as list
""" """
raw = await self.request.post() raw = await self.request.post()
json: Dict[str, Any] = {} json: Dict[str, Any] = {}

View File

@ -17,6 +17,9 @@ def mapping(configuration: Configuration, database: SQLite) -> Mapping:
Returns: Returns:
Mapping: auth service instance Mapping: auth service instance
Raises:
""" """
return Mapping(configuration, database) return Mapping(configuration, database)
@ -32,6 +35,9 @@ def oauth(configuration: Configuration, database: SQLite) -> OAuth:
Returns: Returns:
OAuth: OAuth2 service instance OAuth: OAuth2 service instance
Raises:
""" """
configuration.set("web", "address", "https://example.com") configuration.set("web", "address", "https://example.com")
return OAuth(configuration, database) return OAuth(configuration, database)