167 lines
5.6 KiB
Python
167 lines
5.6 KiB
Python
# This python file use the following encoding: utf-8
|
|
|
|
from operator import itemgetter
|
|
import psutil
|
|
|
|
import e
|
|
|
|
from efl import ecore
|
|
from efl import evas
|
|
from efl import edje
|
|
from efl.evas import EXPAND_BOTH, FILL_BOTH
|
|
from efl import elementary as elm
|
|
|
|
|
|
__gadget_name__ = 'CPU Monitor'
|
|
__gadget_vers__ = '0.2'
|
|
__gadget_auth__ = 'DaveMDS'
|
|
__gadget_mail__ = 'dave@gurumeditation.it'
|
|
__gadget_desc__ = 'Multicore CPU monitor'
|
|
__gadget_vapi__ = 2
|
|
__gadget_opts__ = { 'popup_on_desktop': False }
|
|
|
|
|
|
# def DBG(msg):
|
|
# print("CPU: %s" % msg)
|
|
# sys.stdout.flush()
|
|
|
|
|
|
class Gadget(e.Gadget):
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
self.num_cores = len(psutil.cpu_percent(interval=0, percpu=True))
|
|
self.aspect = None
|
|
self.main_poller = None
|
|
self.popups_poller = None
|
|
self.popups_itc = elm.GenlistItemClass(item_style='default',
|
|
text_get_func=self.gl_text_get,
|
|
content_get_func=self.gl_content_get)
|
|
|
|
def instance_created(self, obj, site):
|
|
super().instance_created(obj, site)
|
|
|
|
if self.aspect is None:
|
|
w, h = obj.data_get('aspect_w'), obj.data_get('aspect_h')
|
|
self.aspect = int(w), int(h)
|
|
|
|
obj.data['bars'] = list()
|
|
for i in range(self.num_cores):
|
|
bar = edje.Edje(obj.evas, size_hint_expand=EXPAND_BOTH,
|
|
size_hint_fill=FILL_BOTH)
|
|
e.theme_object_set(bar, 'cpu', 'bar')
|
|
obj.part_box_append('main.box', bar)
|
|
bar.show()
|
|
obj.data['bars'].append(bar)
|
|
|
|
obj.size_hint_aspect = (evas.EVAS_ASPECT_CONTROL_BOTH,
|
|
self.aspect[0] * self.num_cores, self.aspect[1])
|
|
|
|
if self.main_poller is None:
|
|
self.main_poller = ecore.Poller(8, self.main_poller_cb)
|
|
|
|
def instance_destroyed(self, obj):
|
|
super().instance_destroyed(obj)
|
|
|
|
if len(self._instances) < 1 and self.main_poller is not None:
|
|
self.main_poller.delete()
|
|
self.main_poller = None
|
|
|
|
def main_poller_cb(self):
|
|
percents = psutil.cpu_percent(interval=0, percpu=True)
|
|
|
|
for obj in self._instances:
|
|
for i, bar in enumerate(obj.data['bars']):
|
|
bar.message_send(0, percents[i])
|
|
|
|
return ecore.ECORE_CALLBACK_RENEW
|
|
|
|
def popup_created(self, elm_parent):
|
|
table = elm.Table(elm_parent)
|
|
table.show()
|
|
|
|
en = elm.Entry(table, single_line=True, editable=False)
|
|
en.text_style_user_push("DEFAULT='font_weight=Bold'")
|
|
table.pack(en, 0, 0, 1, 1)
|
|
en.show()
|
|
|
|
li = elm.Genlist(table, homogeneous=True, mode=elm.ELM_LIST_COMPRESS,
|
|
select_mode=elm.ELM_OBJECT_SELECT_MODE_NONE,
|
|
size_hint_expand=EXPAND_BOTH, size_hint_fill=FILL_BOTH)
|
|
table.pack(li, 0, 1, 1, 1)
|
|
li.show()
|
|
|
|
rect = evas.Rectangle(table.evas, color=(0,0,0,0),
|
|
size_hint_min=(300,300))
|
|
table.pack(rect, 0, 1, 1, 1)
|
|
|
|
table.data['head'] = en
|
|
table.data['list'] = li
|
|
|
|
self.popups_poller_cb()
|
|
if self.popups_poller is None:
|
|
self.popups_poller = ecore.Poller(16, self.popups_poller_cb)
|
|
self.popup_update(table)
|
|
|
|
return table
|
|
|
|
def popup_destroyed(self, popup):
|
|
if len(self._popups) < 1 and self.popups_poller is not None:
|
|
self.popups_poller.delete()
|
|
self.popups_poller = None
|
|
|
|
def popup_update(self, popup):
|
|
li = popup.data['list']
|
|
|
|
# adjust the size (items count) of the genlist
|
|
items_count = li.items_count()
|
|
procs_count = len(self.top_procs)
|
|
if procs_count > items_count:
|
|
for idx in range(items_count, procs_count):
|
|
li.item_append(self.popups_itc, idx)
|
|
elif procs_count < items_count:
|
|
for idx in range(procs_count, items_count):
|
|
li.last_item.delete()
|
|
|
|
# update visible list items and the header text
|
|
li.realized_items_update()
|
|
popup.data['head'].text = '{} Running processes'.format(procs_count)
|
|
|
|
def popups_poller_cb(self):
|
|
# build an orderd list of all running procs (pid, name, cpu_perc, mun_t)
|
|
if psutil.version_info[0] < 2:
|
|
self.top_procs = [ (p.pid, p.name,
|
|
p.get_cpu_percent(interval=0) / self.num_cores,
|
|
p.get_num_threads())
|
|
for p in psutil.process_iter() ]
|
|
else:
|
|
self.top_procs = [ (p.pid, p.name(),
|
|
p.cpu_percent(interval=0) / self.num_cores,
|
|
p.num_threads())
|
|
for p in psutil.process_iter() ]
|
|
self.top_procs.sort(key=itemgetter(2), reverse=True)
|
|
|
|
# update all the visible popups
|
|
for popup in self._popups:
|
|
self.popup_update(popup)
|
|
|
|
return ecore.ECORE_CALLBACK_RENEW
|
|
|
|
def gl_text_get(self, gl, part, idx):
|
|
pid, name, cpu, num_t = self.top_procs[idx]
|
|
if num_t > 1:
|
|
return '[{}] {} ({} threads)'.format(pid, name, num_t)
|
|
else:
|
|
return '[{}] {}'.format(pid, name)
|
|
|
|
def gl_content_get(self, gl, part, idx):
|
|
pid, name, cpu, num_t = self.top_procs[idx]
|
|
if part == 'elm.swallow.end':
|
|
return elm.Label(gl, text='{0:.1f} %'.format(cpu))
|
|
if part == 'elm.swallow.icon':
|
|
try:
|
|
return elm.Icon(gl, standard=name)
|
|
except RuntimeWarning: # icon not found
|
|
return None
|