Browse Source

Add api CRUD endpoints for posts

master
Tovi Jaeschke-Rogers 3 years ago
parent
commit
7c66aba3b9
16 changed files with 947 additions and 68 deletions
  1. +76
    -0
      Api/JsonSerialization/DeserializePostJson.go
  2. +87
    -0
      Api/JsonSerialization/VerifyJson.go
  3. +257
    -0
      Api/Posts.go
  4. +289
    -0
      Api/Posts_test.go
  5. +28
    -0
      Api/ReturnJson.go
  6. +29
    -0
      Api/Routes.go
  7. +10
    -10
      Database/Init.go
  8. +90
    -0
      Database/Posts.go
  9. +5
    -5
      Models/Base.go
  10. +53
    -0
      Models/Posts.go
  11. +1
    -1
      Models/Subscriptions.go
  12. +0
    -1
      database/Posts.go
  13. +2
    -0
      go.mod
  14. +4
    -0
      go.sum
  15. +16
    -3
      main.go
  16. +0
    -48
      models/Posts.go

+ 76
- 0
Api/JsonSerialization/DeserializePostJson.go View File

@ -0,0 +1,76 @@
package JsonSerialization
import (
"encoding/json"
"errors"
"fmt"
"strings"
"git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Models"
schema "github.com/Kangaroux/go-map-schema"
)
func DeserializePost(data []byte, allowMissing []string, allowAllMissing bool) (Models.Post, error) {
var (
postData Models.Post = Models.Post{}
jsonStructureTest map[string]interface{} = make(map[string]interface{})
jsonStructureTestResults *schema.CompareResults
field schema.FieldMissing
allowed string
missingFields []string
i int
err error
)
// Verify the JSON has the correct structure
json.Unmarshal(data, &jsonStructureTest)
jsonStructureTestResults, err = schema.CompareMapToStruct(
&postData,
jsonStructureTest,
&schema.CompareOpts{
ConvertibleFunc: CanConvert,
TypeNameFunc: schema.DetailedTypeName,
})
if err != nil {
return postData, err
}
if len(jsonStructureTestResults.MismatchedFields) > 0 {
return postData, errors.New(fmt.Sprintf(
"MismatchedFields found when deserializing data: %s",
jsonStructureTestResults.Errors().Error(),
))
}
// Remove allowed missing fields from MissingFields
for _, allowed = range allowMissing {
for i, field = range jsonStructureTestResults.MissingFields {
if allowed == field.String() {
jsonStructureTestResults.MissingFields = append(
jsonStructureTestResults.MissingFields[:i],
jsonStructureTestResults.MissingFields[i+1:]...,
)
}
}
}
if !allowAllMissing && len(jsonStructureTestResults.MissingFields) > 0 {
for _, field = range jsonStructureTestResults.MissingFields {
missingFields = append(missingFields, field.String())
}
return postData, errors.New(fmt.Sprintf(
"MissingFields found when deserializing data: %s",
strings.Join(missingFields, ", "),
))
}
// Deserialize the JSON into the struct
err = json.Unmarshal(data, &postData)
if err != nil {
return postData, err
}
return postData, err
}

+ 87
- 0
Api/JsonSerialization/VerifyJson.go View File

