Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modules loading, and dbus method for module info #9

Merged
merged 1 commit into from
Dec 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions dbus.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"github.com/godbus/dbus/v5"
"github.com/unix-streamdeck/api"
"github.com/unix-streamdeck/streamdeckd/handlers"
"log"
)

Expand Down Expand Up @@ -61,6 +62,18 @@ func (StreamDeckDBus) CommitConfig() *dbus.Error {
return nil
}

func (StreamDeckDBus) GetModules() (string, *dbus.Error) {
var modules []api.Module
for _, module := range handlers.AvailableModules() {
modules = append(modules, api.Module{Name: module.Name, IconFields: module.IconFields, KeyFields: module.KeyFields, IsIcon: module.NewIcon != nil, IsKey: module.NewKey != nil})
}
modulesString, err := json.Marshal(modules)
if err != nil {
return "", dbus.MakeFailedError(err)
}
return string(modulesString), nil
}

func InitDBUS() error {
var err error
conn, err = dbus.SessionBus()
Expand Down
17 changes: 16 additions & 1 deletion handlers/counter.go → handlers/examples/counter.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package handlers
package examples

import (
"github.com/unix-streamdeck/api"
"github.com/unix-streamdeck/streamdeckd/handlers"
"image"
"image/draw"
"log"
"strconv"
)

type CounterIconHandler struct {
Count int
Running bool
Callback func(image image.Image)
}

func (c *CounterIconHandler) Start(k api.Key, info api.StreamDeckInfo, callback func(image image.Image)) {
if c.Callback == nil {
c.Callback = callback
Expand Down Expand Up @@ -49,3 +56,11 @@ func (CounterKeyHandler) Key(key api.Key, info api.StreamDeckInfo) {
handler.Start(key, info, handler.Callback)
}
}

func RegisterCounter() handlers.Module {
return handlers.Module{NewIcon: func() api.IconHandler {
return &CounterIconHandler{Running: true, Count: 0}
}, NewKey: func() api.KeyHandler {
return &CounterKeyHandler{}
}, Name: "Counter"}
}
18 changes: 17 additions & 1 deletion handlers/gif.go → handlers/examples/gif.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
package handlers
package examples

import (
"context"
"github.com/unix-streamdeck/api"
"github.com/unix-streamdeck/streamdeckd/handlers"
"golang.org/x/sync/semaphore"
"image"
"image/gif"
"log"
"os"
"time"
)

type GifIconHandler struct {
Running bool
Lock *semaphore.Weighted
}

func (s *GifIconHandler) Start(key api.Key, info api.StreamDeckInfo, callback func(image image.Image)) {
if s.Lock == nil {
s.Lock = semaphore.NewWeighted(1)
}
s.Running = true
f, err := os.Open(key.Icon)
if err != nil {
Expand Down Expand Up @@ -67,3 +77,9 @@ func loop(frames []image.Image, timeDelay int, callback func(image image.Image),
time.Sleep(time.Duration(timeDelay * 10000000))
}
}

func RegisterGif() handlers.Module {
return handlers.Module{NewIcon: func() api.IconHandler {
return &GifIconHandler{Running: true, Lock: semaphore.NewWeighted(1)}
}, Name: "Gif"}
}
10 changes: 10 additions & 0 deletions handlers/examples/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package examples

import "github.com/unix-streamdeck/streamdeckd/handlers"

func RegisterBaseModules() {
handlers.RegisterModule(RegisterGif())
handlers.RegisterModule(RegisterTime())
handlers.RegisterModule(RegisterCounter())
handlers.RegisterModule(RegisterSpotify())
}
131 changes: 131 additions & 0 deletions handlers/examples/spotify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package examples

import (
"errors"
"github.com/godbus/dbus/v5"
"github.com/unix-streamdeck/api"
"github.com/unix-streamdeck/streamdeckd/handlers"
"image"
"log"
"net/http"
"strings"
"time"
)

type SpotifyIconHandler struct {
Running bool
oldUrl string
}

func (s *SpotifyIconHandler) Start(key api.Key, info api.StreamDeckInfo, callback func(image image.Image)) {
s.Running = true
c, err := Connect()
if err != nil {
log.Println(err)
return
}
go run(c, s, callback)
}

func (s *SpotifyIconHandler) IsRunning() bool {
return s.Running
}

func (s *SpotifyIconHandler) SetRunning(running bool) {
s.Running = running
}

func (s *SpotifyIconHandler) Stop() {
s.Running = false
}

func run(c *Connection, s *SpotifyIconHandler, callback func(image image.Image)) {
defer c.Close()
for s.Running {
url, err := c.GetAlbumArtUrl()
if err != nil {
log.Println(err)
time.Sleep(time.Second)
continue
}
if url == s.oldUrl {
time.Sleep(time.Second)
continue
}
img, err := getImage(url)
if err != nil {
log.Println(err)
time.Sleep(time.Second)
continue
}
callback(img)
s.oldUrl = url
time.Sleep(time.Second)
}
}

func RegisterSpotify() handlers.Module {
return handlers.Module{NewIcon: func() api.IconHandler {
return &SpotifyIconHandler{Running: true}
}, Name: "Spotify"}
}

// region DBus
func getImage(url string) (image.Image, error) {
response, err := http.Get(url)
if err != nil {
return nil, err
}
if response.StatusCode != 200 {
return nil, errors.New("Couldn't get Image from URL")
}
defer response.Body.Close()
img, _, err := image.Decode(response.Body)
if err != nil {
return nil, err
}
return img, nil
}


type Connection struct {
busobj dbus.BusObject
conn *dbus.Conn
}

func Connect() (*Connection, error) {
conn, err := dbus.ConnectSessionBus()
if err != nil {
return nil, err
}
return &Connection{
conn: conn,
busobj: conn.Object("org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2"),
}, nil
}

func (c *Connection) GetAlbumArtUrl() (string, error) {
variant, err := c.busobj.GetProperty("org.mpris.MediaPlayer2.Player.Metadata")
if err != nil {
return "", err
}
metadataMap := variant.Value().(map[string]dbus.Variant)
var url string
for key, val := range metadataMap {
if key == "mpris:artUrl" {
url = val.String()
}
}
if url == "" {
return "", errors.New("Couldn't get URL from DBus")
}
url = strings.ReplaceAll(url, "\"", "")
url = strings.ReplaceAll(url, "https://open.spotify.com/image/", "https://i.scdn.co/image/")
return url, nil
}

func (c *Connection) Close() {
c.conn.Close()
}

// endregion
12 changes: 11 additions & 1 deletion handlers/time.go → handlers/examples/time.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package handlers
package examples

import (
"github.com/unix-streamdeck/api"
"github.com/unix-streamdeck/streamdeckd/handlers"
"image"
"image/draw"
"log"
"time"
)

type TimeIconHandler struct {
Running bool
}

func (t *TimeIconHandler) Start(k api.Key, info api.StreamDeckInfo, callback func(image image.Image)) {
t.Running = true
Expand Down Expand Up @@ -40,4 +44,10 @@ func timeLoop(k api.Key, info api.StreamDeckInfo, callback func(image image.Imag
}
time.Sleep(time.Second)
}
}

func RegisterTime() handlers.Module {
return handlers.Module{NewIcon: func() api.IconHandler {
return &TimeIconHandler{Running: true}
}, Name: "Time"}
}
57 changes: 46 additions & 11 deletions handlers/handlers.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,56 @@
package handlers

import (
"golang.org/x/sync/semaphore"
"image"
"github.com/unix-streamdeck/api"
"log"
"plugin"
)

type CounterIconHandler struct {
Count int
Running bool
Callback func(image image.Image)
type Module struct {
Name string
NewIcon func() api.IconHandler
NewKey func() api.KeyHandler
IconFields []api.Field
KeyFields []api.Field
}

type GifIconHandler struct {
Running bool
Lock *semaphore.Weighted


var modules []Module


func AvailableModules() []Module {
return modules
}

func RegisterModule(m Module) {
for _, module := range modules {
if module.Name == m.Name {
log.Println("Module already loaded: " + m.Name)
return
}
}
log.Println("Loaded module " + m.Name)
modules = append(modules, m)
}

type TimeIconHandler struct {
Running bool
func LoadModule(path string) {
plug, err := plugin.Open(path)
if err != nil {
//log.Println("Failed to load module: " + path)
log.Println(err)
return
}
mod, err := plug.Lookup("GetModule")
if err != nil {
log.Println(err)
return
}
var modMethod func() Module
modMethod, ok := mod.(func() Module)
if !ok {
log.Println("Failed to load module: " + path)
return
}
RegisterModule(modMethod())
}
18 changes: 10 additions & 8 deletions interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,11 @@ func SetKey(currentKey *api.Key, i int, page int) {

} else if currentKey.IconHandlerStruct == nil {
var handler api.IconHandler
if currentKey.IconHandler == "Gif" {
handler = &handlers.GifIconHandler{Running:true, Lock:semaphore.NewWeighted(1)}
} else if currentKey.IconHandler == "Counter" {
handler = &handlers.CounterIconHandler{Count:0, Running: true}
} else if currentKey.IconHandler == "Time" {
handler = &handlers.TimeIconHandler{Running:true}
modules := handlers.AvailableModules()
for _, module := range modules {
if module.Name == currentKey.IconHandler {
handler = module.NewIcon()
}
}
if handler == nil {
return
Expand Down Expand Up @@ -151,8 +150,11 @@ func HandleInput(key *api.Key, page int) {
if key.KeyHandler != "" {
if key.KeyHandlerStruct == nil {
var handler api.KeyHandler
if key.KeyHandler == "Counter" {
handler = handlers.CounterKeyHandler{}
modules := handlers.AvailableModules()
for _, module := range modules {
if module.Name == key.KeyHandler {
handler = module.NewKey()
}
}
if handler == nil {
return
Expand Down
Loading