Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ The server can be configured via environment variables or `.env` file:
* `SINGLE_USER_AUTO_LOGIN`: Skip login when only one user exists (default: `false`).
* `SYSTEM_APPS_REPO`: Git repository URL for system apps (default: `https://github.com/tronbyt/apps.git`).
* `SYSTEM_APPS_AUTO_REFRESH`: Automatically refresh the system apps repository (default: `false`).
* `CUSTOM_APPS_AUTO_REFRESH`: Automatically refresh every user's custom apps repository, every 12h (default: `false`).
* `GITHUB_TOKEN`: GitHub token for private app repositories (optional).
* `REDIS_URL`: Redis connection string for caching (optional).
* `LOG_LEVEL`: Logging verbosity: `DEBUG`, `INFO`, `WARN`, `ERROR` (default: `INFO`).
Expand Down
1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Settings struct {
SingleUserAutoLogin bool `env:"SINGLE_USER_AUTO_LOGIN"`
SystemAppsAutoRefresh bool `env:"SYSTEM_APPS_AUTO_REFRESH"`
SystemAppsRepo string `env:"SYSTEM_APPS_REPO" envDefault:"https://github.com/tronbyt/apps.git"`
CustomAppsAutoRefresh bool `env:"CUSTOM_APPS_AUTO_REFRESH"`
GitHubToken string `env:"GITHUB_TOKEN"`
RedisURL string `env:"REDIS_URL"`
Host string `env:"TRONBYT_HOST" envDefault:""`
Expand Down
41 changes: 41 additions & 0 deletions internal/server/handlers_user.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package server

import (
"context"
"encoding/json"
"fmt"
"io"
Expand All @@ -9,6 +10,7 @@ import (
"os"
"path/filepath"
"strings"
"time"

"tronbyt-server/internal/data"
"tronbyt-server/internal/gitutils"
Expand Down Expand Up @@ -275,6 +277,45 @@ func (s *Server) handleRefreshUserRepo(w http.ResponseWriter, r *http.Request) {
s.flashAndRedirect(w, r, "User repository refreshed successfully.", "/settings/content", http.StatusSeeOther)
}

// autoRefreshCustomAppsRepos periodically re-pulls every user's custom apps
// repo, mirroring autoRefreshSystemRepo for the per-user equivalent.
func (s *Server) autoRefreshCustomAppsRepos() {
if !s.Config.CustomAppsAutoRefresh {
return
}

slog.Info("Scheduled custom apps auto-refresh enabled (every 12h)")

ticker := time.NewTicker(12 * time.Hour)
defer ticker.Stop()
for range ticker.C {
if !s.Config.CustomAppsAutoRefresh {
slog.Info("Custom apps auto-refresh disabled, stopping ticker")
return
}
slog.Info("Performing scheduled custom apps refresh")
s.refreshAllCustomAppsRepos()
}
}

// refreshAllCustomAppsRepos re-pulls the custom apps repo for every user that
// has one configured. A failure for one user is logged and does not stop the
// others from refreshing.
func (s *Server) refreshAllCustomAppsRepos() {
users, err := gorm.G[data.User](s.DB).Where("app_repo_url <> ?", "").Find(context.Background())
if err != nil {
slog.Error("Failed to list users with custom apps repos", "error", err)
return
}

for _, user := range users {
appsPath := filepath.Join(s.DataDir, "users", user.Username, "repo")
if err := gitutils.EnsureRepo(appsPath, user.AppRepoURL, s.Config.GitHubToken, true); err != nil {
slog.Error("Scheduled refresh of custom apps repo failed", "user", user.Username, "error", err)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
}

func (s *Server) handleExportUserConfig(w http.ResponseWriter, r *http.Request) {
userContext := GetUser(r)

Expand Down
1 change: 1 addition & 0 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ func NewServer(db *gorm.DB, cfg *config.Settings) *Server {

go s.checkForUpdates(context.Background())
go s.autoRefreshSystemRepo()
go s.autoRefreshCustomAppsRepos()

s.routes()
return s
Expand Down