@ -0,0 +1,87 @@
package JsonSerialization
import (
"math"
"reflect"
)
// isIntegerType returns whether the type is an integer and if it's unsigned.
// See: https://github.com/Kangaroux/go-map-schema/blob/master/schema.go#L328
func isIntegerType(t reflect.Type) (yes bool, unsigned bool) {
switch t.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
yes = true
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
yes = true
unsigned = true
}
return
}
// isFloatType returns true if the type is a floating point. Note that this doesn't
// care about the value -- unmarshaling the number "0" gives a float, not an int.
// See: https://github.com/Kangaroux/go-map-schema/blob/master/schema.go#L319
func isFloatType(t reflect.Type) (yes bool) {
switch t.Kind() {
case reflect.Float32, reflect.Float64:
yes = true
}
return
}
// CanConvert returns whether value v is convertible to type t.
//
// If t is a pointer and v is not nil, it checks if v is convertible to the type that
// t points to.
// Modified due to not handling slices (DefaultCanConvert fails on PhotoUrls and Tags)
// See: https://github.com/Kangaroux/go-map-schema/blob/master/schema.go#L191
func CanConvert(t reflect.Type, v reflect.Value) bool {
isPtr := t.Kind() == reflect.Ptr
isStruct := t.Kind() == reflect.Struct
dstType := t
// Check if v is a nil value.
if !v.IsValid() || (v.CanAddr() && v.IsNil()) {
return isPtr
}
// If the dst is a pointer, check if we can convert to the type it's pointing to.
if isPtr {
dstType = t.Elem()
isStruct = t.Elem().Kind() == reflect.Struct
}
// If the dst is a struct, we should check its nested fields.
if isStruct {
return v.Kind() == reflect.Map
}
if t.Kind() == reflect.Slice {
return v.Kind() == reflect.Slice
}
if !v.Type().ConvertibleTo(dstType) {
return false
}
// Handle converting to an integer type.
if dstInt, unsigned := isIntegerType(dstType); dstInt {
if isFloatType(v.Type()) {
f := v.Float()
if math.Trunc(f) != f {
return false
} else if unsigned && f < 0 {
return false
}
} else if srcInt, _ := isIntegerType(v.Type()); srcInt {
if unsigned && v.Int() < 0 {
return false
}
}
}
return true
}

+ 257
- 0
Api/Posts.go View File

