go-tg-screenshot-bot
174 строки · 5.9 Кб
1package dbus
2
3import (
4"context"
5"errors"
6"strings"
7)
8
9// BusObject is the interface of a remote object on which methods can be
10// invoked.
11type BusObject interface {
12Call(method string, flags Flags, args ...interface{}) *Call
13CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call
14Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call
15GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call
16AddMatchSignal(iface, member string, options ...MatchOption) *Call
17RemoveMatchSignal(iface, member string, options ...MatchOption) *Call
18GetProperty(p string) (Variant, error)
19StoreProperty(p string, value interface{}) error
20SetProperty(p string, v interface{}) error
21Destination() string
22Path() ObjectPath
23}
24
25// Object represents a remote object on which methods can be invoked.
26type Object struct {
27conn *Conn
28dest string
29path ObjectPath
30}
31
32// Call calls a method with (*Object).Go and waits for its reply.
33func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call {
34return <-o.createCall(context.Background(), method, flags, make(chan *Call, 1), args...).Done
35}
36
37// CallWithContext acts like Call but takes a context
38func (o *Object) CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call {
39return <-o.createCall(ctx, method, flags, make(chan *Call, 1), args...).Done
40}
41
42// AddMatchSignal subscribes BusObject to signals from specified interface,
43// method (member). Additional filter rules can be added via WithMatch* option constructors.
44// Note: To filter events by object path you have to specify this path via an option.
45//
46// Deprecated: use (*Conn) AddMatchSignal instead.
47func (o *Object) AddMatchSignal(iface, member string, options ...MatchOption) *Call {
48base := []MatchOption{
49withMatchType("signal"),
50WithMatchInterface(iface),
51WithMatchMember(member),
52}
53
54options = append(base, options...)
55return o.conn.BusObject().Call(
56"org.freedesktop.DBus.AddMatch",
570,
58formatMatchOptions(options),
59)
60}
61
62// RemoveMatchSignal unsubscribes BusObject from signals from specified interface,
63// method (member). Additional filter rules can be added via WithMatch* option constructors
64//
65// Deprecated: use (*Conn) RemoveMatchSignal instead.
66func (o *Object) RemoveMatchSignal(iface, member string, options ...MatchOption) *Call {
67base := []MatchOption{
68withMatchType("signal"),
69WithMatchInterface(iface),
70WithMatchMember(member),
71}
72
73options = append(base, options...)
74return o.conn.BusObject().Call(
75"org.freedesktop.DBus.RemoveMatch",
760,
77formatMatchOptions(options),
78)
79}
80
81// Go calls a method with the given arguments asynchronously. It returns a
82// Call structure representing this method call. The passed channel will
83// return the same value once the call is done. If ch is nil, a new channel
84// will be allocated. Otherwise, ch has to be buffered or Go will panic.
85//
86// If the flags include FlagNoReplyExpected, ch is ignored and a Call structure
87// is returned with any error in Err and a closed channel in Done containing
88// the returned Call as it's one entry.
89//
90// If the method parameter contains a dot ('.'), the part before the last dot
91// specifies the interface on which the method is called.
92func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
93return o.createCall(context.Background(), method, flags, ch, args...)
94}
95
96// GoWithContext acts like Go but takes a context
97func (o *Object) GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
98return o.createCall(ctx, method, flags, ch, args...)
99}
100
101func (o *Object) createCall(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
102if ctx == nil {
103panic("nil context")
104}
105iface := ""
106i := strings.LastIndex(method, ".")
107if i != -1 {
108iface = method[:i]
109}
110method = method[i+1:]
111msg := new(Message)
112msg.Type = TypeMethodCall
113msg.Flags = flags & (FlagNoAutoStart | FlagNoReplyExpected)
114msg.Headers = make(map[HeaderField]Variant)
115msg.Headers[FieldPath] = MakeVariant(o.path)
116msg.Headers[FieldDestination] = MakeVariant(o.dest)
117msg.Headers[FieldMember] = MakeVariant(method)
118if iface != "" {
119msg.Headers[FieldInterface] = MakeVariant(iface)
120}
121msg.Body = args
122if len(args) > 0 {
123msg.Headers[FieldSignature] = MakeVariant(SignatureOf(args...))
124}
125return o.conn.SendWithContext(ctx, msg, ch)
126}
127
128// GetProperty calls org.freedesktop.DBus.Properties.Get on the given
129// object. The property name must be given in interface.member notation.
130func (o *Object) GetProperty(p string) (Variant, error) {
131var result Variant
132err := o.StoreProperty(p, &result)
133return result, err
134}
135
136// StoreProperty calls org.freedesktop.DBus.Properties.Get on the given
137// object. The property name must be given in interface.member notation.
138// It stores the returned property into the provided value.
139func (o *Object) StoreProperty(p string, value interface{}) error {
140idx := strings.LastIndex(p, ".")
141if idx == -1 || idx+1 == len(p) {
142return errors.New("dbus: invalid property " + p)
143}
144
145iface := p[:idx]
146prop := p[idx+1:]
147
148return o.Call("org.freedesktop.DBus.Properties.Get", 0, iface, prop).
149Store(value)
150}
151
152// SetProperty calls org.freedesktop.DBus.Properties.Set on the given
153// object. The property name must be given in interface.member notation.
154func (o *Object) SetProperty(p string, v interface{}) error {
155idx := strings.LastIndex(p, ".")
156if idx == -1 || idx+1 == len(p) {
157return errors.New("dbus: invalid property " + p)
158}
159
160iface := p[:idx]
161prop := p[idx+1:]
162
163return o.Call("org.freedesktop.DBus.Properties.Set", 0, iface, prop, v).Err
164}
165
166// Destination returns the destination that calls on (o *Object) are sent to.
167func (o *Object) Destination() string {
168return o.dest
169}
170
171// Path returns the path that calls on (o *Object") are sent to.
172func (o *Object) Path() ObjectPath {
173return o.path
174}
175