Merge lp:~kylehuff/awn-extras/0.4-bandwidth-monitor into lp:~awn-extras/awn-extras/extras-trunk-rewrite-and-random-breakage

Proposed by Kyle L. Huff
Status: Merged
Approved by: Mark Lee
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~kylehuff/awn-extras/0.4-bandwidth-monitor
Merge into: lp:~awn-extras/awn-extras/extras-trunk-rewrite-and-random-breakage
Diff against target: 1546 lines (+1481/-0)
10 files modified
applets/Makefile.am (+1/-0)
applets/maintained/bandwidth-monitor/CHANGELOG (+126/-0)
applets/maintained/bandwidth-monitor/Makefile.am (+16/-0)
applets/maintained/bandwidth-monitor/TODO (+19/-0)
applets/maintained/bandwidth-monitor/awn-applet-bandwidth-monitor.schema-ini (+40/-0)
applets/maintained/bandwidth-monitor/awn-bwm.py (+688/-0)
applets/maintained/bandwidth-monitor/bandwidth-monitor.desktop.in.in (+11/-0)
applets/maintained/bandwidth-monitor/bandwidth-monitor.ui (+300/-0)
applets/maintained/bandwidth-monitor/bwmprefs.py (+278/-0)
configure.ac (+2/-0)
To merge this branch: bzr merge lp:~kylehuff/awn-extras/0.4-bandwidth-monitor
Reviewer Review Type Date Requested Status
Mark Lee Approve
Michal Hruby (community) Approve
Review via email: mp+16747@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Mark Lee (malept) wrote :

> +Version=0.3.9.2

That's not what the Version key is for. Please see <http://standards.freedesktop.org/desktop-entry-spec/1.0/ar01s05.html>.

review: Needs Fixing (desktop file)
Revision history for this message
Michal Hruby (mhr3) wrote :

After looking over the repaint() method I see that the applet doesn't properly support side orientations, which is very bad, I know that you display text on the icon and it's pretty hard to deal with this when using side orientations, but the options I see are:
1) rotate the whole icon 90 degrees and display the text vertically
2) use smaller text size when using side orientation, so there's no need to have the icon wider than width of the panel
3) display only the graph when using side orient and don't show the overlay

review: Needs Fixing (orientation-support)
Revision history for this message
Mark Lee (malept) wrote :

> + i = 0
[...]
> + for device_pref in prefs:
> + dpv = device_pref.split("|")
> + if dpv[0] == model[path][0]:
> + ''' If the current column is 1 or 2, it is a checkbox,
> + so transpose from bool to int '''
> + dpv[col_number] = parameter
> + prefs[i] = "%s|%s|%s|%s|%s" % (dpv[0], dpv[1], dpv[2], dpv[3], dpv[4])
> + i += 1

Because I'm a pedant, this could be rewritten as follows:

for i, device_pref in enumerate(prefs):
    dpv = device_pref.split('|')
    if dpv[0] == model[path][0]:
        ''' If the current column is 1 or 2, it is a checkbox,
        so transpose from bool to int '''
        dpv[col_number] = parameter
        prefs[i] = '|'.join(dpv)

Revision history for this message
Mark Lee (malept) wrote :

+ gobject.timeout_add(1000, self.update_net_stats)

You should use gobject.timeout_add_seconds when possible. See <http://live.gnome.org/GnomeGoals/UseTimeoutAddSeconds>.

An example of backwards-compatible usage in Python is available in the digital-clock applet: <http://bazaar.launchpad.net/~awn-extras/awn-extras/extras-trunk-rewrite-and-random-breakage/annotate/1406/src/digitalClock/digitalClock.py#L42>.

review: Needs Fixing (saving-the-world)
1861. By Kyle L. Huff <kylehuff@slaveduo>

bandwidth monitor applet -
    removed edits to un-related Makefile

1862. By Kyle L. Huff <kylehuff@slaveduo>

bandwidth monitor applet -
    Removed LICENSE file - provided by AWN
    Fixed desktop file version
    Removed "Encoding" from desktop file
    Improved logic for setting device preference values per Mark Lee's suggestion
    Added timeout_add_seconds wrapper function
    Adjusted width calculation if orientation is vertical

Revision history for this message
Kyle L. Huff (kylehuff) wrote :

I have committed fixes for the review items above;

- Desktop file has been corrected
- Correct repaint to account for vertical orientations
- Improvements to the device preference parsing committed
- Changed instances of timeout_add that have a whole-number timeout greater than or equal to 1 to use tmeout_add_seconds

1863. By Kyle L. Huff <kylehuff@slaveduo>

bandwidth monitor applet -
    Change version string to use awn.extras.__version__
    Shortened orientation logic 'if' statement
    Changed email address

1864. By Kyle L. Huff <kylehuff@slaveduo>

bandwidth monitor applet -
    Minor syntax changes
    More vertical orientation fixes (font size)

1865. By Kyle L. Huff <kylehuff@slaveduo>

bandwidth monitor applet -
    Changed loading default settings from applet.settings.load() to applet.settings.load_preferences()

Revision history for this message
Michal Hruby (mhr3) wrote :

Overlay font-size on side orients is fine now, but it doesn't change to the original size when it's switched back to top/bottom orient.

review: Needs Fixing (orientation-support)
1866. By Kyle L. Huff <kylehuff@slaveduo>

bandwidth monitor applet -
   Removed settings.load/load_preferences
   Fix for applet/font-sizing when changing orientation

Revision history for this message
Kyle L. Huff (kylehuff) wrote :

> Overlay font-size on side orients is fine now, but it doesn't change to the
> original size when it's switched back to top/bottom orient.

This should be fixed in r1866

1867. By Kyle L. Huff <kylehuff@slaveduo>

bandwidth monitor applet -
    Changed instantiation of color objects to use gtk.gdk.color_parse instead of gtk.gdk.Color('#XXX') for older systems
    Changed handling of default preferences/unassigned keys

Revision history for this message
Michal Hruby (mhr3) wrote :

No more blocking problems from my side, though I did notice that on my system the redrawing doesn't feel smooth, it's like it updates every second, but from time to time it completely skips a frame. Anyone else seeing this?

review: Approve
1868. By Kyle L. Huff <kylehuff@slaveduo>

bandwidth monitor applet -
    PEP8 cleanup of all lines > 80 chars
    Rename of classes/variables for space/consistency
    Change of timer values for consistent drawing.
    Removed some unused modules.
    Removed 'blank.png' - initial icon is now created with gtk.gdk.pixbuf_new_from_xpm_data()

1869. By Kyle L. Huff <kylehuff@slaveduo>

bandwidth monitor applet -
    Removed reference to blank.png from Makefile.am

Revision history for this message
Mark Lee (malept) wrote :

Here's some things that I noted in my last round of reviewing the merge request:
* what are the valid values for ``DEFAULT/unit``? Presumably (currently) deals with bits vs. bytes? This should probably be documented in the description.
* is ``DEFAULT/draw_threshold`` dependent upon ``DEFAULT/unit``?
* I don't remember if you had problems with desktopagnostic.Color, but you can use that in place of #abcdef|0.5 config values
* something to think about post-merge, pre-0.4.0: i18n (gettext) / l10n support
* bwmprefs.py doesn't need the shebang (``#!``) line
* update your copyright statements to 2010 :)

review: Needs Fixing (minor)
Revision history for this message
Mark Lee (malept) wrote :

> Here's some things that I noted in my last round of reviewing the merge
> request:
> * what are the valid values for ``DEFAULT/unit``? Presumably (currently) deals
> with bits vs. bytes? This should probably be documented in the description.
> * is ``DEFAULT/draw_threshold`` dependent upon ``DEFAULT/unit``?
> * I don't remember if you had problems with desktopagnostic.Color, but you can
> use that in place of #abcdef|0.5 config values
> * something to think about post-merge, pre-0.4.0: i18n (gettext) / l10n
> support
> * bwmprefs.py doesn't need the shebang (``#!``) line
> * update your copyright statements to 2010 :)

I've handled everything except the desktopagnostic.Color point in my branch:
lp:~awn-extras/awn-extras/0.4-bwm-minor-fixes

I've also fixed a typo and a small error in the build system.

Please review and merge into your branch :)

Revision history for this message
Mark Lee (malept) wrote :