@ -0,0 +1,257 @@
package Api
import (
"encoding/json"
"errors"
"io/ioutil"
"log"
"net/http"
"net/url"
"strconv"
"git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Api/JsonSerialization"
"git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Database"
"git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Models"
"github.com/gorilla/mux"
)
func getPostById(w http.ResponseWriter, r *http.Request) (Models.Post, error) {
var (
postData Models.Post
urlVars map[string]string
id string
ok bool
err error
)
urlVars = mux.Vars(r)
id, ok = urlVars["postID"]
if !ok {
log.Printf("Error encountered getting id\n")
JsonReturn(w, 500, "An error occured")
return postData, errors.New("Could not get id")
}
postData, err = Database.GetPostById(id)
if err != nil {
log.Printf("Could not find pet with id %s\n", id)
JsonReturn(w, 404, "Not found")
return postData, err
}
return postData, nil
}
func getPosts(w http.ResponseWriter, r *http.Request) {
var (
posts []Models.Post
returnJson []byte
values url.Values
page, pageSize int
err error
)
values = r.URL.Query()
page, err = strconv.Atoi(values.Get("page"))
if err != nil {
log.Println("Could not parse page url argument")
JsonReturn(w, 500, "An error occured")
return
}
page, err = strconv.Atoi(values.Get("pageSize"))
if err != nil {
log.Println("Could not parse pageSize url argument")
JsonReturn(w, 500, "An error occured")
return
}
posts, err = Database.GetPosts(page, pageSize)
if err != nil {
log.Printf("An error occured: %s\n", err.Error())
JsonReturn(w, 500, "An error occured")
return
}
returnJson, err = json.MarshalIndent(posts, "", " ")
if err != nil {
JsonReturn(w, 500, "An error occured")
return
}
// Return updated json
w.WriteHeader(http.StatusOK)
w.Write(returnJson)
}
func getFrontPagePosts(w http.ResponseWriter, r *http.Request) {
var (
posts []Models.Post
returnJson []byte
err error
)
posts, err = Database.GetFrontPagePosts()
if err != nil {
log.Printf("An error occured: %s\n", err.Error())
JsonReturn(w, 500, "An error occured")
return
}
returnJson, err = json.MarshalIndent(posts, "", " ")
if err != nil {
JsonReturn(w, 500, "An error occured")
return
}
// Return updated json
w.WriteHeader(http.StatusOK)
w.Write(returnJson)
}
func getPost(w http.ResponseWriter, r *http.Request) {
var (
postData Models.Post
returnJson []byte
err error
)
postData, err = getPostById(w, r)
if err != nil {
return
}
returnJson, err = json.MarshalIndent(postData, "", " ")
if err != nil {
JsonReturn(w, 500, "An error occured")
return
}
// Return updated json
w.WriteHeader(http.StatusOK)
w.Write(returnJson)
}
func createPost(w http.ResponseWriter, r *http.Request) {
var (
requestBody []byte
postData Models.Post
returnJson []byte
err error
)
// TODO: Add auth
log.Printf("Posts handler recieved %s request", r.Method)
requestBody, err = ioutil.ReadAll(r.Body)
if err != nil {
log.Printf("Error encountered reading POST body: %s\n", err.Error())
JsonReturn(w, 500, "An error occured")
return
}
postData, err = JsonSerialization.DeserializePost(requestBody, []string{
"id",
"links",
"images",
"videos",
"audios",
}, false)
if err != nil {
log.Printf("Invalid data provided to posts API: %s\n", err.Error())
JsonReturn(w, 405, "Invalid data")
return
}
err = Database.CreatePost(&postData)
if err != nil {
JsonReturn(w, 405, "Invalid data")
}
returnJson, err = json.MarshalIndent(postData, "", " ")
if err != nil {
log.Printf("An error occured: %s\n", err.Error())
JsonReturn(w, 500, "An error occured")
return
}
// Return updated json
w.WriteHeader(http.StatusOK)
w.Write(returnJson)
}
func updatePost(w http.ResponseWriter, r *http.Request) {
var (
postData Models.Post
requestBody []byte
returnJson []byte
urlVars map[string]string
id string
ok bool
err error
)
urlVars = mux.Vars(r)
id, ok = urlVars["postID"]
if !ok {
log.Printf("Error encountered getting id\n")
JsonReturn(w, 500, "An error occured")
return
}
requestBody, err = ioutil.ReadAll(r.Body)
if err != nil {
log.Printf("Error encountered reading POST body: %s\n", err.Error())
JsonReturn(w, 500, "An error occured")
return
}
postData, err = JsonSerialization.DeserializePost(requestBody, []string{}, true)
if err != nil {
log.Printf("Invalid data provided to posts API: %s\n", err.Error())
JsonReturn(w, 405, "Invalid data")
return
}
postData, err = Database.UpdatePost(id, &postData)
if err != nil {
log.Printf("An error occured: %s\n", err.Error())
JsonReturn(w, 500, "An error occured")
return
}
returnJson, err = json.MarshalIndent(postData, "", " ")
if err != nil {
log.Printf("An error occured: %s\n", err.Error())
JsonReturn(w, 500, "An error occured")
return
}
// Return updated json
w.WriteHeader(http.StatusOK)
w.Write(returnJson)
}
func deletePost(w http.ResponseWriter, r *http.Request) {
var (
postData Models.Post
err error
)
postData, err = getPostById(w, r)
if err != nil {
return
}
err = Database.DeletePost(&postData)
if err != nil {
log.Printf("An error occured: %s\n", err.Error())
JsonReturn(w, 500, "An error occured")
return
}
// Return updated json
w.WriteHeader(http.StatusOK)
}

+ 289
- 0
Api/Posts_test.go View File

