commit 42b47ec
sewn
·
2026-07-23 17:33:49 +0000 UTC
parent 55c3548
Revert "Support opening irc:// links in senpai" This reverts commit 8a399a916e2b1277dd792df446a0dde37d0d3c17.
13 files changed,
+34,
-402
M
app.go
+8,
-155
1@@ -27,7 +27,6 @@ import (
2 "unicode"
3 "unicode/utf8"
4
5- "git.sr.ht/~delthas/senpai/varlinkservice"
6 "git.sr.ht/~rockorager/vaxis"
7 "golang.org/x/net/proxy"
8
9@@ -134,8 +133,8 @@ type App struct {
10
11 monitor map[string]map[string]struct{} // set of targets we want to monitor per netID, best-effort. netID->target->{}
12
13- networkLock sync.RWMutex // locks networks
14- networks map[string]map[string]string // set of network IDs to attributes we want to connect to; to be locked with networkLock
15+ networkLock sync.RWMutex // locks networks
16+ networks map[string]struct{} // set of network IDs we want to connect to; to be locked with networkLock
17
18 pendingCompletions map[string][]pendingCompletion
19 pendingCompletionsOff int
20@@ -171,7 +170,7 @@ func NewApp(cfg Config) (app *App, err error) {
21 }
22
23 app = &App{
24- networks: map[string]map[string]string{
25+ networks: map[string]struct{}{
26 "": {}, // add the master network by default
27 },
28 pendingCompletions: make(map[string][]pendingCompletion),
29@@ -386,41 +385,6 @@ func (app *App) wantsNetwork(netID string) bool {
30 return ok
31 }
32
33-func (app *App) findNetworkByLink(link string) (host string, target string, netID string) {
34- // links often do not contain encoded #
35- link = strings.ReplaceAll(link, "#", "%23")
36-
37- u, err := url.Parse(link)
38- if err != nil {
39- return "", "", ""
40- }
41- host, port, err := net.SplitHostPort(u.Host)
42- if err != nil {
43- host = u.Host
44- port = "6697"
45- }
46- target = strings.TrimLeft(u.Path, "/")
47- if i := strings.IndexAny(target, "/,"); i >= 0 {
48- target = target[:i]
49- }
50- app.networkLock.Lock()
51- defer app.networkLock.Unlock()
52- for netID, attrs := range app.networks {
53- if attrs["host"] != host {
54- continue
55- }
56- p := attrs["port"]
57- if p == "" {
58- p = "6697"
59- }
60- if p != port {
61- continue
62- }
63- return u.Host, target, netID
64- }
65- return u.Host, target, ""
66-}
67-
68 // ircLoop maintains a connection to the IRC server by connecting and then
69 // forwarding IRC events to app.events repeatedly.
70 func (app *App) ircLoop(netID string) {
71@@ -684,38 +648,6 @@ func (app *App) handleUIEvent(ev interface{}) bool {
72 } else {
73 app.uploadingProgress = &ev.Progress
74 }
75- case *events.EventOpenLink:
76- host, target, netID := app.findNetworkByLink(ev.Link)
77- if netID != "" {
78- if cNetID, _ := app.win.CurrentBuffer(); cNetID != netID {
79- app.win.JumpBufferNetwork(netID, "")
80- }
81- if target == "" {
82- break
83- }
84- if !app.win.JumpBufferNetwork(netID, target) {
85- if s := app.sessions[netID]; s != nil && s.IsChannel(target) {
86- cNetID, cTarget := app.win.CurrentBuffer()
87- app.win.AddLine(cNetID, cTarget, ui.Line{
88- At: time.Now(),
89- Head: ui.PlainString("--"),
90- Body: ui.PlainString("An IRC link of a new channel was opened. Enter to add and join that channel."),
91- })
92- app.win.InputSet(fmt.Sprintf("/join %v", target))
93- } else {
94- i, _ := app.addUserBuffer(netID, target, time.Time{})
95- app.win.JumpBufferIndex(i)
96- }
97- }
98- } else {
99- netID, target := app.win.CurrentBuffer()
100- app.win.AddLine(netID, target, ui.Line{
101- At: time.Now(),
102- Head: ui.PlainString("--"),
103- Body: ui.PlainString("An IRC link of a new network was opened. Enter to add and join that network."),
104- })
105- app.win.InputSet(fmt.Sprintf("/bouncer network create -addr %q", host))
106- }
107 default:
108 // TODO: missing event types
109 }
110@@ -1573,37 +1505,6 @@ func (app *App) handleIRCEvent(netID string, ev interface{}) {
111 // TODO: batch MONITOR +
112 s.MonitorAdd(target)
113 }
114-
115- if netID == "" || app.cfg.OpenLink == "" {
116- break
117- }
118- _, target, foundNetID := app.findNetworkByLink(app.cfg.OpenLink)
119- if netID != foundNetID {
120- break
121- }
122- app.cfg.OpenLink = ""
123- app.lastNetID = ""
124- app.lastBuffer = ""
125- if cNetID, _ := app.win.CurrentBuffer(); cNetID != netID {
126- app.win.JumpBufferNetwork(netID, "")
127- }
128- if target == "" {
129- break
130- }
131- if !app.win.JumpBufferNetwork(netID, target) {
132- if s.IsChannel(target) {
133- cNetID, cTarget := app.win.CurrentBuffer()
134- app.win.AddLine(cNetID, cTarget, ui.Line{
135- At: time.Now(),
136- Head: ui.PlainString("--"),
137- Body: ui.PlainString("An IRC link of a new channel was opened. Enter to add and join that channel."),
138- })
139- app.win.InputSet(fmt.Sprintf("/join %v", target))
140- } else {
141- i, _ := app.addUserBuffer(netID, target, time.Time{})
142- app.win.JumpBufferIndex(i)
143- }
144- }
145 case irc.SelfNickEvent:
146 if !app.cfg.StatusEnabled {
147 break
148@@ -1856,17 +1757,11 @@ func (app *App) handleIRCEvent(netID string, ev interface{}) {
149 }
150 case irc.BouncerNetworkEvent:
151 if !ev.Delete {
152- app.networkLock.Lock()
153- if _, ok := app.networks[ev.ID]; !ok {
154- app.networks[ev.ID] = ev.Attrs
155- } else {
156- for k, v := range ev.Attrs {
157- app.networks[ev.ID][k] = v
158- }
159- }
160- app.networkLock.Unlock()
161- _, added := app.win.AddBuffer(ev.ID, ev.Attrs["name"], "")
162+ _, added := app.win.AddBuffer(ev.ID, ev.Name, "")
163 if added {
164+ app.networkLock.Lock()
165+ app.networks[ev.ID] = struct{}{}
166+ app.networkLock.Unlock()
167 go app.ircLoop(ev.ID)
168 }
169 } else {
170@@ -1882,39 +1777,6 @@ func (app *App) handleIRCEvent(netID string, ev interface{}) {
171 }
172 app.win.RemoveNetworkBuffers(ev.ID)
173 }
174- case irc.BouncerNetworkListEvent:
175- for _, ev := range ev {
176- app.networkLock.Lock()
177- if _, ok := app.networks[ev.ID]; !ok {
178- app.networks[ev.ID] = ev.Attrs
179- } else {
180- for k, v := range ev.Attrs {
181- app.networks[ev.ID][k] = v
182- }
183- }
184- app.networkLock.Unlock()
185- _, added := app.win.AddBuffer(ev.ID, ev.Attrs["name"], "")
186- if added {
187- go app.ircLoop(ev.ID)
188- }
189- }
190-
191- if app.cfg.OpenLink == "" {
192- break
193- }
194- host, _, foundNetID := app.findNetworkByLink(app.cfg.OpenLink)
195- if foundNetID != "" {
196- // We will handle the link in the session for that network.
197- break
198- }
199- app.cfg.OpenLink = ""
200- netID, target := app.win.CurrentBuffer()
201- app.win.AddLine(netID, target, ui.Line{
202- At: time.Now(),
203- Head: ui.PlainString("--"),
204- Body: ui.PlainString("An IRC link of a new network was opened. Enter to add and join that network."),
205- })
206- app.win.InputSet(fmt.Sprintf("/bouncer network create -addr %q", host))
207 case irc.ListEvent:
208 for _, item := range ev {
209 text := fmt.Sprintf("There are %4s users on channel %s", item.Count, item.Channel)
210@@ -1943,6 +1805,7 @@ func (app *App) handleIRCEvent(netID string, ev interface{}) {
211 Foreground: app.cfg.Colors.Status,
212 }),
213 })
214+ return
215 case irc.ErrorEvent:
216 var head string
217 var body string
218@@ -2627,16 +2490,6 @@ func (app *App) addUserBuffer(netID, buffer string, t time.Time) (i int, added b
219 return
220 }
221
222-func (app *App) OpenLink(in *varlinkservice.OpenLinkIn) (*varlinkservice.OpenLinkOut, error) {
223- app.postEvent(event{
224- src: "*",
225- content: &events.EventOpenLink{
226- Link: in.Link,
227- },
228- })
229- return nil, nil
230-}
231-
232 func keyNameMatch(name string) *keyMatch {
233 parts := strings.Split(name, "+")
234 mods := parts[:len(parts)-1]
+0,
-82
1@@ -7,8 +7,6 @@ import (
2 "fmt"
3 "hash/fnv"
4 "io"
5- "net"
6- "net/url"
7 "os"
8 "os/signal"
9 "os/user"
10@@ -20,8 +18,6 @@ import (
11 "time"
12
13 "git.sr.ht/~delthas/senpai"
14- "git.sr.ht/~delthas/senpai/varlinkservice"
15- "github.com/emersion/go-varlink"
16 )
17
18 func main() {
19@@ -44,26 +40,6 @@ func main() {
20 return
21 }
22
23- socketDir := os.Getenv("XDG_RUNTIME_DIR")
24- if socketDir == "" {
25- socketDir = os.TempDir()
26- }
27- socketDir = filepath.Join(socketDir, "senpai")
28-
29- var link string
30- if _, err := url.Parse(flag.Arg(0)); err == nil {
31- link = flag.Arg(0)
32- }
33- if link != "" {
34- ok, err := sendOpenLink(socketDir, link)
35- if err != nil {
36- fmt.Fprintf(os.Stderr, "failed to send open link to another instance: %v\n", err)
37- } else if ok {
38- // Sent link open command to another instance, exit.
39- return
40- }
41- }
42-
43 var previousConfigPath string
44 if configPath == "" {
45 configDir, err := os.UserConfigDir()
46@@ -195,7 +171,6 @@ func main() {
47 fmt.Fprintf(os.Stderr, "\n")
48 }
49
50- cfg.OpenLink = link
51 cfg.Debug = cfg.Debug || debug
52 if nickname != "" {
53 cfg.Nick = nickname
54@@ -223,14 +198,6 @@ func main() {
55 app.Close()
56 }()
57
58- if cfg.LocalIntegrations {
59- socketPath := filepath.Join(socketDir, fmt.Sprintf("%v.sock", os.Getpid()))
60- if err := listenVarlink(socketPath, app); err != nil {
61- fmt.Fprintf(os.Stderr, "failed to send open link to another instance: %v\n", err)
62- }
63- defer os.Remove(socketPath)
64- }
65-
66 app.Run()
67 app.Close()
68 if !cfg.Transient {
69@@ -373,52 +340,3 @@ func writeLastStamp(app *senpai.App, hash string) {
70 fmt.Fprintf(os.Stderr, "failed to write last stamp at %q: %s\n", p, err)
71 }
72 }
73-
74-func sendOpenLink(socketDir string, link string) (ok bool, err error) {
75- es, err := os.ReadDir(socketDir)
76- if os.IsNotExist(err) {
77- return false, nil
78- }
79- if err != nil {
80- return false, err
81- }
82- for _, e := range es {
83- if filepath.Ext(e.Name()) != ".sock" {
84- continue
85- }
86- conn, err := net.Dial("unix", filepath.Join(socketDir, e.Name()))
87- if err != nil {
88- return false, err
89- }
90- c := varlinkservice.Client{Client: varlink.NewClient(conn)}
91- defer c.Close()
92- if _, err := c.OpenLink(&varlinkservice.OpenLinkIn{Link: link}); err != nil {
93- return false, err
94- }
95- return true, nil
96- }
97- return false, nil
98-}
99-
100-func listenVarlink(socketPath string, backend varlinkservice.Backend) error {
101- if err := os.MkdirAll(filepath.Dir(socketPath), 0700); err != nil {
102- return err
103- }
104- if err := os.Remove(socketPath); err != nil && !os.IsNotExist(err) {
105- return err
106- }
107- l, err := net.Listen("unix", socketPath)
108- if err != nil {
109- return err
110- }
111- server := varlink.NewServer()
112- server.Handler = varlinkservice.Handler{
113- Backend: backend,
114- }
115- go func() {
116- if err := server.Serve(l); err != nil {
117- fmt.Fprintf(os.Stderr, "failed to serve varlink server: %v\n", err)
118- }
119- }()
120- return nil
121-}
+0,
-1
1@@ -115,7 +115,6 @@ type Config struct {
2
3 Colors ui.ConfigColors
4
5- OpenLink string
6 Debug bool
7 Transient bool
8 LocalIntegrations bool
+1,
-2
1@@ -8,7 +8,6 @@ Keywords=Chat;IRC;IM;Messaging
2 Categories=Network;InstantMessaging;Chat;IRCClient;ConsoleOnly
3
4 Type=Application
5-MimeType=x-scheme-handler/irc;x-scheme-handler/ircs
6 Icon=senpai
7 Terminal=true
8-Exec=senpai %u
9+Exec=senpai
+1,
-4
1@@ -6,7 +6,7 @@ senpai - your everyday IRC student
2
3 # SYNOPSIS
4
5-*senpai* [options...] [link]
6+*senpai* [options...]
7
8 # OPTIONS
9
10@@ -24,9 +24,6 @@ senpai - your everyday IRC student
11 *-version*
12 Display version info.
13
14-senpai can also be opened with an _irc://_ link to a server or target. In that
15-case, the link is opened in an existing instance if available.
16-
17 # DESCRIPTION
18
19 senpai is an IRC client made for bouncers. It supports the newest IRC
+0,
-4
1@@ -45,7 +45,3 @@ type EventFileUpload struct {
2 Location string
3 Error string
4 }
5-
6-type EventOpenLink struct {
7- Link string
8-}
M
go.mod
+1,
-3
1@@ -9,20 +9,18 @@ require (
2 github.com/delthas/go-libnp v0.2.0
3 github.com/delthas/go-localeinfo v0.2.0
4 github.com/disintegration/imaging v1.6.2
5- github.com/emersion/go-varlink v0.0.0-20251006073247-e7ad9f7950c7
6 github.com/godbus/dbus/v5 v5.1.0
7 github.com/rivo/uniseg v0.4.7
8- golang.org/x/image v0.24.0
9 golang.org/x/net v0.35.0
10 golang.org/x/time v0.10.0
11 mvdan.cc/xurls/v2 v2.5.0
12 )
13
14 require (
15- github.com/dave/jennifer v1.7.1 // indirect
16 github.com/go-ole/go-ole v1.3.0 // indirect
17 github.com/mattn/go-runewidth v0.0.16 // indirect
18 github.com/mattn/go-sixel v0.0.5 // indirect
19 github.com/soniakeys/quant v1.0.0 // indirect
20+ golang.org/x/image v0.24.0 // indirect
21 golang.org/x/sys v0.30.0 // indirect
22 )
M
go.sum
+0,
-4
1@@ -4,8 +4,6 @@ git.sr.ht/~rockorager/vaxis v0.15.1-0.20260305170555-c3371e09d426 h1:UPaRLWZqH6s
2 git.sr.ht/~rockorager/vaxis v0.15.1-0.20260305170555-c3371e09d426/go.mod h1:ptCAzb19xAhqhfAmCsN9Xnxdx01vlXkwZcuMYPnyqzE=
3 github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
4 github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
5-github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo=
6-github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
7 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9 github.com/delthas/go-libnp v0.2.0 h1:OVll7Z9CER0rYpgiglXN1QvuNtkyY5X9uzLqm+xDstA=
10@@ -14,8 +12,6 @@ github.com/delthas/go-localeinfo v0.2.0 h1:0K5F5GQ5p4ealZjuBs4eubHLOIL21/YWSxs55
11 github.com/delthas/go-localeinfo v0.2.0/go.mod h1:sG54BxlyQgIskYURLrg7mvhoGBe0Qq12DNtYRALwNa4=
12 github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
13 github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
14-github.com/emersion/go-varlink v0.0.0-20251006073247-e7ad9f7950c7 h1:GtfymsmxgcEdOuYLm5CR6VS5pTEXfUKkQDp/wRvvyA8=
15-github.com/emersion/go-varlink v0.0.0-20251006073247-e7ad9f7950c7/go.mod h1:0/V0Ta8VUzKRLXUtyZS49soMI93Taqlm63wX5nx6YEo=
16 github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
17 github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
18 github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
+1,
-3
1@@ -128,8 +128,6 @@ type MetadataChangeEvent struct {
2
3 type BouncerNetworkEvent struct {
4 ID string
5- Attrs map[string]string
6+ Name string
7 Delete bool
8 }
9-
10-type BouncerNetworkListEvent []BouncerNetworkEvent
+22,
-40
1@@ -129,15 +129,14 @@ type Session struct {
2 typings *Typings // incoming typing notifications.
3 typingStamps map[string]typingStamp // user typing instants.
4
5- nick string
6- nickCf string // casemapped nickname.
7- user string
8- real string
9- acct string
10- host string
11- netID string
12- netAttrs map[string]string
13- auth SASLClient
14+ nick string
15+ nickCf string // casemapped nickname.
16+ user string
17+ real string
18+ acct string
19+ host string
20+ netID string
21+ auth SASLClient
22
23 availableCaps map[string]string
24 enabledCaps map[string]struct{}
25@@ -163,21 +162,18 @@ type Session struct {
26 clientTagListIsAllow bool // whether clientTagList is an allowlist (true) or a blocklist (false)
27 clientTagList map[string]struct{}
28
29- users map[string]*User // known users.
30- channels map[string]Channel // joined channels.
31- metadata map[string]Metadata // known target metadata.
32- chBatches map[string]HistoryEvent // channel history batches being processed.
33- chReqs map[string]struct{} // set of targets for which history is currently requested.
34- targetsBatchID string // ID of the channel history targets batch being processed.
35- targetsBatch HistoryTargetsEvent // channel history targets batch being processed.
36- searchBatchID string // ID of the search targets batch being processed.
37- searchBatch SearchEvent // search batch being processed.
38- bouncerNetworksBatchID string // ID of the bouncer network batch being processed.
39- bouncerNetworksBatch BouncerNetworkListEvent // bouncer network batch being processed.
40- monitors map[string]struct{} // set of users we want to monitor (and keep even if they are disconnected).
41- pendingList ListEvent // current list response being received (flushed on list end).
42-
43- pendingChannels map[string]time.Time // set of join requests stamps for channels.
44+ users map[string]*User // known users.
45+ channels map[string]Channel // joined channels.
46+ metadata map[string]Metadata // known target metadata.
47+ chBatches map[string]HistoryEvent // channel history batches being processed.
48+ chReqs map[string]struct{} // set of targets for which history is currently requested.
49+ targetsBatchID string // ID of the channel history targets batch being processed.
50+ targetsBatch HistoryTargetsEvent // channel history targets batch being processed.
51+ searchBatchID string // ID of the search targets batch being processed.
52+ searchBatch SearchEvent // search batch being processed.
53+ monitors map[string]struct{} // set of users we want to monitor (and keep even if they are disconnected).
54+ pendingList ListEvent // current list response being received (flushed on list end).
55+ pendingChannels map[string]time.Time // set of join requests stamps for channels.
56
57 receivedISupport bool
58 receivedUserMode bool
59@@ -797,15 +793,6 @@ func (s *Session) handleRegistered(msg Message) (Event, error) {
60 s.searchBatch.Messages = append(s.searchBatch.Messages, ev)
61 return nil, nil
62 }
63- } else if id == s.bouncerNetworksBatchID {
64- ev, err := s.handleMessageRegistered(msg, true)
65- if err != nil {
66- return nil, err
67- }
68- if ev, ok := ev.(BouncerNetworkEvent); ok {
69- s.bouncerNetworksBatch = append(s.bouncerNetworksBatch, ev)
70- return nil, nil
71- }
72 } else if b, ok := s.chBatches[id]; ok {
73 ev, err := s.handleMessageRegistered(msg, true)
74 if err != nil {
75@@ -1468,9 +1455,6 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er
76 case "soju.im/search":
77 s.searchBatchID = id
78 s.searchBatch = SearchEvent{}
79- case "soju.im/bouncer-networks":
80- s.bouncerNetworksBatchID = id
81- s.bouncerNetworksBatch = BouncerNetworkListEvent{}
82 }
83 } else {
84 if b, ok := s.chBatches[id]; ok {
85@@ -1484,9 +1468,6 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er
86 } else if s.searchBatchID == id {
87 s.searchBatchID = ""
88 return s.searchBatch, nil
89- } else if s.bouncerNetworksBatchID == id {
90- s.bouncerNetworksBatchID = ""
91- return s.bouncerNetworksBatch, nil
92 }
93 }
94 case "NICK":
95@@ -1594,7 +1575,8 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er
96 ID: id,
97 }
98 if msg.Params[2] != "*" {
99- event.Attrs = parseTags(msg.Params[2])
100+ attrs := parseTags(msg.Params[2])
101+ event.Name = attrs["name"]
102 } else {
103 event.Delete = true
104 }
+0,
-92
1@@ -1,92 +0,0 @@
2-// Code generated by go-varlink/varlinkgen. DO NOT EDIT.
3-
4-package varlinkservice
5-
6-import (
7- "encoding/json"
8-
9- govarlink "github.com/emersion/go-varlink"
10-)
11-
12-type OpenLinkIn struct {
13- Link string `json:"link"`
14-}
15-type OpenLinkOut struct{}
16-
17-type Client struct {
18- *govarlink.Client
19-}
20-
21-func unmarshalError(err error) error {
22- verr, ok := err.(*govarlink.ClientError)
23- if !ok {
24- return err
25- }
26- var v error
27- switch verr.Name {
28- default:
29- return err
30- }
31- if err := json.Unmarshal(verr.Parameters, v); err != nil {
32- return err
33- }
34- return v
35-}
36-func (c Client) OpenLink(in *OpenLinkIn) (*OpenLinkOut, error) {
37- if in == nil {
38- in = new(OpenLinkIn)
39- }
40- out := new(OpenLinkOut)
41- err := c.Client.Do("fr.delthas.senpai.OpenLink", in, out)
42- return out, unmarshalError(err)
43-}
44-
45-type Backend interface {
46- OpenLink(*OpenLinkIn) (*OpenLinkOut, error)
47-}
48-
49-type Handler struct {
50- Backend Backend
51-}
52-
53-func marshalError(err error) error {
54- var name string
55- switch err.(type) {
56- default:
57- return err
58- }
59- return &govarlink.ServerError{
60- Name: name,
61- Parameters: err,
62- }
63-}
64-func (h Handler) HandleVarlink(call *govarlink.ServerCall, req *govarlink.ServerRequest) error {
65- var (
66- out interface{}
67- err error
68- )
69- switch req.Method {
70- case "fr.delthas.senpai.OpenLink":
71- in := new(OpenLinkIn)
72- if err := json.Unmarshal(req.Parameters, in); err != nil {
73- return err
74- }
75- out, err = h.Backend.OpenLink(in)
76- default:
77- err = &govarlink.ServerError{
78- Name: "org.varlink.service.MethodNotFound",
79- Parameters: map[string]string{"method": req.Method},
80- }
81- }
82- if err != nil {
83- return marshalError(err)
84- }
85- return call.CloseWithReply(out)
86-}
87-
88-func (h Handler) Register(reg *govarlink.Registry) {
89- reg.Add(&govarlink.RegistryInterface{
90- Definition: "interface fr.delthas.senpai\n\nmethod OpenLink(link: string) -> ()\n",
91- Name: "fr.delthas.senpai",
92- }, h)
93-}
1@@ -1,3 +0,0 @@
2-interface fr.delthas.senpai
3-
4-method OpenLink(link: string) -> ()
+0,
-9
1@@ -1,9 +0,0 @@
2-//go:build generate
3-
4-package varlinkservice
5-
6-import (
7- _ "github.com/emersion/go-varlink/cmd/varlinkgen"
8-)
9-
10-//go:generate go run github.com/emersion/go-varlink/cmd/varlinkgen -i fr.delthas.senpai.varlink