~alexeftimie/+junk/indicator-sysmonitor

« back to all changes in this revision

Viewing changes to indicator-sysmonitor

  • Committer: Alex Eftimie
  • Date: 2011-05-04 18:09:27 UTC
  • mfrom: (4.2.10 indicator-sysmonitor)
  • Revision ID: alex@rosedu.org-20110504180927-p0j8t95rw0rgmpa3
merged Olivier Silver temps branch. Many thanks for the work. Releasing 0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/python
 
2
# coding: utf-8
2
3
import sys
3
4
import os
4
5
import json
 
6
from copy import deepcopy
5
7
from threading import Thread, Event
6
8
import subprocess
7
9
import time
10
12
logging.basicConfig(file=sys.stderr,level=logging.INFO)
11
13
import gobject
12
14
import gtk
 
15
import string
13
16
import appindicator
14
17
 
15
18
gtk.gdk.threads_init()
46
49
        free_mem = sum([int(i) for i in free_mem.split()])
47
50
        return 100 - 100 * float(free_mem) / float(total_mem)
48
51
 
 
52
    def _fetch_sensor(self, sensor_name):
 
53
        sensor_data = sensor_name.split('//')
 
54
 
 
55
        if (len(sensor_data) != 2):
 
56
            return 'N/A'
 
57
 
 
58
        sensor_item = sensor_data[1].replace('-', '.')
 
59
        postfix = ''
 
60
        if sensor_data[0] == 'hddtemp':
 
61
            sensor_cmd = 'netcat localhost 7634'
 
62
            netcat_value = subprocess.Popen(sensor_cmd, stdout=subprocess.PIPE, shell=True).communicate()[0].strip()
 
63
            sensor_value = ''
 
64
 
 
65
            for hd_data in self.parse_hddtemp_entries(netcat_value):
 
66
                if hd_data[0] == sensor_item:
 
67
                    sensor_value = hd_data[2] + '°' + hd_data[3]
 
68
        else:
 
69
            if sensor_data[0] == 'nvidia':
 
70
                if sensor_item == 'gputemp':
 
71
                    sensor_cmd = 'nvidia-settings -q [gpu:0]/GPUCoreTemp | grep "Attribute" | sed -e "s/.*: //g" -e "s/\.//g"'
 
72
                    postfix = '°C'
 
73
                elif sensor_item == 'fanspeed':
 
74
                    sensor_cmd = 'nvidia-settings -q [fan:0]/GPUCurrentFanSpeed | grep "Attribute" | sed -e "s/.*: //g" -e "s/\.//g"'
 
75
                    postfix = ' RPM'
 
76
                else:
 
77
                    sensor_cmd = None
 
78
            else:
 
79
                sensor_cmd = 'sensors -A ' + sensor_data[0] + " | grep -i '" + sensor_item + "' | cut -f 2 -d ':'  | awk '{print $1}'"
 
80
 
 
81
            sensor_value = subprocess.Popen(sensor_cmd, stdout=subprocess.PIPE, shell=True).communicate()[0].strip()
 
82
 
 
83
        if len(sensor_value):
 
84
            return sensor_value + postfix
 
85
        else:
 
86
            if sensor_cmd == None:
 
87
                logging.info('Sensor not supported: ' + sensor_name)
 
88
            else:
 
89
                logging.info('Sensor command failed:\n' + sensor_cmd)
 
90
            return 'N/A'
 
91
 
 
92
    def _get_sensors_to_fetch(self):
 
93
        fmt = string.Formatter()
 
94
        tokens = []
 
95
        for token in fmt.parse(self.parent.custom_text):
 
96
            tokens.append(str(token[1]))
 
97
 
 
98
        return tokens
 
99
 
49
100
    def _fetch(self):
50
 
        mem_pct = self._fetch_mem()
51
 
        cpu_pct = self._fetch_cpu()
52
 
        return {'cpu': '%2.0f%%' % cpu_pct,
53
 
            'mem': '%2.0f%%' % mem_pct,
54
 
        }
 
101
        res = {}
 
102
        for sensor in self._get_sensors_to_fetch():
 
103
            if sensor == 'cpu':
 
104
                res['cpu'] = '%2.0f%%' % self._fetch_cpu()
 
105
            elif sensor == 'mem':
 
106
                res['mem'] = '%2.0f%%' % self._fetch_mem()
 
107
            else:
 
108
                res[sensor] = '%s' % self._fetch_sensor(sensor)
 
109
 
 
110
        return res
55
111
 
56
112
    def _fetch_user(self, command):
57
113
        try:
64
120
          logging.error('Error running: '+command)
65
121
        return output
66
122
 
 
123
    def parse_hddtemp_entries(self, netcat_value):
 
124
        hddtemp_entries = []
 
125
 
 
126
        if len(netcat_value):
 
127
            for hd_row in netcat_value.strip('|').split('||'):
 
128
                hddtemp_entries.append(hd_row.split('|'))
 
129
 
 
130
        return hddtemp_entries
 
131
 
67
132
    def run(self):
68
133
        while(self.parent.alive.isSet()):
69
134
            if self.parent.mode_user:
74
139
                self.parent.update(data)
75
140
            time.sleep(self.parent.interval)
76
141
 
 
142
class SensorsListModel:
 
143
    def __init__(self, parent):
 
144
        self.ind_parent = parent
 
145
        self.tree_store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)
 
146
 
 
147
        # lib sensors
 
148
        for sensor_data in subprocess.Popen('sensors', stdout=subprocess.PIPE, shell=True).communicate()[0].split('\n\n'):
 
149
            sensor_name = None
 
150
            skip_line = False
 
151
            for line in sensor_data.split('\n'):
 
152
                if len(line):
 
153
                    if skip_line:
 
154
                        skip_line = False
 
155
                    else:
 
156
                        if sensor_name == None:
 
157
                            logging.info("New sensor found: " + line)
 
158
                            sensor_name = line
 
159
                            parent = self.tree_store.append(None, (sensor_name, None, False))
 
160
                            skip_line = True
 
161
                        else:
 
162
                            logging.info("Sensor entry: " + line)
 
163
                            self.tree_store.append(parent, (line, self.generate_sensor_item_name(sensor_name, line), False))
 
164
 
 
165
        # hddtemp
 
166
        hddtemp = subprocess.Popen('netcat localhost 7634', stdout=subprocess.PIPE, shell=True).communicate()[0].strip()
 
167
        if len(hddtemp):
 
168
            sensor_name = 'hddtemp'
 
169
            logging.info("New sensor found: " + sensor_name)
 
170
            parent = self.tree_store.append(None, (sensor_name, None, False))
 
171
            for hd_data in self.ind_parent.ind_parent.fetch.parse_hddtemp_entries(hddtemp):
 
172
                logging.info("Sensor entry: " + hd_data[0])
 
173
                self.tree_store.append(parent, (hd_data[0] + ' - ' + hd_data[1] + ' - ' + hd_data[2] + '°' + hd_data[3], self.generate_sensor_item_name(sensor_name, hd_data[0]), False))
 
174
 
 
175
        # nvidia GPU
 
176
        nvidia_model = subprocess.Popen("lspci | grep nVidia | sed -e 's/.*\[//g' -e 's/\].*//g'", stdout=subprocess.PIPE, shell=True).communicate()[0].strip()
 
177
        if len(nvidia_model):
 
178
            sensor_name = 'nvidia'
 
179
            logging.info("New sensor found: " + sensor_name)
 
180
            parent = self.tree_store.append(None, (sensor_name, None, False))
 
181
            self.tree_store.append(parent, (nvidia_model + ' - Temperature', self.generate_sensor_item_name(sensor_name, 'gputemp'), False))
 
182
            self.tree_store.append(parent, (nvidia_model + ' - Fan speed', self.generate_sensor_item_name(sensor_name, 'fanspeed'), False))
 
183
 
 
184
    def get_view(self):
 
185
        self.view = gtk.Frame('')
 
186
 
 
187
        self.vb = gtk.VBox(False, 3)
 
188
 
 
189
        self.tree_view = gtk.TreeView(self.tree_store)
 
190
 
 
191
        # setup the text cell renderer
 
192
        self.renderer = gtk.CellRendererText()
 
193
        self.renderer.set_property('editable', False)
 
194
 
 
195
        # sensor name render
 
196
        self.renderer1 = gtk.CellRendererText()
 
197
        self.renderer1.set_property('editable', False)
 
198
 
 
199
        # quick add checkbox render
 
200
        self.renderer2 = gtk.CellRendererToggle()
 
201
        self.renderer2.set_property('activatable', True)
 
202
        self.renderer2.connect('toggled', self.quick_add_cb_toggled, self.tree_store)
 
203
 
 
204
        # create columns
 
205
        self.column0 = gtk.TreeViewColumn('Sensor', self.renderer, text=0)
 
206
        self.column1 = gtk.TreeViewColumn('Identifier', self.renderer1, text=1)
 
207
        self.column2 = gtk.TreeViewColumn('', self.renderer2, active=2)
 
208
        self.tree_view.append_column(self.column0)
 
209
        self.tree_view.append_column(self.column1)
 
210
        self.tree_view.append_column(self.column2)
 
211
 
 
212
        self.tree_view.expand_all()
 
213
        self.vb.add(self.tree_view)
 
214
 
 
215
        self.add_bt = gtk.Button('Add selected sensors')
 
216
        self.add_bt.connect('clicked', self.update_custom_text)
 
217
        self.vb.add(self.add_bt)
 
218
 
 
219
        self.view.add(self.vb)
 
220
        self.view.show()
 
221
 
 
222
        return self.view
 
223
 
 
224
    def quick_add_cb_toggled(self, cell, path, tree_store):
 
225
        tree_store[path][2] = not tree_store[path][2]
 
226
        iter = tree_store.iter_children(tree_store.get_iter(path))
 
227
        while iter:
 
228
            tree_store.set_value(iter, 2, tree_store[path][2])
 
229
            iter = tree_store.iter_next(iter)
 
230
 
 
231
    def generate_sensor_item_name(self, sensor_name, sensor_item_label):
 
232
        return sensor_name + '//' + sensor_item_label.split(':')[0].lower().replace('.', '-')
 
233
 
 
234
    def update_custom_text(self, event=None):
 
235
        iter = self.tree_store.get_iter_root()
 
236
 
 
237
        while iter:
 
238
            iter_children = self.tree_store.iter_children(iter)
 
239
            while iter_children:
 
240
                if self.tree_store.get_value(iter_children, 2):
 
241
                    current_text = self.ind_parent.custom_entry.get_text()
 
242
                    to_add_value = '{' + self.tree_store.get_value(iter_children, 1) + '}'
 
243
                    if string.find(current_text, to_add_value) == -1:
 
244
                        self.ind_parent.custom_entry.set_text(current_text + ' ' + to_add_value)
 
245
                iter_children = self.tree_store.iter_next(iter_children)
 
246
 
 
247
            iter = self.tree_store.iter_next(iter)
 
248
 
77
249
class Preferences(gtk.Window):
78
250
    def __init__(self, parent):
79
251
        gtk.Window.__init__(self)
90
262
        hb = gtk.VBox()
91
263
        self.custom_radio = gtk.RadioButton(label='Customize output:')
92
264
        hb.pack_start(self.custom_radio)
93
 
        self.custom_entry = gtk.Entry(max=100)
 
265
        self.custom_entry = gtk.Entry()
94
266
        hb.pack_end(self.custom_entry)
95
267
        vb.add(hb)
96
268
 
115
287
 
116
288
        notebook.append_page(vb, gtk.Label('Advanced'))
117
289
 
 
290
        sensors_list = SensorsListModel(self)
 
291
        if sensors_list.tree_store.get_iter_root() != None:
 
292
            vb.add(sensors_list.get_view())
 
293
 
118
294
        vb = gtk.VBox()
119
295
        vb.pack_start(notebook)
120
296
        buttons = gtk.HButtonBox()
199
375
        self.ind.set_menu(self.menu)
200
376
 
201
377
        logging.info("Menu shown")
 
378
 
 
379
        self.load_settings()
 
380
 
202
381
        self.alive = Event()
203
382
        self.alive.set()
204
383
        self.fetch = StatusFetcher(self)
205
384
        self.fetch.start()
206
385
        logging.info("Fetcher started")
207
386
 
208
 
        self.load_settings()
209
 
 
210
387
    def update(self, data):
211
388
        try:
212
 
          label = self.custom_text.format(mem=data['mem'], cpu=data['cpu'])
213
 
          guide = self.custom_text.format(mem="0000%", cpu="0000%")
 
389
            label = self.custom_text.format(**data)
 
390
            cdata = deepcopy(data)
 
391
            cdata['mem'] = cdata['cpu'] = '000%'
 
392
            guide = self.custom_text.format(**cdata)
 
393
        except KeyError as e:
 
394
            logging.info(str(e) + ' not found in dataset')
 
395
            return
214
396
        except:
215
 
          label = 'Error: ' + self.custom_text
216
 
          guide = label
 
397
            label = 'Unknown error'
217
398
        self.last_data = data
 
399
        self.last_guide = guide
218
400
        self.update_text(label, guide)
219
401
 
220
402
    def update_text(self, text, guide):
221
403
        self.last_text = text
222
404
        self.last_guide = guide
223
 
        print text, guide
224
405
        self.ind.set_label(text, guide)
225
406
 
226
407
    def force_update(self):
275
456
 
276
457
if __name__ == "__main__":
277
458
    sys.exit(main(sys.argv))
278