diff options
| author | Caroline Larimore <caroline@larimo.re> | 2025-01-30 21:47:09 -0800 |
|---|---|---|
| committer | Caroline Larimore <caroline@larimo.re> | 2025-01-30 21:47:09 -0800 |
| commit | 4b5ff500b97cb86a5fbaaf5f3c5f9a004d1334f0 (patch) | |
| tree | bd1db5355acb7edb46294c67fc809036ba07c59f | |
| parent | 784ee51b9613cac5764c9a33c343655e514e20f0 (diff) | |
Restructure
| -rw-r--r-- | cmd/corvid-msg/main.go | 22 | ||||
| -rw-r--r-- | cmd/corvid/main.go | 10 | ||||
| -rw-r--r-- | corvid.go | 85 | ||||
| -rw-r--r-- | srv/corvidServer.go | 39 | ||||
| -rw-r--r-- | srv/notifServer.go (renamed from server.go) | 98 | ||||
| -rw-r--r-- | srv/notification.go (renamed from notification.go) | 28 | ||||
| -rw-r--r-- | srv/server.go | 84 |
7 files changed, 241 insertions, 125 deletions
diff --git a/cmd/corvid-msg/main.go b/cmd/corvid-msg/main.go new file mode 100644 index 0000000..abb87a5 --- /dev/null +++ b/cmd/corvid-msg/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "log" + + "github.com/godbus/dbus/v5" +) + +func main() { + const CORVID_DBUS_OBJECT = "/sh/cxl/Corvid" + const CORVID_DBUS_NAME = "sh.cxl.Corvid" + + conn, err := dbus.SessionBus() + if err != nil { + log.Fatal(err) + } + + call := conn.Object(CORVID_DBUS_NAME, CORVID_DBUS_OBJECT).Call(CORVID_DBUS_NAME+".Test", 0, uint32(13)) + if call.Err != nil { + log.Fatal(call.Err) + } +} diff --git a/cmd/corvid/main.go b/cmd/corvid/main.go new file mode 100644 index 0000000..9064ad6 --- /dev/null +++ b/cmd/corvid/main.go @@ -0,0 +1,10 @@ +package main + +import ( + "github.com/CartConnoisseur/corvid/srv" +) + +func main() { + srv.Start() + select {} +} diff --git a/corvid.go b/corvid.go deleted file mode 100644 index 267f4e5..0000000 --- a/corvid.go +++ /dev/null @@ -1,85 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "log" - "slices" - "sync" - - "github.com/godbus/dbus/v5" -) - -const DEFAULT_EXPIRATION = 5000 -const SORT_DIRECTION = 1 // 1 = newest first, -1 = oldest first -const DBUS_OBJECT = "/org/freedesktop/Notifications" -const DBUS_NAME = "org.freedesktop.Notifications" - -var conn *dbus.Conn - -type notificationStack = struct { - mutex *sync.Mutex - notifications map[uint32]notification - nextId uint32 -} - -var notifications = notificationStack{ - mutex: &sync.Mutex{}, - notifications: make(map[uint32]notification), - nextId: 1, -} - -func output() { - arr := make([]notification, len(notifications.notifications)) - - i := 0 - for _, notification := range notifications.notifications { - arr[i] = notification - i++ - } - - slices.SortFunc(arr, func(a, b notification) int { - if a.Timestamp > b.Timestamp { - return SORT_DIRECTION - } else if a.Timestamp < b.Timestamp { - return -SORT_DIRECTION - } else { - if a.Id > b.Id { - return SORT_DIRECTION - } else if a.Id < b.Id { - return -SORT_DIRECTION - } - } - - return 0 - }) - - j, err := json.Marshal(arr) - if err != nil { - log.Fatalln(err) - } - - fmt.Println(string(j)) -} - -func main() { - var err error - conn, err = dbus.SessionBus() - if err != nil { - log.Fatal(err) - } - - conn.Export(server{}, DBUS_OBJECT, DBUS_NAME) - - reply, err := conn.RequestName(DBUS_NAME, dbus.NameFlagReplaceExisting|dbus.NameFlagDoNotQueue) - if err != nil { - log.Fatal(err) - } - - if reply != dbus.RequestNameReplyPrimaryOwner { - log.Fatalf("'%s' already taken", DBUS_NAME) - } - - log.Print("connected to dbus") - select {} -} diff --git a/srv/corvidServer.go b/srv/corvidServer.go new file mode 100644 index 0000000..4a0556d --- /dev/null +++ b/srv/corvidServer.go @@ -0,0 +1,39 @@ +package srv + +import ( + "log" + + "github.com/godbus/dbus/v5" +) + +type corvidServer server + +func (s corvidServer) Test(param uint32) (e *dbus.Error) { + log.Printf("Test called %d", param) + return nil +} + +// func (s corvidServer) GetCapabilities() (e *dbus.Error) { +// log.Print("GetCapabilities called") +// return nil +// } + +// func (s corvidServer) GetServerInformation() (name, vendor, version, specVersion string, e *dbus.Error) { +// // log.Print("GetServerInformation called") +// return "corvid", "CartConnoisseur", "0.1.0", "1.2", nil +// } + +// func (s corvidServer) CloseNotification(id uint32) (e *dbus.Error) { +// // log.Printf("CloseNotification called: %d", id) +// notification, ok := notifications.notifications[id] +// if ok { +// notification.close(CloseReasonClosed) +// } + +// return nil +// } + +// func (s corvidServer) Notify(appName string, replacesId uint32, appIcon string, summary string, body string, actions []string, hints map[string]dbus.Variant, expireTimeout int32) (id uint32, e *dbus.Error) { +// // log.Print("Notify called") + +// } diff --git a/server.go b/srv/notifServer.go index 9b94f70..00038cc 100644 --- a/server.go +++ b/srv/notifServer.go @@ -1,19 +1,25 @@ -package main +package srv import ( + "encoding/json" + "fmt" "image" "image/png" "log" "os" + "slices" "strings" "time" "github.com/godbus/dbus/v5" ) -type server struct{} +type notifServer struct { + notifications *notificationStack + server +} -func (s server) GetCapabilities() (capabilities []string, e *dbus.Error) { +func (s notifServer) GetCapabilities() (capabilities []string, e *dbus.Error) { // log.Print("GetCapabilities called") return []string{ "body", @@ -21,29 +27,25 @@ func (s server) GetCapabilities() (capabilities []string, e *dbus.Error) { }, nil } -func (s server) GetServerInformation() (name, vendor, version, specVersion string, e *dbus.Error) { +func (s notifServer) GetServerInformation() (name, vendor, version, specVersion string, e *dbus.Error) { // log.Print("GetServerInformation called") return "corvid", "CartConnoisseur", "0.1.0", "1.2", nil } -func (s server) CloseNotification(id uint32) (e *dbus.Error) { +func (s notifServer) CloseNotification(id uint32) (e *dbus.Error) { // log.Printf("CloseNotification called: %d", id) - notification, ok := notifications.notifications[id] - if ok { - notification.close(CloseReasonClosed) - } - + s.close(id, CloseReasonClosed) return nil } -func (s server) Notify(appName string, replacesId uint32, appIcon string, summary string, body string, actions []string, hints map[string]dbus.Variant, expireTimeout int32) (id uint32, e *dbus.Error) { +func (s notifServer) Notify(appName string, replacesId uint32, appIcon string, summary string, body string, actions []string, hints map[string]dbus.Variant, expireTimeout int32) (id uint32, e *dbus.Error) { // log.Print("Notify called") - notifications.mutex.Lock() - defer notifications.mutex.Unlock() + s.notifications.mutex.Lock() + defer s.notifications.mutex.Unlock() if replacesId == 0 { - id = notifications.nextId - notifications.nextId++ + id = s.notifications.nextId + s.notifications.nextId++ } else { id = replacesId } @@ -122,12 +124,72 @@ func (s server) Notify(appName string, replacesId uint32, appIcon string, summar if expireTimeout != 0 { notification.timer = time.AfterFunc(time.Duration(expireTimeout)*time.Millisecond, func() { - notification.close(CloseReasonExpire) + s.close(notification.Id, CloseReasonExpire) }) } - notifications.notifications[id] = notification - output() + s.notifications.notifications[id] = notification + s.output() return id, nil } + +func (s notifServer) close(id uint32, reason closeReason) { + s.notifications.mutex.Lock() + defer s.notifications.mutex.Unlock() + + n, ok := s.notifications.notifications[id] + if !ok { + return + } + + if n.timer != nil { + n.timer.Stop() + } + + if n.Image != "" { + os.Remove(n.Image) + } + + delete(s.notifications.notifications, n.Id) + s.output() + + err := s.conn.Emit(s.object, s.name+".NotificationClosed", n.Id, reason) + if err != nil { + log.Print(err) + } +} + +// TODO: relocate to cmd/corvid +func (s notifServer) output() { + arr := make([]notification, len(s.notifications.notifications)) + + i := 0 + for _, notification := range s.notifications.notifications { + arr[i] = notification + i++ + } + + slices.SortFunc(arr, func(a, b notification) int { + if a.Timestamp > b.Timestamp { + return SORT_DIRECTION + } else if a.Timestamp < b.Timestamp { + return -SORT_DIRECTION + } else { + if a.Id > b.Id { + return SORT_DIRECTION + } else if a.Id < b.Id { + return -SORT_DIRECTION + } + } + + return 0 + }) + + j, err := json.Marshal(arr) + if err != nil { + log.Fatalln(err) + } + + fmt.Println(string(j)) +} diff --git a/notification.go b/srv/notification.go index 2d5625d..dcea9d9 100644 --- a/notification.go +++ b/srv/notification.go @@ -1,9 +1,8 @@ -package main +package srv import ( "encoding/json" - "log" - "os" + "sync" "time" "github.com/godbus/dbus/v5" @@ -64,23 +63,8 @@ type notification struct { timer *time.Timer } -func (n notification) close(reason closeReason) { - notifications.mutex.Lock() - defer notifications.mutex.Unlock() - - if n.timer != nil { - n.timer.Stop() - } - - if n.Image != "" { - os.Remove(n.Image) - } - - delete(notifications.notifications, n.Id) - output() - - err := conn.Emit(DBUS_OBJECT, DBUS_NAME+".NotificationClosed", n.Id, reason) - if err != nil { - log.Print(err) - } +type notificationStack = struct { + mutex *sync.Mutex + notifications map[uint32]notification + nextId uint32 } diff --git a/srv/server.go b/srv/server.go new file mode 100644 index 0000000..673081b --- /dev/null +++ b/srv/server.go @@ -0,0 +1,84 @@ +package srv + +import ( + "fmt" + "log" + "sync" + + "github.com/godbus/dbus/v5" +) + +const DEFAULT_EXPIRATION = 5000 +const SORT_DIRECTION = 1 // 1 = newest first, -1 = oldest first + +type server = struct { + conn *dbus.Conn + object dbus.ObjectPath + name string +} + +func Start() { + const NOTIF_DBUS_OBJECT = "/org/freedesktop/Notifications" + const NOTIF_DBUS_NAME = "org.freedesktop.Notifications" + const CORVID_DBUS_OBJECT = "/sh/cxl/Corvid" + const CORVID_DBUS_NAME = "sh.cxl.Corvid" + + notifications := notificationStack{ + mutex: &sync.Mutex{}, + notifications: make(map[uint32]notification), + nextId: 1, + } + + conn, err := dbus.SessionBus() + if err != nil { + log.Fatal(err) + } + + err = startDBusServer( + conn, + corvidServer{ + conn: conn, + object: CORVID_DBUS_OBJECT, + name: CORVID_DBUS_NAME, + }, + CORVID_DBUS_OBJECT, + CORVID_DBUS_NAME, + ) + if err != nil { + log.Fatal(err) + } + + err = startDBusServer( + conn, + notifServer{ + notifications: ¬ifications, + server: server{ + conn: conn, + object: NOTIF_DBUS_OBJECT, + name: NOTIF_DBUS_NAME, + }, + }, + NOTIF_DBUS_OBJECT, + NOTIF_DBUS_NAME, + ) + if err != nil { + log.Fatal(err) + } +} + +func startDBusServer(conn *dbus.Conn, v interface{}, object dbus.ObjectPath, name string) error { + conn.Export(v, object, name) + + reply, err := conn.RequestName(name, dbus.NameFlagReplaceExisting|dbus.NameFlagDoNotQueue) + if err != nil { + return err + } + + if reply != dbus.RequestNameReplyPrimaryOwner { + return fmt.Errorf("'%s' already taken", name) + } + + log.Printf("connected to dbus as %s @ %s", name, object) + + return nil +} |