Compare commits

..

100 Commits

Author SHA1 Message Date
e2b01f6585 chore(deps): lock file maintenance
Some checks failed
continuous-integration/drone/push Build is failing
2024-10-21 23:42:02 +00:00
37b41e2d4b chore(deps): update dependency svelte to v5.0.5
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-21 19:43:34 +00:00
ed8648fcf0 chore(deps): update typescript-eslint monorepo to v8.11.0
Some checks failed
continuous-integration/drone/push Build is failing
2024-10-21 17:39:56 +00:00
114430ed6d chore(deps): update dependency svelte to v5.0.4
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-21 11:45:18 +00:00
9a90ef7f30 chore(deps): lock file maintenance
Some checks failed
continuous-integration/drone/push Build is failing
2024-10-21 00:53:14 +00:00
78006a9da8 chore(deps): update dependency svelte to v5.0.3
Some checks failed
continuous-integration/drone/push Build is failing
2024-10-20 13:47:10 +00:00
edffa5ddf6 chore(deps): update dependency @sveltejs/kit to v2.7.2
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-19 23:56:28 +00:00
77c6b1adc6 chore(deps): update dependency svelte to v5.0.2
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-19 21:56:31 +00:00
0ee5b8a90d chore(deps): update dependency svelte to v5
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-19 19:51:39 +00:00
b65344a766 fix(deps): update dependency sass to v1.80.3
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-18 23:55:52 +00:00
8ed5ef9b35 chore(deps): update dependency eslint to v9.13.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-18 21:49:09 +00:00
dc565088ea fix(deps): update dependency sass to v1.80.2
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-17 21:45:46 +00:00
f2587de80f chore(deps): update typescript-eslint monorepo to v8.10.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-17 17:46:23 +00:00
a83d94b562 fix(deps): update dependency sass to v1.80.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-17 03:48:21 +00:00
0795fc616e chore(deps): update dependency @sveltejs/kit to v2.7.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-14 22:42:33 +00:00
3818e3926a chore(deps): update typescript-eslint monorepo to v8.9.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-14 17:44:57 +00:00
6c28be7f72 fix(deps): update dependency vite to v5.4.9
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-14 11:42:30 +00:00
e716097f9b chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-14 00:48:17 +00:00
79192bd277 chore(deps): update dependency @sveltejs/kit to v2.7.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-11 18:43:23 +00:00
5b8e676e71 chore(deps): update dependency svelte-check to v4.0.5
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-11 16:48:54 +00:00
a3b00fe38d Add pre-alarm action
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2024-10-11 18:00:15 +02:00
86c81396e2 fix(deps): update dependency sass to v1.79.5
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-11 01:36:40 +00:00
e131a6fdce chore(deps): update dependency typescript to v5.6.3
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-09 11:43:31 +00:00
0265f4cb7b chore(deps): update dependency @sveltejs/kit to v2.6.4
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-09 10:37:07 +00:00
7152c7f377 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-07 19:50:08 +00:00
4c1a2c7b01 chore(deps): update dependency @sveltejs/kit to v2.6.3
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-07 18:42:34 +00:00
b6d37527d7 chore(deps): update typescript-eslint monorepo to v8.8.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-07 17:33:25 +00:00
c8cff15d28 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-07 00:42:14 +00:00
bef1c4a3b6 chore(deps): update dependency @sveltejs/kit to v2.6.2
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-06 06:37:12 +00:00
8c09ac3fbe chore(deps): update dependency eslint to v9.12.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-04 21:34:34 +00:00
d4efcf2986 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-30 19:55:03 +00:00
3387b78a42 chore(deps): update typescript-eslint monorepo to v8.8.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-30 17:45:54 +00:00
f4e546a3f1 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-30 01:51:04 +00:00
2026afdb8e fix(deps): update dependency sass to v1.79.4
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-28 03:59:56 +00:00
a4faf89474 chore(deps): update dependency svelte-check to v4.0.4
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-27 23:48:41 +00:00
fd8dcca8e8 chore(deps): update dependency @sveltejs/kit to v2.6.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-27 21:42:29 +00:00
e52bb4ff5a chore(deps): update dependency @sveltejs/kit to v2.6.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-27 01:43:55 +00:00
98466d797a chore(deps): update dependency svelte-check to v4.0.3
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-26 13:50:04 +00:00
313aa152ed chore(deps): update dependency prettier-plugin-svelte to v3.2.7
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-26 11:42:18 +00:00
4bf61270d6 fix(deps): update dependency vite to v5.4.8
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-25 04:39:29 +00:00
f3399f39c6 chore(deps): update dependency eslint to v9.11.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-23 19:48:33 +00:00
7277799e5d chore(deps): update typescript-eslint monorepo to v8.7.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-23 17:41:16 +00:00
85ece4a101 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-23 00:44:07 +00:00
0a954669be fix(deps): update dependency sass to v1.79.3
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-20 21:41:21 +00:00
47e16d4610 chore(deps): update dependency eslint to v9.11.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-20 17:47:36 +00:00
a77422a561 fix(deps): update dependency vite to v5.4.7
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-20 15:48:46 +00:00
e60059ac13 fix(deps): update dependency sass-loader to v16.0.2
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-20 13:49:03 +00:00
c7d5e61ba6 fix(deps): update dependency sass to v1.79.2
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-19 23:43:31 +00:00
c4d5fb3a96 chore(deps): update dependency @sveltejs/kit to v2.5.28
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-18 01:46:39 +00:00
947c2a2403 fix(deps): update dependency sass to v1.79.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-18 00:41:59 +00:00
145bbd4bf1 chore(deps): update dependency @sveltejs/adapter-static to v3.0.5
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-17 17:39:54 +00:00
c45c67d59f fix(deps): update dependency vite to v5.4.6
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-16 20:39:55 +00:00
4e2ffd3e60 chore(deps): update typescript-eslint monorepo to v8.6.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-16 17:37:32 +00:00
c31b1d3188 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-16 00:40:57 +00:00
714fd7636c chore(deps): update dependency @sveltejs/kit to v2.5.27
Some checks reported errors
continuous-integration/drone/push Build was killed
2024-09-13 16:36:33 +00:00
a8f36c833f fix(deps): update dependency vite to v5.4.5
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-13 09:41:53 +00:00
0085d40b4d chore(deps): update dependency svelte-check to v4.0.2
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-12 11:34:57 +00:00
b055cee040 fix(deps): update dependency vite to v5.4.4
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-11 08:35:18 +00:00
7cacf2dfb7 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-09 18:42:05 +00:00
ac8069f184 chore(deps): update typescript-eslint monorepo to v8.5.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-09 17:34:47 +00:00
890d2a3565 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-09 00:38:40 +00:00
054e575257 chore(deps): update dependency eslint to v9.10.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-06 21:29:59 +00:00
cb9e04fc1d chore(deps): update dependency @sveltejs/kit to v2.5.26
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-04 18:40:50 +00:00
7866f2b0b8 chore(deps): update dependency svelte-check to v4.0.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-04 12:33:26 +00:00
5eea245c7c fix(deps): update dependency sass to v1.78.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-03 23:33:48 +00:00
980a99c1c4 fix(deps): update dependency vite to v5.4.3
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-03 16:34:26 +00:00
f933c32ace chore(deps): update typescript-eslint monorepo to v8.4.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-02 17:32:31 +00:00
12a48d025e chore(deps): update dependency svelte-check to v4
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-02 12:32:42 +00:00
271fea3e8a chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-02 00:38:33 +00:00
4f615662f3 Sort track in track list
All checks were successful
continuous-integration/drone/push Build is passing
2024-09-01 17:14:30 +02:00
23fb78b037 chore(deps): update dependency @sveltejs/kit to v2.5.25
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-27 21:34:01 +00:00
7343424b18 chore(deps): update typescript-eslint monorepo to v8.3.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-26 17:30:33 +00:00
92a1643598 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-26 00:38:58 +00:00
006e2722c6 chore(deps): update dependency eslint to v9.9.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-23 21:37:02 +00:00
67a0277b42 chore(deps): update dependency svelte to v4.2.19
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-23 16:34:34 +00:00
505bfd81e0 chore(deps): update dependency svelte-check to v3.8.6
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-22 16:28:33 +00:00
a910029353 fix(deps): update dependency dayjs to v1.11.13
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-20 15:31:48 +00:00
8bfd5489b3 fix(deps): update dependency vite to v5.4.2
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-20 14:27:07 +00:00
e3cbfd3d07 chore(deps): update typescript-eslint monorepo to v8.2.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-19 21:35:50 +00:00
b94aea0f33 fix(deps): update dependency sass-loader to v16.0.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-19 19:36:41 +00:00
b0c9467ab7 chore(deps): update dependency @sveltejs/kit to v2.5.24
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-19 11:29:49 +00:00
5e91f7227f chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-19 00:35:31 +00:00
02a4cb15a2 fix(deps): update dependency vite to v5.4.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-15 15:45:36 +00:00
34aa7477a5 chore(deps): update typescript-eslint monorepo to v8.1.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-15 13:42:21 +00:00
6b914029c9 chore(deps): update dependency @sveltejs/adapter-static to v3.0.4
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-15 11:46:25 +00:00
086bacbedd chore(deps): update dependency @sveltejs/kit to v2.5.22
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-15 08:07:53 +00:00
4c5ebe5988 chore(deps): update dependency eslint to v9
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-06 08:26:48 +00:00
c2fd3d679b chore(deps): update typescript-eslint monorepo to v8
Some checks are pending
continuous-integration/drone/push Build is running
2024-08-06 08:24:37 +00:00
ebffb7b168 fix(deps): update dependency sass-loader to v16
Some checks are pending
continuous-integration/drone/push Build is running
2024-08-06 08:22:58 +00:00
3bc3b1c96d chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-05 00:26:04 +00:00
732df88b04 chore(deps): update dependency @sveltejs/kit to v2.5.20
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-02 17:28:37 +00:00
dd375b79b6 chore(deps): update dependency @sveltejs/kit to v2.5.19
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-01 11:29:18 +00:00
a55084dfd8 chore(deps): update dependency svelte-check to v3.8.5
All checks were successful
continuous-integration/drone/push Build is passing
2024-07-30 17:29:22 +00:00
c8c6282216 Refactor federation + can sync track between instances
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2024-07-30 11:00:05 +02:00
e99efdb43f chore(deps): update typescript-eslint monorepo to v7.18.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-07-29 17:26:17 +00:00
700e3ad178 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-07-29 13:27:39 +00:00
25e5362d01 Add delay on federation
All checks were successful
continuous-integration/drone/push Build is passing
2024-07-29 11:16:51 +02:00
5f2a515437 chore(deps): lock file maintenance
All checks were successful
continuous-integration/drone/push Build is passing
2024-07-29 00:35:52 +00:00
8d8fa1f855 fix(deps): update dependency sass-loader to v15
All checks were successful
continuous-integration/drone/push Build is passing
2024-07-26 07:09:36 +00:00
424eeeaa56 chore(deps): update dependency typescript to v5.5.4
Some checks are pending
continuous-integration/drone/push Build is running
2024-07-25 18:31:55 +00:00
13 changed files with 1308 additions and 995 deletions

