1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#!/usr/bin/python
import logging
import os
import string
import subprocess
try:
import glib
import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
except ImportError, e:
sys.stderr.write("Failed to import '%s', can not use dbus" % e)
sys.exit(1)
class PermissionDeniedError(dbus.DBusException):
" permission denied by policy "
pass
class AptXapianIndexDBusService(dbus.service.Object):
DBUS_INTERFACE_NAME = "org.debian.AptXapianIndex"
def __init__(self):
bus_name = dbus.service.BusName(self.DBUS_INTERFACE_NAME,
bus=dbus.SystemBus())
dbus.service.Object.__init__(self, bus_name, '/')
self._active_axi = None
def _authWithPolicyKit(self, sender, connection, priv):
system_bus = dbus.SystemBus()
obj = system_bus.get_object("org.freedesktop.PolicyKit1",
"/org/freedesktop/PolicyKit1/Authority",
"org.freedesktop.PolicyKit1.Authority")
policykit = dbus.Interface(obj, "org.freedesktop.PolicyKit1.Authority")
info = dbus.Interface(connection.get_object('org.freedesktop.DBus',
'/org/freedesktop/DBus/Bus',
False),
'org.freedesktop.DBus')
pid = info.GetConnectionUnixProcessID(sender)
subject = ('unix-process',
{ 'pid' : dbus.UInt32(pid, variant_level=1),
'start-time' : dbus.UInt64(0, variant_level=1),
}
)
details = { '' : '' }
flags = dbus.UInt32(1) # AllowUserInteraction = 0x00000001
cancel_id = ''
(ok, notused, details) = policykit.CheckAuthorization(
subject, priv, details, flags, cancel_id)
return ok
@dbus.service.signal(dbus_interface=DBUS_INTERFACE_NAME,
signature="b")
def UpdateFinished(self, res):
logging.debug("Emitting UpdateFinished: %s" % res)
@dbus.service.signal(dbus_interface=DBUS_INTERFACE_NAME,
signature="i")
def UpdateProgress(self, percent):
logging.debug("Emitting UpdateProgress: %s" % percent)
def _update_apt_xapian_index(self, cmd):
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
self._active_axi = p
while True:
while gobject.main_context_default().pending():
gobject.main_context_default().iteration()
res = p.poll()
if res is not None:
break
line = p.stdout.readline().strip()
if not line:
continue
try:
(op, progress) = string.split(line, sep=":", maxsplit=1)
if op == "progress":
percent = int(progress.split("/")[0])
self.UpdateProgress(percent)
except ValueError:
pass
# axi finished
self._active_axi = None
# emit finish signal
self.UpdateFinished(res == 0)
@dbus.service.method(DBUS_INTERFACE_NAME,
in_signature='bb',
out_signature='',
sender_keyword='sender',
connection_keyword='conn')
def update_async(self, force, update_only, sender=None, conn=None):
if not self._authWithPolicyKit(sender, conn,
"org.debian.aptxapianindex.update"):
raise PermissionDeniedError, "Permission denied by policy"
# do not start update-apt-xapian-index twice, the clients will
# get the finished signal from the previous running one
if self._active_axi:
return
cmd = ["/usr/sbin/update-apt-xapian-index", "--batch-mode"]
if force:
cmd.append("--force")
if update_only:
cmd.append("--update")
glib.timeout_add(100, self._update_apt_xapian_index, cmd)
if __name__ == "__main__":
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
server = AptXapianIndexDBusService()
gobject.MainLoop().run()
|