Initial Commit
This commit is contained in:
169
api/app-routes.go
Normal file
169
api/app-routes.go
Normal file
@@ -0,0 +1,169 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"reichard.io/bbank/database"
|
||||
"reichard.io/bbank/metadata"
|
||||
)
|
||||
|
||||
func baseResourceRoute(template string, args ...map[string]any) func(c *gin.Context) {
|
||||
variables := gin.H{"RouteName": template}
|
||||
if len(args) > 0 {
|
||||
variables = args[0]
|
||||
}
|
||||
|
||||
return func(c *gin.Context) {
|
||||
rUser, _ := c.Get("AuthorizedUser")
|
||||
variables["User"] = rUser
|
||||
c.HTML(http.StatusOK, template, variables)
|
||||
}
|
||||
}
|
||||
|
||||
func (api *API) createAppResourcesRoute(routeName string, args ...map[string]any) func(*gin.Context) {
|
||||
// Merge Optional Template Data
|
||||
var templateVars = gin.H{}
|
||||
if len(args) > 0 {
|
||||
templateVars = args[0]
|
||||
}
|
||||
templateVars["RouteName"] = routeName
|
||||
|
||||
return func(c *gin.Context) {
|
||||
rUser, _ := c.Get("AuthorizedUser")
|
||||
qParams := bindQueryParams(c)
|
||||
templateVars["User"] = rUser
|
||||
|
||||
if routeName == "documents" {
|
||||
documents, err := api.DB.Queries.GetDocumentsWithStats(api.DB.Ctx, database.GetDocumentsWithStatsParams{
|
||||
UserID: rUser.(string),
|
||||
Offset: (*qParams.Page - 1) * *qParams.Limit,
|
||||
Limit: *qParams.Limit,
|
||||
})
|
||||
if err != nil {
|
||||
log.Info(err)
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
||||
return
|
||||
}
|
||||
|
||||
templateVars["Data"] = documents
|
||||
} else if routeName == "home" {
|
||||
weekly_streak, _ := api.DB.Queries.GetUserWindowStreaks(api.DB.Ctx, database.GetUserWindowStreaksParams{
|
||||
UserID: rUser.(string),
|
||||
Window: "WEEK",
|
||||
})
|
||||
|
||||
daily_streak, _ := api.DB.Queries.GetUserWindowStreaks(api.DB.Ctx, database.GetUserWindowStreaksParams{
|
||||
UserID: rUser.(string),
|
||||
Window: "DAY",
|
||||
})
|
||||
|
||||
database_info, _ := api.DB.Queries.GetDatabaseInfo(api.DB.Ctx, rUser.(string))
|
||||
read_graph_data, err := api.DB.Queries.GetDailyReadStats(api.DB.Ctx, rUser.(string))
|
||||
if err != nil {
|
||||
log.Info("HMMMM:", err)
|
||||
}
|
||||
|
||||
templateVars["Data"] = gin.H{
|
||||
"DailyStreak": daily_streak,
|
||||
"WeeklyStreak": weekly_streak,
|
||||
"DatabaseInfo": database_info,
|
||||
"GraphData": read_graph_data,
|
||||
}
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, routeName, templateVars)
|
||||
}
|
||||
}
|
||||
|
||||
func (api *API) getDocumentCover(c *gin.Context) {
|
||||
var rDoc requestDocumentID
|
||||
if err := c.ShouldBindUri(&rDoc); err != nil {
|
||||
c.AbortWithStatus(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Validate Document Exists in DB
|
||||
document, err := api.DB.Queries.GetDocument(api.DB.Ctx, rDoc.DocumentID)
|
||||
if err != nil {
|
||||
c.AbortWithStatus(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Handle Identified Document
|
||||
if document.Olid != nil {
|
||||
if *document.Olid == "UNKNOWN" {
|
||||
c.Redirect(http.StatusFound, "/assets/no-cover.jpg")
|
||||
return
|
||||
}
|
||||
|
||||
// Derive Path
|
||||
fileName := "." + filepath.Clean(fmt.Sprintf("/%s.jpg", *document.Olid))
|
||||
safePath := filepath.Join(api.Config.DataPath, "covers", fileName)
|
||||
|
||||
// Validate File Exists
|
||||
_, err = os.Stat(safePath)
|
||||
if err != nil {
|
||||
c.Redirect(http.StatusFound, "/assets/no-cover.jpg")
|
||||
return
|
||||
}
|
||||
|
||||
c.File(safePath)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
This is a bit convoluted because we want to ensure we set the OLID to
|
||||
UNKNOWN if there are any errors. This will ideally prevent us from
|
||||
hitting the OpenLibrary API multiple times in the future.
|
||||
*/
|
||||
|
||||
var coverID string = "UNKNOWN"
|
||||
var coverFilePath *string
|
||||
|
||||
// Identify Documents & Save Covers
|
||||
coverIDs, err := metadata.GetCoverIDs(document.Title, document.Author)
|
||||
if err == nil && len(coverIDs) > 0 {
|
||||
coverFilePath, err = metadata.DownloadAndSaveCover(coverIDs[0], api.Config.DataPath)
|
||||
if err == nil {
|
||||
coverID = coverIDs[0]
|
||||
}
|
||||
}
|
||||
|
||||
// Upsert Document
|
||||
if _, err = api.DB.Queries.UpsertDocument(api.DB.Ctx, database.UpsertDocumentParams{
|
||||
ID: document.ID,
|
||||
Olid: &coverID,
|
||||
}); err != nil {
|
||||
log.Error("Document Upsert Error")
|
||||
}
|
||||
|
||||
// Return Unknown Cover
|
||||
if coverID == "UNKNOWN" {
|
||||
c.Redirect(http.StatusFound, "/assets/no-cover.jpg")
|
||||
return
|
||||
}
|
||||
|
||||
c.File(*coverFilePath)
|
||||
}
|
||||
|
||||
/*
|
||||
METADATA:
|
||||
- Metadata Match
|
||||
- Update Metadata
|
||||
*/
|
||||
|
||||
/*
|
||||
GRAPHS:
|
||||
- Streaks (Daily, Weekly, Monthly)
|
||||
- Last Week Activity (Daily - Pages & Time)
|
||||
|
||||
|
||||
- Pages Read (Daily, Weekly, Monthly)
|
||||
- Reading Progress
|
||||
- Average Reading Time (Daily, Weekly, Monthly)
|
||||
*/
|
||||
Reference in New Issue
Block a user