root/branch/ggpolo/umitInventory/Viewer.py @ 1023

Revision 1023, 32.2 kB (checked in by ggpolo, 6 years ago)

Several updates for Timeline integration.

Line 
1# Copyright (C) 2007 Insecure.Com LLC.
2#
3# Authors: Guilherme Polo <ggpolo@gmail.com>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18# USA
19
20"""
21Inventories Viewer
22"""
23
24import os
25import sys
26import gtk
27import time
28import pango
29import cairo
30import gobject
31import subprocess
32from gtk import gdk
33from ConfigParser import ConfigParser
34
35from os.path import join, split
36
37from higwidgets.higwindows import HIGMainWindow
38from higwidgets.hignotebooks import HIGNotebook, HIGAnimatedTabLabel
39from higwidgets.higscrollers import HIGScrolledWindow
40from higwidgets.higboxes import HIGHBox, HIGVBox
41
42from umitCore.Paths import Path
43from umitCore.I18N import _
44
45from umitDB.Connection import ConnectDB
46from umitDB.Retrieve import InventoryRetrieve
47from umitDB.Search import SearchDB
48
49from umitInventory.NewInventory import NewInventory
50from umitInventory.SearchBar import SearchBar
51from umitInventory.ChangesList import ChangesList
52from umitInventory.ChangesDiff import ChangesDiff
53from umitInventory.InventoryTree import InventoryTree
54from umitInventory.Timeline import TLHolder
55from umitInventory.Utils import check_process
56
57try:
58    umitdb = Path.umitdb_ng
59except:
60    Path.set_umit_conf(join(split(__file__)[0], 'config', 'umit.conf'))
61    umitdb = Path.umitdb_ng
62
63NI_VER = '0.2'
64controller = Path.sched_control
65inventory_info = _("Info")
66
67def gen_index(max):
68    """
69    Generate an index for using in search results.
70    """
71    for i in range(max):
72        yield i
73       
74
75class InventoryNB(gtk.Notebook):
76    """
77    Inventory Notebook for each Inventory.
78    """
79
80    def __init__(self, daddy, inventory_name, inv_activated=False):
81        gtk.Notebook.__init__(self)
82       
83        self.daddy = daddy
84        self.pages = [ ]
85               
86        self.__layout()
87   
88
89    def append_inv(self, title="Info", box=None):
90        """
91        Add info page.
92        """
93        if self.page_exists(title):
94            return
95       
96        custom_title = self.__create_custom_title(title, box)
97        box.show()
98        custom_title.show()
99        self.append_page(box, custom_title)
100        self.pages.append(title)
101           
102        self.__layout(box)
103       
104       
105    def append_host(self, host_addr, box):
106        """
107        Add host page.
108        """
109        if self.page_exists(host_addr):
110            return
111       
112        custom_title = self.__create_custom_title(host_addr, box)
113        box.show()
114        custom_title.show()
115        self.append_page(box, custom_title)
116        self.pages.append(host_addr)
117           
118        self.__layout(box)
119
120   
121    def page_exists(self, pagetitle):
122        """
123        Check if there is a page with pagetitle in this notebook.
124        """
125        if pagetitle in self.pages:
126            return True
127       
128        return False
129
130
131    def remove_page(self, button, page, text):
132        """
133        Remove a page from notebook and from self.pages
134        """
135        del self.pages[self.pages.index(text)]
136        self.remove(page)
137       
138        if not len(self.pages): # last page in this inventory was just removed
139            self.daddy._delete_inventory_page() # delete notebook
140
141
142    def __add_close_icon_to_button(self, button):
143        """
144        Adds a close image to the page title close button.
145        """
146        image = gtk.Image()
147        image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU)
148        image.show()
149
150        gtk.Button.set_relief(button, gtk.RELIEF_NONE)
151        settings = gtk.Widget.get_settings(button)
152
153        (w,h) = gtk.icon_size_lookup_for_settings(settings, gtk.ICON_SIZE_MENU)
154
155        gtk.Widget.set_size_request(button, w + 4, h + 4)
156       
157        icon_hbox = gtk.HBox(False, 0)
158        icon_hbox.pack_start(image, True, False, 0)
159        icon_hbox.show()
160       
161        button.add(icon_hbox)
162
163
164    def __create_custom_title(self, title, widget):
165        """
166        Creates a title with close button.
167        """
168        title_eb = gtk.EventBox()
169       
170        label = gtk.Label(_("%s" % title))
171        label.show()
172
173        title_hbox = gtk.HBox(False)       
174        title_hbox.pack_start(label, False, False, 0)
175
176        title_eb.add(title_hbox)
177       
178        if self.daddy.invnb_close_btn:
179            button = gtk.Button()
180            button.connect('clicked', self.remove_page, widget, title)
181            button.show()
182
183            self.__add_close_icon_to_button(button)
184            title_hbox.pack_end(button, False, False, 0)
185       
186        title_hbox.show()
187       
188        return title_eb
189
190       
191    def __layout(self, box=None):
192        """
193        Update notebook.
194        """
195        self.show()
196
197
198class InventoryViewer(HIGMainWindow):
199    """
200    Load Inventories from database.
201    """
202
203    def __init__(self, daddy=None):
204        HIGMainWindow.__init__(self)
205       
206        self.daddy = daddy
207        self.tip_timer = -1
208        self.main_accel_group = gtk.AccelGroup()
209        self.add_accel_group(self.main_accel_group)
210       
211        self.viewernb = HIGNotebook()
212       
213        self.invsearch = SearchDB(umitdb)
214        self.invdb = InventoryRetrieve(umitdb)
215        self.invtree = InventoryTree(self)
216        self.invnb = HIGNotebook()
217        self.invnb_close_btn = True
218        self.invnbpages_titles = [ ]
219        self.invnbpages_objects = [ ]
220       
221        # timeline tab
222        self.timeline = TLHolder()
223       
224        # statusbar
225        self.statusbar = gtk.Statusbar()
226        self.sbcid = self.statusbar.get_context_id("TimeLine")
227        self.write_tips = True
228       
229        # timer for checking updates
230        self.scheduler_running = False
231        self.db_stat = os.stat(umitdb).st_mtime
232        self.schema_stat = os.stat(Path.sched_schemas).st_mtime
233        self.timer_updater = gobject.timeout_add(4200, 
234                                                 self.__check_for_updates)
235       
236        self._fill_tree()
237        self._create_ui_manager()
238        self.__set_props()
239        self.__do_layout()
240       
241        self.connect('destroy', self._exit_ni)
242        self.connect('inventory-activated', self._inventory_activated)
243        self.connect('realize', self.on_realize)
244       
245
246    def on_realize(self, event):
247        """
248        After realizing, change to first page in main notebook.
249        """
250        self.viewernb.set_current_page(0)
251   
252   
253    def _close_current_hosttab(self, event):
254        """
255        Closes current active Host tab.
256        """
257        holder = self.invnb.get_nth_page(self.invnb.get_current_page())
258        if holder:
259            title = self.invnb.get_tab_label_text(holder)
260            p = self.invnbpages_objects[self.invnbpages_titles.index(title)]
261           
262            if len(p.pages):
263                tab_label = p.pages[p.get_current_page()]
264                content = p.get_nth_page(p.get_current_page())
265                p.remove_page(None, content, tab_label)
266           
267
268    def _close_current_invtab(self, event):
269        """
270        Closes current active inventory notebook.
271        """
272        holder = self.invnb.get_nth_page(self.invnb.get_current_page())
273        if holder:
274            label = self.invnb.get_tab_label_text(holder)
275            del_index = self.invnbpages_titles.index(label)
276           
277            page = self.invnbpages_objects[del_index]
278            for p in xrange(page.get_n_pages()-1):
279                tab_label = page.pages[p]
280                content = page.get_nth_page(p)
281                page.remove_page(None, content, tab_label)
282            self._delete_inventory_page()
283       
284
285    def _delete_inventory_page(self):
286        """
287        Removed last page from an Inventory notebook, now remove the Inventory
288        notebook.
289        """
290        cur_page = self.invnb.get_current_page()
291        page = self.invnb.get_nth_page(cur_page)
292        page_label = self.invnb.get_tab_label_text(page)
293        del_index = self.invnbpages_titles.index(page_label)
294        del self.invnbpages_titles[del_index]
295        del self.invnbpages_objects[del_index]
296       
297        self.invnb.remove_page(cur_page)
298   
299   
300    def _inventory_activated(self, event, data):
301        """
302        Activated some item on Inventory tree.
303        """
304        if not data['host_addr']:
305            # clicked on Inventory title, dont do nothing
306            return
307           
308        title = data["root"] # inventory name
309       
310        # check if activated inventory isnt open already
311        if not title in self.invnbpages_titles:
312            # create new notebook to hold this Inventory
313            newinvnb = InventoryNB(self, title)
314            self.invnb.append_page(newinvnb, gtk.Label(_("%s" % title)))
315               
316            self.invnbpages_titles.append(title)
317            self.invnbpages_objects.append(newinvnb)
318           
319            # check if a host was activated
320            if data["host_addr"] != inventory_info: 
321                box = self._load_inventory_host_data(title, data["host_addr"])
322                newinvnb.append_host(data["host_addr"], box)
323            else:
324                # inventory info
325                box = self._load_inventory_data(title)
326                if box:
327                    newinvnb.append_inv(box=box)
328               
329        else:
330            # get Inventory notebook
331            p = self.invnbpages_objects[self.invnbpages_titles.index(title)]
332           
333            # check if a host was activated
334            if data["host_addr"] != inventory_info and \
335                not p.page_exists(data["host_addr"]):
336                box = self._load_inventory_host_data(title, data["host_addr"])
337                p.append_host(data["host_addr"], box)
338               
339            # if it is not a host, it was inventory info
340            elif data["host_addr"] == inventory_info:
341                box = self._load_inventory_data(title)
342                if box:
343                    p.append_inv(box=box)
344               
345   
346    def _load_inventory_data(self, inventory_name):
347        """
348        Load data for activated Inventory.
349        """
350        if not self.addresses.has_key(inventory_name):
351            # ToDo, show that Inventory is still empty.
352            return None
353
354        fk_inventory = self.invdb.get_inventory_id_for_name(inventory_name)
355        scans = self.invdb.get_scans_id_for_inventory(fk_inventory)
356        last_scan_id = scans[len(scans)-1][0]
357        hosts = self.addresses[inventory_name]
358       
359        box = gtk.VBox()
360       
361        # scan info
362        hb = gtk.HBox()
363        hb.pack_start(gtk.Label(_("Scan count: %d" % len(scans))), False, 
364                      False, 0)
365        box.pack_start(hb, False, False, 0)
366       
367        hb = gtk.HBox()
368        last_scan_date = self.invdb.get_finish_timestamp_for_scan_from_db(last_scan_id)
369        hb.pack_start(gtk.Label(_("Last scan date: %s" % last_scan_date)), 
370                      False, False, 0)
371        box.pack_start(hb, False, False, 0)
372       
373        details = self.invdb.get_scan_details_for_scan_from_db(scans[0][0])
374        detc = [ _("Scan args"), _("XML output version"), _("Verbose"), 
375                 _("Debugging"), _("Scanner name"), _("Scanner version") ]
376        for indx, item in enumerate(details):
377            hb = gtk.HBox()
378            hb.pack_start(gtk.Label("%s: %s" % (detc[indx], item)), False, 
379                          False, 0)
380            box.pack_start(hb, False, False, 0)
381       
382        # "separator"
383        hb = gtk.HBox()
384        hb.pack_start(gtk.Label("\n"), False, False, 0)
385        box.pack_start(hb, False, False, 0)
386       
387        # hosts info
388        hb = gtk.HBox()
389        hb.pack_start(gtk.Label(_("Hosts: %s" % ', '.join(host for host in hosts))), False, False, 0)
390        box.pack_start(hb, False, False, 0)
391       
392        hb = gtk.HBox()
393        hb.pack_start(gtk.Label(_("Host count: %s" % len(hosts))), False, 
394                      False, 0)
395        box.pack_start(hb, False, False, 0)
396       
397        sw = gtk.ScrolledWindow()
398        sw.add_with_viewport(box)
399        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
400        sw.show_all()
401       
402        return sw
403
404
405    def _load_inventory_host_data(self, inventory_name, host_addr):
406        """
407        Load data for a host in an inventory.
408        """
409        changesd = ChangesDiff(self.invdb)
410        changesl = ChangesList(inventory_name, host_addr, changesd)
411        changesd.invdb = changesl.invdb
412
413        paned = gtk.VPaned()
414        paned.add1(changesl)
415        paned.add2(changesd)
416
417        return paned
418
419
420    def _fill_tree(self):
421        """
422        Fill inventory tree list.
423        """
424        self.addresses = { }
425        timestamps = [ ]
426       
427        tr = self.invtree.treestore
428        tr.clear()
429       
430        # retrieve inventories
431        for invid, invname in self.invdb.get_inventories_ids_names():
432            root = tr.append(None, ['%s' % invname])
433            tr.append(root, [inventory_info])
434           
435            # retrieve scans id for each inventory
436            for scan in self.invdb.get_scans_id_for_inventory(invid):
437
438                # retrieve scan finish timestamp
439                fts = self.invdb.get_finish_timestamp_for_scan_from_db(scan[0])
440                timestamps.append(fts)
441               
442                # retrieve hosts id for each scan
443                for host in self.invdb.get_hosts_id_for_scan_from_db(scan[0]):
444                   
445                    # retrieve ipv4 address for host
446                    addr = self.invdb.get_ipv4_for_host_from_db(host[0])
447                   
448                    # check if host is already in current Inventory
449                    new_host = False                   
450                    if self.addresses.has_key(invname):
451                        if not addr in self.addresses[invname]:
452                            newlist = self.addresses[invname] # this is the old
453                                                              # list actually
454                            newlist.append(addr) # now this is the new list
455                            self.addresses[invname] = newlist
456                            new_host = True
457                    else:
458                        self.addresses[invname] = [addr]
459                        new_host = True
460                   
461                    if new_host:
462                        tr.append(root, ['%s' % addr])
463       
464        # Check if some inventory is not in database yet (no finished scans)
465        schemas = ConfigParser()
466        schemas.read(Path.sched_schemas)
467        for section in schemas.sections():
468            for item in schemas.items(section):
469                if item[0] == 'addtoinv' and \
470                  not self.addresses.has_key(section):
471                    if item[1] == '2':
472                        tr.append(None, ['%s' % section])
473
474   
475        self.invtree.treeview.expand_all()
476        self.invtree.set_title("My Inventories (%d)" % len(tr))
477
478
479    def _update_viewer(self):
480        """
481        Call this when needed to update Network Inventory Viewer.
482        """
483        self._fill_tree()
484        # ToDo: Reload data on open tabs
485       
486       
487    def _build_results_view(self, query, returned, buildnow=False):
488        """
489        Build a TreeView with returned results from search or perform search
490        and then Build TreeView.
491        """
492        def close_page(widget, data):
493            """
494            Close search page.
495            """
496            page_num = self.viewernb.page_num(data)
497            self.viewernb.remove_page(page_num)
498           
499           
500        def row_activated(tv, path, tvcolumn):
501            """
502            Activated some row in results treeview.
503            """
504            # create page at "Inventory"
505            model = tv.get_model()
506            iter = model.get_iter(path)
507            host_addr = model.get_value(iter, 1)
508           
509            data = { }
510            root = model[path[0]][0]
511            data["root"] = root
512            data["host_addr"] = host_addr
513           
514            self.emit('inventory-activated', data)
515           
516            # write to statusbar
517            if self.write_tips:
518                self.statusbar.pop(self.sbcid)
519                self.statusbar.push(self.sbcid, _("A page was open at \
520\"Inventory\"!"))
521                # remove tip after 15 seconds
522                self.tip_timer = gobject.timeout_add(15000, 
523                                                     self._clear_statusbar)
524       
525           
526        def buildtv(*args):
527            """
528            Build treeview and append results.
529            """
530            lsmodel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING,
531                                    gobject.TYPE_STRING, gobject.TYPE_STRING)
532            tview = gtk.TreeView(lsmodel)
533            columns = 4
534            columns_text = ( _("Inventory"), _("Host"), 
535                             _("First Matched Category"), _("Entry Date") )
536            tview.columns = [None]*columns
537       
538            for n in range(columns):
539                tview.columns[n] = gtk.TreeViewColumn(columns_text[n])
540                tview.append_column(tview.columns[n])
541                tview.columns[n].cell = gtk.CellRendererText()
542                tview.columns[n].pack_start(tview.columns[n].cell, True)
543                tview.columns[n].set_attributes(tview.columns[n].cell, text=n)
544               
545            # connect method for handling selection
546            tview.connect('row-activated', row_activated)
547
548            # layout
549            matches = len(args[1])
550            plural = (matches > 1 or matches == 0) and 's' or ''
551            upper_title = gtk.Label()
552            upper_title.set_markup(_("<b>%d result%s found.</b>" % (matches,
553                                                                    plural)))
554            upper_title.show()
555            hutbox = HIGHBox()
556            hutbox._pack_noexpand_nofill(upper_title)
557            hutbox.show()
558            tview.show()
559            sw = HIGScrolledWindow()
560            sw.add(tview)
561            sw.show()
562            vbox = gtk.VBox()
563            vbox.pack_start(hutbox, False, False, 3)
564            vbox.pack_start(sw, True, True, 0)
565            vbox.show()
566
567            # append results to treeview
568            results = args[1]
569            for i in range(len(results)): # get ordered results
570                # get inventory name
571                invname = self.invdb.get_inventory_name_for_id(results[i][0])
572               
573                lsmodel.append((invname, results[i][1], results[i][3],
574                                str(results[i][2])))
575         
576            title = _("Search: %s") % args[0]
577            tab_label = HIGAnimatedTabLabel(title)
578            tab_label.connect("close-clicked", close_page, vbox)
579            self.viewernb.append_page(vbox, tab_label)
580
581
582        if buildnow:
583            # uhm.. nice, we already have the results.
584            buildtv(query, returned)
585           
586        else:
587            index = gen_index(len(returned)) # max results = number of hosts
588            results = { }
589            host_matches = { }
590            # no results yet, will get them now!
591            for key, values in returned.items():
592                host_id = key
593                inv_id = values[0]
594                host_addr = values[1]
595                date = values[2]
596                res = self.invsearch.search(host_id, query)
597                if res: # res == category
598                    if host_matches.has_key(host_addr):
599                        if inv_id in host_matches[host_addr]:
600                            # host already matched
601                            continue
602                        else:
603                            # host already on results, but for different
604                            # inventory. mark this new inventory as "used"
605                            # now.
606                            new_invlist = host_matches[host_addr]
607                            new_invlist.append(inv_id)
608                            host_matches[host_addr] = new_invlist
609                    else:
610                        # first time host matched search_text, add the
611                        # inventory that this host belongs to the host_matches.
612                        host_matches[host_addr] = [inv_id, ]
613                     
614                    results[index.next()] = (inv_id, host_addr, date, res)
615                   
616            # build treeview now
617            buildtv(query, results)               
618
619       
620    def _clear_statusbar(self):
621        """
622        Clear statusbar.
623        """
624        self.statusbar.pop(self.sbcid)
625        self.tip_timer = -1
626        return False
627   
628
629    def _create_ui_manager(self):
630        """
631        Set up user interface.
632        """
633        self.ui_manager = gtk.UIManager()
634        self.main_action_group = gtk.ActionGroup("MainActionGroup")
635
636        sched_icon, sched_text = self._scheduler_status_ret()
637        if sched_icon == gtk.STOCK_YES:
638            self.scheduler_running = True
639        else:
640            self.scheduler_running = False
641            self.statusbar.pop(self.sbcid)
642            self.statusbar.push(self.sbcid, _("Scheduler is not running!"))
643       
644        main_actions = [ \
645            ("File", None, _("_File"), None),
646            ("Edit", None, _("_Edit" ), None),
647            ("ToolbarOpt", None, _("Tool_bar"), None),
648            ("InvTabs", None, _("_Tabs"), None),
649            ("Inventory", None, _("_Inventories"), None),
650
651            # File
652            ("New", gtk.STOCK_NEW, _("_New Inventory"), None,
653             _("Create new Inventory"), self._create_new),
654           
655            ("CloseHostTab", None, _("Close Host tab"), "<Control>W",
656             _("Close current host tab"), self._close_current_hosttab),
657           
658            ("CloseInvTab", None, _("Close Inventory tab"), 
659             "<Shift><Control>W", _("Close current Inventory tab"), 
660             self._close_current_invtab),
661           
662            ("Quit", gtk.STOCK_QUIT, _("_Quit"), None,
663             _("Close Network Inventory"), self._exit_ni),
664           
665            # Edit/ToolbarOpt
666            ("TBIcon", None, _("Icons only"), None,
667             _("Show only icons in Toolbar"), lambda i: \
668             self.ui_manager.get_widget("/Toolbar").set_style(gtk.TOOLBAR_ICONS)),
669
670            ("TBText", None, _("Text only"), None,
671             _("Show only text in Toolbar"), lambda i: \
672             self.ui_manager.get_widget("/Toolbar").set_style(gtk.TOOLBAR_TEXT)),
673           
674            ("TBBoth", None, _("Icons and text"), None,
675             _("Show icons and text in Toolbar"), lambda i: \
676             self.ui_manager.get_widget("/Toolbar").set_style(gtk.TOOLBAR_BOTH)),
677           
678            # Toolbar
679            ("Scheduler Status", sched_icon, 
680              sched_text, None, sched_text,
681              self._scheduler_control)
682        ]
683       
684        inventories = [ ]
685        invmenu = ''
686        schemas = ConfigParser()
687        schemas.read(Path.sched_schemas)
688        for section in schemas.sections():
689            for item in schemas.items(section):
690                if item[0] == 'addtoinv':
691                    if item[1] == '2':
692                        inventories.append((section, None, section, None,
693                                            _("Edit Inventory %s") % section,
694                                            self._edit_inventory))
695                        invmenu += "<menuitem action='%s' />" % section
696   
697        toggle_actions = [ \
698            # Edit
699            ("ShowTips", None,
700             _("Show Ti_ps"), None,
701             _("Enable disable tip showing"),
702             lambda c: self.set_write_tips(not self.write_tips),
703             self.write_tips),
704
705            # Edit/Notebooks
706            ("TabCloseBtn", None,
707             _("Place close button"), None,
708             _("Place a close button upon tab creation"),
709             lambda c: self.set_invnb_cbtn(not self.invnb_close_btn),
710             self.invnb_close_btn)
711        ]
712       
713        default_ui = """
714            <menubar>
715                <menu action='File'>
716                    <menuitem action='New' />
717                    <separator />
718                    <menuitem action='CloseHostTab' />
719                    <menuitem action='CloseInvTab' />
720                    <menuitem action='Quit' />
721                </menu>
722                <menu action='Edit'>
723                    <menu action='InvTabs'>
724                         <menuitem action='TabCloseBtn' />
725                    </menu>
726                    <menu action='Inventory'>
727                         %s
728                    </menu>
729                    <menuitem action='ShowTips' />
730                </menu>
731            </menubar>
732           
733            <toolbar>
734                <toolitem action='Scheduler Status' />
735                <separator />
736            </toolbar>
737            """ % invmenu
738
739        self.main_action_group.add_actions(main_actions)
740        self.main_action_group.add_actions(inventories)
741        self.main_action_group.add_toggle_actions(toggle_actions)
742
743        for action in self.main_action_group.list_actions():
744            action.set_accel_group(self.main_accel_group)
745            action.connect_accelerator()
746       
747        self.ui_manager.insert_action_group(self.main_action_group, 0)
748        self.ui_manager.add_ui_from_string(default_ui)
749       
750       
751    def _edit_inventory(self, event):
752        """
753        Open inventory for editing.
754        """
755        w = NewInventory(event.get_name(), edit_mode=True)
756        w.show_all()
757       
758   
759    def _scheduler_status_ret(self):
760        """
761        Return stock icon and text based on scheduler status.
762        """
763        try:
764            sched_f = os.path.join(os.path.split(Path.config_file)[0], "schedrunning")
765            pid = open(sched_f, 'r')
766            pid = int(pid.readlines()[0])
767            running = check_process(pid)
768            if not running:
769                os.remove(sched_f)
770                return (gtk.STOCK_NO, _("Stop Scheduler"))
771
772            return (gtk.STOCK_YES, _("Stop Scheduler"))
773        except IOError:
774            return (gtk.STOCK_NO, _("Start Scheduler"))
775       
776   
777    def _scheduler_control(self, event):
778        """
779        Stop/Start scheduler.
780        """
781        controller = Path.sched_control
782        # ToDo: run scheduler with sudo
783        if self._scheduler_status_ret()[0] == gtk.STOCK_NO:
784            subprocess.Popen([sys.executable, controller, 'start'])
785        else:
786            subprocess.Popen([sys.executable, controller, 'stop'])
787       
788        gobject.timeout_add(500, self._update_sched_status)
789       
790       
791    def _update_sched_status(self):
792        """
793        Update toolbutton for Scheduler Status.
794        """
795        sched_status = self.ui_manager.get_widget('/toolbar/Scheduler Status')
796        new_icon, new_text = self._scheduler_status_ret()
797        tooltips = gtk.Tooltips()
798        sched_status.set_tooltip(tooltips, new_text)
799        sched_status.set_label(new_text)
800        sched_status.set_stock_id(new_icon)
801
802        self.statusbar.pop(self.sbcid)
803        if new_icon == gtk.STOCK_NO:
804            self.statusbar.push(self.sbcid, _("Scheduler is not running!"))
805       
806        return False
807   
808       
809    def _create_new(self, event):
810        """
811        Open dialog for creating New Inventory.
812        """
813        w = NewInventory()
814        w.show_all()
815   
816
817    def _exit_ni(self, event):
818        """
819        Destroy window.
820        """
821        # do necessary cleanup before destroying window.
822        #if self.newtl.tdg.orig_timer != -1: # needs to do this for new timeline
823        #    gobject.source_remove(self.newtl.tdg.orig_timer)
824        if self.daddy:
825            self.daddy.running_ni = False
826        if self.tip_timer != -1:
827            gobject.source_remove(self.tip_timer)
828           
829        gobject.source_remove(self.timer_updater)
830        self.destroy()
831
832
833    def __check_for_updates(self):
834        """
835        Check for some possible visual update needed to be done.
836        """
837        # check for scheduler status change
838        prev_state = self.scheduler_running
839        possibly_new = self._scheduler_status_ret()[0]
840        if  possibly_new != prev_state:
841            self._update_sched_status()
842            self.scheduler_running = possibly_new
843       
844        # check for database changes
845        prev_stat = self.db_stat
846        try:
847            possibly_new = os.stat(umitdb).st_mtime
848        except OSError:
849            return True
850
851        if prev_stat != possibly_new:
852            #print "db changed"
853            self._update_viewer()
854            self.db_stat = possibly_new
855
856        # check for changes in schemas
857        prev_state = self.schema_stat
858        try:
859            possibly_new = os.stat(Path.sched_schemas).st_mtime
860        except OSError:
861            return True
862
863        if prev_state != possibly_new:
864            #print "schemas changed"
865            self._update_viewer()
866            self.schema_stat = possibly_new
867           
868        return True
869       
870
871    def __set_props(self):
872        """
873        Set window properties.
874        """
875        self.set_title(_("UMIT Network Inventory %s" % NI_VER))
876        # a size for testing
877        self.set_position(gtk.WIN_POS_CENTER)
878        width, height = gtk.gdk.get_default_root_window().get_size()
879        self.set_default_size((width*3)/4, (height*3)/4)
880       
881
882    def __do_layout(self):
883        """
884        Layout window widgets.
885        """
886        main_vbox = gtk.VBox()
887        main_hpaned = gtk.HPaned()
888        nb_tl_hpaned = gtk.HPaned()
889        tlbox = HIGHBox()
890        yahbox = HIGVBox()
891
892        menubar = self.ui_manager.get_widget('/menubar')
893        main_vbox.pack_start(menubar, False, False, 0)
894       
895        sched_bar = self.ui_manager.get_widget('/toolbar')
896        sched_bar.set_show_arrow(False)
897        sched_bar.set_style(gtk.TOOLBAR_ICONS)
898        toolbar = SearchBar(self, self.invdb)
899        toolbar_box = gtk.HBox()
900        toolbar_box.pack_start(sched_bar, False, False, 0)
901        toolbar_box.pack_start(toolbar, True, True, 0)
902        main_vbox.pack_start(toolbar_box, False, False, 0)
903
904        left_pane_box = gtk.VBox()
905        left_pane_box.pack_start(self.invtree, True, True, 0)
906       
907        main_hpaned.add1(left_pane_box)
908        main_hpaned.add2(nb_tl_hpaned)
909
910        # place inventories notebook in a scrolledwindow
911        nbscroll = gtk.ScrolledWindow()
912        nbscroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
913        nbscroll.add_with_viewport(self.invnb)
914        nb_tl_hpaned.pack1(nbscroll, True, False)
915
916       
917        self.viewernb.append_page(main_hpaned, gtk.Label(_(" Historic "))) 
918        self.viewernb.append_page(self.timeline, gtk.Label(_(" Timeline ")))
919
920        self.timeline.show_all()
921
922        main_vbox.pack_start(self.viewernb, True, True, 0)
923        main_vbox.pack_end(self.statusbar, False, False, 0)
924
925        self.add(main_vbox)
926   
927   
928    def get_write_tips(self):
929        """
930        Returns True if tips should be written at statusbar, otherwise, False.
931        """
932        return self.__wtips
933   
934   
935    def set_write_tips(self, write):
936        """
937        Sets to write tips or not at statusbar.
938        """
939        self.__wtips = write
940        if not self.write_tips:
941            self.statusbar.pop(self.sbcid)
942       
943       
944    def get_invnb_cbtn(self):
945        """
946        Returns True if Inventory tabs have a close button placed on them.
947        """
948        return self.__invcbtn
949   
950   
951    def set_invnb_cbtn(self, enable):
952        """
953        Sets to show or not close button in each Inventory tab.
954        """
955        self.__invcbtn = enable
956   
957   
958    # Properties
959    write_tips = property(get_write_tips, set_write_tips)
960    invnb_close_btn = property(get_invnb_cbtn, set_invnb_cbtn)
961   
962
963gobject.signal_new("inventory-activated", InventoryViewer,
964                   gobject.SIGNAL_RUN_LAST,
965                   gobject.TYPE_NONE,
966                   (gobject.TYPE_PYOBJECT,))
967
968
969if __name__ == "__main__":
970    w = InvViewer()
971    w.show_all()
972    w.connect('destroy', lambda q: gtk.main_quit())
973    gtk.main()
Note: See TracBrowser for help on using the browser.