Files
at-container-registry/pkg/appview/handlers/repository.go
T
2025-10-08 20:50:27 -05:00

108 lines
2.7 KiB
Go

package handlers
import (
"database/sql"
"html/template"
"log"
"net/http"
"atcr.io/pkg/appview/db"
"atcr.io/pkg/appview/middleware"
"atcr.io/pkg/atproto"
"atcr.io/pkg/auth/oauth"
"github.com/bluesky-social/indigo/atproto/identity"
"github.com/gorilla/mux"
)
// RepositoryPageHandler handles the public repository page
type RepositoryPageHandler struct {
DB *sql.DB
Templates *template.Template
RegistryURL string
Directory identity.Directory
Refresher *oauth.Refresher
}
func (h *RepositoryPageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
handle := vars["handle"]
repository := vars["repository"]
// Look up user by handle
owner, err := db.GetUserByHandle(h.DB, handle)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if owner == nil {
http.Error(w, "User not found", http.StatusNotFound)
return
}
// Fetch repository data
repo, err := db.GetRepository(h.DB, owner.DID, repository)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if repo == nil || len(repo.Manifests) == 0 {
http.Error(w, "Repository not found", http.StatusNotFound)
return
}
// Fetch star count
stats, err := db.GetRepositoryStats(h.DB, owner.DID, repository)
if err != nil {
log.Printf("Failed to fetch repository stats: %v", err)
// Continue with zero stats on error
stats = &db.RepositoryStats{StarCount: 0}
}
// Check if current user has starred this repo
isStarred := false
user := middleware.GetUser(r)
if user != nil && h.Refresher != nil && h.Directory != nil {
// Get OAuth session for the authenticated user
session, err := h.Refresher.GetSession(r.Context(), user.DID)
if err == nil {
// Get user's PDS client
apiClient := session.APIClient()
pdsClient := atproto.NewClientWithIndigoClient(user.PDSEndpoint, user.DID, apiClient)
// Check if star record exists
rkey := atproto.StarRecordKey(owner.DID, repository)
_, err = pdsClient.GetRecord(r.Context(), atproto.StarCollection, rkey)
isStarred = (err == nil)
}
}
// Check if current user is the repository owner
isOwner := false
if user != nil {
isOwner = (user.DID == owner.DID)
}
data := struct {
PageData
Owner *db.User // Repository owner
Repository *db.Repository
StarCount int
IsStarred bool
IsOwner bool // Whether current user owns this repository
}{
PageData: NewPageData(r, h.RegistryURL),
Owner: owner,
Repository: repo,
StarCount: stats.StarCount,
IsStarred: isStarred,
IsOwner: isOwner,
}
if err := h.Templates.ExecuteTemplate(w, "repository", data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}