@ -0,0 +1,289 @@
package Api
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"strings"
"testing"
"git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Database"
"git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Models"
"github.com/gorilla/mux"
)
func Test_getPosts(t *testing.T) {
log.SetOutput(ioutil.Discard)
Database.Init()
r := mux.NewRouter()
r.HandleFunc("/post", getPosts).Methods("GET")
ts := httptest.NewServer(r)
defer ts.Close()
for i := 0; i < 20; i++ {
postData := Models.Post{
Title: "Test post",
Content: "Test content",
FrontPage: true,
Order: i,
PostLinks: []Models.PostLink{
{
Type: "Facebook",
Link: "http://google.com/",
},
},
}
Database.CreatePost(&postData)
defer Database.DB.Unscoped().Delete(&postData)
}
res, err := http.Get(ts.URL + "/post?page=1&pageSize=10")
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
}
if res.StatusCode != http.StatusOK {
t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode)
}
getPostsData := new([]Models.Post)
err = json.NewDecoder(res.Body).Decode(getPostsData)
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
}
if len(*getPostsData) != 10 {
t.Errorf("Expected 10, recieved %d", len(*getPostsData))
}
}
func Test_getPost(t *testing.T) {
log.SetOutput(ioutil.Discard)
Database.Init()
r := mux.NewRouter()
r.HandleFunc("/post/{postID}", getPost).Methods("GET")
ts := httptest.NewServer(r)
defer ts.Close()
postData := Models.Post{
Title: "Test post",
Content: "Test content",
FrontPage: true,
Order: 1,
PostLinks: []Models.PostLink{
{
Type: "Facebook",
Link: "http://google.com/",
},
},
}
Database.CreatePost(&postData)
res, err := http.Get(fmt.Sprintf(
"%s/post/%s",
ts.URL,
postData.ID,
))
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
}
if res.StatusCode != http.StatusOK {
t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode)
}
getPostData := new(Models.Post)
err = json.NewDecoder(res.Body).Decode(getPostData)
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
}
Database.DB.Unscoped().Delete(&postData)
}
func Test_createPost(t *testing.T) {
log.SetOutput(ioutil.Discard)
Database.Init()
r := mux.NewRouter()
r.HandleFunc("/post", createPost).Methods("POST")
ts := httptest.NewServer(r)
defer ts.Close()
postJson := `
{
"title": "Test post",
"content": "Test content",
"front_page": true,
"order": 1,
"links": [{
"type": "Facebook",
"link": "http://google.com/"
}]
}
`
res, err := http.Post(ts.URL+"/post", "application/json", strings.NewReader(postJson))
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
}
if res.StatusCode != http.StatusOK {
t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode)
}
postData := new(Models.Post)
err = json.NewDecoder(res.Body).Decode(postData)
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
}
if postData.Title != "Test post" {
t.Errorf("Expected title \"Test post\", recieved \"%s\"", postData.Title)
}
if postData.Content != "Test content" {
t.Errorf("Expected content \"Test content\", recieved \"%s\"", postData.Content)
}
Database.DB.Unscoped().Delete(&postData)
}
func Test_deletePost(t *testing.T) {
log.SetOutput(ioutil.Discard)
Database.Init()
r := mux.NewRouter()
r.HandleFunc("/post/{postID}", deletePost).Methods("DELETE")
ts := httptest.NewServer(r)
defer ts.Close()
postData := Models.Post{
Title: "Test post",
Content: "Test content",
FrontPage: true,
Order: 1,
PostLinks: []Models.PostLink{
{
Type: "Facebook",
Link: "http://google.com/",
},
},
}
Database.CreatePost(&postData)
req, err := http.NewRequest("DELETE", fmt.Sprintf(
"%s/post/%s",
ts.URL,
postData.ID,
), nil)
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
}
// Fetch Request
res, err := http.DefaultClient.Do(req)
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
return
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode)
}
Database.DB.Unscoped().Delete(&postData)
}
func Test_updatePost(t *testing.T) {
log.SetOutput(ioutil.Discard)
Database.Init()
r := mux.NewRouter()
r.HandleFunc("/post/{postID}", updatePost).Methods("PUT")
ts := httptest.NewServer(r)
defer ts.Close()
postData := Models.Post{
Title: "Test post",
Content: "Test content",
FrontPage: true,
Order: 1,
PostLinks: []Models.PostLink{
{
Type: "Facebook",
Link: "http://google.com/",
},
},
}
Database.CreatePost(&postData)
postJson := `
{
"content": "New test content",
"front_page": false,
"order": 2
}
`
req, err := http.NewRequest("PUT", fmt.Sprintf(
"%s/post/%s",
ts.URL,
postData.ID,
), strings.NewReader(postJson))
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
}
// Fetch Request
res, err := http.DefaultClient.Do(req)
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode)
}
updatePostData := new(Models.Post)
err = json.NewDecoder(res.Body).Decode(updatePostData)
if err != nil {
t.Errorf("Expected nil, recieved %s", err.Error())
}
if updatePostData.Content != "New test content" {
t.Errorf("Expected \"New test content\", recieved %s", updatePostData.Content)
}
if updatePostData.FrontPage != false {
t.Errorf("Expected false, recieved %t", updatePostData.FrontPage)
}
if updatePostData.Order != 2 {
t.Errorf("Expected 2, recieved %d", updatePostData.Order)
}
Database.DB.Unscoped().Delete(&postData)
}