View File

@ -62,7 +62,7 @@ func declareAlarmRoutes(cfg *config.Config, router *gin.RouterGroup) {
}
for k, srv := range settings.Federation {
err = player.FederatedStop(srv)
err = srv.WakeStop()
if err != nil {
log.Printf("Unable to do federated wakeup on %s: %s", k, err.Error())
} else {

View File

@ -1,12 +1,15 @@
package api
import (
"bytes"
"fmt"
"net/http"
"time"
"github.com/gin-gonic/gin"
"git.nemunai.re/nemunaire/reveil/config"
"git.nemunai.re/nemunaire/reveil/model"
"git.nemunai.re/nemunaire/reveil/player"
)
@ -47,4 +50,127 @@ func declareFederationRoutes(cfg *config.Config, router *gin.RouterGroup) {
c.JSON(http.StatusOK, true)
})
router.GET("/federation", func(c *gin.Context) {
settings, err := reveil.ReadSettings(cfg.SettingsFile)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
return
}
c.JSON(http.StatusOK, settings.Federation)
})
federationsRoutes := router.Group("/federation/:fid")
federationsRoutes.Use(func(c *gin.Context) {
settings, err := reveil.ReadSettings(cfg.SettingsFile)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
return
}
f, ok := settings.Federation[string(c.Param("fid"))]
if !ok {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Action not found"})
return
}
c.Set("federation", &f)
c.Next()
})
federationsRoutes.GET("", func(c *gin.Context) {
c.JSON(http.StatusOK, c.MustGet("federation"))
})
federationsRoutes.POST("sync", func(c *gin.Context) {
srv := c.MustGet("federation").(*reveil.FederationServer)
// Retrieve music list on remote
remoteMusics, err := srv.GetMusics()
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to retrieve remote tracks lists: %s", err.Error())})
return
}
// Retrieve local music list
localMusics, err := reveil.LoadTracks(cfg)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to retrieve local tracks: %s", err.Error())})
return
}
// Compute diff
var newMusics []reveil.Track
var oldMusics []reveil.Track
var musicsToEnable []reveil.Track
for _, rTrack := range remoteMusics {
found := false
for _, lTrack := range localMusics {
if bytes.Compare(lTrack.Id, rTrack.Id) == 0 || lTrack.Name == rTrack.Name {
if lTrack.Enabled != rTrack.Enabled {
if lTrack.Enabled {
musicsToEnable = append(musicsToEnable, rTrack)
} else {
oldMusics = append(oldMusics, *lTrack)
}
}
found = true
break
}
}
if !found && rTrack.Enabled {
oldMusics = append(oldMusics, rTrack)
}
}
for _, lTrack := range localMusics {
found := false
for _, rTrack := range remoteMusics {
if bytes.Compare(lTrack.Id, rTrack.Id) == 0 || lTrack.Name == rTrack.Name {
found = true
break
}
}
if !found && lTrack.Enabled {
newMusics = append(newMusics, *lTrack)
}
}
// Disable unexistant musics on local
for _, t := range oldMusics {
t.Enabled = false
err = srv.UpdateTrack(&t)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("An error occurs when disabling remote tracks (unexistant on local): %s: %s", t.Id.ToString(), err.Error())})
return
}
}
// Enable existant musics on remote
for _, t := range musicsToEnable {
t.Enabled = true
err = srv.UpdateTrack(&t)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
return
}
}
// Send new musics
for _, t := range newMusics {
err = srv.SendTrack(&t)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
return
}
}
c.JSON(http.StatusOK, true)
})
}

