can update a list of software to a desired version from github
This commit is contained in:
parent
f6a8e260d5
commit
223bda4a25
6 changed files with 105 additions and 25 deletions
|
@ -1,7 +1,7 @@
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from losoup.models import Asset, GithubSoftware
|
from models import Asset, GithubSoftware
|
||||||
from losoup.cvs.github_settings import GithubSettings
|
from cvs.github_settings import GithubSettings
|
||||||
|
|
||||||
|
|
||||||
class GithubConnector:
|
class GithubConnector:
|
||||||
|
@ -21,11 +21,21 @@ class GithubConnector:
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
def get_release_asset(self, software: GithubSoftware) -> Asset:
|
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:
|
if asset.name == software.filename:
|
||||||
return asset
|
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:
|
def download_release_asset(self, asset: Asset) -> bytes:
|
||||||
headers = {
|
headers = {
|
||||||
|
|
|
@ -2,7 +2,7 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
|
|
||||||
class GithubSettings(BaseSettings):
|
class GithubSettings(BaseSettings):
|
||||||
model_config = SettingsConfigDict(env_prefix="GITHUB_")
|
model_config = SettingsConfigDict(env_prefix="GITHUB_", env_file=".env")
|
||||||
|
|
||||||
token: str
|
token: str
|
||||||
url: str = "https://api.github.com/repos"
|
url: str = "https://api.github.com/repos"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from losoup.models import Software, Asset
|
from models import Software
|
||||||
|
|
||||||
|
|
||||||
class LocalFile:
|
class LocalFile:
|
||||||
|
@ -17,8 +17,21 @@ class LocalFile:
|
||||||
def is_file_absent(self):
|
def is_file_absent(self):
|
||||||
return not self.is_file_present()
|
return not self.is_file_present()
|
||||||
|
|
||||||
def write_file(self, file: Asset) -> None:
|
def write_file(self, file: bytes) -> None:
|
||||||
self.software.absolute_path.write_bytes(file.content)
|
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):
|
def delete_file(self):
|
||||||
self.software.absolute_path.unlink()
|
self.software.absolute_path.unlink()
|
||||||
|
|
|
@ -1,9 +1,30 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Annotated
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from losoup.file_operations import local_files
|
from file_operations.local_files import LocalFile
|
||||||
from losoup.models import Software, GitlabSoftware, GithubSoftware
|
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]:
|
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:
|
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__":
|
if __name__ == "__main__":
|
||||||
pass
|
typer.run(main)
|
||||||
|
|
|
@ -24,18 +24,17 @@ class Software(BaseModel):
|
||||||
def absolute_path(self) -> Path:
|
def absolute_path(self) -> Path:
|
||||||
return Path(self.folder, self.filename)
|
return Path(self.folder, self.filename)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def filename_pattern(self) -> str:
|
||||||
|
return self.filename_format.replace("{{version}}", "*")
|
||||||
|
|
||||||
|
|
||||||
class GithubSoftware(Software):
|
class GithubSoftware(Software):
|
||||||
base_url: str = "https://api.github.com"
|
base_url: str = "https://api.github.com"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def release_url(self):
|
def releases_url(self):
|
||||||
if self.version == "latest":
|
return f"{self.base_url}/repos/{self.owner}/{self.repo}/releases"
|
||||||
release_path = self.version
|
|
||||||
else:
|
|
||||||
release_path = f"tags/{self.version}"
|
|
||||||
|
|
||||||
return f"{self.base_url}/repos/{self.owner}/{self.repo}/releases/{release_path}"
|
|
||||||
|
|
||||||
|
|
||||||
class GitlabSoftware(Software):
|
class GitlabSoftware(Software):
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
software:
|
software:
|
||||||
- name: NextCloud
|
- name: Nextcloud
|
||||||
cvs: github
|
cvs: github
|
||||||
owner: nextcloud-releases
|
owner: nextcloud-releases
|
||||||
repo: desktop
|
repo: desktop
|
||||||
version: latest
|
version: 3.14.0
|
||||||
folder: /home/stan/Softwares
|
folder: /home/stan/Softwares
|
||||||
filenameFormat: KeePassXC-{{version}}-x86_64.AppImage
|
filenameFormat: Nextcloud-{{version}}-x86_64.AppImage
|
||||||
|
|
||||||
- name: KeePassXC
|
- name: KeePassXC
|
||||||
cvs: giTHub
|
cvs: giTHub
|
||||||
owner: keepassxreboot
|
owner: keepassxreboot
|
||||||
repo: keepassxc
|
repo: keepassxc
|
||||||
version: latest
|
version: 2.7.9
|
||||||
folder: /home/stan/Softwares
|
folder: /home/stan/Softwares
|
||||||
filenameFormat: Nextcloud-{{version}}-x86_64.AppImage
|
filenameFormat: KeePassXC-{{version}}-x86_64.AppImage
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue