~woutc/specto/specto-dbus-client

« back to all changes in this revision

Viewing changes to spectlib/plugins/watch_system_process.py

  • Committer: Jean-François Fortin Tam
  • Author(s): Wout Clymans
  • Date: 2008-07-22 23:22:49 UTC
  • Revision ID: jeff@kiki-20080722232249-l64srclhp6u6qyrw
WARNING: this commit contains all the significant changes that happened in a specto-woutc branch over the past year. Large change log follows. Some commit log lines were intentionally left out.

- A dialog with debug information is shown when specto has a system/programming error.
- Disable renaming watches in the listview, make it a Jump To action instead
- All mandatory fields have to be filled in now (add and edit watch)
- The error log now shows the lines in color according to the severity
- Better file size cache name
- Added more error-handling
- The filesize is now saved in a different cache file (not in watches.list), may fix issue 37?
- Icons are now shown in the combobox when you add a new watch (buggy, patches welcome)
- Improved the pop3, imap and gmail watches
- The gmail watch now saves what unread mails there already were last time
- Convert HTML entities for the web diff
- Moved some code so the file dialog will show faster
- A watch will be marked updated when you didn't clear it on quit.
- Removed double call to refresh the watch info
- Made a general gtkutil file where you can define widgets used in the edit and add watch windows
- Removed the class name from the logger
- Clear the watch when you open it using the balloon
- Make some watch names clearer
- Error log tab in notifier window
- Added "clear" button in the edit menu
- Show simple diff from webpage difference
- Console mode (specto --console or specto --console --help)
- Watch menu when you right-click a watch entry in the notifier window
- Ability to run a command when a watch is updated
- Ability to run a command when a watch is cleared
- Fields in the add and edit windows are now dynamic; when creating a new watch plugin, you don't have to write all the gui code anymore
- More space for the extra information in the info panel
- code cleanup
- use plugin-system

- Fix issue 150: Gmail.com - that address is disabled in Germany - hence you can't go to messages directly
- Fix issue 93: Gmail library can support no more than 19 new mails
- Fix issue 131: bombs on special characters
- Fix issue 134: harmonized colors
- Fix issue 119: don't let the log file get huge
- Fix issue 143: Site adress in "About" box is not clickable
- Fix issue 146: Per-watch option to prevent URL redirects; To use this option add "redirect = True" to the watch that is allowed to redirect
- Fix issue 145: abnormal behavior with ampersands in a web watch
- Fix issue 51: Specto stores passwords in plaintext (started keyring support)
- Fix issue 135: Proxy support (already proxy support for web watch)
- Fix issue 128: allow specifying a port for mail watches (add 'port = 323' to your watch config)
- Fix issue 132: removing a watch should remove its cache files
- Fix issue 136: Support specific folder monitor over IMAP (add 'folder = work' to your imap watch config)
- Fix issue 63: Google Reader Watch does not support more than 20 items
- Fix issue 39: POP3 & IMAP watches not on par with gmail watch's message counting logic
- Fix issue 100: gmail with google apps should point to the right domain when clicking Jump to
- Fix issue 95: statusbar should show something else when updates are done
- Fix issue 112: hide error log tabs when debug mode is deactivated
- Fix issue 101: show the import dialog after the file chooser
- Fix issue 114: removing a watch should show a confirmation dialog
- Fix issue 73: brackets in watch name lead to startup crash (brackets can now be used in the name!)
- Fix issue 69: startup fails due to wrong glade file path  
- Fix issue 12: provide more information
- Fix issue 13: watch list importing and exporting
- Fix issue 20: Organise specto source into modules
- Fix issue 33: ability to run a command instead of notifying
- Fix issue 54: freedesktop-compliant user directories
- Fix issue 72: "show in window list" preference is not saved
- Fix issue 77: don't mess up if ekiga's sound files are not present
- Fix issue 118: add http:// automatically for web watches (also @gmail.com added for gmail accounts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
# Specto , Unobtrusive event notifier
4
4
#
5
 
#       watch_process.py
 
5
#       watch_system_process.py
6
6
#
7
7
# Copyright (c) 2005-2007, Jean-François Fortin Tam
8
8
 
22
22
# Boston, MA 02111-1307, USA.
23
23
 
24
24
from spectlib.watch import Watch
 
25
import spectlib.config
25
26
from spectlib.i18n import _
26
 
from spectlib.process import ProcessList
27
 
 
28
 
import thread
29
 
import gtk, time
30
 
import os
31
 
 
32
 
class Process_watch(Watch):
 
27
 
 
28
type = "Watch_system_process"
 
29
type_desc = "Process"
 
30
icon = 'applications-system'
 
31
 
 
32
def get_add_gui_info():
 
33
    return [
 
34
            ("process", spectlib.gtkconfig.Entry("Process"))
 
35
           ]
 
36
 
 
37
 
 
38
class Watch_system_process(Watch):
33
39
    """ 
34
 
    Watch class that will check if a file was modified, removed or created. 
 
40
    Watch class that will check if a process is running or not. 
35
41
    """
36
 
    updated = False
37
 
    type = 3
38
42
    
39
 
    def __init__(self, refresh, process, specto, id,  name = _("Unknown Process Watch")):
40
 
        Watch.__init__(self, specto)
41
 
        self.name = name
42
 
        self.refresh = refresh
