Self-updates and program list from the repo

This commit is contained in:
sarah committed 2026-10-09 10:38:21 +02:00
1 parent d9da8438c2
commit e4272bd606
9 files changed
+416 -15

No files matched your search

+70 -7
View File
@@ -10,9 +10,11 @@ from typing import Callable
import flet as ft
import SelfUpdate
from Catalog import UpdateCatalog
from Core import (
AppName, ApplyAppearance, AssetsDir, BuildTheme, BundledFontFamily, ChipButtonStyle, DataDir,
DataHome, EffectiveSettings, LoadConfig, ManifestsDir, Palette,
AppName, AppVersion, ApplyAppearance, AssetsDir, BuildTheme, BundledFontFamily, ChipButtonStyle, DataDir,
BundledManifestsDir, DataHome, EffectiveSettings, LoadConfig, Palette,
)
from Dialogs import ShowInstallDialog, ShowOptionsDialog, ShowRemoveDialog, ShowUpdateDialog
from Installer import Apply, Fetch, FetchCommit, GetStatus, PlanConfigs, PlanRemoval, Remove, SourceVersion
@@ -31,7 +33,7 @@ _MenuIcon = DataDir / "SaraSuite.png"
def _LoadFletIdentity():
# Lives in Programs/ (bundled as data) because installed programs get a
# copy of the same file next to them.
Spec = importlib.util.spec_from_file_location("FletIdentity", ManifestsDir / "FletIdentity.py")
Spec = importlib.util.spec_from_file_location("FletIdentity", BundledManifestsDir / "FletIdentity.py")
Module = importlib.util.module_from_spec(Spec)
Spec.loader.exec_module(Module)
return Module
@@ -85,9 +87,12 @@ def Main(Page: ft.Page) -> None:
del LogView.controls[: len(LogView.controls) - _MaxLogLines]
LogView.update()
# Both lists are changed in place when the program list is updated from
# the SaraSuite repo (Catalog.py), so everything holding them stays valid.
Programs = LoadPrograms()
Cards: list[ProgramCard] = []
State = {"Busy": False}
CardList = ft.ListView(Cards, expand=True, spacing=12, padding=16)
State = {"Busy": False, "Release": None}
def RefreshCard(Card: ProgramCard) -> None:
try:
@@ -99,17 +104,70 @@ def Main(Page: ft.Page) -> None:
Card.ShowStatus(Current, Leftovers, State["Busy"])
Card.update()
def BuildCards() -> None:
Cards[:] = [ProgramCard(Program, OnInstall, OnUpdate, OnRemove, OnOptions) for Program in Programs]
CardList.controls = Cards
def RefreshAll() -> None:
# A new program list from the SaraSuite repo first, then every
# program's status, then whether there's a newer SaraSuite.
if UpdateCatalog(Log):
Programs[:] = LoadPrograms()
BuildCards()
CardList.update()
for Card in Cards:
RefreshCard(Card)
CheckSelfUpdate()
def CanSelfUpdate() -> bool:
Latest = State["Release"]
return Latest is not None and bool(Latest.AssetUrl) and SelfUpdate.RunningAppImage() is not None
def CheckSelfUpdate() -> None:
Latest = SelfUpdate.LatestRelease()
State["Release"] = Latest if Latest is not None and SelfUpdate.IsNewer(Latest.Version) else None
if State["Release"] is None:
SelfUpdateButton.visible = False
else:
Version = State["Release"].Version.lstrip("v")
# Only an AppImage can replace itself; from source, just say so.
SelfUpdateButton.visible = True
SelfUpdateButton.disabled = not CanSelfUpdate()
SelfUpdateButton.content = f"Update SaraSuite to {Version}"
SelfUpdateButton.tooltip = None if not SelfUpdateButton.disabled else "Running from source: pull and rebuild instead"
SelfUpdateButton.update()
def OnSelfUpdate(e) -> None:
Latest = State["Release"]
if Latest is None:
return
def Work() -> None:
SelfUpdate.Install(Latest, Log)
Page.show_dialog(ft.AlertDialog(
title="SaraSuite updated",
content=ft.Text(f"SaraSuite {Latest.Version.lstrip('v')} is installed. Restart now to use it?"),
actions=[
ft.OutlinedButton(content="Later", style=ChipButtonStyle(), on_click=lambda e: Page.pop_dialog()),
ft.OutlinedButton(content="Restart", style=ChipButtonStyle(), on_click=lambda e: Restart()),
],
))
def Restart() -> None:
SelfUpdate.Restart()
Page.run_task(Page.window.destroy)
RunOperation(None, Work)
def SetBusy(Busy: bool, Working: ProgramCard | None = None) -> None:
State["Busy"] = Busy
RefreshButton.disabled = Busy
SelfUpdateButton.disabled = Busy or not CanSelfUpdate()
for Card in Cards:
Card.SetBusy(Busy, Card is Working)
Card.update()
RefreshButton.update()
SelfUpdateButton.update()
def RunOperation(Card: ProgramCard | None, Work: Callable[[], None]) -> None:
"""Run Work in a background thread with every card locked, then
@@ -180,8 +238,7 @@ def Main(Page: ft.Page) -> None:
),
)
for Program in Programs:
Cards.append(ProgramCard(Program, OnInstall, OnUpdate, OnRemove, OnOptions))
BuildCards()
def ToggleMenuEntry(e) -> None:
_SetMenuEntry(not _MenuEntry.exists())
@@ -195,6 +252,10 @@ def Main(Page: ft.Page) -> None:
on_click=ToggleMenuEntry,
)
SelfUpdateButton = ft.OutlinedButton(
content="Update SaraSuite", style=ChipButtonStyle(), visible=False, on_click=OnSelfUpdate,
)
RefreshButton = ft.IconButton(
icon=ft.Icons.REFRESH,
icon_color=Palette.Mauve,
@@ -217,7 +278,9 @@ def Main(Page: ft.Page) -> None:
ft.Container(
content=ft.Row([
ft.Text(AppName, size=24, color=Palette.Mauve),
ft.Text(AppVersion, size=12, color=Palette.Overlay0),
ft.Container(expand=True),
SelfUpdateButton,
MenuButton,
RefreshButton,
SettingsButton,
@@ -226,7 +289,7 @@ def Main(Page: ft.Page) -> None:
bgcolor=Palette.Mantle,
border=ft.Border.only(bottom=ft.BorderSide(1, Palette.Surface1)),
),
ft.ListView(Cards, expand=True, spacing=12, padding=16),
CardList,
ft.Container(
content=LogView,
height=200,