35
app.go
View File

@ -21,6 +21,7 @@ type App struct {
router *gin.Engine
srv *http.Server
nextAlarm *time.Timer
nextPreAlarm *time.Timer
}
func NewApp(cfg *config.Config) *App {
@ -76,11 +77,45 @@ func (app *App) Start() {
func (app *App) ResetTimer() {
if app.nextAlarm != nil {
app.nextAlarm.Stop()
app.nextPreAlarm = nil
app.nextAlarm = nil
}
settings, _ := reveil.ReadSettings(app.cfg.SettingsFile)
if na, routines, federated, err := reveil.GetNextAlarm(app.cfg, app.db); err == nil && na != nil {
if settings != nil && settings.PreAlarmAction != "" {
app.nextPreAlarm = time.AfterFunc(time.Until(*na)-settings.PreAlarmActionDelay*time.Minute, func() {
app.nextPreAlarm = nil
settings, err := reveil.ReadSettings(app.cfg.SettingsFile)
if err != nil {
log.Println("Unable to read settings:", err.Error())
return
}
action, err := reveil.LoadAction(app.cfg, settings.PreAlarmAction)
if err != nil {
log.Println("Unable to load pre-alarm action:", err.Error())
}
cmd, err := action.Launch(settings)
if err != nil {
log.Println(err.Error())
return
}
go func() {
err := cmd.Wait()
if err != nil {
log.Printf("%q: %s", action.Name, err.Error())
}
}()
})
log.Println("Next pre-alarm programmed for", time.Time(*na).Add(settings.PreAlarmActionDelay*-1*time.Minute))
}
app.nextAlarm = time.AfterFunc(time.Until(*na), func() {
app.nextPreAlarm = nil
app.nextAlarm = nil
reveil.RemoveOldAlarmsSingle(app.db)

137
model/federation.go Normal file
View File

@ -0,0 +1,137 @@
package reveil
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
)
type FederationServer struct {
URL string `json:"url"`
Delay uint `json:"delay"`
}
func (srv *FederationServer) WakeUp(seed int64) error {
req := map[string]interface{}{"seed": seed}
req_enc, err := json.Marshal(req)
if err != nil {
return err
}
res, err := http.Post(srv.URL+"/api/federation/wakeup", "application/json", bytes.NewBuffer(req_enc))
if err != nil {
return err
}
res.Body.Close()
return nil
}
func (srv *FederationServer) WakeStop() error {
res, err := http.Post(srv.URL+"/api/federation/wakeok", "application/json", nil)
if err != nil {
return err
}
res.Body.Close()
return nil
}
func (srv *FederationServer) GetMusics() ([]Track, error) {
res, err := http.Get(srv.URL + "/api/tracks")
if err != nil {
return nil, err
}
defer res.Body.Close()
var tracks []Track
err = json.NewDecoder(res.Body).Decode(&tracks)
if err != nil {
return nil, err
}
return tracks, nil
}
func (srv *FederationServer) UpdateTrack(t *Track) error {
req_enc, err := json.Marshal(t)
if err != nil {
return err
}
req, err := http.NewRequest("PUT", srv.URL+"/api/tracks/"+t.Id.ToString(), bytes.NewBuffer(req_enc))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode == http.StatusOK {
var track Track
err = json.NewDecoder(res.Body).Decode(&track)
if err != nil {
return err
}
} else {
var errmsg map[string]string
err = json.NewDecoder(res.Body).Decode(&errmsg)
if err != nil {
return err
} else {
return fmt.Errorf("%s", errmsg["errmsg"])
}
}
return nil
}
func (srv *FederationServer) SendTrack(track *Track) error {
// Retrieve file
fd, err := track.Open()
if err != nil {
return err
}
defer fd.Close()
var b bytes.Buffer
w := multipart.NewWriter(&b)
var fw io.Writer
// Add an image file
if fw, err = w.CreateFormFile("trackfile", fd.Name()); err != nil {
return err
}
if _, err = io.Copy(fw, fd); err != nil {
return err
}
w.Close()
//
req, err := http.NewRequest("POST", srv.URL+"/api/tracks", &b)
if err != nil {
return err
}
req.Header.Set("Content-Type", w.FormDataContentType())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
if res.StatusCode != http.StatusOK {
return fmt.Errorf("bad status: %s", res.Status)
}
return nil
}

View File

@ -6,19 +6,17 @@ import (
"time"
)
type FederationSettings struct {
URL string `json:"url"`
}
// Settings represents the settings panel.
type Settings struct {
Language string `json:"language"`
GongInterval time.Duration `json:"gong_interval"`
WeatherDelay time.Duration `json:"weather_delay"`
WeatherAction string `json:"weather_action"`
PreAlarmActionDelay time.Duration `json:"pre_alarm_delay"`
PreAlarmAction string `json:"pre_alarm_action"`
MaxRunTime time.Duration `json:"max_run_time"`
MaxVolume uint16 `json:"max_volume"`
Federation map[string]FederationSettings `json:"federation"`
Federation map[string]FederationServer `json:"federation"`
}
// ExistsSettings checks if the settings file can by found at the given path.

View File

@ -1,35 +1,29 @@
package player
import (
"bytes"
"encoding/json"
"net/http"
"log"
"time"
"git.nemunai.re/nemunaire/reveil/model"
)
func FederatedWakeUp(srv reveil.FederationSettings, seed int64) error {
req := map[string]interface{}{"seed": seed}
req_enc, err := json.Marshal(req)
func FederatedWakeUp(k string, srv reveil.FederationServer, seed int64) {
if srv.Delay == 0 {
err := srv.WakeUp(seed)
if err != nil {
return err
log.Printf("Unable to do federated wakeup on %s: %s", k, err.Error())
} else {
log.Printf("Federated wakeup on %s: launched!", k)
}
res, err := http.Post(srv.URL+"/api/federation/wakeup", "application/json", bytes.NewBuffer(req_enc))
} else {
go func() {
time.Sleep(time.Duration(srv.Delay) * time.Millisecond)
err := srv.WakeUp(seed)
if err != nil {
return err
log.Printf("Unable to do federated wakeup on %s: %s", k, err.Error())
} else {
log.Printf("Federated wakeup on %s: launched!", k)
}
}()
}
res.Body.Close()
return nil
}
func FederatedStop(srv reveil.FederationSettings) error {
res, err := http.Post(srv.URL+"/api/federation/wakeok", "application/json", nil)
if err != nil {
return err
}
res.Body.Close()
return nil
}

View File

@ -58,12 +58,7 @@ func WakeUp(cfg *config.Config, routine []reveil.Identifier, federated bool) (er
}
for k, srv := range settings.Federation {
err = FederatedWakeUp(srv, seed)
if err != nil {
log.Printf("Unable to do federated wakeup on %s: %s", k, err.Error())
} else {
log.Printf("Federated wakeup on %s: launched!", k)
}
FederatedWakeUp(k, srv, seed)
}
}

1775
ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,18 +15,18 @@
"@sveltejs/adapter-static": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"bootstrap": "^5.1.3",
"bootstrap-icons": "^1.8.0",
"bootswatch": "^5.1.3",
"eslint": "^8.0.0",
"eslint": "^9.0.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-svelte": "^2.33.0",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
"svelte": "^4.0.0",
"svelte-check": "^3.4.3",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"svelte-preprocess": "^6.0.0",
"tslib": "^2.3.1",
"typescript": "^5.0.0"
@ -35,7 +35,7 @@
"dependencies": {
"dayjs": "^1.11.5",
"sass": "^1.49.7",
"sass-loader": "^14.0.0",
"sass-loader": "^16.0.0",
"@sveltestrap/sveltestrap": "^6.0.0",
"vite": "^5.0.0"
}

View File

@ -2,9 +2,14 @@
import { createEventDispatcher } from 'svelte';
import {
Button,
Col,
Icon,
Input,
InputGroup,
InputGroupText,
Row,
Spinner,
} from '@sveltestrap/sveltestrap';
const dispatch = createEventDispatcher();
@ -23,11 +28,26 @@
delete value[bak];
}
}
const syncInProgress = { };
async function syncMusic(srv) {
syncInProgress[srv] = true;
const res = await fetch(`api/federation/${srv}/sync`, {
method: 'POST',
headers: {'Accept': 'application/json'}
});
if (res.status != 200) {
throw new Error((await res.json()).errmsg);
}
syncInProgress[srv] = false;
}
</script>
{#if value}
{#each Object.keys(value) as key}
<Row>
<Row class="mb-3">
<Col>
<Input
type="string"
@ -37,12 +57,50 @@
/>
</Col>
<Col>
<InputGroup>
<Input
type="string"
placeholder="https://reveil.fr/"
bind:value={value[key].url}
on:change={() => dispatch("input")}
/>
<Button
href={value[key].url}
target="_blank"
>
<Icon name="globe" />
</Button>
</InputGroup>
</Col>
<Col>
<Row>
<Col>
<InputGroup>
<Input
type="number"
placeholder="60"
bind:value={value[key].delay}
on:change={() => dispatch("input")}
/>
<InputGroupText>ms</InputGroupText>
</InputGroup>
</Col>
<Col xs="auto">
<Button
color="info"
disabled={syncInProgress[key]}
title="Synchroniser les musiques"
type="button"
on:click={() => syncMusic(key)}
>
{#if syncInProgress[key]}
<Spinner size="sm" />
{:else}
<Icon name="music-note-list" />
{/if}
</Button>
</Col>
</Row>
</Col>
</Row>
{/each}
@ -65,4 +123,12 @@
value=""
/>
</Col>
<Col>
<Input
type="number"
placeholder="60"
disabled
value=""
/>
</Col>
</Row>

View File

@ -5,11 +5,13 @@ export class Settings {
}
}
update({ language, gong_interval, weather_delay, weather_action, max_run_time, max_volume, federation }) {
update({ language, gong_interval, weather_delay, weather_action, pre_alarm_delay, pre_alarm_action, max_run_time, max_volume, federation }) {
this.language = language;
this.gong_interval = gong_interval;
this.weather_delay = weather_delay;
this.weather_action = weather_action;
this.pre_alarm_delay = pre_alarm_delay;
this.pre_alarm_action = pre_alarm_action;
this.max_run_time = max_run_time;
this.max_volume = max_volume;
this.federation = federation;

View File

@ -2,6 +2,18 @@ import { writable } from 'svelte/store';
import { getTracks } from '$lib/track'
function cmpTracks(a, b) {
if (a.enabled && !b.enabled) return -1;
if (!a.enabled && b.enabled) return 1;
if (a.path.toLowerCase() > b.path.toLowerCase())
return 1;
if (a.path.toLowerCase() < b.path.toLowerCase())
return -1;
return 0;
}
function createTracksStore() {
const { subscribe, set, update } = writable({list: null});
@ -14,6 +26,7 @@ function createTracksStore() {
refresh: async () => {
const list = await getTracks();
list.sort(cmpTracks);
update((m) => Object.assign(m, {list}));
return list;
},

View File

@ -89,6 +89,40 @@
{/if}
</FormGroup>
<FormGroup>
<Label for="preAlarmDelay">Lancement action pré-alarme</Label>
<InputGroup>
<Input
type="number"
id="preAlarmDelay"
placeholder="5"
bind:value={settings.pre_alarm_delay}
on:input={submitSettings}
/>
<InputGroupText>min</InputGroupText>
</InputGroup>
</FormGroup>
<FormGroup>
<Label for="preAlarmRituel">Action pour l'action pré-alarme</Label>
{#if $actions.list}
<Input
type="select"
id="preAlarmRituel"
bind:value={settings.pre_alarm_action}
on:input={submitSettings}
>
{#each $actions.list as action (action.id)}
<option value="{action.path}">{action.name}</option>
{/each}
</Input>
{:else}
<div class="d-flex justify-content-center align-items-center gap-2">
<Spinner color="primary" /> Chargement en cours&hellip;
</div>
{/if}
</FormGroup>
<FormGroup>
<Label for="greetingLanguage">Langue de salutation</Label>
<Input