43
 
        self.process = process
44
 
        self.id = id
45
 
        self.error = False
46
 
        self.actually_updated=False
 
43
    def __init__(self, specto, id, values):
 
44
        
 
45
        watch_values = [ 
 
46
                        ( "process", spectlib.config.String(True) )
 
47
                       ]
 
48
        
 
49
        self.icon = icon
 
50
        self.open_command = ''
 
51
        self.type_desc = type_desc
 
52
        self.status = ""
 
53
                
 
54
        #Init the superclass and set some specto values
 
55
        Watch.__init__(self, specto, id, values, watch_values)
 
56
 
47
57
        self.running = self.check_process()
48
58
 
49
 
    def dict_values(self):
50
 
        return { 'name': self.name, 'refresh': self.refresh, 'process': self.process, 'type':3 }
51
 
       
52
 
    def start_watch(self):
53
 
        """ Start the watch. """
54
 
        self.thread_update()
55
 
        
56
 
    def thread_update(self):
57
 
        lock = thread.allocate_lock()
58
 
        lock.acquire()
59
 
        t=thread.start_new_thread(self.update,(lock,))
60
 
        while lock.locked():
61
 
            while gtk.events_pending():
62
 
                gtk.main_iteration()
63
 
            time.sleep(0.05)
64
 
        while gtk.events_pending():
65
 
            gtk.main_iteration()  
66
 
                
67
 
    def update(self, lock):
68
 
        """ See if a file was modified or created. """
69
 
        self.error = False
70
 
        self.specto.mark_watch_busy(True, self.id)
71
 
        self.specto.logger.log(_("Updating watch: \"%s\"") % self.name, "info", self.__class__)
72
 
        
 
59
 
 
60
    def update(self):
 
61
        """ See if a file was modified or created. """        
73
62
        try:
74
63
            process = self.check_process()
75
64
            if self.running and process == False:
76
65
                self.running = False
77
66
                self.updated = True
78
67
                self.actually_updated = True
 
68
                self.status = "Not running"
79
69
            elif self.running == False and process == True:
80
70
                self.running = True 
81
71
                self.actually_updated = True
82
 
            else: self.actually_updated=False
 
72
                self.status = "Running"
 
73
            else: 
 
74
                self.actually_updated=False
 
75
                self.status = "Unknown"
83
76
        except:
84
77
            self.error = True
85
78
            self.specto.logger.log(_("Watch: \"%s\" has an error") % self.name, "error", self.__class__)
86
79
        
87
 
        self.specto.mark_watch_busy(False, self.id)
88
 
        Watch.update(self, lock)
 
80
        Watch.timer_update(self)
89
81
        
90
82
    def check_process(self):
91
83
        """ see if the process is running or not """
96
88
        else:
97
89
            return False
98
90
        
99
 
    def set_process(self, process):
100
 
        self.process = process
 
91
    def get_gui_info(self):
 
92
        return [ 
 
93
                ('Name', self.name),
 
94
                ('Last updated', self.last_updated),
 
95
                ('Process', self.process),
 
96
                ('Status', self.status)
 
97
                ]
 
98
        
 
99
 
 
100
 
 
101
"""
 
102
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick
 
103
 
 
104
Manage Processes and a ProcessList under Linux.
 
105
"""
 
106
 
 
107
import os
 
108
import signal
 
109
 
 
110
class Process(object):
 
111
    """Represents a process"""
 
112
    def __init__(self, pid):
 
113
        """Make a new Process object"""
 
114
        self.proc = "/proc/%d" % pid
 
115
        pid,command,state,parent_pid = file(os.path.join(self.proc, "stat")).read().strip().split()[:4]
 
116
        command = command[1:-1]
 
117
        self.pid = int(pid)
 
118
        self.command = command
 
119
        self.state = state
 
120
        self.parent_pid = int(parent_pid)
 
121
        self.parent = None
 
122
        self.children = []
 
123
    def kill(self, sig = signal.SIGTERM):
 
124
        """Kill this process with SIGTERM by default"""
 
125
        os.kill(self.pid, sig)
 
126
    def __repr__(self):
 
127
        return "Process(pid = %r)" % self.pid
 
128
    def getcwd(self):
 
129
        """Read the current directory of this process or None for can't"""
 
130
        try:
 
131
            return os.readlink(os.path.join(self.proc, "cwd"))
 
132
        except OSError:
 
133
            return None
 
134
    
 
135
class ProcessList(object):
 
136
    """Represents a list of processes"""
 
137
    def __init__(self):
 
138
        """Read /proc and fill up the process lists"""
 
139
        self.by_pid = {}
 
140
        self.by_command = {}
 
141
        for f in os.listdir("/proc"):
 
142
            if f.isdigit():
 
143
                process = Process(int(f))
 
144
                self.by_pid[process.pid] = process
 
145
                self.by_command.setdefault(process.command, []).append(process)
 
146
        for process in self.by_pid.values():
 
147
            try:
 
148
                parent = self.by_pid[process.parent_pid]
 
149
                parent.children.append(process)
 
150
                process.parent = parent
 
151
            except KeyError:
 
152
                pass
 
153
    def named(self, name):
 
154
        """Returns a list of processes with the given name"""
 
155
        return self.by_command.get(name, [])
 
 
b'\\ No newline at end of file'