mirror of
https://github.com/lnbits/lnbits-legend.git
synced 2024-11-19 18:11:30 +01:00
feat: separate extension release into new API
This commit is contained in:
parent
a73e8ae44d
commit
27b308ae1a
@ -153,18 +153,25 @@
|
||||
|
||||
<q-dialog v-model="showUpgradeDialog">
|
||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<div class="col-12 col-md-5 q-gutter-y-md" v-if="selectedExtensionRepos">
|
||||
<q-card v-for="repo of Object.keys(selectedExtensionRepos)" :key="repo">
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">Repo name</h6>
|
||||
<h6 class="text-subtitle1 q-my-none">
|
||||
<q-badge color="primary" rounded
|
||||
><small v-text="repo"></small
|
||||
></q-badge>
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
<q-list>
|
||||
<q-expansion-item
|
||||
v-for="release of selectedExtensionRepos[repo]"
|
||||
:key="release.version"
|
||||
group="extras"
|
||||
icon="download"
|
||||
label="Version"
|
||||
:label="release.description"
|
||||
:caption="'Version: ' + release.version"
|
||||
:content-inset-level="0.5"
|
||||
>
|
||||
<q-expansion-item
|
||||
@ -229,6 +236,8 @@
|
||||
showUpgradeDialog: false,
|
||||
showDetailsDialog: false,
|
||||
selectedExtension: null,
|
||||
selectedExtensionReleases: null,
|
||||
selectedExtensionRepos: null,
|
||||
maxStars: 0
|
||||
}
|
||||
},
|
||||
@ -317,12 +326,19 @@
|
||||
console.log('### showUpgrade')
|
||||
this.selectedExtension = extension
|
||||
this.showUpgradeDialog = true
|
||||
const releases = await LNbits.api.request(
|
||||
const {data} = await LNbits.api.request(
|
||||
'GET',
|
||||
`/api/v1/extension/${extension.id}/releases?usr=${this.g.user.id}`,
|
||||
this.g.user.wallets[0].adminkey
|
||||
)
|
||||
console.log('### releases', releases)
|
||||
this.selectedExtensionReleases = data
|
||||
this.selectedExtensionRepos = data.reduce((repos, release) => {
|
||||
repos[release.source_repo] = repos[release.source_repo] || []
|
||||
repos[release.source_repo].push(release)
|
||||
return repos
|
||||
}, {})
|
||||
console.log('### releases', this.selectedExtensionReleases)
|
||||
console.log('### repos', this.selectedExtensionRepos)
|
||||
},
|
||||
|
||||
showExtensionDetails: function (extension) {
|
||||
|
@ -42,6 +42,7 @@ from lnbits.decorators import (
|
||||
)
|
||||
from lnbits.extension_manger import (
|
||||
Extension,
|
||||
ExtensionRelease,
|
||||
InstallableExtension,
|
||||
get_valid_extensions,
|
||||
)
|
||||
@ -800,12 +801,11 @@ async def api_uninstall_extension(ext_id: str, user: User = Depends(check_admin)
|
||||
@core_app.get("/api/v1/extension/{ext_id}/releases")
|
||||
async def get_extension_releases(ext_id: str, user: User = Depends(check_admin)):
|
||||
try:
|
||||
installable_extensions: List[
|
||||
InstallableExtension
|
||||
] = await InstallableExtension.get_installable_extensions()
|
||||
extensions = [e for e in installable_extensions if e.id == ext_id]
|
||||
extension_releases: List[
|
||||
ExtensionRelease
|
||||
] = await InstallableExtension.get_extension_releases(ext_id)
|
||||
|
||||
return extensions
|
||||
return extension_releases
|
||||
|
||||
except Exception as ex:
|
||||
raise HTTPException(
|
||||
|
@ -113,7 +113,9 @@ async def extensions_install(
|
||||
"dependencies": ext.dependencies,
|
||||
"isInstalled": ext.id in installed_extensions,
|
||||
"isActive": not ext.id in inactive_extensions,
|
||||
"release": dict(ext.release) if ext.release else None,
|
||||
"latestRelease": dict(ext.latest_release)
|
||||
if ext.latest_release
|
||||
else None,
|
||||
},
|
||||
extension_list,
|
||||
)
|
||||
|
@ -6,7 +6,6 @@ import sys
|
||||
import urllib.request
|
||||
import zipfile
|
||||
from http import HTTPStatus
|
||||
from platform import release
|
||||
from typing import List, NamedTuple, Optional
|
||||
|
||||
import httpx
|
||||
@ -107,6 +106,7 @@ class ExtensionRelease(BaseModel):
|
||||
name: str
|
||||
version: str
|
||||
archive: str
|
||||
source_repo: str
|
||||
hash: Optional[str]
|
||||
published_at: Optional[str]
|
||||
url: Optional[str]
|
||||
@ -118,6 +118,7 @@ class ExtensionRelease(BaseModel):
|
||||
name=r["name"],
|
||||
version=r["tag_name"],
|
||||
archive=r["zipball_url"],
|
||||
# source_repo=r[]
|
||||
# description=r["body"], # bad for JSON
|
||||
published_at=r["published_at"],
|
||||
url=r["html_url"],
|
||||
@ -127,7 +128,7 @@ class ExtensionRelease(BaseModel):
|
||||
class InstallableExtension(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
archive: str #todo: move to installed_release
|
||||
archive: str # todo: move to installed_release
|
||||
hash: str
|
||||
short_description: Optional[str] = None
|
||||
details: Optional[str] = None
|
||||
@ -137,7 +138,9 @@ class InstallableExtension(BaseModel):
|
||||
is_admin_only: bool = False
|
||||
version: str = "none" # todo: move to Release
|
||||
stars: int = 0
|
||||
release: Optional[ExtensionRelease]
|
||||
latest_release: Optional[ExtensionRelease]
|
||||
installed_release: Optional[ExtensionRelease]
|
||||
all_releases: List[ExtensionRelease] = []
|
||||
|
||||
@property
|
||||
def zip_path(self) -> str:
|
||||
@ -233,7 +236,7 @@ class InstallableExtension(BaseModel):
|
||||
version="0",
|
||||
stars=repo["stargazers_count"],
|
||||
icon_url=icon_to_github_url(org, config.get("tile")),
|
||||
release=ExtensionRelease.from_github_release(latest_release),
|
||||
latest_release=ExtensionRelease.from_github_release(latest_release),
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(e)
|
||||
@ -268,6 +271,7 @@ class InstallableExtension(BaseModel):
|
||||
@classmethod
|
||||
async def get_installable_extensions(cls) -> List["InstallableExtension"]:
|
||||
extension_list: List[InstallableExtension] = []
|
||||
extension_id_list: List[str] = []
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
for url in settings.lnbits_extensions_manifests:
|
||||
@ -278,7 +282,9 @@ class InstallableExtension(BaseModel):
|
||||
continue
|
||||
manifest = resp.json()
|
||||
if "extensions" in manifest:
|
||||
for e in manifest["extensions"] or []:
|
||||
for e in manifest["extensions"]:
|
||||
if e["id"] in extension_id_list:
|
||||
continue
|
||||
extension_list += [
|
||||
InstallableExtension(
|
||||
id=e["id"],
|
||||
@ -293,18 +299,51 @@ class InstallableExtension(BaseModel):
|
||||
else [],
|
||||
)
|
||||
]
|
||||
extension_id_list += [e["id"]]
|
||||
if "repos" in manifest:
|
||||
for r in manifest["repos"]:
|
||||
ext = await InstallableExtension.from_repo(
|
||||
r["organisation"], r["repository"]
|
||||
)
|
||||
if ext:
|
||||
if ext.id in extension_id_list:
|
||||
continue
|
||||
extension_list += [ext]
|
||||
extension_id_list += [ext.id]
|
||||
except Exception as e:
|
||||
logger.warning(f"Manifest {url} failed with '{str(e)}'")
|
||||
|
||||
return extension_list
|
||||
|
||||
@classmethod
|
||||
async def get_extension_releases(cls, ext_id: str) -> List["ExtensionRelease"]:
|
||||
extension_releases: List[ExtensionRelease] = []
|
||||
async with httpx.AsyncClient() as client:
|
||||
for url in settings.lnbits_extensions_manifests:
|
||||
try:
|
||||
resp = await client.get(url)
|
||||
if resp.status_code != 200:
|
||||
logger.warning(f"Cannot fetch extensions manifest at: {url}")
|
||||
continue
|
||||
manifest = resp.json()
|
||||
if "extensions" in manifest:
|
||||
for e in manifest["extensions"]:
|
||||
if e["id"] == ext_id:
|
||||
extension_releases += [
|
||||
ExtensionRelease(
|
||||
name=e["name"],
|
||||
version=e["version"],
|
||||
archive=e["archive"],
|
||||
hash=e["hash"],
|
||||
source_repo=url,
|
||||
description=e["shortDescription"],
|
||||
)
|
||||
]
|
||||
except Exception as e:
|
||||
logger.warning(f"Manifest {url} failed with '{str(e)}'")
|
||||
|
||||
return extension_releases
|
||||
|
||||
|
||||
class InstalledExtensionMiddleware:
|
||||
def __init__(self, app: ASGIApp) -> None:
|
||||
|
Loading…
Reference in New Issue
Block a user