chore: delete dead progress handlers, no-op scar, split fused helper line
Batch H1 step 4: - Handler GetUniversalProgress (progress.go) deleted — no route mounts it; only /api/progress/:id/history (GetProgressHistory) and the SSR /progress page exist. Note: the bruno universal-progress suite documents GET/PUT /api/progress/:id + /api/progress/device/:device_id — those routes do NOT exist server-side; that suite is stale documentation, flagged in the plan. - Handler GetAllProgress deleted — unregistered near-copy of GetAllProgressData (which the /progress SSR page uses and stays). - series.go: dropped the `_ = libTypes` no-op (libTypes IS used by the Badge line right below — the assignment stays). - router/helpers.go: visibleLibraryIDsFor's signature and first statement were fused onto one line; split for readability. No behavior change.
This commit is contained in:
1 parent
8fc74c908a
commit
721139dc16
3 files changed
+5
-140
No files matched your search
@@ -6,13 +6,11 @@ import (
|
|||||||
"bookhoard/internal/utils"
|
"bookhoard/internal/utils"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jackc/pgx/v5"
|
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
"github.com/labstack/echo/v5"
|
"github.com/labstack/echo/v5"
|
||||||
)
|
)
|
||||||
@@ -31,72 +29,6 @@ func getDeviceIcon(deviceType string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUniversalProgress retrieves progress with all location references
|
|
||||||
func (h *Handler) GetUniversalProgress(c *echo.Context) error {
|
|
||||||
user := MustGetAuthenticatedUser(c)
|
|
||||||
|
|
||||||
mediaItemID, err := uuid.Parse(c.Param("id"))
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusBadRequest, "invalid media item ID")
|
|
||||||
}
|
|
||||||
|
|
||||||
progress, err := h.db.GetUniversalProgress(context.Background(), database.GetUniversalProgressParams{
|
|
||||||
MediaItemID: pgtype.UUID{Bytes: mediaItemID, Valid: true},
|
|
||||||
UserID: pgtype.UUID{Bytes: user.ID.Bytes, Valid: true},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, pgx.ErrNoRows) {
|
|
||||||
return c.JSON(http.StatusOK, map[string]interface{}{
|
|
||||||
"media_item_id": mediaItemID,
|
|
||||||
"progress": nil,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "failed to get progress")
|
|
||||||
}
|
|
||||||
|
|
||||||
response := map[string]interface{}{
|
|
||||||
"book_id": progress.MediaItemID.Bytes,
|
|
||||||
"format_group": progress.FormatGroup,
|
|
||||||
"universal_progress": map[string]interface{}{
|
|
||||||
"percentage": progress.Percentage.Float64,
|
|
||||||
},
|
|
||||||
"location_references": map[string]interface{}{
|
|
||||||
"percentage": progress.Percentage.Float64,
|
|
||||||
"page": int(progress.CurrentPage.Int32),
|
|
||||||
"total_pages": int(progress.TotalPages.Int32),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if progress.Epubcfi.Valid {
|
|
||||||
response["location_references"].(map[string]interface{})["epubcfi"] = progress.Epubcfi.String
|
|
||||||
}
|
|
||||||
if progress.Chapter.Valid {
|
|
||||||
response["location_references"].(map[string]interface{})["chapter"] = int(progress.Chapter.Int32)
|
|
||||||
}
|
|
||||||
if progress.ChapterProgress.Valid {
|
|
||||||
response["location_references"].(map[string]interface{})["chapter_progress"] = progress.ChapterProgress.Float64
|
|
||||||
}
|
|
||||||
if progress.CharacterOffset.Valid {
|
|
||||||
response["location_references"].(map[string]interface{})["character"] = progress.CharacterOffset.Int64
|
|
||||||
}
|
|
||||||
|
|
||||||
deviceSync := map[string]interface{}{}
|
|
||||||
if progress.LastSyncDevice.Valid {
|
|
||||||
deviceSync["device"] = progress.LastSyncDevice.String
|
|
||||||
}
|
|
||||||
if progress.LastSyncSource.Valid {
|
|
||||||
deviceSync["source"] = progress.LastSyncSource.String
|
|
||||||
}
|
|
||||||
if progress.LastSyncTimestamp.Valid {
|
|
||||||
deviceSync["last_sync"] = progress.LastSyncTimestamp.Time
|
|
||||||
}
|
|
||||||
if len(deviceSync) > 0 {
|
|
||||||
response["device_sync"] = deviceSync
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, response)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateUniversalProgress updates progress with automatic conversion
|
// UpdateUniversalProgress updates progress with automatic conversion
|
||||||
// GetProgressHistory retrieves reading session history
|
// GetProgressHistory retrieves reading session history
|
||||||
func (h *Handler) GetProgressHistory(c *echo.Context) error {
|
func (h *Handler) GetProgressHistory(c *echo.Context) error {
|
||||||
@@ -168,76 +100,9 @@ func audioDurationFrom(raw []byte) float64 {
|
|||||||
return payload.DurationSeconds
|
return payload.DurationSeconds
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAllProgress retrieves all progress for a user with sync source info
|
// GetAllProgressData retrieves all progress for a user with sync source info.
|
||||||
func (h *Handler) GetAllProgress(c *echo.Context) error {
|
// The registered /progress SSR page renders this (frontend.go); the old
|
||||||
user := MustGetAuthenticatedUser(c)
|
// GetAllProgress HTTP handler (an unregistered near-copy) was deleted.
|
||||||
|
|
||||||
progressList := []ProgressWithMedia{}
|
|
||||||
|
|
||||||
mediaItems, err := h.db.ListMediaItems(c.Request().Context(), database.ListMediaItemsParams{
|
|
||||||
Limit: 1000, Offset: 0,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "failed to get media items")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, mediaItem := range mediaItems {
|
|
||||||
progress, err := h.db.GetUniversalProgress(c.Request().Context(), database.GetUniversalProgressParams{
|
|
||||||
MediaItemID: mediaItem.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
coverPath := utils.ResolveMediaURL(mediaItem.LibraryID, mediaItem.CoverImagePath)
|
|
||||||
|
|
||||||
author := ""
|
|
||||||
if mediaItem.Author.Valid {
|
|
||||||
author = mediaItem.Author.String
|
|
||||||
}
|
|
||||||
|
|
||||||
epubcfi := ""
|
|
||||||
if progress.Epubcfi.Valid {
|
|
||||||
epubcfi = progress.Epubcfi.String
|
|
||||||
}
|
|
||||||
|
|
||||||
deviceName := ""
|
|
||||||
if progress.LastSyncDevice.Valid {
|
|
||||||
deviceName = progress.LastSyncDevice.String
|
|
||||||
}
|
|
||||||
|
|
||||||
lastUpdated := ""
|
|
||||||
if progress.LastReadAt.Valid {
|
|
||||||
lastUpdated = utils.FormatTimeInTimezone(progress.LastReadAt.Time, user.Timezone.String)
|
|
||||||
}
|
|
||||||
|
|
||||||
progressList = append(progressList, ProgressWithMedia{
|
|
||||||
MediaItemID: progress.MediaItemID.Bytes,
|
|
||||||
Title: mediaItem.Title,
|
|
||||||
Author: author,
|
|
||||||
CoverImagePath: coverPath,
|
|
||||||
Percentage: progress.Percentage.Float64,
|
|
||||||
CurrentPage: progress.CurrentPage.Int32,
|
|
||||||
TotalPages: progress.TotalPages.Int32,
|
|
||||||
LastReadAt: progress.LastReadAt.Time,
|
|
||||||
Epubcfi: epubcfi,
|
|
||||||
LastSyncDevice: deviceName,
|
|
||||||
ProgressPercentage: progress.Percentage.Float64 * 100,
|
|
||||||
EpubCFI: epubcfi,
|
|
||||||
LastUpdated: lastUpdated,
|
|
||||||
DeviceIcon: getDeviceIcon(deviceName),
|
|
||||||
FormatGroup: mediaItem.FormatGroup,
|
|
||||||
EstimatedPages: wsync.EstimatedPages(mediaItem.TotalCharacters.Int64),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, map[string]interface{}{
|
|
||||||
"progress": progressList,
|
|
||||||
"total": len(progressList),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) GetAllProgressData(c *echo.Context) ([]ProgressWithMedia, error) {
|
func (h *Handler) GetAllProgressData(c *echo.Context) ([]ProgressWithMedia, error) {
|
||||||
user := MustGetAuthenticatedUser(c)
|
user := MustGetAuthenticatedUser(c)
|
||||||
|
|
||||||
|
|||||||
@@ -157,7 +157,6 @@ func (h *SeriesHandler) GetSeriesBooks(c *echo.Context) error {
|
|||||||
for _, item := range books {
|
for _, item := range books {
|
||||||
itemUUID, _ := uuid.FromBytes(item.ID.Bytes[0:16])
|
itemUUID, _ := uuid.FromBytes(item.ID.Bytes[0:16])
|
||||||
libTypes := LibraryTypeMap(c.Request().Context(), h.db)
|
libTypes := LibraryTypeMap(c.Request().Context(), h.db)
|
||||||
_ = libTypes
|
|
||||||
bookCards = append(bookCards, BookInfo{
|
bookCards = append(bookCards, BookInfo{
|
||||||
MediaItemID: itemUUID.String(),
|
MediaItemID: itemUUID.String(),
|
||||||
Title: item.Title,
|
Title: item.Title,
|
||||||
|
|||||||
@@ -252,7 +252,8 @@ func resolveLibrary(c *echo.Context, cfg *Config, userUUID string) LibraryResolu
|
|||||||
|
|
||||||
// visibleLibraryIDsFor returns the requester's visible-library id set (for
|
// visibleLibraryIDsFor returns the requester's visible-library id set (for
|
||||||
// membership checks) plus the ids themselves (for SQL ANY() filters).
|
// membership checks) plus the ids themselves (for SQL ANY() filters).
|
||||||
func visibleLibraryIDsFor(c *echo.Context, cfg *Config) (map[string]bool, []pgtype.UUID, error) { userUUIDStr, ok := c.Get("user_id").(string)
|
func visibleLibraryIDsFor(c *echo.Context, cfg *Config) (map[string]bool, []pgtype.UUID, error) {
|
||||||
|
userUUIDStr, ok := c.Get("user_id").(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, echo.NewHTTPError(http.StatusUnauthorized, "invalid user")
|
return nil, nil, echo.NewHTTPError(http.StatusUnauthorized, "invalid user")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user