feat: persisting remotes and commands in database
This commit is contained in:
parent
db1beac033
commit
6cefa7392c
75
data/command.go
Normal file
75
data/command.go
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package data
|
||||||
|
|
||||||
|
const SAMSUNG_PROTOCOL = "samsung"
|
||||||
|
const NEC_PROTOCOL = "nec"
|
||||||
|
const ONKYO_PROTOCOL = "onkyo"
|
||||||
|
const APPLE_PROTOCOL = "apple"
|
||||||
|
const DENON_PROTOCOL = "denon"
|
||||||
|
const SHARP_PROTOCOL = "sharp"
|
||||||
|
const PANASONIC_PROTOCOL = "panasonic"
|
||||||
|
const KASEIKYO_PROTOCOL = "kaseikyo"
|
||||||
|
const JVC_PROTOCOL = "jvc"
|
||||||
|
const LG_PROTOCOL = "lg"
|
||||||
|
const SONY_PROTOCOL = "sony"
|
||||||
|
const RC5_PROTOCOL = "rc5"
|
||||||
|
const RC6_PROTOCOL = "rc6"
|
||||||
|
const UNIVERSAL_PULSE_DISTANCE_PROTOCOL = "universal_pulse_distance"
|
||||||
|
const UNIVERSAL_PULSE_WIDTH_PROTOCOL = "universal_pulse_width"
|
||||||
|
const UNIVERSAL_PULSE_DISTANCE_WIDTH_PROTOCOL = "universal_pulse_distance_width"
|
||||||
|
const HASH_PROTOCOL = "hash"
|
||||||
|
const PRONTO_PROTOCOL = "pronto"
|
||||||
|
const BOSE_WAVE_PROTOCOL = "bose_wave"
|
||||||
|
const BANG_OLUFSEN_PROTOCOL = "bang_olufsen"
|
||||||
|
const LEGO_PROTOCOL = "lego"
|
||||||
|
const FAST_PROTOCOL = "fast"
|
||||||
|
const WHYNTER_PROTOCOL = "whynter"
|
||||||
|
const MAGIQUEST_PROTOCOL = "magiquest"
|
||||||
|
|
||||||
|
const POWER_COMMAND_TYPE = "power"
|
||||||
|
const INPUT_COMMAND_TYPE = "input"
|
||||||
|
const ONE_COMMAND_TYPE = "1"
|
||||||
|
const TWO_COMMAND_TYPE = "2"
|
||||||
|
const THREE_COMMAND_TYPE = "3"
|
||||||
|
const FOUR_COMMAND_TYPE = "4"
|
||||||
|
const FIVE_COMMAND_TYPE = "5"
|
||||||
|
const SIX_COMMAND_TYPE = "6"
|
||||||
|
const SEVEN_COMMAND_TYPE = "7"
|
||||||
|
const EIGHT_COMMAND_TYPE = "8"
|
||||||
|
const NINE_COMMAND_TYPE = "9"
|
||||||
|
const ZERO_COMMAND_TYPE = "0"
|
||||||
|
const VOLUME_UP_COMMAND_TYPE = "volume_up"
|
||||||
|
const VOLUME_DOWN_COMMAND_TYPE = "volume_down"
|
||||||
|
const MUTE_COMMAND_TYPE = "mute"
|
||||||
|
const CHANNEL_UP_COMMAND_TYPE = "channel_up"
|
||||||
|
const CHANNEL_DOWN_COMMAND_TYPE = "channel_down"
|
||||||
|
const MENU_COMMAND_TYPE = "menu"
|
||||||
|
const HOME_COMMAND_TYPE = "home"
|
||||||
|
const SETTINGS_COMMAND_TYPE = "settings"
|
||||||
|
const OPTIONS_COMMAND_TYPE = "options"
|
||||||
|
const UP_COMMAND_TYPE = "up"
|
||||||
|
const DOWN_COMMAND_TYPE = "down"
|
||||||
|
const LEFT_COMMAND_TYPE = "left"
|
||||||
|
const RIGHT_COMMAND_TYPE = "right"
|
||||||
|
const ENTER_COMMAND_TYPE = "enter"
|
||||||
|
const INFO_COMMAND_TYPE = "info"
|
||||||
|
const RETURN_COMMAND_TYPE = "return"
|
||||||
|
const EXIT_COMMAND_TYPE = "exit"
|
||||||
|
const RED_COMMAND_TYPE = "red"
|
||||||
|
const GREEN_COMMAND_TYPE = "green"
|
||||||
|
const YELLOW_COMMAND_TYPE = "yellow"
|
||||||
|
const BLUE_COMMAND_TYPE = "blue"
|
||||||
|
const REWIND_COMMAND_TYPE = "rewind"
|
||||||
|
const PLAY_COMMAND_TYPE = "play"
|
||||||
|
const PAUSE_COMMAND_TYPE = "pause"
|
||||||
|
const STOP_COMMAND_TYPE = "stop"
|
||||||
|
const FORWARD_COMMAND_TYPE = "forward"
|
||||||
|
const OTHER_COMMAND_TYPE = "other"
|
||||||
|
|
||||||
|
type Command struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
CommandNumber int `json:"commandNumber"`
|
||||||
|
Device int `json:"device"`
|
||||||
|
CommandType string `json:"commandType"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
}
|
||||||
7
data/remote.go
Normal file
7
data/remote.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package data
|
||||||
|
|
||||||
|
type Remote struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Commands []Command `json:"commands"`
|
||||||
|
}
|
||||||
200
data/remote_database.go
Normal file
200
data/remote_database.go
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
package data
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
gonanoid "github.com/matoous/go-nanoid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RemoteDatabase struct {
|
||||||
|
Connection *sql.DB
|
||||||
|
databaseDirectory string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) Initialize() error {
|
||||||
|
connection, error := sql.Open("sqlite3", filepath.Join(db.databaseDirectory, "remotes.db"))
|
||||||
|
if error != nil {
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
db.Connection = connection
|
||||||
|
|
||||||
|
_, error = db.Connection.Exec(`PRAGMA foreign_keys = ON;`)
|
||||||
|
if error != nil {
|
||||||
|
return fmt.Errorf("error enabling foreign keys: %s", error)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, error = db.Connection.Exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS Remotes (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
title TEXT NOT NULL
|
||||||
|
);`)
|
||||||
|
if error != nil {
|
||||||
|
return fmt.Errorf("error creating remotes table: %s", error)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, error = db.Connection.Exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS Commands (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
protocol TEXT,
|
||||||
|
commandNumber INTEGER,
|
||||||
|
device INTEGER,
|
||||||
|
commandType TEXT,
|
||||||
|
title TEXT
|
||||||
|
);`)
|
||||||
|
if error != nil {
|
||||||
|
return fmt.Errorf("error creating commands table: %s", error)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, error = db.Connection.Exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS RemoteCommands (
|
||||||
|
remote_id TEXT NOT NULL,
|
||||||
|
command_id TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (remote_id, command_id),
|
||||||
|
FOREIGN KEY (remote_id) REFERENCES Remotes(id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (command_id) REFERENCES Commands(id) ON DELETE CASCADE
|
||||||
|
);`)
|
||||||
|
if error != nil {
|
||||||
|
return fmt.Errorf("error creating remote-commands table: %s", error)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) Close() error {
|
||||||
|
return db.Connection.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) CreateRemote(remote Remote) (string, error) {
|
||||||
|
remoteId, err := gonanoid.Nanoid(8)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
queryString := "INSERT INTO Remotes (id, title) VALUES (?, ?)"
|
||||||
|
_, err = db.Connection.Exec(queryString, remoteId, remote.Title)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
commandIds := []string{}
|
||||||
|
for _, command := range remote.Commands {
|
||||||
|
commandIds = append(commandIds, command.Id)
|
||||||
|
}
|
||||||
|
err = db.CreateRemoteCommands(remoteId, commandIds)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return remoteId, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) CreateRemoteCommands(remoteId string, commandIds []string) error {
|
||||||
|
for _, commandId := range commandIds {
|
||||||
|
queryString := "INSERT INTO RemoteCommands (remote_id, command_id) VALUES (?, ?)"
|
||||||
|
_, err := db.Connection.Exec(queryString, remoteId, commandId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) GetRemotes() ([]Remote, error) {
|
||||||
|
rows, error := db.Connection.Query("SELECT id, title FROM Remotes")
|
||||||
|
if error != nil {
|
||||||
|
return nil, fmt.Errorf("error querying remotes: %s", error)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
remotes := []Remote{}
|
||||||
|
for rows.Next() {
|
||||||
|
var remote Remote
|
||||||
|
error = rows.Scan(&remote.Id, &remote.Title)
|
||||||
|
if error != nil {
|
||||||
|
return nil, fmt.Errorf("error scanning remote: %s", error)
|
||||||
|
}
|
||||||
|
remotes = append(remotes, remote)
|
||||||
|
}
|
||||||
|
return remotes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) DeleteRemote(remoteId string) error {
|
||||||
|
queryString := "DELETE FROM Remotes WHERE id = ?"
|
||||||
|
_, error := db.Connection.Exec(queryString, remoteId)
|
||||||
|
if error != nil {
|
||||||
|
return fmt.Errorf("error deleting remote %s: %s", remoteId, error)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) GetCommandsByRemoteId(remoteId string) ([]Command, error) {
|
||||||
|
rows, error := db.Connection.Query("SELECT id, protocol, commandNumber, device, commandType, title FROM Commands WHERE id IN (SELECT command_id FROM RemoteCommands WHERE remote_id = ?)", remoteId)
|
||||||
|
if error != nil {
|
||||||
|
return nil, fmt.Errorf("error querying commands for remote %s: %s", remoteId, error)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
commands := []Command{}
|
||||||
|
for rows.Next() {
|
||||||
|
var command Command
|
||||||
|
error = rows.Scan(&command.Id, &command.Protocol, &command.CommandNumber, &command.Device, &command.CommandType, &command.Title)
|
||||||
|
if error != nil {
|
||||||
|
return nil, fmt.Errorf("error scanning command: %s", error)
|
||||||
|
}
|
||||||
|
commands = append(commands, command)
|
||||||
|
}
|
||||||
|
return commands, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) CreateCommand(command Command) (string, error) {
|
||||||
|
commandId, err := gonanoid.Nanoid(8)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
queryString := "INSERT INTO Commands (id, protocol, commandNumber, device, commandType, title) VALUES (?, ?, ?, ?, ?, ?)"
|
||||||
|
_, err = db.Connection.Exec(queryString, commandId, command.Protocol, command.CommandNumber, command.Device, command.CommandType, command.Title)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return commandId, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) CreateCommands(commands []Command) error {
|
||||||
|
for _, command := range commands {
|
||||||
|
_, err := db.CreateCommand(command)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) GetCommands() ([]Command, error) {
|
||||||
|
rows, error := db.Connection.Query("SELECT id, protocol, commandNumber, device, commandType, title FROM Commands")
|
||||||
|
if error != nil {
|
||||||
|
return nil, fmt.Errorf("error querying commands: %s", error)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
commands := []Command{}
|
||||||
|
for rows.Next() {
|
||||||
|
var command Command
|
||||||
|
error = rows.Scan(&command.Id, &command.Protocol, &command.CommandNumber, &command.Device, &command.CommandType, &command.Title)
|
||||||
|
if error != nil {
|
||||||
|
return nil, fmt.Errorf("error scanning command: %s", error)
|
||||||
|
}
|
||||||
|
commands = append(commands, command)
|
||||||
|
}
|
||||||
|
return commands, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) DeleteCommand(commandId string) error {
|
||||||
|
queryString := "DELETE FROM Commands WHERE id = ?"
|
||||||
|
_, error := db.Connection.Exec(queryString, commandId)
|
||||||
|
if error != nil {
|
||||||
|
return fmt.Errorf("error deleting command %s: %s", commandId, error)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *RemoteDatabase) SetDirectory(directory string) {
|
||||||
|
db.databaseDirectory = directory
|
||||||
|
}
|
||||||
20
main/main.go
20
main/main.go
@ -39,6 +39,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer deviceDatabase.Close()
|
defer deviceDatabase.Close()
|
||||||
|
|
||||||
|
remoteDatabase := data.RemoteDatabase{}
|
||||||
|
remoteDatabase.SetDirectory(configuration.DatabaseDirectory)
|
||||||
|
err = remoteDatabase.Initialize()
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("failed to initialize remote database")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer remoteDatabase.Close()
|
||||||
|
|
||||||
userManager := management.UserManager{}
|
userManager := management.UserManager{}
|
||||||
err = userManager.Initialize(&userDatabase)
|
err = userManager.Initialize(&userDatabase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -51,6 +60,12 @@ func main() {
|
|||||||
log.Error().Err(err).Msg("failed to initialize device manager")
|
log.Error().Err(err).Msg("failed to initialize device manager")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remoteManager := management.RemoteManager{}
|
||||||
|
err = remoteManager.Initialize(&remoteDatabase)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("failed to initialize remote manager")
|
||||||
|
}
|
||||||
|
|
||||||
webServer := server.WebServer{}
|
webServer := server.WebServer{}
|
||||||
webServer.SetWebAppDirectoryPath("www")
|
webServer.SetWebAppDirectoryPath("www")
|
||||||
webServer.SetPort(configuration.Port)
|
webServer.SetPort(configuration.Port)
|
||||||
@ -71,6 +86,11 @@ func main() {
|
|||||||
deviceApiHandler.SetRouter(webServer.Router())
|
deviceApiHandler.SetRouter(webServer.Router())
|
||||||
deviceApiHandler.Initialize(&authenticator)
|
deviceApiHandler.Initialize(&authenticator)
|
||||||
|
|
||||||
|
remoteApiHandler := server.RemoteApiHandler{}
|
||||||
|
remoteApiHandler.SetRemoteManager(&remoteManager)
|
||||||
|
remoteApiHandler.SetRouter(webServer.Router())
|
||||||
|
remoteApiHandler.Initialize(&authenticator)
|
||||||
|
|
||||||
webSocketServer := server.WebsocketServer{}
|
webSocketServer := server.WebsocketServer{}
|
||||||
webSocketServer.SetRouter(webServer.Router())
|
webSocketServer.SetRouter(webServer.Router())
|
||||||
webSocketServer.Initialize(&authenticator)
|
webSocketServer.Initialize(&authenticator)
|
||||||
|
|||||||
50
management/remote_manager.go
Normal file
50
management/remote_manager.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package management
|
||||||
|
|
||||||
|
import (
|
||||||
|
d "playback-device-server/data"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RemoteManager struct {
|
||||||
|
remoteDatabase *d.RemoteDatabase
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rm *RemoteManager) Initialize(remoteDatabase *d.RemoteDatabase) error {
|
||||||
|
rm.remoteDatabase = remoteDatabase
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rm *RemoteManager) CreateRemote(remote d.Remote) (string, error) {
|
||||||
|
return rm.remoteDatabase.CreateRemote(remote)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rm *RemoteManager) GetRemotes() ([]d.Remote, error) {
|
||||||
|
remotes, err := rm.remoteDatabase.GetRemotes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return remotes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rm *RemoteManager) DeleteRemote(remoteID string) error {
|
||||||
|
return rm.remoteDatabase.DeleteRemote(remoteID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rm *RemoteManager) CreateCommand(command d.Command) (string, error) {
|
||||||
|
return rm.remoteDatabase.CreateCommand(command)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rm *RemoteManager) CreateCommands(commands []d.Command) error {
|
||||||
|
return rm.remoteDatabase.CreateCommands(commands)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rm *RemoteManager) GetCommands() ([]d.Command, error) {
|
||||||
|
return rm.remoteDatabase.GetCommands()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rm *RemoteManager) SetRemoteDatabase(remoteDatabase *d.RemoteDatabase) {
|
||||||
|
rm.remoteDatabase = remoteDatabase
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rm *RemoteManager) DeleteCommand(commandID string) error {
|
||||||
|
return rm.remoteDatabase.DeleteCommand(commandID)
|
||||||
|
}
|
||||||
103
server/remote_api_handler.go
Normal file
103
server/remote_api_handler.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
d "playback-device-server/data"
|
||||||
|
m "playback-device-server/management"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RemoteApiHandler struct {
|
||||||
|
router *echo.Echo
|
||||||
|
remoteManager *m.RemoteManager
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoteApiHandler) Initialize(authenticator *Authenticator) {
|
||||||
|
r.router.Use(authenticator.Authenticate("/api/remotes", []string{}))
|
||||||
|
remotesApi := r.router.Group("/api/remotes")
|
||||||
|
remotesApi.GET("", r.handleGetRemotes)
|
||||||
|
remotesApi.POST("", r.handleCreateRemote)
|
||||||
|
remotesApi.DELETE("/:id", r.handleDelteRemote)
|
||||||
|
|
||||||
|
r.router.Use(authenticator.Authenticate("/api/commands", []string{}))
|
||||||
|
commandsApi := r.router.Group("/api/commands")
|
||||||
|
commandsApi.GET("", r.handleGetCommands)
|
||||||
|
commandsApi.POST("", r.handleCreateCommands)
|
||||||
|
commandsApi.DELETE("/:id", r.handleDeleteCommand)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoteApiHandler) handleCreateRemote(context echo.Context) error {
|
||||||
|
remote := d.Remote{}
|
||||||
|
if err := context.Bind(&remote); err != nil {
|
||||||
|
SendError(400, context, err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
id, err := r.remoteManager.CreateRemote(remote)
|
||||||
|
if err != nil {
|
||||||
|
SendError(500, context, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
remote.Id = id
|
||||||
|
return context.JSON(200, remote)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoteApiHandler) handleGetRemotes(context echo.Context) error {
|
||||||
|
remotes, err := r.remoteManager.GetRemotes()
|
||||||
|
if err != nil {
|
||||||
|
SendError(500, context, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return context.JSON(200, remotes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoteApiHandler) handleDelteRemote(context echo.Context) error {
|
||||||
|
id := context.Param("id")
|
||||||
|
err := r.remoteManager.DeleteRemote(id)
|
||||||
|
if err != nil {
|
||||||
|
SendError(500, context, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return context.JSON(200, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoteApiHandler) handleCreateCommands(context echo.Context) error {
|
||||||
|
commands := []d.Command{}
|
||||||
|
if err := context.Bind(&commands); err != nil {
|
||||||
|
SendError(400, context, err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := r.remoteManager.CreateCommands(commands)
|
||||||
|
if err != nil {
|
||||||
|
SendError(500, context, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return context.JSON(200, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoteApiHandler) handleGetCommands(context echo.Context) error {
|
||||||
|
commands, err := r.remoteManager.GetCommands()
|
||||||
|
if err != nil {
|
||||||
|
SendError(500, context, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return context.JSON(200, commands)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoteApiHandler) handleDeleteCommand(context echo.Context) error {
|
||||||
|
id := context.Param("id")
|
||||||
|
err := r.remoteManager.DeleteCommand(id)
|
||||||
|
if err != nil {
|
||||||
|
SendError(500, context, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return context.JSON(200, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoteApiHandler) SetRouter(router *echo.Echo) {
|
||||||
|
r.router = router
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemoteApiHandler) SetRemoteManager(remoteManager *m.RemoteManager) {
|
||||||
|
r.remoteManager = remoteManager
|
||||||
|
}
|
||||||
@ -1,11 +1,14 @@
|
|||||||
function Command({
|
function Command({
|
||||||
id,
|
id = "",
|
||||||
protocol,
|
protocol = "",
|
||||||
commandNumber,
|
commandNumber = -1,
|
||||||
device,
|
device = -1,
|
||||||
commandType,
|
commandType = "",
|
||||||
title,
|
title = "",
|
||||||
} = {}) {
|
} = {}) {
|
||||||
|
if (typeof commandNumber !== "number")
|
||||||
|
throw new Error("Command number must be a number");
|
||||||
|
if (typeof device !== "number") throw new Error("Device must be a number");
|
||||||
let _id = id;
|
let _id = id;
|
||||||
let _protocol = protocol;
|
let _protocol = protocol;
|
||||||
let _commandNumber = commandNumber;
|
let _commandNumber = commandNumber;
|
||||||
@ -34,6 +37,8 @@ function Command({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setCommandNumber(commandNumber) {
|
function setCommandNumber(commandNumber) {
|
||||||
|
if (typeof commandNumber !== "number")
|
||||||
|
throw new Error("Command number must be a number");
|
||||||
_commandNumber = commandNumber;
|
_commandNumber = commandNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +47,7 @@ function Command({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setDevice(device) {
|
function setDevice(device) {
|
||||||
|
if (typeof device !== "number") throw new Error("Device must be a number");
|
||||||
_device = device;
|
_device = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,20 +31,46 @@ const Serializer = (function () {
|
|||||||
if (!objects) return [];
|
if (!objects) return [];
|
||||||
return objects.map((object) => deserializeIntegration(object));
|
return objects.map((object) => deserializeIntegration(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function serializeCommand(command) {
|
||||||
|
return {
|
||||||
|
id: command.getId(),
|
||||||
|
protocol: command.getProtocol(),
|
||||||
|
commandNumber: command.getCommandNumber(),
|
||||||
|
device: command.getDevice(),
|
||||||
|
commandType: command.getCommandType(),
|
||||||
|
title: command.getTitle(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function serializeCommands(commands) {
|
||||||
|
if (!commands) return [];
|
||||||
|
return commands.map((command) => serializeCommand(command));
|
||||||
|
}
|
||||||
|
|
||||||
function deserializeCommand(object) {
|
function deserializeCommand(object) {
|
||||||
return new Command(object);
|
return new Command(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
function deserializeCommands(objects) {
|
function deserializeCommands(objects) {
|
||||||
if (!objects) return [];
|
if (!objects) return [];
|
||||||
return objects.map((object) => deserializeCommand(object));
|
return objects.map((object) => deserializeCommand(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function serializeRemote(remote) {
|
||||||
|
return {
|
||||||
|
id: remote.getId(),
|
||||||
|
title: remote.getTitle(),
|
||||||
|
commands: remote.getCommands().map((command) => ({
|
||||||
|
id: command.getId(),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function deserializeRemote(object) {
|
function deserializeRemote(object) {
|
||||||
return new Remote(object);
|
return new Remote(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
function deserializeRemotes(objects) {
|
function deserializeRemotes(objects) {
|
||||||
if (!objects) return [];
|
if (!objects) return [];
|
||||||
return objects.map((object) => deserializeRemote(object));
|
return objects.map((object) => deserializeRemote(object));
|
||||||
@ -57,8 +83,11 @@ const Serializer = (function () {
|
|||||||
deserializeDevices,
|
deserializeDevices,
|
||||||
deserializeIntegration,
|
deserializeIntegration,
|
||||||
deserializeIntegrations,
|
deserializeIntegrations,
|
||||||
|
serializeCommand,
|
||||||
|
serializeCommands,
|
||||||
deserializeCommand,
|
deserializeCommand,
|
||||||
deserializeCommands,
|
deserializeCommands,
|
||||||
|
serializeRemote,
|
||||||
deserializeRemote,
|
deserializeRemote,
|
||||||
deserializeRemotes,
|
deserializeRemotes,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -24,7 +24,9 @@ function CreateCommandModal(props) {
|
|||||||
);
|
);
|
||||||
const isDeviceValid = createMemo(() => device() !== "" && !isNaN(device()));
|
const isDeviceValid = createMemo(() => device() !== "" && !isNaN(device()));
|
||||||
const isCommandTypeValid = createMemo(() => commandType() !== "");
|
const isCommandTypeValid = createMemo(() => commandType() !== "");
|
||||||
const isTitleValid = createMemo(() => title().length >= MIN_TITLE_LENGTH);
|
const isTitleValid = createMemo(
|
||||||
|
() => title() === "" || title().length >= MIN_TITLE_LENGTH
|
||||||
|
);
|
||||||
|
|
||||||
const isFormValid = createMemo(
|
const isFormValid = createMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -41,8 +43,8 @@ function CreateCommandModal(props) {
|
|||||||
command = await RemotesService.createCommand(
|
command = await RemotesService.createCommand(
|
||||||
new Command({
|
new Command({
|
||||||
protocol: protocol(),
|
protocol: protocol(),
|
||||||
commandNumber: commandNumber(),
|
commandNumber: parseInt(commandNumber()),
|
||||||
device: device(),
|
device: parseInt(device()),
|
||||||
commandType: commandType(),
|
commandType: commandType(),
|
||||||
title: title(),
|
title: title(),
|
||||||
})
|
})
|
||||||
|
|||||||
@ -37,6 +37,7 @@ function CreateRemoteModal(props) {
|
|||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setError(e.message);
|
setError(e.message);
|
||||||
|
console.error(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resetFields();
|
resetFields();
|
||||||
|
|||||||
@ -360,7 +360,11 @@ function ImportCommandsModal(props) {
|
|||||||
let protocol = valueMapping()[PROTOCOL_FIELD][row[protocolField]];
|
let protocol = valueMapping()[PROTOCOL_FIELD][row[protocolField]];
|
||||||
if (!protocol) return null;
|
if (!protocol) return null;
|
||||||
let commandNumber = row[commandNumberField];
|
let commandNumber = row[commandNumberField];
|
||||||
|
if (isNaN(commandNumber)) return null;
|
||||||
|
commandNumber = parseInt(commandNumber);
|
||||||
let device = row[deviceField];
|
let device = row[deviceField];
|
||||||
|
if (isNaN(device)) return null;
|
||||||
|
device = parseInt(device);
|
||||||
let commandType =
|
let commandType =
|
||||||
valueMapping()[COMMAND_TYPE_FIELD][row[commandTypeField]];
|
valueMapping()[COMMAND_TYPE_FIELD][row[commandTypeField]];
|
||||||
if (!commandType) return null;
|
if (!commandType) return null;
|
||||||
|
|||||||
@ -1,78 +1,93 @@
|
|||||||
import Command from "../data/command";
|
import Command from "../data/command";
|
||||||
import Serializer from "../data/serializer";
|
import Serializer from "../data/serializer";
|
||||||
|
import Net from "../tools/net";
|
||||||
|
|
||||||
function RemotesService() {
|
function RemoteService() {
|
||||||
let _commands = [
|
|
||||||
new Command({
|
|
||||||
id: 1,
|
|
||||||
protocol: "samsung",
|
|
||||||
commandNumber: 1,
|
|
||||||
device: 7,
|
|
||||||
commandType: "power",
|
|
||||||
title: "Power Samsung",
|
|
||||||
}),
|
|
||||||
new Command({
|
|
||||||
id: 2,
|
|
||||||
protocol: "samsung",
|
|
||||||
commandNumber: 2,
|
|
||||||
device: 7,
|
|
||||||
commandType: "input",
|
|
||||||
title: "Input Samsung",
|
|
||||||
}),
|
|
||||||
new Command({
|
|
||||||
id: 3,
|
|
||||||
protocol: "samsung",
|
|
||||||
commandNumber: 3,
|
|
||||||
device: 7,
|
|
||||||
commandType: "volume_up",
|
|
||||||
title: "Volume Up Samsung",
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
let remotes = [];
|
let remotes = [];
|
||||||
|
|
||||||
async function getRemotes() {
|
async function getRemotes() {
|
||||||
return [].concat(remotes);
|
let response = await Net.sendRequest({
|
||||||
|
method: "GET",
|
||||||
|
url: "/api/remotes",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
let responseData = JSON.parse(response.data);
|
||||||
|
throw new Error(responseData.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
let remoteObjects = JSON.parse(response.data);
|
||||||
|
return Serializer.deserializeRemotes(remoteObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createRemote(remote) {
|
async function createRemote(remote) {
|
||||||
let id = Math.random().toString(36).substr(2, 9);
|
let remoteObject = Serializer.serializeRemote(remote);
|
||||||
remote.setId(id);
|
let response = await Net.sendJsonRequest({
|
||||||
remotes.push(remote);
|
method: "POST",
|
||||||
return remote;
|
url: "/api/remotes",
|
||||||
|
data: remoteObject,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
let responseData = JSON.parse(response.data);
|
||||||
|
throw new Error(responseData.error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteRemote(remoteId) {
|
async function deleteRemote(remoteId) {
|
||||||
let index = remotes.findIndex((remote) => remote.getId() === remoteId);
|
let response = await Net.sendRequest({
|
||||||
if (index >= 0) {
|
method: "DELETE",
|
||||||
remotes.splice(index, 1);
|
url: "/api/remotes/" + remoteId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
let responseData = JSON.parse(response.data);
|
||||||
|
throw new Error(responseData.error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getCommands() {
|
async function getCommands() {
|
||||||
return [].concat(_commands);
|
let response = await Net.sendRequest({
|
||||||
|
method: "GET",
|
||||||
|
url: "/api/commands",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
let responseData = JSON.parse(response.data);
|
||||||
|
throw new Error(responseData.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
let commandObjects = JSON.parse(response.data);
|
||||||
|
return Serializer.deserializeCommands(commandObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createCommand(command) {
|
async function createCommand(command) {
|
||||||
let id = Math.random().toString(36).substr(2, 9);
|
return createCommands([command]);
|
||||||
command.setId(id);
|
|
||||||
_commands.push(command);
|
|
||||||
return command;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createCommands(commands) {
|
async function createCommands(commands) {
|
||||||
if (!commands || commands.length === 0) return [];
|
let commandObjects = Serializer.serializeCommands(commands);
|
||||||
commands.forEach((command) => {
|
let response = await Net.sendJsonRequest({
|
||||||
let id = Math.random().toString(36).substr(2, 9);
|
method: "POST",
|
||||||
command.setId(id);
|
url: "/api/commands",
|
||||||
_commands.push(command);
|
data: commandObjects,
|
||||||
});
|
});
|
||||||
return commands;
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
let responseData = JSON.parse(response.data);
|
||||||
|
throw new Error(responseData.error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteCommand(commandId) {
|
async function deleteCommand(commandId) {
|
||||||
let index = _commands.findIndex((command) => command.getId() === commandId);
|
let response = await Net.sendRequest({
|
||||||
if (index >= 0) {
|
method: "DELETE",
|
||||||
_commands.splice(index, 1);
|
url: "/api/commands/" + commandId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
let responseData = JSON.parse(response.data);
|
||||||
|
throw new Error(responseData.error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +102,6 @@ function RemotesService() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
RemotesService = new RemotesService();
|
RemoteService = new RemoteService();
|
||||||
|
|
||||||
export default RemotesService;
|
export default RemoteService;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user