add gorm
add history init/pull/push
This commit is contained in:
parent
c9450de603
commit
3af050caa0
25 changed files with 525 additions and 124 deletions
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
func Process(name, route string, data any) bool {
|
||||
log.Print("Init of " + name)
|
||||
response, err := client.Init(route, data)
|
||||
response, err := client.InitPush(route, data)
|
||||
res := true
|
||||
|
||||
if err != nil {
|
||||
|
|
|
|||
45
cmd/action/pullcmd/process.go
Normal file
45
cmd/action/pullcmd/process.go
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package pullcmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"gitnet.fr/deblan/freetube-sync/store/file"
|
||||
"gitnet.fr/deblan/freetube-sync/web/client"
|
||||
)
|
||||
|
||||
func ProcessHistory() bool {
|
||||
log.Print("Pull of history")
|
||||
items, err := client.PullHistory()
|
||||
res := true
|
||||
|
||||
if err != nil {
|
||||
log.Print("Error while pulling history: " + err.Error())
|
||||
res = false
|
||||
} else {
|
||||
lines := []string{}
|
||||
|
||||
for _, item := range items {
|
||||
line, _ := json.Marshal(item)
|
||||
lines = append(lines, string(line))
|
||||
}
|
||||
|
||||
file.UpdateHistory(lines)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func Run() {
|
||||
a := ProcessHistory()
|
||||
// b := Process("playlists", route.PlaylistPull)
|
||||
// c := Process("profiles", route.ProfilePull)
|
||||
|
||||
// if a && b && c {
|
||||
if a {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
@ -1,13 +1,35 @@
|
|||
package watchcmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
config "gitnet.fr/deblan/freetube-sync/config/client"
|
||||
filestore "gitnet.fr/deblan/freetube-sync/store/file"
|
||||
"gitnet.fr/deblan/freetube-sync/web/client"
|
||||
"gitnet.fr/deblan/freetube-sync/web/route"
|
||||
)
|
||||
|
||||
func Process(name, route string, data any) bool {
|
||||
log.Print("Push of " + name)
|
||||
response, err := client.InitPush(route, data)
|
||||
res := true
|
||||
|
||||
if err != nil {
|
||||
log.Print("Error while pushing " + name + ": " + err.Error())
|
||||
res = false
|
||||
} else {
|
||||
if response.Code == 201 {
|
||||
log.Print(name + " pushed!")
|
||||
} else {
|
||||
log.Print("Error while pushing " + name + ": " + response.Message)
|
||||
res = false
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func Run() {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
|
||||
|
|
@ -16,6 +38,7 @@ func Run() {
|
|||
}
|
||||
|
||||
defer watcher.Close()
|
||||
c := config.GetConfig()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
|
|
@ -26,12 +49,12 @@ func Run() {
|
|||
}
|
||||
if event.Has(fsnotify.Write) {
|
||||
switch event.Name {
|
||||
case config.GetConfig().Path + "/history.db":
|
||||
fmt.Printf("%+v\n", "update history")
|
||||
case config.GetConfig().Path + "/playlists.db":
|
||||
fmt.Printf("%+v\n", "update playlists")
|
||||
case config.GetConfig().Path + "/profiles.db":
|
||||
fmt.Printf("%+v\n", "update profiles")
|
||||
case c.DbPath("history"):
|
||||
Process("history", route.HistoryPush, filestore.LoadHistory())
|
||||
case c.DbPath("playlists"):
|
||||
Process("playlists", route.PlaylistPush, filestore.LoadPlaylists())
|
||||
case c.DbPath("profiles"):
|
||||
Process("profiles", route.ProfilePush, filestore.LoadProfiles())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,59 +6,23 @@ import (
|
|||
"os"
|
||||
|
||||
"gitnet.fr/deblan/freetube-sync/cmd/action/initcmd"
|
||||
"gitnet.fr/deblan/freetube-sync/cmd/action/pullcmd"
|
||||
"gitnet.fr/deblan/freetube-sync/cmd/action/watchcmd"
|
||||
config "gitnet.fr/deblan/freetube-sync/config/client"
|
||||
)
|
||||
|
||||
func main() {
|
||||
config.InitConfig()
|
||||
action := flag.Arg(0)
|
||||
|
||||
switch action {
|
||||
switch flag.Arg(0) {
|
||||
case "init":
|
||||
initcmd.Run()
|
||||
case "watch":
|
||||
watchcmd.Run()
|
||||
case "pull":
|
||||
pullcmd.Run()
|
||||
default:
|
||||
fmt.Print("You must pass a sub-command: init, watch")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// lines := file.GetLines("/home/simon/.config/FreeTube/history.db")
|
||||
// collection := []model.Video{}
|
||||
//
|
||||
// for _, line := range lines {
|
||||
// var item model.Video
|
||||
// json.Unmarshal([]byte(line), &item)
|
||||
//
|
||||
// collection = append(collection, item)
|
||||
// }
|
||||
//
|
||||
// data, err := json.Marshal(collection)
|
||||
//
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// req, err := http.NewRequest("POST", "http://localhost:1323/history/push", bytes.NewBuffer(data))
|
||||
// req.Header.Set("X-Machine", "endurance")
|
||||
// req.Header.Set("Content-Type", "application/json")
|
||||
//
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// client := &http.Client{}
|
||||
// resp, err := client.Do(req)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// defer resp.Body.Close()
|
||||
// fmt.Println("response Status:", resp.Status)
|
||||
// fmt.Println("response Headers:", resp.Header)
|
||||
// body, _ := io.ReadAll(resp.Body)
|
||||
// fmt.Println("response Body:", string(body))
|
||||
//
|
||||
// fmt.Printf("%+v\n", data)
|
||||
// fmt.Printf("%+v\n", collection)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,46 +2,26 @@ package main
|
|||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"gitnet.fr/deblan/freetube-sync/model"
|
||||
"gitnet.fr/deblan/freetube-sync/web/route"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
config "gitnet.fr/deblan/freetube-sync/config/server"
|
||||
"gitnet.fr/deblan/freetube-sync/store/database"
|
||||
"gitnet.fr/deblan/freetube-sync/web/controller/history"
|
||||
"gitnet.fr/deblan/freetube-sync/web/controller/playlist"
|
||||
"gitnet.fr/deblan/freetube-sync/web/controller/profile"
|
||||
)
|
||||
|
||||
func main() {
|
||||
config.InitConfig()
|
||||
|
||||
database.GetManager().AutoMigrate()
|
||||
|
||||
e := echo.New()
|
||||
e.HideBanner = true
|
||||
e.Use(middleware.Logger())
|
||||
|
||||
e.POST(route.HistoryInit, func(c echo.Context) error {
|
||||
payload := []model.Video{}
|
||||
err := c.Bind(&payload)
|
||||
history.Register(e)
|
||||
playlist.Register(e)
|
||||
profile.Register(e)
|
||||
|
||||
if err != nil {
|
||||
return c.JSON(400, map[string]any{
|
||||
"code": 400,
|
||||
"message": err,
|
||||
})
|
||||
}
|
||||
|
||||
return c.JSON(201, map[string]any{
|
||||
"code": 201,
|
||||
"message": "ok",
|
||||
})
|
||||
})
|
||||
|
||||
e.POST(route.HistoryPush, func(c echo.Context) error {
|
||||
payload := []model.Video{}
|
||||
err := c.Bind(&payload)
|
||||
|
||||
if err != nil {
|
||||
return c.JSON(400, map[string]any{
|
||||
"code": 400,
|
||||
"message": err,
|
||||
})
|
||||
}
|
||||
|
||||
return c.JSON(201, map[string]any{
|
||||
"code": 201,
|
||||
"message": "ok",
|
||||
})
|
||||
})
|
||||
|
||||
e.Logger.Fatal(e.Start(":1323"))
|
||||
e.Logger.Fatal(e.Start(config.GetConfig().BindAddress))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@ func (c *Config) Define(server, hostname, path string) {
|
|||
c.Path = path
|
||||
}
|
||||
|
||||
func (c *Config) DbPath(name string) string {
|
||||
return c.Path + "/" + name + ".db"
|
||||
}
|
||||
|
||||
func InitConfig() {
|
||||
defaultHostname, _ := os.Hostname()
|
||||
|
||||
|
|
|
|||
34
config/server/config.go
Normal file
34
config/server/config.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
BindAddress string
|
||||
DbPath string
|
||||
}
|
||||
|
||||
var config *Config
|
||||
|
||||
func GetConfig() *Config {
|
||||
if config == nil {
|
||||
config = &Config{}
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
func (c *Config) Define(bindAddress, dbPath string) {
|
||||
c.BindAddress = bindAddress
|
||||
c.DbPath = dbPath
|
||||
}
|
||||
|
||||
func InitConfig() {
|
||||
dbPath := flag.String("d", os.Getenv("HOME")+"/.config/FreeTube/sync.sqlite", "Path to SQlite database")
|
||||
bindAddress := flag.String("b", ":1323", "Bind address")
|
||||
flag.Parse()
|
||||
|
||||
GetConfig().Define(*bindAddress, *dbPath)
|
||||
}
|
||||
12
file/writer.go
Normal file
12
file/writer.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package file
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func WriteDatabase(file string, data []string) error {
|
||||
content := []byte(strings.Join(data, "\n") + "\n")
|
||||
|
||||
return os.WriteFile(file, content, 0644)
|
||||
}
|
||||
16
go.mod
16
go.mod
|
|
@ -3,15 +3,25 @@ module gitnet.fr/deblan/freetube-sync
|
|||
go 1.23.0
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/labstack/echo/v4 v4.12.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
github.com/labstack/echo/v4 v4.12.0
|
||||
gorm.io/driver/sqlite v1.5.6
|
||||
gorm.io/gorm v1.25.11
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/net v0.24.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/text v0.17.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
)
|
||||
|
|
|
|||
26
go.sum
26
go.sum
|
|
@ -1,5 +1,13 @@
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
||||
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
|
|
@ -9,6 +17,12 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
|
|||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
|
|
@ -21,5 +35,13 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=
|
||||
gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
|
||||
gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
|
||||
gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Playlist struct {
|
||||
PlaylistName string `json:"playlistName"`
|
||||
Protected bool `json:"protected"`
|
||||
Description string `json:"description"`
|
||||
Videos []Video `json:"videos"`
|
||||
Id string `json:"_id"`
|
||||
CreatedAt uint64 `json:"createdAt"`
|
||||
LastUpdatedAt uint64 `json:"lastUpdatedAt"`
|
||||
ID uint `json:"-";gorm:"primary_key"`
|
||||
DeletedAt *time.Time `json:"-";sql:"index"`
|
||||
|
||||
PlaylistName string `json:"playlistName"`
|
||||
Protected bool `json:"protected"`
|
||||
Description string `json:"description"`
|
||||
Videos []PlaylistVideo `json:"videos"`
|
||||
Id string `json:"_id"`
|
||||
CreatedAt uint64 `json:"createdAt"`
|
||||
LastUpdatedAt uint64 `json:"lastUpdatedAt"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Profile struct {
|
||||
ID uint `json:"-";gorm:"primary_key"`
|
||||
DeletedAt *time.Time `json:"-";sql:"index"`
|
||||
|
||||
Name string `json:"name"`
|
||||
BgColor string `json:"bgColor"`
|
||||
TextColor string `json:"textColor"`
|
||||
Subscriptions []Subscription `json:"subscriptions"`
|
||||
Subscriptions []Subscription `json:"subscriptions" gorm:"many2many:profile_subscription"`
|
||||
}
|
||||
|
|
|
|||
13
model/pull.go
Normal file
13
model/pull.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Pull struct {
|
||||
ID uint `json:"-";gorm:"primary_key"`
|
||||
|
||||
Hostname string
|
||||
Database string
|
||||
PullAt time.Time
|
||||
}
|
||||
|
|
@ -1,7 +1,13 @@
|
|||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Subscription struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
ID uint `json:"-";gorm:"primary_key"`
|
||||
DeletedAt *time.Time `json:"-";sql:"index"`
|
||||
|
||||
Profiles []Profile `gorm:"many2many:profile_subscription"`
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,41 @@
|
|||
package model
|
||||
|
||||
type Video struct {
|
||||
VideoId string `json:"videoId"`
|
||||
Title string `json:"title"`
|
||||
Author string `json:"author"`
|
||||
AuthorId string `json:"authorId"`
|
||||
Published uint64 `json:"published"`
|
||||
Description string `json:"description"`
|
||||
ViewCount uint64 `json:"viewCount"`
|
||||
LengthSeconds uint64 `json:"lengthSeconds"`
|
||||
WatchProgress uint64 `json:"watchProgress"`
|
||||
TimeWatched uint64 `json:"timeWatched"`
|
||||
LsLive bool `json:"isLive"`
|
||||
Type string `json:"type"`
|
||||
Id string `json:"_id"`
|
||||
LastViewedPlaylistType string `json:"lastViewedPlaylistType"`
|
||||
LastViewedPlaylistItemId string `json:"lastViewedPlaylistItemId"`
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type WatchedVideo struct {
|
||||
ID uint `json:"-";gorm:"primary_key"`
|
||||
DeletedAt *time.Time `json:"-";sql:"index"`
|
||||
|
||||
VideoId string `json:"videoId"`
|
||||
Title string `json:"title"`
|
||||
Author string `json:"author"`
|
||||
AuthorId string `json:"authorId"`
|
||||
Published uint64 `json:"published"`
|
||||
Description string `json:"description"`
|
||||
ViewCount uint64 `json:"viewCount"`
|
||||
LengthSeconds uint64 `json:"lengthSeconds"`
|
||||
WatchProgress uint64 `json:"watchProgress"`
|
||||
TimeWatched uint64 `json:"timeWatched"`
|
||||
IsLive bool `json:"isLive"`
|
||||
Type string `json:"type"`
|
||||
Id string `json:"_id"`
|
||||
LastViewedPlaylistType string `json:"lastViewedPlaylistType"`
|
||||
LastViewedPlaylistItemId *string `json:"lastViewedPlaylistItemId"`
|
||||
}
|
||||
|
||||
type PlaylistVideo struct {
|
||||
ID uint `gorm:"primary_key"`
|
||||
DeletedAt *time.Time `json:"-";sql:"index"`
|
||||
|
||||
PlaylistID uint
|
||||
VideoId string `json:"videoId"`
|
||||
Title string `json:"title"`
|
||||
AuthorId string `json:"authorId"`
|
||||
LengthSeconds uint64 `json:"lengthSeconds"`
|
||||
TimeWatched uint64 `json:"timeWatched"`
|
||||
TimeAdded uint64 `json:"timeAdded"`
|
||||
PlaylistItemId string `json:"playlistItemId"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
|
|
|||
40
store/database/database.go
Normal file
40
store/database/database.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
config "gitnet.fr/deblan/freetube-sync/config/server"
|
||||
"gitnet.fr/deblan/freetube-sync/model"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
Db *gorm.DB
|
||||
}
|
||||
|
||||
var manager *Manager
|
||||
|
||||
func GetManager() *Manager {
|
||||
if manager == nil {
|
||||
manager = &Manager{}
|
||||
db, err := gorm.Open(sqlite.Open(config.GetConfig().DbPath), &gorm.Config{})
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
manager.Db = db
|
||||
}
|
||||
|
||||
return manager
|
||||
}
|
||||
|
||||
func (m *Manager) AutoMigrate() {
|
||||
m.Db.AutoMigrate(&model.Pull{})
|
||||
m.Db.AutoMigrate(&model.WatchedVideo{})
|
||||
m.Db.AutoMigrate(&model.PlaylistVideo{})
|
||||
m.Db.AutoMigrate(&model.Subscription{})
|
||||
m.Db.AutoMigrate(&model.Playlist{})
|
||||
m.Db.AutoMigrate(&model.Profile{})
|
||||
}
|
||||
|
|
@ -8,12 +8,12 @@ import (
|
|||
"gitnet.fr/deblan/freetube-sync/model"
|
||||
)
|
||||
|
||||
func LoadHistory() []model.Video {
|
||||
lines := file.GetLines(config.GetConfig().Path + "/history.db")
|
||||
collection := []model.Video{}
|
||||
func LoadHistory() []model.WatchedVideo {
|
||||
lines := file.GetLines(config.GetConfig().DbPath("history"))
|
||||
collection := []model.WatchedVideo{}
|
||||
|
||||
for _, line := range lines {
|
||||
var item model.Video
|
||||
var item model.WatchedVideo
|
||||
json.Unmarshal([]byte(line), &item)
|
||||
|
||||
collection = append(collection, item)
|
||||
|
|
@ -21,3 +21,7 @@ func LoadHistory() []model.Video {
|
|||
|
||||
return collection
|
||||
}
|
||||
|
||||
func UpdateHistory(data []string) {
|
||||
file.WriteDatabase(config.GetConfig().DbPath("history"), data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
func LoadPlaylists() []model.Playlist {
|
||||
lines := file.GetLines(config.GetConfig().Path + "/playlists.db")
|
||||
lines := file.GetLines(config.GetConfig().DbPath("playlists"))
|
||||
collection := []model.Playlist{}
|
||||
added := make(map[string]bool)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
func LoadProfiles() []model.Profile {
|
||||
lines := file.GetLines(config.GetConfig().Path + "/profiles.db")
|
||||
lines := file.GetLines(config.GetConfig().DbPath("profiles"))
|
||||
collection := []model.Profile{}
|
||||
added := make(map[string]bool)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import (
|
|||
"net/http"
|
||||
|
||||
config "gitnet.fr/deblan/freetube-sync/config/client"
|
||||
"gitnet.fr/deblan/freetube-sync/model"
|
||||
"gitnet.fr/deblan/freetube-sync/web/route"
|
||||
)
|
||||
|
||||
type Data any
|
||||
|
|
@ -55,11 +57,11 @@ func Post(route string, data Data) ([]byte, error) {
|
|||
return Request("POST", route, data)
|
||||
}
|
||||
|
||||
func Get(route string, data Data) ([]byte, error) {
|
||||
return Request("POST", route, data)
|
||||
func Get(route string) ([]byte, error) {
|
||||
return Request("GET", route, nil)
|
||||
}
|
||||
|
||||
func Init(route string, data Data) (PostResponse, error) {
|
||||
func InitPush(route string, data Data) (PostResponse, error) {
|
||||
var value PostResponse
|
||||
|
||||
body, err := Post(route, data)
|
||||
|
|
@ -67,3 +69,12 @@ func Init(route string, data Data) (PostResponse, error) {
|
|||
|
||||
return value, err
|
||||
}
|
||||
|
||||
func PullHistory() ([]model.WatchedVideo, error) {
|
||||
var items []model.WatchedVideo
|
||||
|
||||
body, err := Get(route.HistoryPull)
|
||||
json.Unmarshal(body, &items)
|
||||
|
||||
return items, err
|
||||
}
|
||||
|
|
|
|||
17
web/controller/helper.go
Normal file
17
web/controller/helper.go
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package helper
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
func Ko(c echo.Context, err error) error {
|
||||
return c.JSON(400, map[string]any{
|
||||
"code": 400,
|
||||
"message": err,
|
||||
})
|
||||
}
|
||||
|
||||
func Ok(c echo.Context) error {
|
||||
return c.JSON(201, map[string]any{
|
||||
"code": 201,
|
||||
"message": "ok",
|
||||
})
|
||||
}
|
||||
51
web/controller/history/controller.go
Normal file
51
web/controller/history/controller.go
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package history
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"gitnet.fr/deblan/freetube-sync/model"
|
||||
"gitnet.fr/deblan/freetube-sync/store/database"
|
||||
"gitnet.fr/deblan/freetube-sync/web/helper"
|
||||
"gitnet.fr/deblan/freetube-sync/web/route"
|
||||
)
|
||||
|
||||
func InitPush(c echo.Context) error {
|
||||
payload := []model.WatchedVideo{}
|
||||
err := c.Bind(&payload)
|
||||
manager := database.GetManager()
|
||||
|
||||
if err != nil {
|
||||
return helper.Ko(c, err)
|
||||
}
|
||||
|
||||
for _, item := range payload {
|
||||
manager.Db.Where(item).FirstOrCreate(&item)
|
||||
}
|
||||
|
||||
return helper.Ok(c)
|
||||
}
|
||||
|
||||
func Pull(c echo.Context) error {
|
||||
entities := []model.WatchedVideo{}
|
||||
manager := database.GetManager()
|
||||
|
||||
manager.Db.Find(&entities)
|
||||
|
||||
pull := model.Pull{
|
||||
Hostname: c.Request().Header.Get("X-Machine"),
|
||||
Database: "history",
|
||||
}
|
||||
|
||||
manager.Db.Where(pull).FirstOrCreate(&pull)
|
||||
pull.PullAt = time.Now()
|
||||
manager.Db.Save(&pull)
|
||||
|
||||
return c.JSON(200, entities)
|
||||
}
|
||||
|
||||
func Register(e *echo.Echo) {
|
||||
e.POST(route.HistoryInit, InitPush)
|
||||
e.POST(route.HistoryPush, InitPush)
|
||||
e.GET(route.HistoryPull, Pull)
|
||||
}
|
||||
58
web/controller/playlist/controller.go
Normal file
58
web/controller/playlist/controller.go
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package playlist
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"gitnet.fr/deblan/freetube-sync/web/route"
|
||||
)
|
||||
|
||||
func Ko(c echo.Context, err error) error {
|
||||
return c.JSON(400, map[string]any{
|
||||
"code": 400,
|
||||
"message": err,
|
||||
})
|
||||
}
|
||||
|
||||
func Ok(c echo.Context) error {
|
||||
return c.JSON(201, map[string]any{
|
||||
"code": 201,
|
||||
"message": "ok",
|
||||
})
|
||||
}
|
||||
|
||||
func OkKo(c echo.Context, err error) error {
|
||||
if err != nil {
|
||||
return Ko(c, err)
|
||||
}
|
||||
|
||||
return Ok(c)
|
||||
}
|
||||
|
||||
func Init(c echo.Context) error {
|
||||
// payload := []model.Video{}
|
||||
// err := c.Bind(&payload)
|
||||
var err error
|
||||
|
||||
return OkKo(c, err)
|
||||
}
|
||||
|
||||
func Push(c echo.Context) error {
|
||||
// payload := []model.Video{}
|
||||
// err := c.Bind(&payload)
|
||||
var err error
|
||||
|
||||
return OkKo(c, err)
|
||||
}
|
||||
|
||||
func Pull(c echo.Context) error {
|
||||
// payload := []model.Video{}
|
||||
// err := c.Bind(&payload)
|
||||
var err error
|
||||
|
||||
return OkKo(c, err)
|
||||
}
|
||||
|
||||
func Register(e *echo.Echo) {
|
||||
e.POST(route.PlaylistInit, Init)
|
||||
e.POST(route.PlaylistPush, Push)
|
||||
e.GET(route.PlaylistPull, Pull)
|
||||
}
|
||||
58
web/controller/profile/controller.go
Normal file
58
web/controller/profile/controller.go
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package profile
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"gitnet.fr/deblan/freetube-sync/web/route"
|
||||
)
|
||||
|
||||
func Ko(c echo.Context, err error) error {
|
||||
return c.JSON(400, map[string]any{
|
||||
"code": 400,
|
||||
"message": err,
|
||||
})
|
||||
}
|
||||
|
||||
func Ok(c echo.Context) error {
|
||||
return c.JSON(201, map[string]any{
|
||||
"code": 201,
|
||||
"message": "ok",
|
||||
})
|
||||
}
|
||||
|
||||
func OkKo(c echo.Context, err error) error {
|
||||
if err != nil {
|
||||
return Ko(c, err)
|
||||
}
|
||||
|
||||
return Ok(c)
|
||||
}
|
||||
|
||||
func Init(c echo.Context) error {
|
||||
// payload := []model.Video{}
|
||||
// err := c.Bind(&payload)
|
||||
var err error
|
||||
|
||||
return OkKo(c, err)
|
||||
}
|
||||
|
||||
func Push(c echo.Context) error {
|
||||
// payload := []model.Video{}
|
||||
// err := c.Bind(&payload)
|
||||
var err error
|
||||
|
||||
return OkKo(c, err)
|
||||
}
|
||||
|
||||
func Pull(c echo.Context) error {
|
||||
// payload := []model.Video{}
|
||||
// err := c.Bind(&payload)
|
||||
var err error
|
||||
|
||||
return OkKo(c, err)
|
||||
}
|
||||
|
||||
func Register(e *echo.Echo) {
|
||||
e.POST(route.ProfileInit, Init)
|
||||
e.POST(route.ProfilePush, Push)
|
||||
e.GET(route.ProfilePull, Pull)
|
||||
}
|
||||
17
web/helper/helper.go
Normal file
17
web/helper/helper.go
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package helper
|
||||
|
||||
import "github.com/labstack/echo/v4"
|
||||
|
||||
func Ko(c echo.Context, err error) error {
|
||||
return c.JSON(400, map[string]any{
|
||||
"code": 400,
|
||||
"message": err,
|
||||
})
|
||||
}
|
||||
|
||||
func Ok(c echo.Context) error {
|
||||
return c.JSON(201, map[string]any{
|
||||
"code": 201,
|
||||
"message": "ok",
|
||||
})
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue