__init__.py 8.75 KB
Newer Older
1 2 3
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
4
# Copyright (C) 2016-2018, AquilaNipalensis
5 6 7 8 9 10 11
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version. Please read the COPYING file.
#

12
__version__ = '2.4.7'
Bahadır Kandemir's avatar
Bahadır Kandemir committed
13 14

import dbus
15
import locale
Bahadır Kandemir's avatar
Bahadır Kandemir committed
16
import os
Bahadır Kandemir's avatar
Bahadır Kandemir committed
17
import subprocess
18
from dbus.mainloop.glib import DBusGMainLoop
Bahadır Kandemir's avatar
Bahadır Kandemir committed
19 20 21 22 23 24 25 26 27 28 29

class Call:
    def __init__(self, link, group, class_=None, package=None, method=None):
        self.link = link
        self.group = group
        self.class_ = class_
        self.package = package
        self.method = method
        self.async = None
        self.quiet = False

Bahadır Kandemir's avatar
Bahadır Kandemir committed
30 31 32
        if self.package:
            self.package = self.package.replace("-", "_")

Bahadır Kandemir's avatar
Bahadır Kandemir committed
33 34
    def __getitem__(self, key):
        if not self.class_:
35 36
            raise KeyError("Package should be selected after class")
        if not isinstance(key, str):
Bahadır Kandemir's avatar
Bahadır Kandemir committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
            raise KeyError
        return Call(self.link, self.group, self.class_, key)

    def __getattr__(self, name):
        if self.class_:
            c = Call(self.link, self.group, self.class_, self.package, name)
            return c.call
        else:
            if name[0] < 'A' or name[0] > 'Z':
                raise AttributeError

            return Call(self.link, self.group, name)

    def __iter__(self):
        if self.class_:
            obj = self.link.bus.get_object(self.link.address, "/", introspect=False)
53
            packages = obj.listModelApplications("%s.%s" % (self.group, self.class_), dbus_interface=self.link.interface)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
54
            for package in packages:
55
                yield str(package)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
56 57 58 59

    def call(self, *args, **kwargs):
        self.async = kwargs.get("async", None)
        self.quiet = kwargs.get("quiet", False)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
60
        self.timeout = kwargs.get("timeout", 120)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
61
        if self.async and self.quiet:
62
            raise Exception("async and quiet arguments can't be used together")
Bahadır Kandemir's avatar
Bahadır Kandemir committed
63 64
        if self.async or self.quiet:
            if self.package:
65
                obj = self.link.bus.get_object(self.link.address, "/package/%s" % self.package)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
66 67 68 69 70
                met = getattr(obj, self.method)

                def handleResult(*result):
                    self.async(self.package, None, result)
                def handleError(exception):
Suleyman Poyraz's avatar
Suleyman Poyraz committed
71
                    if "policy.auth" in exception._dbus_error_name or "Scom.PolicyKit" in exception._dbus_error_name:
Bahadır Kandemir's avatar
Bahadır Kandemir committed
72 73 74
                        action = exception.get_dbus_message()
                        if self.queryPolicyKit(action):
                            return self.call(*args, **kwargs)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
75 76 77
                    self.async(self.package, exception, None)

                if self.quiet:
78
                    met(dbus_interface="%s.%s.%s" % (self.link.interface, self.group, self.class_), *args)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
79
                else:
80
                    met(dbus_interface="%s.%s.%s" % (self.link.interface, self.group, self.class_), reply_handler=handleResult, error_handler=handleError, timeout=self.timeout, *args)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
81 82
            else:
                def handlePackages(packages):
83 84
                    if self.quiet:
                        for package in packages:
85
                            obj = self.link.bus.get_object(self.link.address, "/package/%s" % package)
86
                            met = getattr(obj, self.method)
87
                            met(dbus_interface="%s.%s.%s" % (self.link.interface, self.group, self.class_), *args)
88 89 90 91 92 93 94 95 96 97 98
                    else:
                        def handleResult(package):
                            def handler(*result):
                                return self.async(package, None, result)
                            return handler
                        def handleError(package):
                            def handler(exception):
                                return self.async(package, exception, None)
                            return handler

                        for package in packages:
99
                            obj = self.link.bus.get_object(self.link.address, "/package/%s" % package)
100
                            met = getattr(obj, self.method)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
101

102
                            met(dbus_interface="%s.%s.%s" % (self.link.interface, self.group, self.class_), reply_handler=handleResult(package), error_handler=handleError(package), timeout=self.timeout, *args)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
103 104 105 106 107 108 109 110 111

                def handlePackError(exception):
                    if self.quiet:
                        pass
                    else:
                        raise exception

                if self.quiet:
                    obj = self.link.bus.get_object(self.link.address, "/", introspect=False)
112
                    packages = obj.listModelApplications("%s.%s" % (self.group, self.class_), dbus_interface=self.link.interface)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
113 114 115
                    handlePackages(packages)
                else:
                    obj = self.link.bus.get_object(self.link.address, "/", introspect=False)
116
                    obj.listModelApplications("%s.%s" % (self.group, self.class_), dbus_interface=self.link.interface, reply_handler=handlePackages, error_handler=handlePackError, timeout=self.timeout)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
