1#!/usr/local/bin/python3.8
2
3import dbus
4from gi.repository import Gio
5
6LG_DBUS_NAME = "org.Cinnamon.LookingGlass"
7LG_DBUS_PATH = "/org/Cinnamon/LookingGlass"
8
9
10class LookingGlassProxy:
11    def __init__(self):
12        self._signals = []
13        self._status_change_callbacks = []
14        self._proxy = None
15        Gio.bus_watch_name(Gio.BusType.SESSION,
16                           LG_DBUS_NAME,
17                           Gio.BusNameWatcherFlags.NONE,
18                           self.on_connect,
19                           self.on_disconnect)
20
21    def add_status_change_callback(self, callback):
22        self._status_change_callbacks.append(callback)
23
24    def refresh_status(self):
25        self.set_status(self._proxy is not None)
26
27    def get_is_ready(self):
28        return self._proxy is not None
29
30    def connect(self, name, callback):
31        self._signals.append((name, callback))
32
33    def on_signal(self, proxy, sender_name, signal_name, params):
34        for name, callback in self._signals:
35            if signal_name == name:
36                callback(*params)
37
38    def set_status(self, state):
39        for callback in self._status_change_callbacks:
40            callback(state)
41
42    def on_connect(self, connection, name, owner):
43        if self._proxy:
44            return
45        self.init_proxy()
46
47    def on_disconnect(self, connection, name):
48        self._proxy = None
49        self.set_status(False)
50
51    def init_proxy(self):
52        try:
53            self._proxy = Gio.DBusProxy.new_for_bus(Gio.BusType.SESSION,
54                                                    Gio.DBusProxyFlags.NONE,
55                                                    None,
56                                                    LG_DBUS_NAME,
57                                                    LG_DBUS_PATH,
58                                                    LG_DBUS_NAME,
59                                                    None,
60                                                    self.on_proxy_ready,
61                                                    None)
62        except dbus.exceptions.DBusException as exc:
63            print(exc)
64            self._proxy = None
65
66    def on_proxy_ready(self, obj, result, data=None):
67        self._proxy = Gio.DBusProxy.new_for_bus_finish(result)
68        self._proxy.connect("g-signal", self.on_signal)
69        self.set_status(True)
70
71# Proxy Methods:
72    def Eval(self, code):
73        if self._proxy:
74            try:
75                self._proxy.Eval('(s)', code)
76            except Exception:
77                pass
78
79    def GetResults(self):
80        if self._proxy:
81            try:
82                return self._proxy.GetResults('()')
83            except Exception:
84                pass
85        return (False, "")
86
87    def AddResult(self, code):
88        if self._proxy:
89            try:
90                self._proxy.AddResult('(s)', code)
91            except Exception:
92                pass
93
94    def GetErrorStack(self):
95        if self._proxy:
96            try:
97                return self._proxy.GetErrorStack('()')
98            except Exception:
99                pass
100        return (False, "")
101
102    def GetMemoryInfo(self):
103        if self._proxy:
104            try:
105                return self._proxy.GetMemoryInfo('()')
106            except Exception:
107                pass
108        return (False, 0, {})
109
110    def FullGc(self):
111        if self._proxy:
112            try:
113                self._proxy.FullGc('()')
114            except Exception:
115                pass
116
117    def Inspect(self, code):
118        if self._proxy:
119            try:
120                return self._proxy.Inspect('(s)', code)
121            except Exception:
122                pass
123        return (False, "")
124
125    def GetLatestWindowList(self):
126        if self._proxy:
127            try:
128                return self._proxy.GetLatestWindowList('()')
129            except Exception:
130                pass
131        return (False, "")
132
133    def StartInspector(self):
134        if self._proxy:
135            try:
136                self._proxy.StartInspector('()')
137            except Exception:
138                pass
139
140    def GetExtensionList(self):
141        if self._proxy:
142            try:
143                return self._proxy.GetExtensionList('()')
144            except Exception:
145                pass
146        return (False, "")
147
148    def ReloadExtension(self, uuid, xlet_type):
149        if self._proxy:
150            try:
151                return self._proxy.ReloadExtension('(ss)', uuid, xlet_type)
152            except Exception:
153                pass
154        return (False, "")
155