In order to speed up the "Merge 0.4 into trunk" task, I'm approving this merge (specifically, of my modified branch of awn-bwm) and adding Kyle to awn-extras so that he can potentially fix any of the bugs I introduced in my branch, in addition to the usual maintainership responsibilities :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'applets/Makefile.am'
2--- applets/Makefile.am 2009-11-15 21:40:13 +0000
3+++ applets/Makefile.am 2010-01-16 19:06:14 +0000
4@@ -52,6 +52,7 @@
5 SUBDIRS = \
6 maintained/animal-farm \
7 maintained/awnterm \
8+ maintained/bandwidth-monitor \
9 maintained/battery \
10 maintained/cairo-clock \
11 maintained/comics \
12
13=== added directory 'applets/maintained/bandwidth-monitor'
14=== added file 'applets/maintained/bandwidth-monitor/CHANGELOG'
15--- applets/maintained/bandwidth-monitor/CHANGELOG 1970-01-01 00:00:00 +0000
16+++ applets/maintained/bandwidth-monitor/CHANGELOG 2010-01-16 19:06:14 +0000
17@@ -0,0 +1,126 @@
18+01/05/2010:
19+ PEP8 cleanup of all lines > 80 chars
20+ Rename of classes/variables for space/consistency
21+ Change of timer values for consistent drawing.
22+ Removed some unused modules.
23+ Removed 'blank.png' - initial icon is now created with gtk.gdk.pixbuf_new_from_xpm_data()
24+
25+01/03/2010:
26+ Removed settings.load/load_preferences
27+ Fix for applet/font-sizing when changing orientation
28+ Changed instantiation of color objects to use gtk.gdk.color_parse instead of gtk.gdk.Color('#XXX') for older systems
29+ Changed handling of default preferences/unassigned keys
30+
31+
32+01/02/2010:
33+ Fixed bug which caused the unit of measure checkbutton to become out of sync with the gconf value
34+ Changed default interface to '', was wlan0 for some reason..
35+ PEP8 verified - mostly complaint, a few lines are "too long"
36+ Replaced icon
37+ Removed LICENSE file - provided by AWN
38+ Fixed desktop file version
39+ Removed "Encoding" from desktop file
40+ Improved logic for setting device preference values per Mark Lee's suggestion
41+ Added timeout_add_seconds wrapper function
42+ Adjusted width calculation if orientation is vertical
43+ Change version string to use awn.extras.__version__
44+ Changed email address
45+
46+12/20/2009:
47+ Change logic to graph calculation which corrects the following rendering issues -
48+ Graph lines drawing outside of border/frame
49+ Graph normalised top-value was rendering off-screen when applet size smaller than 35
50+ Graph normalised top-value was rendering very low on the graph when applet size greater than 60
51+ Changed scaling of initial icon - it was rendering too large and centered text was displayed with an odd alignment to the dock
52+ Fixed some issues with default values
53+ Changed short-name to 'bandwidth-monitor' to match schema file
54+ Corrected path to UI file
55+ Fixed division by zero error
56+ Addedd bandwidth-monitor.ui and bwmprefs.py to Makefile.am
57+
58+12/19/2009:
59+ Added preferences to control -
60+ Enable/Disable drawing of the background
61+ Enable/Disable drawing of the border
62+ Select color/opacity of background
63+ Select color/opacity of border
64+ Options to control the text representation of throughput
65+ Display Upload/Download text
66+ Display Sum text only
67+ Do not display text - only draw the graph.
68+ Enable/Disable drawing the zero value in the graph (if true, draw a line at the bottom of the graph for zero value)
69+
70+12/18/2009:
71+ Cleaned up code to make it run faster or use less resources
72+ Removed everything related to the status of interfaces (Not required, may add later)
73+ Removed everything related to IP Addresses for interfaces (Not required, may add later)
74+
75+12/16/2009:
76+ Added call to applet.errors.general if read access to /proc/net/dev fails.
77+ Made changes to TODO file
78+ Change parser logic for to handle interfaces with less than 11 columns of output in 'netstat -iea'
79+
80+12/14/2009:
81+ Created preferences dialog to manage options -
82+ An option to select the unit Bytes/bits
83+ A spinbutton entry for setting the minimum threshold
84+ A "Devices" pref-pane which allows selection of interfaces into virtual interfaces
85+ A color picker for upload and download colors for use in the line-graph.
86+ Fixed division by zero that would occur in some scenarios.
87+
88+12/10/2009:
89+ Added virtual interfaces for SUM and MULTI
90+ The Sum Interface is a virtual interface which displays the sum throughput of all interfaces that are selected for "Sum"
91+ The Multi Interface is a virtual interface which displays each individual throughput of the interfaces that are selected for "Multi", each with the colors defined for the interface.
92+ Added logic to parse and use preferences that are planned
93+
94+11/29/2009:
95+ Changed table generation function to be less verbose
96+ Fixed regular expression for gathering IP/Netmask
97+ Changed IP/Netmask tooltip logic
98+ Changed command for device stats gathering to include administratively down-interfaces
99+
100+11/28/2009:
101+ pep8 verified main program file
102+ Added a few non-parsed comments to the source file
103+
104+11/28/2009:
105+ Changed initial ratio value to 1 to prevent the graphs from ignoring data transfers below 3200 bytes
106+ Changed the graph scaling to display the line graph almost center of the graph window below 6400 bytes
107+ Added items to the TODO list
108+
109+11/27/2009:
110+ Filter out the wmaster0 interface.
111+ Applied patch from onox:
112+ Renamed some classes
113+ Removed functions for things abstracted by AWN
114+ Cleaned up some of the syntax
115+ Cleaned up some naming conventions
116+ Created a new branch repository (previous was setup wrong): lp:~kylehuff/awn-extras/0.4-bandwidth-monitor
117+
118+11/27/2009:
119+ Applied patch from mhr3 which included -
120+ Changes to applet short-name
121+ Changes to Makefile.am
122+ Fixed spelling of "CHANGLOG" to "CHANGELOG"
123+ Renamed awn-bwm.schema-ini to awn-applet-bwm.schema-ini
124+ Changed the application of the cairo surface to use applet.set_icon_context()
125+ Fixed bug which caused rendering the scale of the upload speed off-screen
126+ Removed references to some obsolete functions/methods/properties
127+
128+11/25/2009:
129+ Eliminated usage of 'ifconfig' command - moved everything to netstat
130+ Bumped to version v0.3.9.2
131+ Created launchpad branch - lp:~kylehuff/awn-extras/awn-bwm
132+
133+11/24/2009:
134+ Converted text to OverlayText()
135+ Cleaned up some functions
136+ Bumped version to v0.3.9.1
137+
138+11/23/2009:
139+ Implemented API v0.4
140+ Changed from v0.3.2.8 to v0.3.9.0
141+
142+04/18/2006:
143+ Original release - 0.1
144
145=== added file 'applets/maintained/bandwidth-monitor/Makefile.am'
146--- applets/maintained/bandwidth-monitor/Makefile.am 1970-01-01 00:00:00 +0000
147+++ applets/maintained/bandwidth-monitor/Makefile.am 2010-01-16 19:06:14 +0000
148@@ -0,0 +1,16 @@
149+APPLET_NAME = bandwidth-monitor
150+APPLET_MAIN_FILE = awn-bwm.py
151+include $(top_srcdir)/Makefile.python-applet
152+include $(top_srcdir)/Makefile.schemas
153+
154+dist_applet_DATA = \
155+ CHANGELOG \
156+ bwmprefs.py \
157+ bandwidth-monitor.ui \
158+ $(NULL)
159+
160+bwm_iconsdir = $(applet_datadir)/images
161+dist_bwm_icons_DATA = \
162+ images/icon.png \
163+ $(NULL)
164+
165
166=== added file 'applets/maintained/bandwidth-monitor/TODO'
167--- applets/maintained/bandwidth-monitor/TODO 1970-01-01 00:00:00 +0000
168+++ applets/maintained/bandwidth-monitor/TODO 2010-01-16 19:06:14 +0000
169@@ -0,0 +1,19 @@
170+TODO:
171+
172+--- Things that need to happen ---
173+None Left...
174+
175+--- Things I would like ---
176+Add preference control for applying effect to text (new default = True, always apply)
177+Auto select interface (maybe based on default route)
178+Add toggle for enable/disable auto-scaling (so 100Mbps would draw the line at the top of the meter)
179+
180+--- Completed TODO's ---
181+Create preference dialog for selecting the color of the line-graphs, as well as the background
182+ Done
183+Ability to select multiple (or all) devices for a sum throughput -
184+ Done (also created 'multi' interface)
185+Add preference for specifying minimum threshold for charting data
186+ Done
187+
188+
189
190=== added file 'applets/maintained/bandwidth-monitor/awn-applet-bandwidth-monitor.schema-ini'
191--- applets/maintained/bandwidth-monitor/awn-applet-bandwidth-monitor.schema-ini 1970-01-01 00:00:00 +0000
192+++ applets/maintained/bandwidth-monitor/awn-applet-bandwidth-monitor.schema-ini 2010-01-16 19:06:14 +0000
193@@ -0,0 +1,40 @@
194+[DEFAULT/unit]
195+type = integer
196+default = 0
197+description = The display unit for transfer speed
198+[DEFAULT/interface]
199+type = string
200+default =
201+description = The interface currently selected
202+[DEFAULT/draw_threshold]
203+type = float
204+default = 0.0
205+description = Minimum threshold to draw meter
206+[DEFAULT/device_display_parameters]
207+type = list-string
208+default = ;
209+description = Display parameters for interfaces
210+[DEFAULT/background]
211+type = boolean
212+default = true
213+description = Draw the applet background
214+[DEFAULT/background_color]
215+type = string
216+default = #000000|0.5
217+description = Color to draw the background
218+[DEFAULT/border]
219+type = boolean
220+default = false
221+description = Draw the applet border
222+[DEFAULT/border_color]
223+type = string
224+default = #000000|1.0
225+description = Color to draw the border
226+[DEFAULT/label_control]
227+type = integer
228+default = 2
229+description = Throughput label control - 0 = no label, 1 = Sum, 2 = Upload/Download
230+[DEFAULT/graph_zero]
231+type = integer
232+default = 0
233+description = If enabled this will draw a line at the bottom of the graph even if the value is 0. If unchecked, values below 1 are not drawn
234
235=== added file 'applets/maintained/bandwidth-monitor/awn-bwm.py'
236--- applets/maintained/bandwidth-monitor/awn-bwm.py 1970-01-01 00:00:00 +0000
237+++ applets/maintained/bandwidth-monitor/awn-bwm.py 2010-01-16 19:06:14 +0000
238@@ -0,0 +1,688 @@
239+#!/usr/bin/python
240+# -*- coding: utf-8 -*-
241+"""
242+bandwidth-monitor - Network bandwidth monitor.
243+Copyright (c) 2006-2009 Kyle L. Huff (awn-bwm@curetheitch.com)
244+url: <http://www.curetheitch.com/projects/awn-bwm/>
245+Email: awn-bwm@curetheitch.com
246+
247+ This program is free software: you can redistribute it and/or modify
248+ it under the terms of the GNU General Public License as published by
249+ the Free Software Foundation, either version 3 of the License, or
250+ (at your option) any later version.
251+
252+ This program is distributed in the hope that it will be useful,
253+ but WITHOUT ANY WARRANTY; without even the implied warranty of
254+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
255+ GNU General Public License for more details.
256+
257+ You should have received a copy of the GNU General Public License
258+ along with this program. If not, see <http://www.gnu.org/licenses/gpl.txt>.
259+"""
260+
261+from time import time
262+import os
263+import re
264+import sys
265+
266+
267+import gtk
268+import awn
269+
270+from awn.extras import awnlib, __version__
271+import gobject
272+import cairo
273+import bwmprefs
274+
275+APPLET_NAME = "Bandwidth Monitor"
276+APPLET_VERSION = "0.3.9.3"
277+APPLET_COPYRIGHT = "© 2006-2009 CURE|THE|ITCH"
278+APPLET_AUTHORS = ["Kyle L. Huff <awn-bwm@curetheitch.com>"]
279+APPLET_DESCRIPTION = "Network Bandwidth monitor"
280+APPLET_WEBSITE = "http://www.curetheitch.com/projects/awn-bwm/"
281+APPLET_PATH = os.path.dirname(sys.argv[0])
282+APPLET_ICON = APPLET_PATH + "/images/icon.png"
283+UI_FILE = os.path.join(os.path.dirname(__file__), "bandwidth-monitor.ui")
284+
285+
286+class Netstat:
287+
288+ def __init__(self, parent, unit):
289+ self.parent = parent
290+ self.ifaces = {}
291+ self.ifaces["Sum Interface"] = {"collection_time": 0,
292+ "status": "V",
293+ "prbytes": 0,
294+ "ptbytes": 0,
295+ "index": 1,
296+ "rx_history": [0, 0],
297+ "tx_history": [0, 0],
298+ "rx_bytes": 0,
299+ "tx_bytes": 0,
300+ "rx_sum": 0,
301+ "tx_sum": 0,
302+ "rxtx_sum": 0,
303+ "rabytes": 0,
304+ "tabytes": 0,
305+ 'sum_include': False,
306+ 'multi_include': False,
307+ 'upload_color': "#ff0000",
308+ 'download_color': "#ffff00"}
309+ self.ifaces["Multi Interface"] = {"collection_time": 0,
310+ "status": "V",
311+ "prbytes": 0,
312+ "ptbytes": 0,
313+ "index": 1,
314+ "rx_history": [0, 0],
315+ "tx_history": [0, 0],
316+ "rx_bytes": 0,
317+ "tx_bytes": 0,
318+ "rx_sum": 0,
319+ "tx_sum": 0,
320+ "rxtx_sum": 0,
321+ "rabytes": 0,
322+ "tabytes": 0,
323+ 'sum_include': False,
324+ 'multi_include': False}
325+ self.regenerate = False
326+ self.update_net_stats()
327+ gobject.timeout_add(800, self.update_net_stats)
328+
329+ def timeout_add_seconds(self, seconds, callback):
330+ if hasattr(gobject, 'timeout_add_seconds'):
331+ return gobject.timeout_add_seconds(seconds, callback)
332+ else:
333+ return gobject.timeout_add(seconds * 1000, callback)
334+
335+ def update_net_stats(self):
336+ ifcfg_str = os.popen("netstat -eia").read()
337+ if ifcfg_str:
338+ ifcfg_str = ifcfg_str.split("\n\n")
339+ stat_str = "n"
340+ devices = []
341+ ''' Reset the Sum Interface records to zero '''
342+ self.ifaces["Sum Interface"]["rx_sum"] = 0
343+ self.ifaces["Sum Interface"]["tx_sum"] = 0
344+ self.ifaces["Sum Interface"]["rx_bytes"] = 0
345+ self.ifaces["Sum Interface"]["tx_bytes"] = 0
346+ sum_rx_history = 0.0
347+ sum_tx_history = 0.0
348+ ''' Reset the Multi Interface records to zero '''
349+ self.ifaces["Multi Interface"]["rx_sum"] = 0
350+ self.ifaces["Multi Interface"]["tx_sum"] = 0
351+ self.ifaces["Multi Interface"]["rx_bytes"] = 0
352+ self.ifaces["Multi Interface"]["tx_bytes"] = 0
353+ multi_rx_history = 0.0
354+ multi_tx_history = 0.0
355+ if ifcfg_str and stat_str:
356+ for device_group in ifcfg_str:
357+ device_lines = device_group.split("\n")
358+ if "Kernel" in device_lines[0]:
359+ device_lines = device_lines[1:]
360+ iface = re.split('[\W]+',
361+ device_lines[0].strip().replace(":", "_"))[0]
362+ if len(device_lines) > 2:
363+ try:
364+ rx_bytes = float(re.search(r'RX bytes:(\d+)\D',
365+ device_group).group(1))
366+ tx_bytes = float(re.search(r'TX bytes:(\d+)\D',
367+ device_group).group(1))
368+ except:
369+ rx_bytes = 0
370+ tx_bytes = 0
371+ if not iface in self.ifaces:
372+ ddps = "device_display_parameters"
373+ prefs = self.parent.applet.settings[ddps]
374+ sum_include = True
375+ multi_include = True
376+ for device_pref in prefs:
377+ dpv = device_pref.split("|")
378+ if dpv[0] == iface:
379+ sum_include = str(dpv[1])[0].upper() == 'T'
380+ multi_include = str(dpv[2])[0].upper() == 'T'
381+ self.ifaces[iface] = {"collection_time": time(),
382+ "status": None,
383+ "prbytes": rx_bytes,
384+ "ptbytes": tx_bytes,
385+ "index": 1,
386+ "rx_history": [0, 0],
387+ "tx_history": [0, 0],
388+ "sum_include": sum_include,
389+ 'multi_include': multi_include,
390+ 'upload_color': \
391+ self.parent.prefs.get_color(iface, "upload"),
392+ 'download_color': \
393+ self.parent.prefs.get_color(iface, "download")}
394+ collection = (
395+ time() - self.ifaces[iface]["collection_time"])
396+ rbytes = ((rx_bytes - self.ifaces[iface]["prbytes"])
397+ * self.parent.unit) / collection
398+ tbytes = ((tx_bytes - self.ifaces[iface]["ptbytes"])
399+ * self.parent.unit) / collection
400+ rabytes = (rx_bytes - self.ifaces[iface]["prbytes"]) \
401+ / collection
402+ tabytes = (tx_bytes - self.ifaces[iface]["ptbytes"]) \
403+ / collection
404+ self.ifaces[iface]["rabytes"] = rabytes
405+ self.ifaces[iface]["tabytes"] = tabytes
406+ rxtx_sum = rx_bytes + tx_bytes
407+ if self.ifaces[iface]['sum_include']:
408+ self.ifaces["Sum Interface"]["rx_sum"] += rx_bytes
409+ self.ifaces["Sum Interface"]["tx_sum"] += tx_bytes
410+ self.ifaces["Sum Interface"]["rx_bytes"] += rbytes
411+ self.ifaces["Sum Interface"]["tx_bytes"] += tbytes
412+ sum_rx_history += rabytes
413+ sum_tx_history += tabytes
414+ if self.ifaces[iface]['multi_include']:
415+ self.ifaces["Multi Interface"]["rx_sum"] += rx_bytes
416+ self.ifaces["Multi Interface"]["tx_sum"] += tx_bytes
417+ self.ifaces["Multi Interface"]["rx_bytes"] += rbytes
418+ self.ifaces["Multi Interface"]["tx_bytes"] += tbytes
419+ multi_rx_history += rabytes
420+ multi_tx_history += tabytes
421+ ifstatus = "BRMU"
422+ self.ifaces[iface]["rx_bytes"] = rbytes
423+ self.ifaces[iface]["tx_bytes"] = tbytes
424+ self.ifaces[iface]["prbytes"] = rx_bytes
425+ self.ifaces[iface]["ptbytes"] = tx_bytes
426+ self.ifaces[iface]["rx_sum"] = rx_bytes
427+ self.ifaces[iface]["tx_sum"] = tx_bytes
428+ self.ifaces[iface]["rxtx_sum"] = rxtx_sum
429+ self.ifaces[iface]["status"] = ifstatus
430+ self.ifaces[iface]["collection_time"] = time()
431+ offset = self.parent.meter_scale - 1 \
432+ if self.parent.border else self.parent.meter_scale
433+ self.ifaces[iface]["rx_history"] = \
434+ self.ifaces[iface]["rx_history"][0 - offset:]
435+ self.ifaces[iface]["rx_history"].append(
436+ self.ifaces[iface]["rabytes"])
437+ self.ifaces[iface]["tx_history"] = \
438+ self.ifaces[iface]["tx_history"][0 - offset:]
439+ self.ifaces[iface]["tx_history"].append(
440+ self.ifaces[iface]["tabytes"])
441+ devices.append(iface)
442+ self.ifaces["Sum Interface"]["rx_history"] = \
443+ self.ifaces["Sum Interface"]["rx_history"][0 - offset:]
444+ self.ifaces["Sum Interface"]["rx_history"].append(sum_rx_history)
445+ self.ifaces["Sum Interface"]["tx_history"] = \
446+ self.ifaces["Sum Interface"]["tx_history"][0 - offset:]
447+ self.ifaces["Sum Interface"]["tx_history"].append(sum_tx_history)
448+ for dev in self.ifaces.keys():
449+ if not dev in devices and not "Sum Interface" in dev \
450+ and not "Multi Interface" in dev:
451+ ''' The device does not exist, remove it.
452+ del dictionary[key] is faster than dictionary.pop(key) '''
453+ del self.ifaces[dev]
454+ self.regenerate = True
455+ return True
456+
457+
458+class AppletBandwidthMonitor:
459+
460+ def __init__(self, applet):
461+ ''' Test if user has access to /proc/net/dev '''
462+ if not os.access('/proc/net/dev', os.R_OK):
463+ applet.errors.general(('Unable to caclulate statistics',
464+ 'Statistics calculation requires read access to /proc/net/dev'))
465+ applet.errors.set_error_icon_and_click_to_restart()
466+ return None
467+ self.applet = applet
468+ self.UI_FILE = UI_FILE
469+ applet.tooltip.set("Bandwidth Monitor")
470+ self.meter_scale = 25
471+ icon = gtk.gdk.pixbuf_new_from_xpm_data(["1 1 1 1",
472+ " c #000",
473+ " "])
474+ height = self.applet.get_size() * 1.5
475+ if height != icon.get_height():
476+ icon = icon.scale_simple(int(height), \
477+ int(height / 1.5), gtk.gdk.INTERP_BILINEAR)
478+ self.applet.set_icon_pixbuf(icon)
479+ self.dialog = applet.dialog.new("main")
480+ self.vbox = gtk.VBox()
481+ self.dialog.add(self.vbox)
482+ button = gtk.Button("Change Unit")
483+ self.dialog.add(button)
484+ defaults = {'unit': 8,
485+ 'interface': '',
486+ 'draw_threshold': 0.0,
487+ 'device_display_parameters': [],
488+ 'background': True,
489+ 'background_color': "#000000|0.5",
490+ 'border': False,
491+ 'border_color': "#000000|1.0",
492+ 'label_control': 2,
493+ 'graph_zero': 0}
494+ for key, value in defaults.items():
495+ if not key in self.applet.settings:
496+ self.applet.settings[key] = value
497+ self.iface = self.applet.settings['interface']
498+ self.unit = self.applet.settings['unit']
499+ self.label_control = self.applet.settings["label_control"]
500+ self.background = self.applet.settings['background']
501+ self.background_color = self.applet.settings['background_color']
502+ self.border = self.applet.settings['border']
503+ self.border_color = self.applet.settings['border_color']
504+ self.graph_zero = self.applet.settings['graph_zero']
505+ if not self.unit:
506+ self.change_unit(defaults['unit'])
507+ if self.applet.settings['draw_threshold'] == 0.0:
508+ self.ratio = 1
509+ else:
510+ ratio = self.applet.settings['draw_threshold']
511+ self.ratio = ratio * 1024 if self.unit == 1 else ratio * 1024 / 8
512+ self.prefs = bwmprefs.Preferences(self.applet, self)
513+ self.netstats = Netstat(self, self.unit)
514+ applet.tooltip.connect_becomes_visible(self.enter_notify)
515+ self.table = self.generate_table()
516+ self.vbox.add(self.table)
517+ self.upload_ot = awn.OverlayText()
518+ self.download_ot = awn.OverlayText()
519+ self.sum_ot = awn.OverlayText()
520+ self.upload_ot.props.gravity = gtk.gdk.GRAVITY_NORTH
521+ self.download_ot.props.gravity = gtk.gdk.GRAVITY_SOUTH
522+ self.sum_ot.props.gravity = gtk.gdk.GRAVITY_NORTH
523+ applet.add_overlay(self.upload_ot)
524+ applet.add_overlay(self.download_ot)
525+ applet.add_overlay(self.sum_ot)
526+ self.default_font_size = self.upload_ot.props.font_sizing
527+ self.upload_ot.props.y_override = 4
528+ self.download_ot.props.y_override = 18
529+ self.sum_ot.props.y_override = 11
530+ self.upload_ot.props.apply_effects = True
531+ self.download_ot.props.apply_effects = True
532+ self.sum_ot.props.apply_effects = True
533+ self.upload_ot.props.text = "Scanning"
534+ self.download_ot.props.text = "Devices"
535+ self.prefs.setup()
536+ ''' connect the left-click dialog button "Change Unit" to
537+ the call_change_unit function, which does not call
538+ self.change_unit directly, instead it toggles the "active"
539+ property of the checkbutton so everything that needs to
540+ happen, happens. '''
541+ button.connect("clicked", self.call_change_unit)
542+ gobject.timeout_add(100, self.first_paint)
543+ gobject.timeout_add(800, self.subsequent_paint)
544+
545+ def change_draw_ratio(self, widget):
546+ ratio = widget.get_value()
547+ self.ratio = ratio * 1024 if self.unit == 1 else ratio * 1024 / 8
548+ self.applet.settings["draw_threshold"] = ratio
549+
550+ def call_change_unit(self, *args):
551+ if self.unit == 8:
552+ self.prefs.uomCheckbutton.set_property('active', True)
553+ else:
554+ self.prefs.uomCheckbutton.set_property('active', False)
555+
556+ def change_unit(self, widget=None, scaleThresholdSBtn=None, label=None):
557+ self.unit = 8 if self.unit == 1 else 1
558+ ''' normalize and update the label, and normalize the spinbutton '''
559+ if label:
560+ if self.unit == 1:
561+ label.set_text("KBps")
562+ scaleThresholdSBtn.set_value(
563+ self.applet.settings["draw_threshold"] / 8)
564+ else:
565+ label.set_text("Kbps")
566+ scaleThresholdSBtn.set_value(
567+ self.applet.settings["draw_threshold"] * 8)
568+ self.applet.settings["unit"] = self.unit
569+
570+ def change_iface(self, widget, iface):
571+ if widget.get_active():
572+ ''' Changed to interface %s" % iface '''
573+ self.iface = iface
574+ self.applet.settings["interface"] = iface
575+
576+ def generate_table(self):
577+ table = gtk.Table(100, 100, False)
578+ col_iter = 0
579+ row_iter = 2
580+ for i in [0, 1, 2, 3, 4, 5, 6]:
581+ table.set_col_spacing(i, 20)
582+ table.attach(gtk.Label(""),
583+ 0, 1, 0, 1,
584+ xoptions=gtk.EXPAND | gtk.FILL,
585+ yoptions=gtk.EXPAND | gtk.FILL,
586+ xpadding=0, ypadding=0)
587+ table.attach(gtk.Label("Interface"),
588+ 1, 2, 0, 1,
589+ xoptions=gtk.EXPAND | gtk.FILL,
590+ yoptions=gtk.EXPAND | gtk.FILL,
591+ xpadding=0, ypadding=0)
592+ table.attach(gtk.Label("Sent"),
593+ 2, 3, 0, 1,
594+ xoptions=gtk.EXPAND | gtk.FILL,
595+ yoptions=gtk.EXPAND | gtk.FILL,
596+ xpadding=0, ypadding=0)
597+ table.attach(gtk.Label("Received"),
598+ 3, 4, 0, 1,
599+ xoptions=gtk.EXPAND | gtk.FILL,
600+ yoptions=gtk.EXPAND | gtk.FILL,
601+ xpadding=0, ypadding=0)
602+ table.attach(gtk.Label("Sending"),
603+ 4, 5, 0, 1,
604+ xoptions=gtk.EXPAND | gtk.FILL,
605+ yoptions=gtk.EXPAND | gtk.FILL,
606+ xpadding=0, ypadding=0)
607+ table.attach(gtk.Label("Receiving"),
608+ 5, 6, 0, 1,
609+ xoptions=gtk.EXPAND | gtk.FILL,
610+ yoptions=gtk.EXPAND | gtk.FILL,
611+ xpadding=0, ypadding=0)
612+ radio = None
613+ for iface in sorted(self.netstats.ifaces):
614+ widget = gtk.Label()
615+ widget.toggle = gtk.RadioButton(group=radio)
616+ radio = widget.toggle
617+ if iface == self.iface:
618+ widget.toggle.set_active(True)
619+ widget.toggle.connect("clicked", self.change_iface, iface)
620+ widget.name_label = gtk.Label(str(iface))
621+ widget.sent_label = gtk.Label(str(
622+ readable_speed(self.netstats.ifaces[iface]["tx_sum"],
623+ self.unit, False).strip()))
624+ widget.received_label = gtk.Label(str(
625+ readable_speed(self.netstats.ifaces[iface]["rx_sum"],
626+ self.unit, False).strip()))
627+ widget.tx_speed_label = gtk.Label(str(
628+ readable_speed(self.netstats.ifaces[iface]["tx_bytes"]
629+ * self.unit, self.unit).strip()))
630+ widget.rx_speed_label = gtk.Label(str(
631+ readable_speed(self.netstats.ifaces[iface]["rx_bytes"]
632+ * self.unit, self.unit).strip()))
633+ self.netstats.ifaces[iface]["widget"] = widget
634+ for widget_object in [widget.toggle,
635+ widget.name_label,
636+ widget.sent_label,
637+ widget.received_label,
638+ widget.tx_speed_label,
639+ widget.rx_speed_label]:
640+ table.attach(widget_object,
641+ col_iter, col_iter + 1,
642+ row_iter, row_iter + 1,
643+ xoptions=gtk.EXPAND | gtk.FILL,
644+ yoptions=gtk.EXPAND | gtk.FILL,
645+ xpadding=0, ypadding=0)
646+ col_iter += 1
647+ row_iter += 1
648+ col_iter = 0
649+ return table
650+
651+ def enter_notify(self):
652+ if not self.applet.dialog.is_visible("main"):
653+ if not self.iface in self.netstats.ifaces:
654+ self.applet.set_tooltip_text(
655+ "Please select a valid Network Device")
656+ else:
657+ self.applet.set_tooltip_text(
658+ "Total Sent: %s - Total Received: %s (All Interfaces)" % (
659+ readable_speed(
660+ self.netstats.ifaces[self.iface]["tx_sum"]
661+ * self.unit, self.unit, False),
662+ readable_speed(
663+ self.netstats.ifaces[self.iface]["rx_sum"]
664+ * self.unit, self.unit, False)))
665+
666+ def first_paint(self):
667+ self.repaint()
668+ return False
669+
670+ def subsequent_paint(self):
671+ self.repaint()
672+ return True
673+
674+ def draw_background(self, ct, x0, y0, x1, y1, radius):
675+ ct.move_to(x0, y0 + radius)
676+ ct.curve_to(x0, y0, x0, y0, x0 + radius, y0)
677+ ct.line_to(x1 - radius, y0)
678+ ct.curve_to(x1, y0, x1, y0, x1, y0 + radius)
679+ ct.line_to(x1, y1 - radius)
680+ ct.curve_to(x1, y1, x1, y1, x1 - radius, y1)
681+ ct.line_to(x0 + radius, y1)
682+ ct.curve_to(x0, y1, x0, y1, x0, y1 - radius)
683+ ct.close_path()
684+
685+ def draw_meter(self, ct, width, height, iface, multi=False):
686+ ratio = self.ratio
687+ ct.set_line_width(2)
688+ ''' Create temporary lists to store the values of the transmit
689+ and receive history, which will be then placed into the
690+ _total_hist and sorted by size to set the proper
691+ scale/ratio for the line heights '''
692+ _rx_hist = [1]
693+ _tx_hist = [1]
694+ _total_hist = [1]
695+ if not multi:
696+ if iface in self.netstats.ifaces \
697+ and len(self.netstats.ifaces[iface]["rx_history"]):
698+ _rx_hist = self.netstats.ifaces[iface]["rx_history"]
699+ if iface in self.netstats.ifaces \
700+ and len(self.netstats.ifaces[iface]["tx_history"]):
701+ _tx_hist = self.netstats.ifaces[iface]["tx_history"]
702+ _total_hist.extend(_rx_hist)
703+ _total_hist.extend(_tx_hist)
704+ else:
705+ for device in self.netstats.ifaces:
706+ if self.netstats.ifaces[device]['multi_include']:
707+ _total_hist.extend(
708+ self.netstats.ifaces[device]["rx_history"])
709+ if self.netstats.ifaces[iface]['multi_include']:
710+ _total_hist.extend(
711+ self.netstats.ifaces[device]["tx_history"])
712+ _total_hist.sort()
713+ ''' ratio variable controls the minimum threshold for data -
714+ i.e. 32000 would not draw graphs for data transfers below
715+ 3200 bytes - the initial value of ratio if set to the link
716+ speed will prevent the graph from scaling. If using the
717+ Multi Interface, the ratio will adjust based on the
718+ highest throughput metric. '''
719+ max_val = _total_hist[-1]
720+ ratio = max_val / 28 if max_val > self.ratio else self.ratio
721+ ''' Change the color of the upload line to configured/default '''
722+ if iface:
723+ color = gtk.gdk.color_parse(
724+ self.netstats.ifaces[iface]['upload_color'])
725+ ct.set_source_rgba(color.red / 65535.0,
726+ color.green / 65535.0,
727+ color.blue / 65535.0, 1.0)
728+ else:
729+ ct.set_source_rgba(0.1, 0.1, 0.1, 0.5)
730+ ''' Set the initial position and iter to 0 '''
731+ x_pos = 2 if self.border else 0
732+ cnt = 0
733+ ''' If a transmit history exists, draw it '''
734+ if iface in self.netstats.ifaces \
735+ and len(self.netstats.ifaces[iface]["tx_history"]):
736+ for value in self.netstats.ifaces[iface]["tx_history"]:
737+ x_pos_end = (x_pos - width) + 2 if self.border \
738+ and x_pos > width else 0
739+ ct.line_to(x_pos - x_pos_end, self.chart_coords(value, ratio))
740+ ct.move_to(x_pos, self.chart_coords(value, ratio))
741+ x_pos += width / self.meter_scale
742+ cnt += 1
743+ ct.close_path()
744+ ct.stroke()
745+ ''' Change the color of the download line to configured/default '''
746+ if iface:
747+ color = gtk.gdk.color_parse(
748+ self.netstats.ifaces[iface]['download_color'])
749+ ct.set_source_rgba(color.red / 65535.0,
750+ color.green / 65535.0,
751+ color.blue / 65535.0, 1.0)
752+ else:
753+ ct.set_source_rgba(0.1, 0.1, 0.1, 0.5)
754+ ''' Reset the position and iter to 0 '''
755+ x_pos = 2 if self.border else 0
756+ cnt = 0
757+ ''' If a receive history exists, draw it '''
758+ if iface in self.netstats.ifaces \
759+ and len(self.netstats.ifaces[iface]["rx_history"]):
760+ for value in self.netstats.ifaces[iface]["rx_history"]:
761+ x_pos_end = (x_pos - width) + 2 if self.border \
762+ and x_pos > width else 0
763+ ct.line_to(x_pos - x_pos_end, self.chart_coords(value, ratio))
764+ ct.move_to(x_pos, self.chart_coords(value, ratio))
765+ x_pos += width / self.meter_scale
766+ cnt += 1
767+ ct.close_path()
768+ ct.stroke()
769+
770+ def chart_coords(self, value, ratio=1):
771+ ratio = 1 if ratio < 1 else ratio
772+ pos = float(self.applet.get_size()) / 58
773+ bottom = 2.0 if self.border else 0
774+ return (self.applet.get_size() - pos \
775+ * (value / int(ratio))) + self.graph_zero - bottom
776+
777+ def repaint(self):
778+ orientation = self.applet.get_pos_type()
779+ if orientation in (gtk.POS_LEFT, gtk.POS_RIGHT):
780+ width = self.applet.get_size()
781+ self.upload_ot.props.font_sizing = 9
782+ self.download_ot.props.font_sizing = 9
783+ self.sum_ot.props.font_sizing = 9
784+ else:
785+ width = self.applet.get_size() * 1.5
786+ self.upload_ot.props.font_sizing = self.default_font_size
787+ self.download_ot.props.font_sizing = self.default_font_size
788+ self.sum_ot.props.font_sizing = self.default_font_size
789+ cs = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width),
790+ self.applet.get_size())
791+ ct = cairo.Context(cs)
792+ ct.set_source_surface(cs)
793+ ct.set_line_width(2)
794+ if self.background:
795+ bgColor, alpha = \
796+ self.applet.settings["background_color"].split("|")
797+ bgColor = gtk.gdk.color_parse(bgColor)
798+ ct.set_source_rgba(bgColor.red / 65535.0,
799+ bgColor.green / 65535.0,
800+ bgColor.blue / 65535.0,
801+ float(alpha))
802+ self.draw_background(ct, 0, 0, width, self.applet.get_size(), 10)
803+ ct.fill()
804+ if self.iface == "Multi Interface":
805+ tmp_history = [1]
806+ for iface in self.netstats.ifaces:
807+ if self.netstats.ifaces[iface]['multi_include']:
808+ tmp_history.extend(
809+ self.netstats.ifaces[iface]["rx_history"])
810+ tmp_history.extend(
811+ self.netstats.ifaces[iface]["tx_history"])
812+ tmp_history.sort()
813+ max_val = tmp_history[-1]
814+ self.ratio = max_val / 28 if max_val > self.ratio else 1
815+ for iface in self.netstats.ifaces:
816+ if self.netstats.ifaces[iface]['multi_include']:
817+ self.draw_meter(ct, width, self.applet.get_size(),
818+ iface, True)
819+ else:
820+ self.draw_meter(ct, width, self.applet.get_size(), self.iface)
821+ if self.iface in self.netstats.ifaces:
822+ if self.label_control:
823+ if self.label_control == 2:
824+ self.sum_ot.props.text = ""
825+ self.download_ot.props.text = \
826+ readable_speed(
827+ self.netstats.ifaces[self.iface]["rx_bytes"],
828+ self.unit).strip()
829+ self.upload_ot.props.text = \
830+ readable_speed(
831+ self.netstats.ifaces[self.iface]["tx_bytes"],
832+ self.unit).strip()
833+ else:
834+ self.upload_ot.props.text = ""
835+ self.download_ot.props.text = ""
836+ self.sum_ot.props.text = \
837+ readable_speed(
838+ self.netstats.ifaces[self.iface]["rx_bytes"] \
839+ + self.netstats.ifaces[self.iface]["tx_bytes"],
840+ self.unit).strip()
841+ else:
842+ self.upload_ot.props.text = ""
843+ self.download_ot.props.text = ""
844+ self.sum_ot.props.text = ""
845+ self.title_text = readable_speed(
846+ self.netstats.ifaces[self.iface]["tx_bytes"], self.unit)
847+ else:
848+ self.upload_ot.props.text = "No"
849+ self.download_ot.props.text = "Device"
850+ self.title_text = "Please select a valid device"
851+ if self.border:
852+ line_width = 2
853+ ct.set_line_width(line_width)
854+ borderColor, alpha = \
855+ self.applet.settings["border_color"].split("|")
856+ borderColor = gtk.gdk.color_parse(borderColor)
857+ ct.set_source_rgba(borderColor.red / 65535.0,
858+ borderColor.green / 65535.0,
859+ borderColor.blue / 65535.0,
860+ float(alpha))
861+ self.draw_background(ct,
862+ line_width / 2,
863+ line_width / 2,
864+ width - line_width / 2,
865+ self.applet.get_size() - line_width / 2, 4)
866+ ct.stroke()
867+ self.applet.set_icon_context(ct)
868+ if self.applet.dialog.is_visible("main"):
869+ for iface in self.netstats.ifaces:
870+ if not "widget" in self.netstats.ifaces[iface] \
871+ or self.netstats.regenerate == True:
872+ self.netstats.regenerate = False
873+ self.vbox.remove(self.table)
874+ self.table = self.generate_table()
875+ self.vbox.add(self.table)
876+ self.vbox.show_all()
877+ self.netstats.ifaces[iface]["widget"].rx_speed_label.set_text(
878+ str(readable_speed(self.netstats.ifaces[iface]["rx_bytes"],
879+ self.unit).strip()))
880+ self.netstats.ifaces[iface]["widget"].tx_speed_label.set_text(
881+ str(readable_speed(self.netstats.ifaces[iface]["tx_bytes"],
882+ self.unit).strip()))
883+ self.netstats.ifaces[iface]["widget"].sent_label.set_text(
884+ str(readable_speed(self.netstats.ifaces[iface]["tx_sum"] \
885+ * self.unit, self.unit, False).strip()))
886+ self.netstats.ifaces[iface]["widget"].received_label.set_text(
887+ str(readable_speed(self.netstats.ifaces[iface]["rx_sum"] \
888+ * self.unit, self.unit, False).strip()))
889+ return True
890+
891+
892+def readable_speed(speed, unit, seconds=True):
893+ ''' readable_speed(speed) -> string
894+ speed is in bytes per second
895+ returns a readable version of the speed given '''
896+ speed = 0 if speed is None or speed < 0 else speed
897+ units = ["B ", "KB", "MB", "GB", "TB"] if unit == 1 \
898+ else ["b ", "Kb", "Mb", "Gb", "Tb"]
899+ if seconds:
900+ temp_units = []
901+ for u in units:
902+ temp_units.append("%sps" % u.strip())
903+ units = temp_units
904+ step = 1L
905+ for u in units:
906+ if step > 1:
907+ s = "%4.2f " % (float(speed) / step)
908+ if len(s) <= 5:
909+ return s + u
910+ s = "%4.2f " % (float(speed) / step)
911+ if len(s) <= 5:
912+ return s + u
913+ if speed / step < 1024:
914+ return "%4.1d " % (speed / step) + u
915+ step = step * 1024L
916+ return "%4.1d " % (speed / (step / 1024)) + units[-1]
917+
918+if __name__ == "__main__":
919+ awnlib.init_start(AppletBandwidthMonitor, {"name": APPLET_NAME,
920+ "short": "bandwidth-monitor",
921+ "version": __version__,
922+ "description": APPLET_DESCRIPTION,
923+ "logo": APPLET_ICON,
924+ "author": "Kyle L. Huff",
925+ "copyright-year": "2009",
926+ "authors": APPLET_AUTHORS})
927
928=== added file 'applets/maintained/bandwidth-monitor/bandwidth-monitor.desktop.in.in'
929--- applets/maintained/bandwidth-monitor/bandwidth-monitor.desktop.in.in 1970-01-01 00:00:00 +0000
930+++ applets/maintained/bandwidth-monitor/bandwidth-monitor.desktop.in.in 2010-01-16 19:06:14 +0000
931@@ -0,0 +1,11 @@
932+[Desktop Entry]
933+Version=1.0
934+Name=Bandwidth Monitor
935+Type=Application
936+X-AWN-Type=Applet
937+X-AWN-AppletType=Python
938+Comment=A Network Bandwidth monitor for AWN
939+X-AWN-AppletExec=bandwidth-monitor/awn-bwm.py
940+Exec=awn-applet -p %k
941+Icon=bandwidth-monitor/images/icon
942+X-AWN-AppletCategory=Utility
943
944=== added file 'applets/maintained/bandwidth-monitor/bandwidth-monitor.ui'
945--- applets/maintained/bandwidth-monitor/bandwidth-monitor.ui 1970-01-01 00:00:00 +0000
946+++ applets/maintained/bandwidth-monitor/bandwidth-monitor.ui 2010-01-16 19:06:14 +0000
947@@ -0,0 +1,300 @@
948+<?xml version="1.0"?>
949+<interface>
950+ <!-- interface-requires gtk+ 2.12 -->
951+ <!-- interface-naming-policy toplevel-contextual -->
952+ <object class="GtkAdjustment" id="adjustment-scale-threshold">
953+ <property name="upper">100000</property>
954+ <property name="step_increment">0.01</property>
955+ <property name="page_increment">100</property>
956+ </object>
957+ <object class="GtkWindow" id="general-preferences">
958+ <child>
959+ <object class="GtkNotebook" id="dialog-notebook">
960+ <property name="width_request">500</property>
961+ <property name="visible">True</property>
962+ <property name="can_focus">True</property>
963+ <child>
964+ <object class="GtkFrame" id="frame3">
965+ <property name="visible">True</property>
966+ <property name="label_xalign">0</property>
967+ <property name="shadow_type">none</property>
968+ <child>
969+ <object class="GtkAlignment" id="alignment3">
970+ <property name="visible">True</property>
971+ <property name="top_padding">6</property>
972+ <property name="bottom_padding">6</property>
973+ <property name="left_padding">12</property>
974+ <property name="right_padding">12</property>
975+ <child>
976+ <object class="GtkVBox" id="vbox3">
977+ <property name="visible">True</property>
978+ <property name="orientation">vertical</property>
979+ <property name="spacing">6</property>
980+ <child>
981+ <object class="GtkCheckButton" id="uomCheckbutton">
982+ <property name="label" translatable="yes">Display MBps/KBps (bytes) instead of Mbps/Kbps (bits)</property>
983+ <property name="visible">True</property>
984+ <property name="can_focus">True</property>
985+ <property name="receives_default">False</property>
986+ <property name="tooltip_text" translatable="yes">If this is checked, the common display unit will be Bytes</property>
987+ <property name="use_underline">True</property>
988+ <property name="draw_indicator">True</property>
989+ </object>
990+ <packing>
991+ <property name="expand">False</property>
992+ <property name="padding">6</property>
993+ <property name="position">0</property>
994+ </packing>
995+ </child>
996+ <child>
997+ <object class="GtkHBox" id="bgHbox">
998+ <property name="visible">True</property>
999+ <child>
1000+ <object class="GtkCheckButton" id="bgCheckbutton">
1001+ <property name="label" translatable="yes">Draw Background</property>
1002+ <property name="width_request">200</property>
1003+ <property name="visible">True</property>
1004+ <property name="can_focus">True</property>
1005+ <property name="receives_default">False</property>
1006+ <property name="tooltip_text" translatable="yes">If this is checked the applet background will use the selected color. If unchecked, background will be transparent</property>
1007+ <property name="active">True</property>
1008+ <property name="draw_indicator">True</property>
1009+ </object>
1010+ <packing>
1011+ <property name="position">0</property>
1012+ </packing>
1013+ </child>
1014+ <child>
1015+ <object class="GtkColorButton" id="bgColorbutton">
1016+ <property name="visible">True</property>
1017+ <property name="can_focus">True</property>
1018+ <property name="receives_default">True</property>
1019+ <property name="events">GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK</property>
1020+ <property name="tooltip_text" translatable="yes">Background Color</property>
1021+ <property name="use_alpha">True</property>
1022+ <property name="title" translatable="yes">Background Color</property>
1023+ <property name="color">#000000000000</property>
1024+ <property name="alpha">32767</property>
1025+ </object>
1026+ <packing>
1027+ <property name="padding">10</property>
1028+ <property name="position">1</property>
1029+ </packing>
1030+ </child>
1031+ </object>
1032+ <packing>
1033+ <property name="position">1</property>
1034+ </packing>
1035+ </child>
1036+ <child>
1037+ <object class="GtkHBox" id="borderHbox">
1038+ <property name="visible">True</property>
1039+ <child>
1040+ <object class="GtkCheckButton" id="borderCheckbutton">
1041+ <property name="label" translatable="yes">Draw Border</property>
1042+ <property name="width_request">200</property>
1043+ <property name="visible">True</property>
1044+ <property name="can_focus">True</property>
1045+ <property name="receives_default">False</property>
1046+ <property name="tooltip_text" translatable="yes">If this is checked the applet border will use the selected color. If unchecked, border will be transparent</property>
1047+ <property name="draw_indicator">True</property>
1048+ </object>
1049+ <packing>
1050+ <property name="position">0</property>
1051+ </packing>
1052+ </child>
1053+ <child>
1054+ <object class="GtkColorButton" id="borderColorbutton">
1055+ <property name="visible">True</property>
1056+ <property name="can_focus">True</property>
1057+ <property name="receives_default">True</property>
1058+ <property name="tooltip_text" translatable="yes">Border Color</property>
1059+ <property name="use_alpha">True</property>
1060+ <property name="title" translatable="yes">Border Color</property>
1061+ <property name="color">#000000000000</property>
1062+ </object>
1063+ <packing>
1064+ <property name="padding">10</property>
1065+ <property name="position">1</property>
1066+ </packing>
1067+ </child>
1068+ </object>
1069+ <packing>
1070+ <property name="position">2</property>
1071+ </packing>
1072+ </child>
1073+ <child>
1074+ <object class="GtkHBox" id="hbox1">
1075+ <property name="visible">True</property>
1076+ <child>
1077+ <object class="GtkRadioButton" id="labelBothRadiobutton">
1078+ <property name="label" translatable="yes">Display Speed Text</property>
1079+ <property name="visible">True</property>
1080+ <property name="can_focus">True</property>
1081+ <property name="receives_default">False</property>
1082+ <property name="tooltip_text" translatable="yes">Display upload and download text representation of speed</property>
1083+ <property name="draw_indicator">True</property>
1084+ </object>
1085+ <packing>
1086+ <property name="position">0</property>
1087+ </packing>
1088+ </child>
1089+ <child>
1090+ <object class="GtkRadioButton" id="labelSumRadiobutton">
1091+ <property name="label" translatable="yes">Sum</property>
1092+ <property name="visible">True</property>
1093+ <property name="can_focus">True</property>
1094+ <property name="receives_default">False</property>
1095+ <property name="tooltip_text" translatable="yes">Display the sum of upload and download</property>
1096+ <property name="draw_indicator">True</property>
1097+ <property name="group">labelBothRadiobutton</property>
1098+ </object>
1099+ <packing>
1100+ <property name="position">1</property>
1101+ </packing>
1102+ </child>
1103+ <child>
1104+ <object class="GtkRadioButton" id="labelNoneRadiobutton">
1105+ <property name="label" translatable="yes">Graph Only</property>
1106+ <property name="visible">True</property>
1107+ <property name="can_focus">True</property>
1108+ <property name="receives_default">False</property>
1109+ <property name="tooltip_text" translatable="yes">Do not display the speed as text, only draw the graph</property>
1110+ <property name="draw_indicator">True</property>
1111+ <property name="group">labelBothRadiobutton</property>
1112+ </object>
1113+ <packing>
1114+ <property name="position">2</property>
1115+ </packing>
1116+ </child>
1117+ </object>
1118+ <packing>
1119+ <property name="position">3</property>
1120+ </packing>
1121+ </child>
1122+ <child>
1123+ <object class="GtkCheckButton" id="graphZerotoggle">
1124+ <property name="label" translatable="yes">Draw 0 bps in graphs</property>
1125+ <property name="visible">True</property>
1126+ <property name="can_focus">True</property>
1127+ <property name="receives_default">False</property>
1128+ <property name="tooltip_text" translatable="yes">If enabled, this will draw a line at the bottom of the graph even if the value is 0. If unchecked, values below 1 are not drawn in the graph.</property>
1129+ <property name="active">True</property>
1130+ <property name="draw_indicator">True</property>
1131+ </object>
1132+ <packing>
1133+ <property name="position">4</property>
1134+ </packing>
1135+ </child>
1136+ <child>
1137+ <object class="GtkHBox" id="hbox6">
1138+ <property name="visible">True</property>
1139+ <property name="tooltip_text" translatable="yes">Sets the minimum threshold for scaling to not show large spikes for small amounts of traffic. e.g.: Setting to 32.0 KBps will cause the graph to only draw if throughput exceeds 32.0 KBps</property>
1140+ <property name="spacing">12</property>
1141+ <child>
1142+ <object class="GtkLabel" id="label-scale-threshold">
1143+ <property name="visible">True</property>
1144+ <property name="xalign">0</property>
1145+ <property name="label" translatable="yes">Minimum Scaling threshold</property>
1146+ <property name="use_underline">True</property>
1147+ <property name="mnemonic_widget">scaleThresholdSBtn</property>
1148+ </object>
1149+ <packing>
1150+ <property name="expand">False</property>
1151+ <property name="position">0</property>
1152+ </packing>
1153+ </child>
1154+ <child>
1155+ <object class="GtkHBox" id="hbox3">
1156+ <property name="visible">True</property>
1157+ <property name="spacing">6</property>
1158+ <child>
1159+ <object class="GtkSpinButton" id="scaleThresholdSBtn">
1160+ <property name="visible">True</property>
1161+ <property name="can_focus">True</property>
1162+ <property name="invisible_char">&#x25CF;</property>
1163+ <property name="caps_lock_warning">False</property>
1164+ <property name="adjustment">adjustment-scale-threshold</property>
1165+ <property name="digits">2</property>
1166+ <property name="numeric">True</property>
1167+ </object>
1168+ <packing>
1169+ <property name="position">0</property>
1170+ </packing>
1171+ </child>
1172+ <child>
1173+ <object class="GtkLabel" id="label-scaleThreshold">
1174+ <property name="visible">True</property>
1175+ <property name="label" translatable="yes">KBps</property>
1176+ </object>
1177+ <packing>
1178+ <property name="position">1</property>
1179+ </packing>
1180+ </child>
1181+ </object>
1182+ <packing>
1183+ <property name="position">1</property>
1184+ </packing>
1185+ </child>
1186+ </object>
1187+ <packing>
1188+ <property name="padding">6</property>
1189+ <property name="position">5</property>
1190+ </packing>
1191+ </child>
1192+ </object>
1193+ </child>
1194+ </object>
1195+ </child>
1196+ <child type="label">
1197+ <object class="GtkLabel" id="label-display">
1198+ <property name="visible">True</property>
1199+ <property name="label" translatable="yes">&lt;b&gt;Display&lt;/b&gt;</property>
1200+ <property name="use_markup">True</property>
1201+ </object>
1202+ </child>
1203+ </object>
1204+ </child>
1205+ <child type="tab">
1206+ <object class="GtkLabel" id="label-general">
1207+ <property name="visible">True</property>
1208+ <property name="label" translatable="yes">General</property>
1209+ </object>
1210+ <packing>
1211+ <property name="tab_fill">False</property>
1212+ </packing>
1213+ </child>
1214+ <child>
1215+ <object class="GtkAlignment" id="alignment1">
1216+ <property name="height_request">150</property>
1217+ <property name="visible">True</property>
1218+ <child>
1219+ <object class="GtkScrolledWindow" id="scrolledwindow1">
1220+ <property name="visible">True</property>
1221+ <property name="can_focus">True</property>
1222+ <property name="hscrollbar_policy">automatic</property>
1223+ <property name="vscrollbar_policy">automatic</property>
1224+ <child>
1225+ <placeholder/>
1226+ </child>
1227+ </object>
1228+ </child>
1229+ </object>
1230+ <packing>
1231+ <property name="position">1</property>
1232+ </packing>
1233+ </child>
1234+ <child type="tab">
1235+ <object class="GtkLabel" id="label-devices">
1236+ <property name="visible">True</property>
1237+ <property name="label" translatable="yes">Devices</property>
1238+ </object>
1239+ <packing>
1240+ <property name="position">1</property>
1241+ <property name="tab_fill">False</property>
1242+ </packing>
1243+ </child>
1244+ </object>
1245+ </child>
1246+ </object>
1247+</interface>
1248
1249=== added file 'applets/maintained/bandwidth-monitor/bwmprefs.py'
1250--- applets/maintained/bandwidth-monitor/bwmprefs.py 1970-01-01 00:00:00 +0000
1251+++ applets/maintained/bandwidth-monitor/bwmprefs.py 2010-01-16 19:06:14 +0000
1252@@ -0,0 +1,278 @@
1253+#!/usr/bin/python
1254+# -*- coding: utf-8 -*-
1255+"""
1256+bandwidth-monitor - Network bandwidth monitor.
1257+Copyright (c) 2006-2009 Kyle L. Huff (kyle.huff@curetheitch.com)
1258+url: <http://www.curetheitch.com/projects/awn-bwm/>
1259+Email: awn-bwm@curetheitch.com
1260+
1261+ This program is free software: you can redistribute it and/or modify
1262+ it under the terms of the GNU General Public License as published by
1263+ the Free Software Foundation, either version 3 of the License, or
1264+ (at your option) any later version.
1265+
1266+ This program is distributed in the hope that it will be useful,
1267+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1268+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1269+ GNU General Public License for more details.
1270+
1271+ You should have received a copy of the GNU General Public License
1272+ along with this program. If not, see <http://www.gnu.org/licenses/gpl.txt>.
1273+"""
1274+
1275+import gtk
1276+import gobject
1277+
1278+
1279+class Preferences:
1280+
1281+ def __init__(self, applet, parent):
1282+ self.applet = applet
1283+ self.parent = parent
1284+
1285+ def setup(self):
1286+ prefs_ui = gtk.Builder()
1287+ prefs_ui.add_from_file(self.parent.UI_FILE)
1288+ preferences_vbox = self.applet.dialog.new("preferences").vbox
1289+ cell_box = self.create_treeview()
1290+ store = cell_box.liststore
1291+ scaleThresholdSBtn = prefs_ui.get_object("scaleThresholdSBtn")
1292+ thresholdLabel = prefs_ui.get_object("label-scaleThreshold")
1293+ scaleThresholdSBtn.set_value(
1294+ float(self.applet.settings["draw_threshold"]))
1295+ scaleThresholdSBtn.connect(
1296+ 'value-changed', self.parent.change_draw_ratio)
1297+ uomCheckbutton = prefs_ui.get_object('uomCheckbutton')
1298+ self.uomCheckbutton = uomCheckbutton
1299+ if self.parent.unit == 1:
1300+ uomCheckbutton.set_property('active', True)
1301+ thresholdLabel.set_text("KBps")
1302+ else:
1303+ thresholdLabel.set_text("Kbps")
1304+ uomCheckbutton.connect('toggled',
1305+ self.parent.change_unit, scaleThresholdSBtn, thresholdLabel)
1306+ graphZerotoggle = prefs_ui.get_object('graphZerotoggle')
1307+ graphZerotoggle_value = True if not self.parent.graph_zero else False
1308+ graphZerotoggle.set_property('active', graphZerotoggle_value)
1309+ graphZerotoggle.connect('toggled', self.graphZeroToggle_cb)
1310+ bgCheckbutton = prefs_ui.get_object('bgCheckbutton')
1311+ bgCheckbutton.set_active(self.applet.settings["background"])
1312+ bgCheckbutton.connect('toggled', self.bgCheckbutton_cb)
1313+ bgColorbutton = prefs_ui.get_object('bgColorbutton')
1314+ bgColor, bgAlpha = self.applet.settings["background_color"].split("|")
1315+ bgColorbutton.set_color(gtk.gdk.color_parse(bgColor))
1316+ bgColorbutton.set_alpha(int(float(bgAlpha) * 65535.0))
1317+ bgColorbutton.connect('color-set',
1318+ self.backgroundColorbutton_color_set_cb)
1319+ borderCheckbutton = prefs_ui.get_object('borderCheckbutton')
1320+ borderCheckbutton.set_active(self.applet.settings["border"])
1321+ borderCheckbutton.connect('toggled', self.borderCheckbutton_cb)
1322+ borderColorbutton = prefs_ui.get_object('borderColorbutton')
1323+ borderColor, borderAlpha = \
1324+ self.applet.settings["border_color"].split("|")
1325+ borderColorbutton.set_color(gtk.gdk.color_parse(borderColor))
1326+ borderColorbutton.set_alpha(int(float(borderAlpha) * 65535.0))
1327+ borderColorbutton.connect('color-set',
1328+ self.borderColorbutton_color_set_cb)
1329+ labelNoneRadiobutton = prefs_ui.get_object('labelNoneRadiobutton')
1330+ labelSumRadiobutton = prefs_ui.get_object('labelSumRadiobutton')
1331+ labelBothRadiobutton = prefs_ui.get_object('labelBothRadiobutton')
1332+ if self.parent.label_control == 0:
1333+ labelNoneRadiobutton.set_active(True)
1334+ elif self.parent.label_control == 1:
1335+ labelSumRadiobutton.set_active(True)
1336+ else:
1337+ labelBothRadiobutton.set_active(True)
1338+ labelNoneRadiobutton.connect('toggled', self.labelRadio_cb, 0)
1339+ labelSumRadiobutton.connect('toggled', self.labelRadio_cb, 1)
1340+ labelBothRadiobutton.connect('toggled', self.labelRadio_cb, 2)
1341+ for iface in sorted(self.parent.netstats.ifaces):
1342+ if not "Multi Interface" in iface \
1343+ and not "Sum Interface" in iface:
1344+ if self.parent.netstats.ifaces[iface]['sum_include'] == True:
1345+ sum_include = 1
1346+ else:
1347+ sum_include = 0
1348+ if self.parent.netstats.ifaces[iface]['multi_include'] == True:
1349+ muti_include = 1
1350+ else:
1351+ muti_include = 0
1352+ current_iter = store.append([iface, sum_include,
1353+ muti_include, '', '', '#ff0000', '#ffff00'])
1354+ prefs_ui.get_object("scrolledwindow1").add_with_viewport(cell_box)
1355+ prefs_ui.get_object("dialog-notebook").reparent(preferences_vbox)
1356+
1357+ def graphZeroToggle_cb(self, widget):
1358+ self.parent.graph_zero = 0 if widget.get_active() else 1
1359+ self.applet.settings['graph_zero'] = self.parent.graph_zero
1360+
1361+ def labelRadio_cb(self, widget, setting):
1362+ if widget.get_active():
1363+ self.applet.settings["label_control"] = setting
1364+ self.parent.label_control = setting
1365+
1366+ def create_treeview(self):
1367+ cell_box = gtk.HBox()
1368+ liststore = gtk.ListStore(str, gobject.TYPE_BOOLEAN,
1369+ gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN,
1370+ gobject.TYPE_BOOLEAN, str, str)
1371+ treeview = gtk.TreeView(liststore)
1372+ treeview.set_property("rules-hint", True)
1373+ treeview.set_enable_search(True)
1374+ treeview.position = 0
1375+ rows = gtk.VBox(False, 3)
1376+ self.liststore = liststore
1377+ listcols = gtk.HBox(False, 0)
1378+ prows = gtk.VBox(False, 0)
1379+ rows.pack_start(listcols, True, True, 0)
1380+ listcols.pack_start(treeview)
1381+ listcols.pack_start(prows, False, False, 0)
1382+ selection = treeview.get_selection()
1383+ selection.connect('changed', self.on_selection_changed)
1384+ ''' Device '''
1385+ device_renderer = gtk.CellRendererText()
1386+ device_column = gtk.TreeViewColumn("Device", device_renderer)
1387+ device_column.set_property('expand', True)
1388+ device_column.add_attribute(device_renderer, "text", 0)
1389+ ''' Sum '''
1390+ sum_renderer = gtk.CellRendererToggle()
1391+ sum_column = gtk.TreeViewColumn("Sum", sum_renderer)
1392+ sum_column.add_attribute(sum_renderer, 'active', 1)
1393+ sum_renderer.set_property('activatable', True)
1394+ sum_renderer.connect('toggled', self.toggle_cb, liststore, 1, "sum")
1395+ ''' Multi '''
1396+ multi_renderer = gtk.CellRendererToggle()
1397+ multi_column = gtk.TreeViewColumn("Mutli", multi_renderer)
1398+ multi_column.add_attribute(multi_renderer, 'active', 2)
1399+ multi_renderer.set_property('activatable', True)
1400+ multi_renderer.connect('toggled', self.toggle_cb,
1401+ liststore, 2, "multi")
1402+ ''' Upload '''
1403+ uploadColor_renderer = gtk.CellRendererToggle()
1404+ uploadColor_renderer.set_property('indicator-size', 0.1)
1405+ uploadColor_column = gtk.TreeViewColumn("Upload Color",
1406+ uploadColor_renderer, cell_background=5)
1407+ uploadColor_column.add_attribute(uploadColor_renderer, 'active', 3)
1408+ uploadColor_column.set_cell_data_func(uploadColor_renderer,
1409+ self.devlist_cell_func)
1410+ uploadColor_renderer.set_property('activatable', True)
1411+ uploadColor_renderer.connect('toggled', self.color_cb,
1412+ liststore, 3, "upload")
1413+ ''' Download '''
1414+ downloadColor_renderer = gtk.CellRendererToggle()
1415+ downloadColor_renderer.set_property('indicator-size', 0.1)
1416+ downloadColor_column = gtk.TreeViewColumn("Download Color",
1417+ downloadColor_renderer, cell_background=6)
1418+ downloadColor_column.add_attribute(downloadColor_renderer, 'active', 4)
1419+ downloadColor_column.set_cell_data_func(downloadColor_renderer,
1420+ self.devlist_cell_func)
1421+ downloadColor_renderer.set_property('activatable', True)
1422+ downloadColor_renderer.connect('toggled', self.color_cb,
1423+ liststore, 4, "download")
1424+ ''' Apply the before defined cells '''
1425+ cell_box.liststore = liststore
1426+ treeview.append_column(device_column)
1427+ treeview.append_column(sum_column)
1428+ treeview.append_column(multi_column)
1429+ treeview.append_column(uploadColor_column)
1430+ treeview.append_column(downloadColor_column)
1431+ cell_box.listcols = listcols
1432+ cell_box.add(rows)
1433+ return cell_box
1434+
1435+ def on_selection_changed(self, selection):
1436+ ''' If a row is selected; deselect it.. always..
1437+ There is currently no need to have the row selected,
1438+ and the highlight of the row makes it difficult to see
1439+ the colors selected depending on your GTK theme.. '''
1440+ model, paths = selection.get_selected_rows()
1441+ if paths:
1442+ selection.unselect_path(model[paths[0]].path)
1443+
1444+ def devlist_cell_func(self, column, cell, model, iter):
1445+ ''' Changes the cell color to match the preferece or selected value '''
1446+ device = self.liststore.get_value(iter, 0)
1447+ column_title = column.get_title().lower().split(" ")[0]
1448+ cell.set_property("cell-background",
1449+ self.get_color(device, column_title))
1450+
1451+ def bgCheckbutton_cb(self, widget):
1452+ self.applet.settings['background'] = widget.get_active()
1453+ self.parent.background = widget.get_active()
1454+
1455+ def borderCheckbutton_cb(self, widget):
1456+ self.applet.settings['border'] = widget.get_active()
1457+ self.parent.border = widget.get_active()
1458+
1459+ def backgroundColorbutton_color_set_cb(self, widget):
1460+ color = widget.get_color()
1461+ alpha = float("%2.1f" % (widget.get_alpha() / 65535.0))
1462+ self.applet.settings["background_color"] = "%s|%s" % (color, alpha)
1463+ self.parent.background_color = "%s|%s" % (color, alpha)
1464+
1465+ def borderColorbutton_color_set_cb(self, widget):
1466+ color = widget.get_color()
1467+ alpha = float("%2.1f" % (widget.get_alpha() / 65535.0))
1468+ self.applet.settings["border_color"] = "%s|%s" \
1469+ % (color.to_string(), alpha)
1470+ self.parent.border_color = "%s|%s" % (color, alpha)
1471+
1472+ def get_color(self, device, column_name):
1473+ if column_name == "upload":
1474+ i = 3
1475+ color = "#ff0000"
1476+ else:
1477+ i = 4
1478+ color = "#ffff00"
1479+ prefs = self.applet.settings["device_display_parameters"]
1480+ for device_pref in prefs:
1481+ device_pref_values = device_pref.split("|")
1482+ if device_pref_values[0] == device:
1483+ if "#" in device_pref_values[i]:
1484+ color = device_pref_values[i]
1485+ return color
1486+
1487+ def color_cb(self, widget, path, model, col_number, name):
1488+ if col_number == 3:
1489+ prop = "Upload"
1490+ else:
1491+ prop = "Download"
1492+ colorseldlg = gtk.ColorSelectionDialog(
1493+ "%s %s Color" % (model[path][0], prop))
1494+ colorseldlg.colorsel.set_current_color(
1495+ gtk.gdk.color_parse(self.get_color(model[path][0], prop.lower())))
1496+ response = colorseldlg.run()
1497+ if response == gtk.RESPONSE_OK:
1498+ self.color_choice = colorseldlg.colorsel.get_current_color()
1499+ self.parent.netstats.ifaces[model[path][0]]['%s_color' \
1500+ % prop.lower()] = self.color_choice.to_string()
1501+ prefs = self.applet.settings["device_display_parameters"]
1502+ if not prefs:
1503+ prefs = ["%s|True|True|None|None" % (model[path][0])]
1504+ if not model[path][0] in prefs.__str__():
1505+ prefs.append("%s|True|True|None|None" % (model[path][0]))
1506+ for i, device_pref in enumerate(prefs):
1507+ dpv = device_pref.split('|')
1508+ if dpv[0] == model[path][0]:
1509+ dpv[col_number] = self.color_choice.to_string()
1510+ prefs[i] = '|'.join(dpv)
1511+ model[path][col_number + 2] = self.color_choice.to_string()
1512+ self.applet.settings["device_display_parameters"] = prefs
1513+ colorseldlg.hide()
1514+
1515+ def toggle_cb(self, widget, path, model, col_number, name):
1516+ model[path][col_number] = not model[path][col_number]
1517+ parameter = model[path][col_number]
1518+ self.parent.netstats.ifaces[model[path][0]]['%s_include' % name] \
1519+ = parameter
1520+ prefs = self.applet.settings["device_display_parameters"]
1521+ if not prefs:
1522+ prefs = ["%s|True|True|None|None" % (model[path][0])]
1523+ if not model[path][0] in prefs.__str__():
1524+ prefs.append("%s|True|True|None|None" % (model[path][0]))
1525+ for i, device_pref in enumerate(prefs):
1526+ dpv = device_pref.split('|')
1527+ if dpv[0] == model[path][0]:
1528+ dpv[col_number] = str(parameter)
1529+ prefs[i] = '|'.join(dpv)
1530+ self.applet.settings["device_display_parameters"] = prefs
1531
1532=== added directory 'applets/maintained/bandwidth-monitor/images'
1533=== added file 'applets/maintained/bandwidth-monitor/images/icon.png'
1534Binary files applets/maintained/bandwidth-monitor/images/icon.png 1970-01-01 00:00:00 +0000 and applets/maintained/bandwidth-monitor/images/icon.png 2010-01-16 19:06:14 +0000 differ
1535=== modified file 'configure.ac'
1536--- configure.ac 2009-12-29 23:15:57 +0000
1537+++ configure.ac 2010-01-16 19:06:14 +0000
1538@@ -316,6 +316,8 @@
1539 applets/maintained/animal-farm/Makefile
1540 applets/maintained/awnterm/Makefile
1541 applets/maintained/awnterm/awnterm.desktop.in
1542+applets/maintained/bandwidth-monitor/Makefile
1543+applets/maintained/bandwidth-monitor/bandwidth-monitor.desktop.in
1544 applets/maintained/battery/Makefile
1545 applets/maintained/cairo-clock/Makefile
1546 applets/maintained/cairo-menu/Makefile

Subscribers

People subscribed via source and target branches