117 118
        else:
            if self.package:
119
                obj = self.link.bus.get_object(self.link.address, "/package/%s" % self.package)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
120
                met = getattr(obj, self.method)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
121
                try:
122
                    return met(dbus_interface="%s.%s.%s" % (self.link.interface, self.group, self.class_), timeout=self.timeout, *args)
123
                except dbus.DBusException as exception:
Suleyman Poyraz's avatar
Suleyman Poyraz committed
124
                    if "policy.auth" in exception._dbus_error_name or "Scom.PolicyKit" in exception._dbus_error_name:
Bahadır Kandemir's avatar
Bahadır Kandemir committed
125
                        action = exception.get_dbus_message()
Bahadır Kandemir's avatar
Bahadır Kandemir committed
126 127
                        if self.queryPolicyKit(action):
                            return self.call(*args, **kwargs)
128
                    raise dbus.DBusException(exception)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
129
            else:
130
                raise AttributeError("Package name required for non-async calls.")
Bahadır Kandemir's avatar
Bahadır Kandemir committed
131

Bahadır Kandemir's avatar
Bahadır Kandemir committed
132
    def queryPolicyKit(self, action):
Bahadır Kandemir's avatar
Bahadır Kandemir committed
133
        return False
Bahadır Kandemir's avatar
Bahadır Kandemir committed
134

Bahadır Kandemir's avatar
Bahadır Kandemir committed
135 136

class Link:
137
    def __init__(self, version="2", socket=None, alternate=False):
138
        self.version = str(version)
139 140
        self.address = "tr.org.sulin.scom"
        self.interface = "tr.org.sulin.scom"
141
        self.socket = socket
142 143 144

        # Auto-enable agent, if X session present.
        self.use_agent = ("DISPLAY" in os.environ)
145
        DBusGMainLoop(set_as_default=True)
146

147 148 149 150
        if not socket:
            self.bus = dbus.SystemBus()
        else:
            self.bus = dbus.bus.BusConnection(address_or_type="unix:path=%s" % socket)
151
        if alternate:
152
            self.address += "2"
153

Bahadır Kandemir's avatar
Bahadır Kandemir committed
154
    def useAgent(self, agent=True):
155
        self.use_agent = agent
Bahadır Kandemir's avatar
Bahadır Kandemir committed
156

157
    def setLocale(self):
158
        try:
159 160 161 162 163 164
            code, encoding = locale.getdefaultlocale()
            if code:
                if "_" in code:
                    code = code.split("_")[0]
                obj = self.bus.get_object(self.address, '/', introspect=False)
                obj.setLocale(code, dbus_interface=self.interface)
165
        except dbus.DBusException as exception:
166
            pass
167

Bahadır Kandemir's avatar
Bahadır Kandemir committed
168 169 170 171
    def cancel(self, method="*"):
        try:
            obj = self.bus.get_object(self.address, '/', introspect=False)
            return obj.cancel(method, dbus_interface=self.interface)
172
        except dbus.DBusException as exception:
Bahadır Kandemir's avatar
Bahadır Kandemir committed
173 174
            return 0

Bahadır Kandemir's avatar
Bahadır Kandemir committed
175 176 177 178 179
    def listRunning(self, all=True):
        methods = []
        try:
            obj = self.bus.get_object(self.address, '/', introspect=False)
            methods = obj.listRunning(all, dbus_interface=self.interface)
180
        except dbus.DBusException as exception:
Bahadır Kandemir's avatar
Bahadır Kandemir committed
181 182 183 184 185 186
            return methods
        for index, method in enumerate(methods):
            if method.startswith("%s." % self.interface):
                methods[index] = method[len("%s." % self.interface):]
        return methods

Bahadır Kandemir's avatar
Bahadır Kandemir committed
187 188 189 190 191 192 193
    def listenSignals(self, model, handler):
        def sigHandler(*args, **kwargs):
            if "/package/" not in kwargs["path"]:
                return
            package = kwargs["path"].split("/package/")[1]
            signal = kwargs["signal"]
            handler(package, signal, args)
194
        self.bus.add_signal_receiver(sigHandler, dbus_interface="%s.%s" % (self.interface, model), member_keyword="signal", path_keyword="path")
Bahadır Kandemir's avatar
Bahadır Kandemir committed
195

196
    def register(self, app, model, script, timeout=120):
Bahadır Kandemir's avatar
Bahadır Kandemir committed
197
        obj = self.bus.get_object(self.address, '/', introspect=False)
198
        obj.register(app, model, script, dbus_interface=self.interface, timeout=timeout)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
199

200
    def remove(self, app, timeout=120):
Bahadır Kandemir's avatar
Bahadır Kandemir committed
201
        obj = self.bus.get_object(self.address, '/', introspect=False)
202
        obj.remove(app, dbus_interface=self.interface, timeout=timeout)
Bahadır Kandemir's avatar
Bahadır Kandemir committed
203

Bahadır Kandemir's avatar
Bahadır Kandemir committed
204 205 206 207
    def __getattr__(self, name):
        if name[0] < 'A' or name[0] > 'Z':
            raise AttributeError
        return Call(self, name)