personal-website/apps/aboutme/personalprops.go

356 lines
8.2 KiB
Go
Raw Normal View History

2023-05-24 22:51:37 +00:00
package aboutme
2023-03-15 12:32:41 +00:00
2023-03-17 01:16:51 +00:00
import (
2023-05-24 22:51:37 +00:00
"errors"
2023-06-07 00:42:50 +00:00
"html/template"
2023-05-03 21:50:08 +00:00
"net/http"
2023-05-24 22:51:37 +00:00
"path"
"personalwebsite/apps/appCtx"
2023-05-24 22:51:37 +00:00
"personalwebsite/errormessage"
2023-06-07 00:42:50 +00:00
"personalwebsite/libs"
2023-04-29 19:37:08 +00:00
"personalwebsite/webfilesystem"
2023-03-17 01:16:51 +00:00
"github.com/gin-gonic/gin"
2023-04-29 19:37:08 +00:00
"go.mongodb.org/mongo-driver/bson/primitive"
2023-03-17 01:16:51 +00:00
)
2023-05-24 22:51:37 +00:00
type AboutMeApp struct {
fs *webfilesystem.WebFileSystem
appID string
2023-06-07 00:42:50 +00:00
mLib libs.MarkdownLib
2023-03-15 12:32:41 +00:00
}
2023-05-24 22:51:37 +00:00
func NewAboutMeApp(webFs *webfilesystem.WebFileSystem) *AboutMeApp {
newApp := AboutMeApp{
fs: webFs,
appID: "AboutMe",
2023-03-17 01:16:51 +00:00
}
return &newApp
2023-03-15 12:32:41 +00:00
}
2023-05-24 22:51:37 +00:00
func (p *AboutMeApp) PublicRoutes(route *gin.RouterGroup) {
route.POST("render", func(ctx *gin.Context) {
2023-05-07 01:00:22 +00:00
filePath := ctx.Query("path")
if filePath == "" {
ctx.Status(http.StatusBadRequest)
return
}
appCtx := appCtx.AppContext{}
err := ctx.BindJSON(&appCtx)
if err != nil {
ctx.Status(http.StatusBadRequest)
return
}
ginH, err := p.Render(appCtx, filePath)
2023-05-03 21:50:08 +00:00
if err != nil {
ctx.JSON(http.StatusInternalServerError, "TODO") //TODO
2023-05-05 22:50:57 +00:00
return
2023-05-03 21:50:08 +00:00
}
if appCtx.IsMobile {
2023-05-03 21:50:08 +00:00
ctx.HTML(http.StatusOK, "personal-properties/mobile-app.tmpl", ginH)
} else {
ctx.HTML(http.StatusOK, "personal-properties/app.tmpl", ginH)
}
})
}
2023-05-24 22:51:37 +00:00
func (p *AboutMeApp) PrivateRoutes(router *gin.RouterGroup) {
p.PublicRoutes(router)
2023-06-07 00:42:50 +00:00
// router.GET("writeMock", func(ctx *gin.Context) {
// err := p.WriteMock()
// if err != nil {
// ctx.Status(http.StatusInternalServerError)
// }
// ctx.Status(http.StatusOK)
// })
router.GET("getMock", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, PropertiesFileData{
2023-06-07 01:22:25 +00:00
Header: HeaderIsland{
Name: "",
IconPath: "",
Value1: "",
Value2: "",
},
Links: []HeaderLink{
{
Text: "",
Url: "",
Icon: "",
},
},
2023-06-07 00:42:50 +00:00
Islands: []Island{
{
Header: "qq",
Properties: []IslandProperty{
{
Key: "22",
KeyComments: []string{
"45",
"12",
},
Values: []string{
"aaaa",
},
},
},
},
},
})
})
2023-05-24 22:51:37 +00:00
router.GET("read", func(ctx *gin.Context) {
filePath := ctx.Query("path")
if filePath == "" {
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
Message: "File path is empty",
})
return
}
propData, err := p.Read(filePath)
if err != nil {
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
Message: err.Error(),
})
return
}
ctx.JSON(http.StatusOK, propData)
})
router.POST("edit", func(ctx *gin.Context) {
filePath := ctx.Query("path")
if filePath == "" {
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
Message: "File path is empty",
})
return
}
propsData := PropertiesFileData{}
err := ctx.BindJSON(&propsData)
if err != nil {
2023-06-07 00:42:50 +00:00
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
Message: err.Error(),
})
2023-05-24 22:51:37 +00:00
return
}
err = p.Edit(filePath, propsData)
if err != nil {
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
Message: err.Error(),
})
return
}
ctx.Status(http.StatusOK)
})
2023-03-17 01:16:51 +00:00
}
2023-05-24 22:51:37 +00:00
func (p *AboutMeApp) GetAppID() string {
return p.appID
2023-03-17 01:16:51 +00:00
}
2023-06-07 00:42:50 +00:00
// func (p *AboutMeApp) WriteMock() error {
// fileHeader := webfilesystem.FileHeader{
// MongoId: primitive.NewObjectID(),
// Name: "aboutme.props",
// Type: "personal-properties",
// Icon: "",
// }
// fileData := PropertiesFileData{
// Header: HeaderIsland{
// Name: "Test Name",
// IconPath: "test icon path",
// Info1: "Info1",
// Info2: "Info2",
// },
// Props: []PropIsland{
// {
// Header: "Test Prop Header",
// Props: []PropElement{
// {
// Key: "Test key",
// KeyComments: []string{"Test key comment 1", "Test key comment 1"},
// Values: []Value{
// {
// Blocks: []ValueBlock{
// {
// Type: "string",
// Data: []string{"aappo"},
// },
// {
// Type: "link",
// Data: []string{"https://ya.ru", "Azazaza"},
// },
// },
// },
// },
// },
// },
// },
// {
// Header: "Test Prop Header 2",
// Props: []PropElement{
// {
// Key: "Test key",
// KeyComments: []string{"Test key comment 1", "Test key comment 1"},
// Values: []Value{
// {
// Blocks: []ValueBlock{
// {
// Type: "string",
// Data: []string{"aappo"},
// },
// {
// Type: "link",
// Data: []string{"https://ya.ru", "Azazaza"},
// },
// },
// },
// },
// },
// },
// },
// },
// }
// _, _, err := p.fs.Write("/Applications/AboutMe.app/aboutme.props", &fileHeader, fileData)
// return err
// }
2023-05-05 22:50:57 +00:00
2023-05-24 22:51:37 +00:00
func (p *AboutMeApp) Read(filePath string) (*PropertiesFileData, error) {
propData := PropertiesFileData{}
fileHeader, err := p.fs.Read(path.Join(filePath, "aboutme.props"), &propData)
if err != nil {
return nil, err
}
if fileHeader.Type != "personal-properties" {
return nil, errors.New("wrong file type")
}
return &propData, nil
}
func (p *AboutMeApp) Edit(filePath string, blogData PropertiesFileData) error {
propsPath := path.Join(filePath, "aboutme.props")
fileHeader, err := p.fs.Read(propsPath, nil)
if err != nil {
return err
}
if fileHeader.Type != "personal-properties" {
return errors.New("wrong file type")
}
err = p.fs.Remove(propsPath)
if err != nil {
return err
}
fileHeader.MongoId = primitive.NewObjectID()
_, _, err = p.fs.Write(propsPath, fileHeader, blogData)
if err != nil {
return err
}
return nil
}
func (p *AboutMeApp) Render(appCtx appCtx.AppContext, filePath string) (gin.H, error) {
2023-06-07 00:42:50 +00:00
//Read file from WebFS
propsData := &PropertiesFileData{}
filePath = p.fs.RelativeToAbsolute(appCtx, filePath)
2023-05-07 01:00:22 +00:00
_, err := p.fs.Read(filePath, &propsData)
if err != nil {
2023-05-05 22:50:57 +00:00
return nil, err
}
2023-06-07 00:42:50 +00:00
//Render Markdown strings
renderedIslands := []RenderedIsland{}
for _, island := range propsData.Islands {
newRenderedIsland := RenderedIsland{
Header: island.Header,
Properties: []RenderedIslandProperty{},
}
for _, property := range island.Properties {
newRenderedIslandProperty := RenderedIslandProperty{
Key: property.Key,
KeyComments: property.KeyComments,
Values: []template.HTML{},
}
for _, value := range property.Values {
renderedValue := p.mLib.Render([]byte(value), true)
newRenderedIslandProperty.Values = append(newRenderedIslandProperty.Values, renderedValue)
}
newRenderedIsland.Properties = append(newRenderedIsland.Properties, newRenderedIslandProperty)
}
renderedIslands = append(renderedIslands, newRenderedIsland)
}
//Make icon path absolute
propsData.Header.IconPath = p.fs.RelativeToAbsolute(appCtx, propsData.Header.IconPath)
2023-06-07 00:42:50 +00:00
2023-06-07 01:22:25 +00:00
absoluteLinks := []HeaderLink{}
for _, link := range propsData.Links {
absoluteLinks = append(absoluteLinks, HeaderLink{
Text: link.Text,
Url: link.Url,
Icon: p.fs.RelativeToAbsolute(appCtx, link.Icon),
})
}
2023-05-05 22:50:57 +00:00
return gin.H{
2023-06-07 00:42:50 +00:00
"HeaderProps": propsData.Header,
2023-06-07 01:22:25 +00:00
"Links": absoluteLinks,
2023-06-07 00:42:50 +00:00
"Islands": renderedIslands,
2023-05-05 22:50:57 +00:00
}, nil
}
2023-06-07 00:42:50 +00:00
type PropertiesFileData struct {
Header HeaderIsland `bson:"header" json:"header"`
2023-06-07 01:22:25 +00:00
Links []HeaderLink `bson:"links" json:"links"`
Islands []Island `bson:"islands" json:"islands"` //TODO rename
2023-06-07 00:42:50 +00:00
}
type HeaderIsland struct {
Name string `bson:"name" json:"name"`
IconPath string `bson:"iconpath" json:"iconpath"`
Value1 string `bson:"value1" json:"value1"` //TODO Rename to value
Value2 string `bson:"value2" json:"value2"`
2023-03-15 12:32:41 +00:00
}
2023-03-17 01:16:51 +00:00
2023-06-07 01:22:25 +00:00
type HeaderLink struct {
Text string `bson:"text" json:"text"`
Url string `bson:"url" json:"url"`
Icon string `bson:"icon" json:"icon"`
}
2023-06-07 00:42:50 +00:00
type Island struct {
Header string `bson:"header" json:"header"`
Properties []IslandProperty `bson:"properties" json:"properties"`
2023-06-06 22:49:26 +00:00
}
2023-06-07 00:42:50 +00:00
type IslandProperty struct {
Key string `bson:"key" json:"key"`
KeyComments []string `bson:"keycomment" json:"keycomment"`
Values []string `bson:"values" json:"values"`
2023-06-06 22:49:26 +00:00
}
2023-06-07 00:42:50 +00:00
type RenderedIsland struct {
Header string
Properties []RenderedIslandProperty
2023-03-17 01:16:51 +00:00
}
2023-06-07 00:42:50 +00:00
type RenderedIslandProperty struct {
Key string
KeyComments []string
Values []template.HTML
2023-03-18 00:34:56 +00:00
}
2023-06-07 00:42:50 +00:00
// type Value struct {
// Blocks []ValueBlock
// }
// type ValueBlock struct {
// Type string
// Data string
// }