Skip to content

Commit

Permalink
feat: add basic api support
Browse files Browse the repository at this point in the history
  • Loading branch information
scenery committed Aug 29, 2024
1 parent 8159391 commit f0dd706
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 0 deletions.
6 changes: 6 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ const (
MaxCacheSubjects = 1000
MaxCachePages = 50
)

// API Config
var (
CORS_HOST = "*"
RequestLimit = 50
)
52 changes: 52 additions & 0 deletions dataops/export_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dataops

import (
"encoding/json"
"fmt"
"time"

"github.com/scenery/mediax/database"
"github.com/scenery/mediax/models"
)

func ExportToJSONAPI(subjectType string, limit, offset int) ([]byte, error) {
db := database.GetDB()

var subjects []models.SubjectExportItem
query := db.Model(&models.Subject{}).
Select("uuid, subject_type, title, alt_title, pub_date, creator, press, status, rating, summary, comment, external_url, mark_date, created_at").
Order("id DESC").
Offset(offset)
if subjectType != "all" {
query = query.Where("subject_type = ?", subjectType)
}
query = query.Limit(limit)
if err := query.Find(&subjects).Error; err != nil {
return nil, fmt.Errorf("failed to query subjects: %v", err)
}

totalCount := len(subjects)
if totalCount == 0 {
message := map[string]string{
"message": "no records found",
}
jsonData, err := json.Marshal(message)
if err != nil {
return nil, fmt.Errorf("failed to marshal json: %v", err)
}
return jsonData, nil
}

exportData := models.SubjectExportAPI{
Subjects: subjects,
ResponseTime: time.Now().Format(time.RFC3339),
TotalCount: totalCount,
}

jsonData, err := json.MarshalIndent(exportData, "", " ")
if err != nil {
return nil, fmt.Errorf("failed to marshal json: %v", err)
}

return jsonData, nil
}
6 changes: 6 additions & 0 deletions models/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ type SubjectExport struct {
ExportTime string `json:"export_time"`
TotalCount int `json:"total_count"`
}

type SubjectExportAPI struct {
Subjects []SubjectExportItem `json:"subjects"`
ResponseTime string `json:"response_time"`
TotalCount int `json:"total_count"`
}
83 changes: 83 additions & 0 deletions routes/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package routes

import (
"fmt"
"net/http"

"github.com/scenery/mediax/config"
"github.com/scenery/mediax/dataops"
"github.com/scenery/mediax/helpers"
)

func handleAPI(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Origin", config.CORS_HOST)

switch r.Method {
case http.MethodGet:
query := r.URL.Query()
subjectType := query.Get("type")
queryLimit := query.Get("limit")
queryOffset := query.Get("offset")

validTypes := map[string]bool{
"all": true,
"book": true,
"movie": true,
"tv": true,
"anime": true,
"game": true,
}
if subjectType == "" {
subjectType = "all"
} else if !validTypes[subjectType] {
handleAPIError(w, http.StatusBadRequest, "invalid subject type")
return
}

limit := config.RequestLimit
if queryLimit != "" {
var err error
limit, err = helpers.StringToInt(queryLimit)
if err != nil {
handleAPIError(w, http.StatusBadRequest, "invalid limit")
return
}
if limit < 1 || limit > config.RequestLimit {
limit = config.RequestLimit
}
}

offset := 0
if queryOffset != "" {
var err error
offset, err = helpers.StringToInt(queryOffset)
if err != nil {
handleAPIError(w, http.StatusBadRequest, "invalid offset")
return
}
if offset < 1 {
offset = 0
}
}

responseJSON, err := dataops.ExportToJSONAPI(subjectType, limit, offset)
if err != nil {
handleAPIError(w, http.StatusInternalServerError, err.Error())
return
}
w.Write(responseJSON)
return
default:
handleAPIError(w, http.StatusMethodNotAllowed, "method not allowed")
return
}
}

func handleAPIError(w http.ResponseWriter, errStatus int, errMessage string) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(errStatus)
response := fmt.Sprintf(`{"error": "%s"}`, errMessage)
w.Write([]byte(response))
}
2 changes: 2 additions & 0 deletions routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ func setupRoutes() {
http.HandleFunc("/add/subject", handleAddSubject)

http.HandleFunc("/search", handleSearch)

http.HandleFunc("/api/v0/collection", handleAPI)
}

0 comments on commit f0dd706

Please sign in to comment.