+ 28
- 0
Api/ReturnJson.go View File

@ -0,0 +1,28 @@
package Api
import (
"encoding/json"
"log"
"net/http"
)
func JsonReturn(w http.ResponseWriter, code int, msg string) {
var (
responseJsonMap map[string]interface{}
responseJson []byte
err error
)
responseJsonMap = make(map[string]interface{})
w.WriteHeader(code)
responseJsonMap["code"] = code
responseJsonMap["message"] = msg
responseJson, err = json.MarshalIndent(responseJsonMap, "", " ")
if err != nil {
log.Printf("Error occured creating response: %s\n", err.Error())
}
w.Write(responseJson)
}

+ 29
- 0
Api/Routes.go View File

@ -0,0 +1,29 @@
package Api
import (
"log"
"github.com/gorilla/mux"
)
func InitApiEndpoints() *mux.Router {
var (
router *mux.Router
)
log.Println("Initializing API routes...")
router = mux.NewRouter()
// Define routes for posts api
router.HandleFunc("/post", getPosts).Methods("GET")
router.HandleFunc("/frontPagePosts", getFrontPagePosts).Methods("GET")
router.HandleFunc("/post", createPost).Methods("POST")
router.HandleFunc("/post/{postID}", createPost).Methods("GET")
router.HandleFunc("/post/{postID}", updatePost).Methods("PUT")
router.HandleFunc("/post/{postID}", deletePost).Methods("DELETE")
//router.PathPrefix("/").Handler(http.StripPrefix("/images/", http.FileServer(http.Dir("./uploads"))))
return router
}

database/Init.go → Database/Init.go View File


+ 90
- 0
Database/Posts.go View File

