summaryrefslogtreecommitdiffstats
path: root/src/Gui/CCDBusBackend.py
blob: 21d242525c4ee2ad44dbf89bfc796e601dc46cd8 (plain)
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# -*- coding: utf-8 -*-
import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop
import gtk

CC_NAME = 'com.redhat.abrt'
CC_IFACE = 'com.redhat.abrt'
CC_PATH = '/com/redhat/abrt'
APP_NAME = 'com.redhat.abrt.gui'
        

class DBusManager(gobject.GObject):
    """ Class to provide communication with daemon over dbus """
    # and later with policyKit
    uniq_name = None
    pending_jobs = []
    def __init__(self):
        session = None
        try:
            session = dbus.SessionBus()
        except:
            # FIXME: root doesn't have SessionBus
            pass
        if session:
            if session.request_name(APP_NAME, dbus.bus.NAME_FLAG_DO_NOT_QUEUE) != dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER:
                raise Exception("Name %s is taken,\nanother instance is already running." % APP_NAME)
        
        gobject.GObject.__init__(self)
        # signal emited when new crash is detected
        gobject.signal_new ("crash", self ,gobject.SIGNAL_RUN_FIRST,gobject.TYPE_NONE,())
        # signal emited when new analyze is complete
        gobject.signal_new ("analyze-complete", self ,gobject.SIGNAL_RUN_FIRST,gobject.TYPE_NONE,(gobject.TYPE_PYOBJECT,))
        # signal emited when smth fails
        gobject.signal_new ("error", self ,gobject.SIGNAL_RUN_FIRST,gobject.TYPE_NONE,(gobject.TYPE_PYOBJECT,))
        # signal emited to update gui with current status
        gobject.signal_new ("update", self ,gobject.SIGNAL_RUN_FIRST,gobject.TYPE_NONE,(gobject.TYPE_PYOBJECT,))
        # binds the dbus to glib mainloop
        DBusGMainLoop(set_as_default=True)
        self.proxy = None
        self.proxy = self.connect_to_daemon()
        if self.proxy:
            self.cc = dbus.Interface(self.proxy, dbus_interface=CC_IFACE)
            #intr = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Introspectable')
            # new crash notify
            self.proxy.connect_to_signal("Crash",self.crash_cb,dbus_interface=CC_IFACE)
            # BT extracting complete
            self.acconnection = self.proxy.connect_to_signal("AnalyzeComplete",self.analyze_complete_cb,dbus_interface=CC_IFACE)
            # Catch Errors
            self.acconnection = self.proxy.connect_to_signal("Error",self.error_handler_cb,dbus_interface=CC_IFACE)
            # watch for updates
            self.acconnection = self.proxy.connect_to_signal("Update",self.update_cb,dbus_interface=CC_IFACE)
            # watch for job-done signals
            self.acconnection = self.proxy.connect_to_signal("JobDone",self.jobdone_cb,dbus_interface=CC_IFACE)
        else:
            raise Exception("Please check if abrt daemon is running.")

    # disconnect callback
    def disconnected(*args):
        print "disconnect"
    
    def error_handler_cb(self,arg):
        self.emit("error",arg)
    
    def error_handler(self,arg):
        # used to silently ingore dbus timeouts
        pass
    
    def dummy(*args):
        # dummy function for async method call to workaround the timeout
        pass
    
    def crash_cb(self,*args):
        #FIXME "got another crash, gui should reload!"
        #for arg in args:
        #    print arg
        #emit a signal
        #print "crash"
        self.emit("crash")
    
    def update_cb(self, dest, message):
        # FIXME: use dest instead of 0 once we implement it in daemon
        #if self.uniq_name == dest:
        self.emit("update", message)
        
    def analyze_complete_cb(self,dump):
        #for arg in args:
        #    print "Analyze complete for: %s" % arg
        # emit signal to let clients know that analyze has been completed
        # FIXME - rewrite with CCReport class
    #    self.emit("analyze-complete", dump)
        pass
        
    def connect_to_daemon(self):
        bus = dbus.SystemBus()
        self.uniq_name = bus.get_unique_name()
        if not bus:
            raise Exception("Can't connect to dbus")
        try:
            if bus.name_has_owner(CC_NAME):
                return bus.get_object(CC_IFACE, CC_PATH)
            return None
        except Exception, e:
            raise Exception(e.message + "\nCannot create a proxy object!")

    def addJob(self, job_id):
        self.pending_jobs.append(job_id)
        
    def jobdone_cb(self, job_id):
        #if self.uniq_name == client_id:
        try:
            self.pending_jobs.index(job_id)
        except:
            return
        dump = self.cc.GetJobResult(job_id)
        if dump:
            self.emit("analyze-complete", dump)
        
    def getReport(self, UUID):
        try:
            # let's try it async
            # even if it's async it timeouts, so let's try to set the timeout to 60sec
            #self.cc.CreateReport(UUID, reply_handler=self.addJob, error_handler=self.error_handler, timeout=60)
            self.addJob(self.cc.CreateReport(UUID, timeout=60))
        except dbus.exceptions.DBusException, e:
            raise Exception(e.message)
    
    def Report(self,report):
        # FIXME async
        return self.cc.Report(report)
    
    def DeleteDebugDump(self,UUID):
        return self.cc.DeleteDebugDump(UUID)
    
    def getDumps(self):
        row_dict = None
        rows = []
        # FIXME check the arguments
        for row in self.cc.GetCrashInfos():
            row_dict = {}
            for column in row:
                row_dict[column] = row[column]
            rows.append(row_dict);
        return rows