diff --git a/api.go b/api.go index fac6873..3e1ffba 100644 --- a/api.go +++ b/api.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "net/url" + "path" "strconv" "strings" "time" @@ -56,6 +57,40 @@ func catalogEntryToAPICatalogEntry(ce database.CatalogEntry) (APICatalogEntry, e return APICatalogEntry{CatalogEntry: ce, CatalogMeta: *cm}, nil } +func handleBadgeRedirect(w http.ResponseWriter, r *http.Request) { + var ( + compare = r.FormValue("compare") + vars = mux.Vars(r) + name, tag = vars["name"], vars["tag"] + ) + + ce, err := configFile.CatalogEntryByTag(name, tag) + if errors.Is(err, config.ErrCatalogEntryNotFound) { + http.Error(w, "Not found", http.StatusNotFound) + return + } + + cm, err := storage.Catalog.GetMeta(&ce) + if err != nil { + http.Error(w, "Unable to fetch catalog data", http.StatusInternalServerError) + return + } + + color := "green" + if compare != "" && compare != cm.CurrentVersion { + color = "red" + } + + target, err := url.Parse(cfg.BadgeGenInstance) + if err != nil { + http.Error(w, "Misconfigured BadgeGenInstance", http.StatusInternalServerError) + return + } + + target.Path = path.Join(target.Path, "static", ce.Key(), cm.CurrentVersion, color) + http.Redirect(w, r, target.String(), http.StatusFound) +} + func handleCatalogGet(w http.ResponseWriter, r *http.Request) { var ( vars = mux.Vars(r) diff --git a/main.go b/main.go index f933cd5..4948098 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,7 @@ import ( var ( cfg = struct { + BadgeGenInstance string `flag:"badge-gen-instance" default:"https://badges.fyi/" description:"Where to find the badge-gen instance to use badges from"` BaseURL string `flag:"base-url" default:"https://example.com/" description:"Base-URL the application is reachable at"` Config string `flag:"config,c" default:"config.yaml" description:"Configuration file with catalog entries"` Listen string `flag:"listen" default:":3000" description:"Port/IP to listen on"` @@ -84,6 +85,7 @@ func main() { router.HandleFunc("/v1/catalog/{name}/{tag}/version", handleCatalogGetVersion).Methods(http.MethodGet) router.HandleFunc("/v1/log", handleLog).Methods(http.MethodGet) + router.HandleFunc("/{name}/{tag}.svg", handleBadgeRedirect).Methods(http.MethodGet).Name("catalog-entry-badge") router.HandleFunc("/{name}/{tag}/log.rss", handleLogFeed).Methods(http.MethodGet).Name("catalog-entry-rss") router.HandleFunc("/log.rss", handleLogFeed).Methods(http.MethodGet).Name("log-rss") diff --git a/src/app.vue b/src/app.vue index e86847c..249d30e 100644 --- a/src/app.vue +++ b/src/app.vue @@ -35,6 +35,18 @@ /> All Updates + + + + diff --git a/src/catalog_entry.vue b/src/catalog_entry.vue new file mode 100644 index 0000000..a681c19 --- /dev/null +++ b/src/catalog_entry.vue @@ -0,0 +1,155 @@ + + + + + + + {{ entry.current_version }} + {{ moment(entry.version_time).format('lll') }} + + + {{ moment(entry.last_checked).format('lll') }} + + + + Current Version: + + + + Compare to Version: + + + + (Click badge to copy URL) + + + + + + + {{ link.name }} + + + + + + + + + + + + + + + + + + diff --git a/src/log.vue b/src/log.vue index 220d691..4db3ecb 100644 --- a/src/log.vue +++ b/src/log.vue @@ -1,40 +1,20 @@ - - - - {{ data.item.catalog_name }}:{{ data.item.catalog_tag }} - - - - - {{ moment(data.item.timestamp).format('lll') }} - - +
+ Current Version: + +
+ Compare to Version: + +
+ (Click badge to copy URL) +