@ -0,0 +1,90 @@
package Database
import (
"git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Models"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
func GetPosts(page, pageSize int) ([]Models.Post, error) {
var (
posts []Models.Post
err error
)
if page == 0 {
page = 1
}
switch {
case pageSize > 100:
pageSize = 100
case pageSize <= 0:
pageSize = 10
}
err = DB.Offset(page).
Limit(pageSize).
Find(&posts).
Error
return posts, err
}
func GetFrontPagePosts() ([]Models.Post, error) {
var (
posts []Models.Post
err error
)
err = DB.Where("front_page = ?", true).
Order("order asc").
Find(&posts).
Error
return posts, err
}
func GetPostById(id string) (Models.Post, error) {
var (
postData Models.Post
err error
)
err = DB.Preload(clause.Associations).
First(&postData, "id = ?", id).
Error
return postData, err
}
func CreatePost(postData *Models.Post) error {
return DB.Session(&gorm.Session{FullSaveAssociations: true}).
Create(postData).
Error
}
func UpdatePost(id string, postData *Models.Post) (Models.Post, error) {
var (
err error
)
err = DB.Model(&Models.Post{}).
Select("*").
Omit("id", "created_at", "updated_at", "deleted_at").
Where("id = ?", id).
Updates(postData).
Error
if err != nil {
return Models.Post{}, err
}
return GetPostById(id)
}
func DeletePost(postData *Models.Post) error {
return DB.Session(&gorm.Session{FullSaveAssociations: true}).
Delete(postData).
Error
}

models/Base.go → Models/Base.go View File


+ 53
- 0
Models/Posts.go View File

@ -0,0 +1,53 @@
package Models
import (
"github.com/gofrs/uuid"
)
type Post struct {
Base
Title string `gorm:"not null" json:"title"`
Content string `gorm:"not null" json:"content"`
FrontPage bool `gorm:"not null;type:boolean" json:"front_page"`
Order int `gorm:"not null" json:"order"`
PostLinks []PostLink `json:"links"`
PostImages []PostImage `json:"images"`
PostVideos []PostVideo `json:"videos"`
PostAudios []PostAudio `json:"audios"`
}
type PostLinkType string
const (
POST_LINK_FACEBOOK PostLinkType = "Facebook"
POST_LINK_INSTAGRAM PostLinkType = "Instagram"
POST_LINK_YOUTUBE PostLinkType = "YouTube"
POST_LINK_SPOTIFY PostLinkType = "Spotify"
POST_LINK_OTHER PostLinkType = "Other"
)
type PostLink struct {
Base
PostID uuid.UUID `gorm:"type:uuid;column:post_foreign_key;not null;" json:"post_id"`
Link string `gorm:"not null" json:"link"`
Type PostLinkType `gorm:"not null" json:"type"`
}
type PostImage struct {
Base
PostID uuid.UUID `gorm:"type:uuid;column:post_foreign_key;not null;" json:"post_id"`
Filepath string `gorm:"not null" json:"filepath"`
}
type PostVideo struct {
Base
PostID uuid.UUID `gorm:"type:uuid;column:post_foreign_key;not null;" json:"post_id"`
Filepath string `gorm:"not null" json:"filepath"`
}
type PostAudio struct {
Base
PostID uuid.UUID `gorm:"type:uuid;column:post_foreign_key;not null;" json:"post_id"`
Filepath string `gorm:"not null" json:"filepath"`
}

models/Subscriptions.go → Models/Subscriptions.go View File


+ 0
- 1
database/Posts.go View File

@ -1 +0,0 @@
package database

+ 2
- 0
go.mod View File

@ -3,7 +3,9 @@ module git.tovijaeschke.xyz/tovi/SuddenImpactRecords
go 1.17 go 1.17
require ( require (
github.com/Kangaroux/go-map-schema v0.6.1
github.com/gofrs/uuid v4.2.0+incompatible github.com/gofrs/uuid v4.2.0+incompatible
github.com/gorilla/mux v1.8.0
gorm.io/driver/postgres v1.3.1 gorm.io/driver/postgres v1.3.1
gorm.io/gorm v1.23.2 gorm.io/gorm v1.23.2
) )


+ 4
- 0
go.sum View File

@ -1,4 +1,6 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Kangaroux/go-map-schema v0.6.1 h1:jXpOzi7kNFC6M8QSvJuI7xeDxObBrVHwA3D6vSrxuG4=
github.com/Kangaroux/go-map-schema v0.6.1/go.mod h1:56jN+6h/N8Pmn5D+JL9gREOvZTlVEAvXtXyLd/NRjh4=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
@ -16,6 +18,8 @@ github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=


+ 16
- 3
main.go View File

@ -1,11 +1,24 @@
package main package main
import ( import (
"git.tovijaeschke.xyz/tovi/SuddenImpactRecords/database"
"net/http"
"git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Api"
"git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Database"
"github.com/gorilla/mux"
) )
func main() { func main() {
var ()
var (
router *mux.Router
)
Database.Init()
router = Api.InitApiEndpoints()
database.Init()
// TODO: Run this within goroutine when running vue application
// Start and listen to requests
http.ListenAndServe(":8080", router)
} }

+ 0
- 48
models/Posts.go View File

@ -1,48 +0,0 @@
package models
import (
"github.com/gofrs/uuid"
)
type Post struct {
Base
Title string `gorm:"not null"`
Content string `gorm:"not null"`
FrontPage bool `gorm:"not null"`
Order int `gorm:"not null"`
}
type PostLinkType string
const (
POST_LINK_FACEBOOK PostLinkType = "Facebook"
POST_LINK_INSTAGRAM PostLinkType = "Instagram"
POST_LINK_YOUTUBE PostLinkType = "YouTube"
POST_LINK_SPOTIFY PostLinkType = "Spotify"
POST_LINK_OTHER PostLinkType = "Other"
)
type PostLink struct {
Base
PostId uuid.UUID `gorm:"type:uuid;column:post_foreign_key;not null;"`
Link string `gorm:"not null"`
Type PostLinkType `gorm:"not null"`
}
type PostImage struct {
Base
PostId uuid.UUID `gorm:"type:uuid;column:post_foreign_key;not null;"`
Filepath string `gorm:"not null"`
}
type PostVideo struct {
Base
PostId uuid.UUID `gorm:"type:uuid;column:post_foreign_key;not null;"`
Filepath string `gorm:"not null"`
}
type PostAudio struct {
Base
PostId uuid.UUID `gorm:"type:uuid;column:post_foreign_key;not null;"`
Filepath string `gorm:"not null"`
}

Loading…
Cancel
Save