App v0.2.26 and gateway 0.1.20

Client: seek controls, Bazarr subtitle download and cast panel in the
player; MDBList ratings strip; episode and schedule detail pages; series
pace estimate; what's new panel; install-permission onboarding step;
synced per-profile preferences; Emby outage banner.

Gateway: rebuilt admin console (one fragment per page), preference
history and restore, merged Continue Watching, Emby health probe,
subtitle selection and Bazarr download, structured request logging with
per-request identity, and embedded build version.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
ponzischeme89
2026-08-06 22:33:56 +12:00
co-authored by Claude Opus 5
parent 2675e6d82b
commit 4a4df7a73c
257 changed files with 24868 additions and 3108 deletions
+8 -8
View File
@@ -82,13 +82,13 @@ func (s *Server) handleReleasePublish(w http.ResponseWriter, r *http.Request) {
defer source.Close()
if err := os.MkdirAll(s.cfg.ReleaseDir, 0o750); err != nil {
s.log.Error("release directory unavailable", "error", err)
s.loggerFor(r.Context()).Error("release directory unavailable", "error", err)
writeError(w, http.StatusInternalServerError, "release storage unavailable")
return
}
temp, err := os.CreateTemp(s.cfg.ReleaseDir, ".memby-upload-*")
if err != nil {
s.log.Error("release temp file failed", "error", err)
s.loggerFor(r.Context()).Error("release temp file failed", "error", err)
writeError(w, http.StatusInternalServerError, "release storage unavailable")
return
}
@@ -145,19 +145,19 @@ func (s *Server) handleReleasePublish(w http.ResponseWriter, r *http.Request) {
}
newFile = false
} else if !os.IsNotExist(hashErr) {
s.log.Error("existing release could not be verified", "error", hashErr)
s.loggerFor(r.Context()).Error("existing release could not be verified", "error", hashErr)
writeError(w, http.StatusInternalServerError, "could not verify existing release")
return
}
if newFile {
if err := os.Rename(tempName, destination); err != nil {
s.log.Error("release publish rename failed", "error", err)
s.loggerFor(r.Context()).Error("release publish rename failed", "error", err)
writeError(w, http.StatusInternalServerError, "could not publish APK")
return
}
}
if err := os.Chmod(destination, 0o640); err != nil {
s.log.Warn("release permissions could not be tightened", "error", err)
s.loggerFor(r.Context()).Warn("release permissions could not be tightened", "error", err)
}
policy := appupdate.Policy{
@@ -178,17 +178,17 @@ func (s *Server) handleReleasePublish(w http.ResponseWriter, r *http.Request) {
if newFile {
_ = os.Remove(destination)
}
s.log.Error("release policy write failed", "error", err)
s.loggerFor(r.Context()).Error("release policy write failed", "error", err)
writeError(w, http.StatusInternalServerError, "APK stored but update policy could not be saved")
return
}
if err := s.LoadUpdatePolicy(r.Context()); err != nil {
s.log.Error("release policy reload failed", "error", err)
s.loggerFor(r.Context()).Error("release policy reload failed", "error", err)
writeError(w, http.StatusInternalServerError, "APK stored but update policy could not be loaded")
return
}
s.log.Info("release published", "version", version, "mandatory", mandatory,
s.loggerFor(r.Context()).Info("release published", "version", version, "mandatory", mandatory,
"bytes", written, "file", filename)
writeJSON(w, http.StatusCreated, s.updatePolicy.get())
}