Rename backend code references: Bookmann → Bookhoard
Backend changes: - Update import paths: bookmann/internal → bookhoard/internal - Rename struct fields: BookmannUUID → BookhoardUUID - Update handler function names: mapContentIdToBookmannUUID → mapContentIdToBookhoardUUID - Update HTTP response headers: X-Bookmann-* → X-Bookhoard-* - Update service and middleware references - Update main.go imports and references This is part 2 of the project rename to Bookhoard.
This commit is contained in:
+8
-8
@@ -1,14 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/config"
|
"bookhoard/internal/config"
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"bookmann/internal/handlers"
|
"bookhoard/internal/handlers"
|
||||||
"bookmann/internal/middleware"
|
"bookhoard/internal/middleware"
|
||||||
ratelimit "bookmann/internal/middleware"
|
ratelimit "bookhoard/internal/middleware"
|
||||||
"bookmann/internal/services"
|
"bookhoard/internal/services"
|
||||||
"bookmann/internal/sync"
|
"bookhoard/internal/sync"
|
||||||
"bookmann/templates"
|
"bookhoard/templates"
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"bookmann/internal/middleware"
|
"bookhoard/internal/middleware"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"bookmann/internal/services"
|
"bookhoard/internal/services"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -294,7 +294,7 @@ func (h *Handler) AutoLinkBooks(c echo.Context) error {
|
|||||||
bestMatch := match.Matches[0]
|
bestMatch := match.Matches[0]
|
||||||
|
|
||||||
_, err := h.db.CreateDeviceFileAlias(ctx, database.CreateDeviceFileAliasParams{
|
_, err := h.db.CreateDeviceFileAlias(ctx, database.CreateDeviceFileAliasParams{
|
||||||
MediaItemID: pgtype.UUID{Bytes: bestMatch.BookmannUUID, Valid: true},
|
MediaItemID: pgtype.UUID{Bytes: bestMatch.BookhoardUUID, Valid: true},
|
||||||
DeviceID: book.DeviceID,
|
DeviceID: book.DeviceID,
|
||||||
FilePath: book.FilePath.String,
|
FilePath: book.FilePath.String,
|
||||||
FileSha256: pgtype.Text{String: "", Valid: false},
|
FileSha256: pgtype.Text{String: "", Valid: false},
|
||||||
@@ -304,14 +304,14 @@ func (h *Handler) AutoLinkBooks(c echo.Context) error {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
h.db.LinkUnlinkedBook(ctx, database.LinkUnlinkedBookParams{
|
h.db.LinkUnlinkedBook(ctx, database.LinkUnlinkedBookParams{
|
||||||
ID: book.ID,
|
ID: book.ID,
|
||||||
MediaItemID: pgtype.UUID{Bytes: bestMatch.BookmannUUID, Valid: true},
|
MediaItemID: pgtype.UUID{Bytes: bestMatch.BookhoardUUID, Valid: true},
|
||||||
ConfidenceScore: toFloat8(bestMatch.Confidence),
|
ConfidenceScore: toFloat8(bestMatch.Confidence),
|
||||||
})
|
})
|
||||||
|
|
||||||
results = append(results, map[string]interface{}{
|
results = append(results, map[string]interface{}{
|
||||||
"unlinked_book_id": uuid.UUID(book.ID.Bytes).String(),
|
"unlinked_book_id": uuid.UUID(book.ID.Bytes).String(),
|
||||||
"title": book.Title.String,
|
"title": book.Title.String,
|
||||||
"matched_media_item_id": bestMatch.BookmannUUID.String(),
|
"matched_media_item_id": bestMatch.BookhoardUUID.String(),
|
||||||
"confidence": bestMatch.Confidence,
|
"confidence": bestMatch.Confidence,
|
||||||
"match_method": bestMatch.MatchMethod,
|
"match_method": bestMatch.MatchMethod,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"bookmann/internal/services"
|
"bookhoard/internal/services"
|
||||||
wsync "bookmann/internal/sync"
|
wsync "bookhoard/internal/sync"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
wsync "bookmann/internal/sync"
|
wsync "bookhoard/internal/sync"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/config"
|
"bookhoard/internal/config"
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"bookmann/internal/services"
|
"bookhoard/internal/services"
|
||||||
wsync "bookmann/internal/sync"
|
wsync "bookhoard/internal/sync"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|||||||
+18
-18
@@ -1,8 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
wsync "bookmann/internal/sync"
|
wsync "bookhoard/internal/sync"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -25,9 +25,9 @@ func NewKoboHandler(db *database.Queries, connManager *wsync.ConnectionManager)
|
|||||||
return &KoboHandler{db: db, connManager: connManager}
|
return &KoboHandler{db: db, connManager: connManager}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapContentIdToBookmannUUID maps Kobo ContentId to Bookmann UUID with multiple fallback strategies
|
// mapContentIdToBookhoardUUID maps Kobo ContentId to Bookmann UUID with multiple fallback strategies
|
||||||
// Phase 6: Enhanced Kobo Sync - ContentId Mapping Logic
|
// Phase 6: Enhanced Kobo Sync - ContentId Mapping Logic
|
||||||
func (h *KoboHandler) mapContentIdToBookmannUUID(ctx echo.Context, contentId string, deviceID uuid.UUID) (uuid.UUID, error, string) {
|
func (h *KoboHandler) mapContentIdToBookhoardUUID(ctx echo.Context, contentId string, deviceID uuid.UUID) (uuid.UUID, error, string) {
|
||||||
// Step 1: Try direct ContentId lookup in device_catalogs table
|
// Step 1: Try direct ContentId lookup in device_catalogs table
|
||||||
catalog, err := h.db.GetDeviceCatalogByKoboContentId(ctx.Request().Context(), contentId)
|
catalog, err := h.db.GetDeviceCatalogByKoboContentId(ctx.Request().Context(), contentId)
|
||||||
if err == nil && catalog.ID.Valid {
|
if err == nil && catalog.ID.Valid {
|
||||||
@@ -66,7 +66,7 @@ func (h *KoboHandler) mapContentIdToBookmannUUID(ctx echo.Context, contentId str
|
|||||||
MediaItemID: pgtype.UUID{Bytes: mediaItem.ID.Bytes, Valid: true},
|
MediaItemID: pgtype.UUID{Bytes: mediaItem.ID.Bytes, Valid: true},
|
||||||
BookmannUuid: pgtype.UUID{Bytes: mediaItem.ID.Bytes, Valid: true},
|
BookmannUuid: pgtype.UUID{Bytes: mediaItem.ID.Bytes, Valid: true},
|
||||||
KoboContentID: contentId,
|
KoboContentID: contentId,
|
||||||
ContentIDType: pgtype.Text{String: "bookmann_uuid", Valid: true},
|
ContentIDType: pgtype.Text{String: "bookhoard_uuid", Valid: true},
|
||||||
Available: pgtype.Bool{Bool: true, Valid: true},
|
Available: pgtype.Bool{Bool: true, Valid: true},
|
||||||
DeliveryDate: pgtype.Timestamptz{Time: time.Now(), Valid: true},
|
DeliveryDate: pgtype.Timestamptz{Time: time.Now(), Valid: true},
|
||||||
DeliveryMethod: pgtype.Text{String: "sync", Valid: true},
|
DeliveryMethod: pgtype.Text{String: "sync", Valid: true},
|
||||||
@@ -79,11 +79,11 @@ func (h *KoboHandler) mapContentIdToBookmannUUID(ctx echo.Context, contentId str
|
|||||||
return uuid.Nil, fmt.Errorf("unlinked book: ContentId %s not found", contentId), "unlinked"
|
return uuid.Nil, fmt.Errorf("unlinked book: ContentId %s not found", contentId), "unlinked"
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapBookmannUUIDToKoboContentId maps Bookmann UUID to Kobo ContentId
|
// mapBookhoardUUIDToKoboContentId maps Bookmann UUID to Kobo ContentId
|
||||||
// Creates new entry in device_catalogs if not exists
|
// Creates new entry in device_catalogs if not exists
|
||||||
func (h *KoboHandler) mapBookmannUUIDToKoboContentId(c echo.Context, bookmannUUID uuid.UUID, deviceID uuid.UUID) (string, error) {
|
func (h *KoboHandler) mapBookhoardUUIDToKoboContentId(c echo.Context, bookmannUUID uuid.UUID, deviceID uuid.UUID) (string, error) {
|
||||||
// Check if catalog entry already exists
|
// Check if catalog entry already exists
|
||||||
catalog, err := h.db.GetDeviceCatalogByBookmannUUID(c.Request().Context(), database.GetDeviceCatalogByBookmannUUIDParams{
|
catalog, err := h.db.GetDeviceCatalogByBookhoardUUID(c.Request().Context(), database.GetDeviceCatalogByBookhoardUUIDParams{
|
||||||
DeviceID: pgtype.UUID{Bytes: deviceID, Valid: true},
|
DeviceID: pgtype.UUID{Bytes: deviceID, Valid: true},
|
||||||
BookmannUuid: pgtype.UUID{Bytes: bookmannUUID, Valid: true},
|
BookmannUuid: pgtype.UUID{Bytes: bookmannUUID, Valid: true},
|
||||||
})
|
})
|
||||||
@@ -102,7 +102,7 @@ func (h *KoboHandler) mapBookmannUUIDToKoboContentId(c echo.Context, bookmannUUI
|
|||||||
// 2. Use existing entitlement_id from media_items
|
// 2. Use existing entitlement_id from media_items
|
||||||
// 3. Generate new "kobo_" prefixed UUID
|
// 3. Generate new "kobo_" prefixed UUID
|
||||||
var koboContentId string
|
var koboContentId string
|
||||||
contentIdType := "bookmann_generated"
|
contentIdType := "bookhoard_generated"
|
||||||
|
|
||||||
if mediaItem.KoboContentID.Valid && mediaItem.KoboContentID.String != "" {
|
if mediaItem.KoboContentID.Valid && mediaItem.KoboContentID.String != "" {
|
||||||
koboContentId = mediaItem.KoboContentID.String
|
koboContentId = mediaItem.KoboContentID.String
|
||||||
@@ -226,7 +226,7 @@ type KoboLibraryBook struct {
|
|||||||
MimeType string `json:"MimeType"`
|
MimeType string `json:"MimeType"`
|
||||||
FileSize int64 `json:"FileSize"`
|
FileSize int64 `json:"FileSize"`
|
||||||
Categories []string `json:"Categories,omitempty"`
|
Categories []string `json:"Categories,omitempty"`
|
||||||
BookmannUUID string `json:"BookmannUUID,omitempty"`
|
BookhoardUUID string `json:"BookhoardUUID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type KoboLibraryResponse struct {
|
type KoboLibraryResponse struct {
|
||||||
@@ -319,7 +319,7 @@ func (h *KoboHandler) Initialization(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Phase 6: Use ContentId mapping instead of direct UUID
|
// Phase 6: Use ContentId mapping instead of direct UUID
|
||||||
koboContentId, err := h.mapBookmannUUIDToKoboContentId(c, bookmannUUID, deviceUUID)
|
koboContentId, err := h.mapBookhoardUUIDToKoboContentId(c, bookmannUUID, deviceUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Fallback to entitlement_id or generate new one
|
// Fallback to entitlement_id or generate new one
|
||||||
if item.EntitlementID.Valid && item.EntitlementID.String != "" {
|
if item.EntitlementID.Valid && item.EntitlementID.String != "" {
|
||||||
@@ -361,7 +361,7 @@ func (h *KoboHandler) Initialization(c echo.Context) error {
|
|||||||
MimeType: mimeType,
|
MimeType: mimeType,
|
||||||
FileSize: fileSize,
|
FileSize: fileSize,
|
||||||
Categories: collections,
|
Categories: collections,
|
||||||
BookmannUUID: bookmannUUID.String(),
|
BookhoardUUID: bookmannUUID.String(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,7 +397,7 @@ func (h *KoboHandler) Markup(c echo.Context) error {
|
|||||||
|
|
||||||
for _, readingSync := range req.ReadingSync {
|
for _, readingSync := range req.ReadingSync {
|
||||||
// Phase 6: Use ContentId mapping with fallback logic
|
// Phase 6: Use ContentId mapping with fallback logic
|
||||||
bookmannUUID, err, _ := h.mapContentIdToBookmannUUID(c, readingSync.ContentId, deviceUUID)
|
bookmannUUID, err, _ := h.mapContentIdToBookhoardUUID(c, readingSync.ContentId, deviceUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Unlinked book detected
|
// Unlinked book detected
|
||||||
unlinkedBooks++
|
unlinkedBooks++
|
||||||
@@ -434,7 +434,7 @@ func (h *KoboHandler) Markup(c echo.Context) error {
|
|||||||
|
|
||||||
for _, bookmarkSync := range req.BookmarkSync {
|
for _, bookmarkSync := range req.BookmarkSync {
|
||||||
// Phase 6: Use ContentId mapping with fallback logic
|
// Phase 6: Use ContentId mapping with fallback logic
|
||||||
bookmannUUID, err, _ := h.mapContentIdToBookmannUUID(c, bookmarkSync.ContentId, deviceUUID)
|
bookmannUUID, err, _ := h.mapContentIdToBookhoardUUID(c, bookmarkSync.ContentId, deviceUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Unlinked book - skip
|
// Unlinked book - skip
|
||||||
continue
|
continue
|
||||||
@@ -512,7 +512,7 @@ func (h *KoboHandler) Bookmark(c echo.Context) error {
|
|||||||
|
|
||||||
for _, bookmarkSync := range req.BookmarkSync {
|
for _, bookmarkSync := range req.BookmarkSync {
|
||||||
// Phase 6: Use ContentId mapping with fallback logic
|
// Phase 6: Use ContentId mapping with fallback logic
|
||||||
bookmannUUID, err, _ := h.mapContentIdToBookmannUUID(c, bookmarkSync.ContentId, deviceUUID)
|
bookmannUUID, err, _ := h.mapContentIdToBookhoardUUID(c, bookmarkSync.ContentId, deviceUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Unlinked book - skip
|
// Unlinked book - skip
|
||||||
continue
|
continue
|
||||||
@@ -577,7 +577,7 @@ func (h *KoboHandler) AnalyticsGettests(c echo.Context) error {
|
|||||||
|
|
||||||
for _, test := range req {
|
for _, test := range req {
|
||||||
// Phase 6: Use ContentId mapping with fallback logic
|
// Phase 6: Use ContentId mapping with fallback logic
|
||||||
bookmannUUID, err, _ := h.mapContentIdToBookmannUUID(c, test.ContentId, deviceUUID)
|
bookmannUUID, err, _ := h.mapContentIdToBookhoardUUID(c, test.ContentId, deviceUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Unlinked book - skip
|
// Unlinked book - skip
|
||||||
continue
|
continue
|
||||||
@@ -654,7 +654,7 @@ func (h *KoboHandler) SyncFromServer(c echo.Context) error {
|
|||||||
|
|
||||||
for _, syncData := range req {
|
for _, syncData := range req {
|
||||||
// Phase 6: Use ContentId mapping with fallback logic
|
// Phase 6: Use ContentId mapping with fallback logic
|
||||||
bookmannUUID, err, _ := h.mapContentIdToBookmannUUID(c, syncData.ContentId, deviceUUID)
|
bookmannUUID, err, _ := h.mapContentIdToBookhoardUUID(c, syncData.ContentId, deviceUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Unlinked book - skip
|
// Unlinked book - skip
|
||||||
continue
|
continue
|
||||||
@@ -669,7 +669,7 @@ func (h *KoboHandler) SyncFromServer(c echo.Context) error {
|
|||||||
UserID: pgUserID,
|
UserID: pgUserID,
|
||||||
Percentage: pgtype.Float8{Float64: percentage, Valid: true},
|
Percentage: pgtype.Float8{Float64: percentage, Valid: true},
|
||||||
LastSyncDevice: pgtype.Text{String: "kobo", Valid: true},
|
LastSyncDevice: pgtype.Text{String: "kobo", Valid: true},
|
||||||
LastSyncSource: pgtype.Text{String: "bookmann", Valid: true},
|
LastSyncSource: pgtype.Text{String: "bookhoard", Valid: true},
|
||||||
})
|
})
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
wsync "bookmann/internal/sync"
|
wsync "bookhoard/internal/sync"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"bookmann/internal/services"
|
"bookhoard/internal/services"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|||||||
+10
-10
@@ -1,9 +1,9 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"bookmann/internal/opds"
|
"bookhoard/internal/opds"
|
||||||
"bookmann/internal/services"
|
"bookhoard/internal/services"
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
@@ -137,7 +137,7 @@ func (h *OPDSHandler) GetDeviceCatalog(c echo.Context) error {
|
|||||||
// Create OPDS feed
|
// Create OPDS feed
|
||||||
feed := opds.NewFeed(
|
feed := opds.NewFeed(
|
||||||
fmt.Sprintf("urn:uuid:%s", deviceID),
|
fmt.Sprintf("urn:uuid:%s", deviceID),
|
||||||
"Bookmann Library",
|
"Bookhoard Library",
|
||||||
)
|
)
|
||||||
|
|
||||||
// Add feed links
|
// Add feed links
|
||||||
@@ -187,7 +187,7 @@ func (h *OPDSHandler) GetDeviceCatalog(c echo.Context) error {
|
|||||||
|
|
||||||
// Add SHA-256 metadata
|
// Add SHA-256 metadata
|
||||||
if item.FileSha256.Valid {
|
if item.FileSha256.Valid {
|
||||||
entry.AddMetadata("bookmann:sha256", item.FileSha256.String)
|
entry.AddMetadata("bookhoard:sha256", item.FileSha256.String)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add collections as categories
|
// Add collections as categories
|
||||||
@@ -305,7 +305,7 @@ func (h *OPDSHandler) SearchDeviceCatalog(c echo.Context) error {
|
|||||||
entry.SetIdentifier(bookUUID)
|
entry.SetIdentifier(bookUUID)
|
||||||
|
|
||||||
if item.FileSha256.Valid {
|
if item.FileSha256.Valid {
|
||||||
entry.AddMetadata("bookmann:sha256", item.FileSha256.String)
|
entry.AddMetadata("bookhoard:sha256", item.FileSha256.String)
|
||||||
}
|
}
|
||||||
|
|
||||||
collections, err := h.db.GetCollectionsForBook(c.Request().Context(), pgtype.UUID{Bytes: item.ID.Bytes, Valid: true})
|
collections, err := h.db.GetCollectionsForBook(c.Request().Context(), pgtype.UUID{Bytes: item.ID.Bytes, Valid: true})
|
||||||
@@ -466,12 +466,12 @@ func (h *OPDSHandler) DownloadBook(c echo.Context) error {
|
|||||||
filename := filepath.Base(filePath)
|
filename := filepath.Base(filePath)
|
||||||
c.Response().Header().Set("Content-Type", mimeType)
|
c.Response().Header().Set("Content-Type", mimeType)
|
||||||
c.Response().Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename))
|
c.Response().Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename))
|
||||||
c.Response().Header().Set("X-Bookmann-UUID", bookUUID.String())
|
c.Response().Header().Set("X-Bookhoard-UUID", bookUUID.String())
|
||||||
|
|
||||||
if format == "kepub" && fileSha256 != "" {
|
if format == "kepub" && fileSha256 != "" {
|
||||||
c.Response().Header().Set("X-Bookmann-KEPUB-SHA256", fileSha256)
|
c.Response().Header().Set("X-Bookhoard-KEPUB-SHA256", fileSha256)
|
||||||
} else if fileSha256 != "" {
|
} else if fileSha256 != "" {
|
||||||
c.Response().Header().Set("X-Bookmann-SHA256", fileSha256)
|
c.Response().Header().Set("X-Bookhoard-SHA256", fileSha256)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream file
|
// Stream file
|
||||||
@@ -595,7 +595,7 @@ func (h *OPDSHandler) GetDeviceNavigation(c echo.Context) error {
|
|||||||
// Create OPDS navigation feed
|
// Create OPDS navigation feed
|
||||||
feed := opds.NewFeed(
|
feed := opds.NewFeed(
|
||||||
fmt.Sprintf("urn:uuid:%s", deviceID),
|
fmt.Sprintf("urn:uuid:%s", deviceID),
|
||||||
"Bookmann Library Navigation",
|
"Bookhoard Library Navigation",
|
||||||
)
|
)
|
||||||
|
|
||||||
// Add feed links
|
// Add feed links
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
wsync "bookmann/internal/sync"
|
wsync "bookhoard/internal/sync"
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -22,7 +22,7 @@ func NewSidecarHandler(db *database.Queries) *SidecarHandler {
|
|||||||
|
|
||||||
type SidecarConfig struct {
|
type SidecarConfig struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Bookmann SidecarBookmannConfig `json:"bookmann"`
|
Bookmann SidecarBookmannConfig `json:"bookhoard"`
|
||||||
Books map[string]SidecarBook `json:"books"`
|
Books map[string]SidecarBook `json:"books"`
|
||||||
Collections []SidecarCollection `json:"collections"`
|
Collections []SidecarCollection `json:"collections"`
|
||||||
OPDSEnabled bool `json:"opds_enabled"`
|
OPDSEnabled bool `json:"opds_enabled"`
|
||||||
@@ -40,7 +40,7 @@ type SidecarBookmannConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SidecarBook struct {
|
type SidecarBook struct {
|
||||||
BookmannUUID string `json:"bookmann_uuid"`
|
BookhoardUUID string `json:"bookhoard_uuid"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Author string `json:"author"`
|
Author string `json:"author"`
|
||||||
AvailableFormats []string `json:"available_formats"`
|
AvailableFormats []string `json:"available_formats"`
|
||||||
@@ -119,7 +119,7 @@ func (h *SidecarHandler) GetSidecarConfig(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
books[key] = SidecarBook{
|
books[key] = SidecarBook{
|
||||||
BookmannUUID: bookUUID,
|
BookhoardUUID: bookUUID,
|
||||||
Title: item.Title,
|
Title: item.Title,
|
||||||
Author: author,
|
Author: author,
|
||||||
AvailableFormats: availableFormats,
|
AvailableFormats: availableFormats,
|
||||||
@@ -254,7 +254,7 @@ func (h *SidecarHandler) DownloadSidecarConfig(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
books[key] = SidecarBook{
|
books[key] = SidecarBook{
|
||||||
BookmannUUID: bookUUID,
|
BookhoardUUID: bookUUID,
|
||||||
Title: item.Title,
|
Title: item.Title,
|
||||||
Author: author,
|
Author: author,
|
||||||
AvailableFormats: availableFormats,
|
AvailableFormats: availableFormats,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"bookmann/internal/middleware"
|
"bookhoard/internal/middleware"
|
||||||
"bookmann/internal/sync"
|
"bookhoard/internal/sync"
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/config"
|
"bookhoard/internal/config"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ func (e *Entry) AddLink(href, linkType, rel string) {
|
|||||||
// SetIdentifier sets the canonical identifier
|
// SetIdentifier sets the canonical identifier
|
||||||
func (e *Entry) SetIdentifier(id string) {
|
func (e *Entry) SetIdentifier(id string) {
|
||||||
e.Identifier = &Identifier{
|
e.Identifier = &Identifier{
|
||||||
ID: "bookmann",
|
ID: "bookhoard",
|
||||||
Content: id,
|
Content: id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ func TestEntrySetIdentifier(t *testing.T) {
|
|||||||
t.Fatal("expected Identifier to be set, but it was nil")
|
t.Fatal("expected Identifier to be set, but it was nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.Identifier.ID != "bookmann" {
|
if entry.Identifier.ID != "bookhoard" {
|
||||||
t.Errorf("expected Identifier ID to be 'bookmann', got '%s'", entry.Identifier.ID)
|
t.Errorf("expected Identifier ID to be 'bookmann', got '%s'", entry.Identifier.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,14 +131,14 @@ func TestEntrySetIdentifier(t *testing.T) {
|
|||||||
|
|
||||||
func TestEntryAddMetadata(t *testing.T) {
|
func TestEntryAddMetadata(t *testing.T) {
|
||||||
entry := NewEntry("urn:uuid:test-id", "Test Title", "Test Author", "2023-01-01T00:00:00Z")
|
entry := NewEntry("urn:uuid:test-id", "Test Title", "Test Author", "2023-01-01T00:00:00Z")
|
||||||
entry.AddMetadata("bookmann:sha256", "abc123...")
|
entry.AddMetadata("bookhoard:sha256", "abc123...")
|
||||||
|
|
||||||
if len(entry.Metadata) != 1 {
|
if len(entry.Metadata) != 1 {
|
||||||
t.Fatalf("expected 1 metadata item, got %d", len(entry.Metadata))
|
t.Fatalf("expected 1 metadata item, got %d", len(entry.Metadata))
|
||||||
}
|
}
|
||||||
|
|
||||||
meta := entry.Metadata[0]
|
meta := entry.Metadata[0]
|
||||||
if meta.Property != "bookmann:sha256" {
|
if meta.Property != "bookhoard:sha256" {
|
||||||
t.Errorf("expected Property to be 'bookmann:sha256', got '%s'", meta.Property)
|
t.Errorf("expected Property to be 'bookmann:sha256', got '%s'", meta.Property)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ func TestFeedGenerateXML(t *testing.T) {
|
|||||||
entry := NewEntry("urn:uuid:book-id", "Test Book", "Test Author", "2023-01-01T00:00:00Z")
|
entry := NewEntry("urn:uuid:book-id", "Test Book", "Test Author", "2023-01-01T00:00:00Z")
|
||||||
entry.AddAcquisitionLink("http://example.com/book.epub", "application/epub+zip")
|
entry.AddAcquisitionLink("http://example.com/book.epub", "application/epub+zip")
|
||||||
entry.SetIdentifier("book-uuid-123")
|
entry.SetIdentifier("book-uuid-123")
|
||||||
entry.AddMetadata("bookmann:sha256", "abc123...")
|
entry.AddMetadata("bookhoard:sha256", "abc123...")
|
||||||
feed.AddEntry(entry)
|
feed.AddEntry(entry)
|
||||||
|
|
||||||
output, err := feed.GenerateXML()
|
output, err := feed.GenerateXML()
|
||||||
@@ -205,8 +205,8 @@ func TestFeedGenerateXML(t *testing.T) {
|
|||||||
`<dc:creator>Test Author</dc:creator>`,
|
`<dc:creator>Test Author</dc:creator>`,
|
||||||
`<link href="http://example.com/book.epub"`,
|
`<link href="http://example.com/book.epub"`,
|
||||||
`rel="http://opds-spec.org/acquisition/open-access"`,
|
`rel="http://opds-spec.org/acquisition/open-access"`,
|
||||||
`<dc:identifier id="bookmann">book-uuid-123</dc:identifier>`,
|
`<dc:identifier id="bookhoard">book-uuid-123</dc:identifier>`,
|
||||||
`<meta property="bookmann:sha256">abc123...</meta>`,
|
`<meta property="bookhoard:sha256">abc123...</meta>`,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, required := range requiredStrings {
|
for _, required := range requiredStrings {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
// BookMatch represents a potential match with confidence score
|
// BookMatch represents a potential match with confidence score
|
||||||
type BookMatch struct {
|
type BookMatch struct {
|
||||||
MediaItemID uuid.UUID `json:"media_item_id"`
|
MediaItemID uuid.UUID `json:"media_item_id"`
|
||||||
BookmannUUID uuid.UUID `json:"bookmann_uuid"`
|
BookhoardUUID uuid.UUID `json:"bookhoard_uuid"`
|
||||||
Confidence float64 `json:"confidence"`
|
Confidence float64 `json:"confidence"`
|
||||||
MatchMethod string `json:"match_method"`
|
MatchMethod string `json:"match_method"`
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ func (s *BookMatchingService) QueryBooks(ctx context.Context, req *BookQueryRequ
|
|||||||
var matches []BookMatch
|
var matches []BookMatch
|
||||||
|
|
||||||
// Priority 1: Bookmann UUID (canonical) - Confidence: 1.0
|
// Priority 1: Bookmann UUID (canonical) - Confidence: 1.0
|
||||||
if match := s.matchByBookmannUUID(ctx, req.Identifiers); match != nil {
|
if match := s.matchByBookhoardUUID(ctx, req.Identifiers); match != nil {
|
||||||
matches = append(matches, *match)
|
matches = append(matches, *match)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,8 +113,8 @@ func (s *BookMatchingService) QueryBooks(ctx context.Context, req *BookQueryRequ
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// matchByBookmannUUID attempts to match by Bookmann UUID
|
// matchByBookhoardUUID attempts to match by Bookmann UUID
|
||||||
func (s *BookMatchingService) matchByBookmannUUID(ctx context.Context, identifiers []string) *BookMatch {
|
func (s *BookMatchingService) matchByBookhoardUUID(ctx context.Context, identifiers []string) *BookMatch {
|
||||||
for _, id := range identifiers {
|
for _, id := range identifiers {
|
||||||
if len(id) > 4 && id[:4] == "uuid:" {
|
if len(id) > 4 && id[:4] == "uuid:" {
|
||||||
uuidStr := id[5:]
|
uuidStr := id[5:]
|
||||||
@@ -129,7 +129,7 @@ func (s *BookMatchingService) matchByBookmannUUID(ctx context.Context, identifie
|
|||||||
mediaUUID := item.ID.Bytes
|
mediaUUID := item.ID.Bytes
|
||||||
return &BookMatch{
|
return &BookMatch{
|
||||||
MediaItemID: mediaUUID,
|
MediaItemID: mediaUUID,
|
||||||
BookmannUUID: mediaUUID,
|
BookhoardUUID: mediaUUID,
|
||||||
Confidence: 1.0,
|
Confidence: 1.0,
|
||||||
MatchMethod: "uuid_match",
|
MatchMethod: "uuid_match",
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,7 @@ func (s *BookMatchingService) matchByOPFUUID(ctx context.Context, identifiers []
|
|||||||
if item.OpfUuid.Valid && item.OpfUuid.String == uuidStr {
|
if item.OpfUuid.Valid && item.OpfUuid.String == uuidStr {
|
||||||
return &BookMatch{
|
return &BookMatch{
|
||||||
MediaItemID: item.ID.Bytes,
|
MediaItemID: item.ID.Bytes,
|
||||||
BookmannUUID: item.ID.Bytes,
|
BookhoardUUID: item.ID.Bytes,
|
||||||
Confidence: 0.95,
|
Confidence: 0.95,
|
||||||
MatchMethod: "opf_uuid_match",
|
MatchMethod: "opf_uuid_match",
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@ func (s *BookMatchingService) matchBySHA256(ctx context.Context, sha256 string)
|
|||||||
if item.FileSha256.Valid && item.FileSha256.String == sha256 {
|
if item.FileSha256.Valid && item.FileSha256.String == sha256 {
|
||||||
return &BookMatch{
|
return &BookMatch{
|
||||||
MediaItemID: item.ID.Bytes,
|
MediaItemID: item.ID.Bytes,
|
||||||
BookmannUUID: item.ID.Bytes,
|
BookhoardUUID: item.ID.Bytes,
|
||||||
Confidence: 0.9,
|
Confidence: 0.9,
|
||||||
MatchMethod: "sha256_match",
|
MatchMethod: "sha256_match",
|
||||||
}
|
}
|
||||||
@@ -207,7 +207,7 @@ func (s *BookMatchingService) matchByOPFIdentifier(ctx context.Context, identifi
|
|||||||
if item.OpfIdentifier.Valid && item.OpfIdentifier.String == identifier {
|
if item.OpfIdentifier.Valid && item.OpfIdentifier.String == identifier {
|
||||||
return &BookMatch{
|
return &BookMatch{
|
||||||
MediaItemID: item.ID.Bytes,
|
MediaItemID: item.ID.Bytes,
|
||||||
BookmannUUID: item.ID.Bytes,
|
BookhoardUUID: item.ID.Bytes,
|
||||||
Confidence: 0.85,
|
Confidence: 0.85,
|
||||||
MatchMethod: "opf_identifier_match",
|
MatchMethod: "opf_identifier_match",
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ func (s *BookMatchingService) matchByISBNASIN(ctx context.Context, identifiers [
|
|||||||
if item.Isbn.Valid && item.Isbn.String == isbn {
|
if item.Isbn.Valid && item.Isbn.String == isbn {
|
||||||
return &BookMatch{
|
return &BookMatch{
|
||||||
MediaItemID: item.ID.Bytes,
|
MediaItemID: item.ID.Bytes,
|
||||||
BookmannUUID: item.ID.Bytes,
|
BookhoardUUID: item.ID.Bytes,
|
||||||
Confidence: 0.8,
|
Confidence: 0.8,
|
||||||
MatchMethod: "isbn_match",
|
MatchMethod: "isbn_match",
|
||||||
}
|
}
|
||||||
@@ -257,7 +257,7 @@ func (s *BookMatchingService) matchByISBNASIN(ctx context.Context, identifiers [
|
|||||||
if item.Asin.Valid && item.Asin.String == asin {
|
if item.Asin.Valid && item.Asin.String == asin {
|
||||||
return &BookMatch{
|
return &BookMatch{
|
||||||
MediaItemID: item.ID.Bytes,
|
MediaItemID: item.ID.Bytes,
|
||||||
BookmannUUID: item.ID.Bytes,
|
BookhoardUUID: item.ID.Bytes,
|
||||||
Confidence: 0.8,
|
Confidence: 0.8,
|
||||||
MatchMethod: "asin_match",
|
MatchMethod: "asin_match",
|
||||||
}
|
}
|
||||||
@@ -293,7 +293,7 @@ func (s *BookMatchingService) matchByTitleAuthorSize(ctx context.Context, title,
|
|||||||
if titleMatch && authorMatch && sizeMatch {
|
if titleMatch && authorMatch && sizeMatch {
|
||||||
matches = append(matches, BookMatch{
|
matches = append(matches, BookMatch{
|
||||||
MediaItemID: item.ID.Bytes,
|
MediaItemID: item.ID.Bytes,
|
||||||
BookmannUUID: item.ID.Bytes,
|
BookhoardUUID: item.ID.Bytes,
|
||||||
Confidence: 0.5,
|
Confidence: 0.5,
|
||||||
MatchMethod: "title_author_size_match",
|
MatchMethod: "title_author_size_match",
|
||||||
})
|
})
|
||||||
@@ -319,7 +319,7 @@ func (s *BookMatchingService) matchByTitleOnly(ctx context.Context, title string
|
|||||||
if item.Title == title {
|
if item.Title == title {
|
||||||
matches = append(matches, BookMatch{
|
matches = append(matches, BookMatch{
|
||||||
MediaItemID: item.ID.Bytes,
|
MediaItemID: item.ID.Bytes,
|
||||||
BookmannUUID: item.ID.Bytes,
|
BookhoardUUID: item.ID.Bytes,
|
||||||
Confidence: 0.3,
|
Confidence: 0.3,
|
||||||
MatchMethod: "title_match",
|
MatchMethod: "title_match",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"bookmann/internal/utils"
|
"bookhoard/internal/utils"
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package sync
|
package sync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package sync
|
package sync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package sync
|
package sync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package sync
|
package sync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bookmann/internal/database"
|
"bookhoard/internal/database"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|||||||
Reference in New Issue
Block a user