can update a list of software to a desired version from github

This commit is contained in:
Stanislas Jouffroy 2024-09-25 19:27:34 +02:00
parent f6a8e260d5
commit 223bda4a25
6 changed files with 105 additions and 25 deletions

View file

@ -1,7 +1,7 @@
import requests
from losoup.models import Asset, GithubSoftware
from losoup.cvs.github_settings import GithubSettings
from models import Asset, GithubSoftware
from cvs.github_settings import GithubSettings
class GithubConnector:
@ -21,11 +21,21 @@ class GithubConnector:
return assets
def get_release_asset(self, software: GithubSoftware) -> Asset:
for asset in self.get_release_assets_list(software.release_url):
release_url = self.get_release_url(software)
for asset in self.get_release_assets_list(release_url):
if asset.name == software.filename:
return asset
else:
continue
def get_release_url(self, software: GithubSoftware) -> str:
headers = {
"Accept": "application/vnd.github+json",
"Authorization": f"token {self.settings.token}",
"X-Github-Api-Version": "2022-11-28",
}
response = requests.get(software.releases_url, headers=headers)
for release in response.json():
if software.version in release.get("name"):
return release.get("url")
def download_release_asset(self, asset: Asset) -> bytes:
headers = {

View file

@ -2,7 +2,7 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
class GithubSettings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="GITHUB_")
model_config = SettingsConfigDict(env_prefix="GITHUB_", env_file=".env")
token: str
url: str = "https://api.github.com/repos"

View file

@ -1,6 +1,6 @@
from pathlib import Path
from losoup.models import Software, Asset
from models import Software
class LocalFile:
@ -17,8 +17,21 @@ class LocalFile:
def is_file_absent(self):
return not self.is_file_present()
def write_file(self, file: Asset) -> None:
self.software.absolute_path.write_bytes(file.content)
def write_file(self, file: bytes) -> None:
self.software.absolute_path.write_bytes(file)
def chmod(self, mode: oct) -> None:
self.software.absolute_path.chmod(mode)
def chmod_other_versions(self, mode: oct) -> None:
others = Path(self.software.folder).glob(self.software.filename_pattern)
print(list(others))
for other in others:
print(other.name)
print(self.software.filename)
if other.name != self.software.name:
print(f"chmod {other.name}")
other.chmod(mode)
def delete_file(self):
self.software.absolute_path.unlink()

View file

@ -1,9 +1,30 @@
from pathlib import Path
from typing import Annotated
import yaml
from losoup.file_operations import local_files
from losoup.models import Software, GitlabSoftware, GithubSoftware
from file_operations.local_files import LocalFile
from cvs.github import GithubConnector
from cvs.github_settings import GithubSettings
from models import Software, GitlabSoftware, GithubSoftware
import typer
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.console import Console
from rich.theme import Theme
log_theme = Theme(
{
"info": "cyan",
"warning": "yellow",
"error": "bold red",
}
)
console = Console(theme=log_theme)
github_settings = GithubSettings()
github = GithubConnector(github_settings)
def load_software_list(software_file: Path) -> list[Software]:
@ -21,8 +42,45 @@ def load_software_list(software_file: Path) -> list[Software]:
def is_software_to_update(software: Software) -> bool:
return local_files.LocalFile(software).is_file_absent()
return LocalFile(software).is_file_absent()
def update(software: Software) -> None:
if isinstance(software, GithubSoftware):
download = github.download_software(software)
local_file = LocalFile(software)
local_file.write_file(download)
local_file.chmod(0o544)
local_file.chmod_other_versions(0o444)
def main(
file_path: Annotated[
str,
typer.Option(
"--file",
"-f",
help="Configuration file that contains the definition of the software to get and their version",
),
] = "./software_definition.yml"
):
path = Path(file_path).resolve()
software_list = load_software_list(path)
for software in software_list:
if is_software_to_update(software):
with Progress(
SpinnerColumn(),
TextColumn("[progress.desciption]{task.description}"),
transient=True,
) as progress:
progress.add_task(description=f"Updating {software.name}...")
update(software)
else:
console.print(
f"[bold]{software.name}[/bold] is up to date.",
style="info",
)
if __name__ == "__main__":
pass
typer.run(main)

View file

@ -24,18 +24,17 @@ class Software(BaseModel):
def absolute_path(self) -> Path:
return Path(self.folder, self.filename)
@property
def filename_pattern(self) -> str:
return self.filename_format.replace("{{version}}", "*")
class GithubSoftware(Software):
base_url: str = "https://api.github.com"
@property
def release_url(self):
if self.version == "latest":
release_path = self.version
else:
release_path = f"tags/{self.version}"
return f"{self.base_url}/repos/{self.owner}/{self.repo}/releases/{release_path}"
def releases_url(self):
return f"{self.base_url}/repos/{self.owner}/{self.repo}/releases"
class GitlabSoftware(Software):

View file

@ -1,16 +1,16 @@
software:
- name: NextCloud
- name: Nextcloud
cvs: github
owner: nextcloud-releases
repo: desktop
version: latest
version: 3.14.0
folder: /home/stan/Softwares
filenameFormat: KeePassXC-{{version}}-x86_64.AppImage
filenameFormat: Nextcloud-{{version}}-x86_64.AppImage
- name: KeePassXC
cvs: giTHub
owner: keepassxreboot
repo: keepassxc
version: latest
version: 2.7.9
folder: /home/stan/Softwares
filenameFormat: Nextcloud-{{version}}-x86_64.AppImage
filenameFormat: KeePassXC-{{version}}-x86_64.AppImage