From 080b06c3aa4f4de74bc349b8e0c095189f513595 Mon Sep 17 00:00:00 2001 From: gryf Date: Fri, 8 Apr 2022 17:55:07 +0200 Subject: [PATCH] Clean up repository. Remove all non-lib related files including old CVS things, examples, website and so on. --- CVSROOT/checkoutlist | 13 - CVSROOT/commitinfo | 15 - CVSROOT/config | 21 - CVSROOT/cvswrappers | 19 - CVSROOT/editinfo | 21 - CVSROOT/loginfo | 27 - CVSROOT/modules | 26 - CVSROOT/notify | 12 - CVSROOT/rcsinfo | 13 - CVSROOT/taginfo | 20 - CVSROOT/verifymsg | 21 - README.txt => README.rst | 0 examples/README | 97 --- examples/pywmdatetime.py | 206 ------ examples/pywmgeneric.py | 679 ------------------ examples/pywmhdmon.py | 541 -------------- examples/pywmnop.py | 35 - examples/pywmoonop.py | 16 - examples/pywmphoto.py | 42 -- examples/pywmradio.py | 327 --------- examples/pywmseti.py | 502 ------------- examples/pywmsysmon.py | 397 ---------- examples/pywmwet.py | 262 ------- examples/sample.pyradiorc | 18 - examples/sample.pywmdatetimerc | 42 -- examples/sample.pywmgenericrc | 69 -- examples/sample.pywmhdmonrc | 50 -- examples/sample.pywmsetirc | 12 - pywmgeneric/README | 15 - pywmgeneric/__init__.py | 2 - website/index.html | 259 ------- website/my_style.css | 74 -- website/pictures/angelico-mounted.png | Bin 372 -> 0 bytes website/pictures/angelico-unmounted.png | Bin 367 -> 0 bytes website/pictures/croese-mounted.png | Bin 1134 -> 0 bytes website/pictures/croese-vari.png | Bin 11593 -> 0 bytes website/pictures/generic-defaults.png | Bin 2087 -> 0 bytes website/pictures/generic-gray80-black.png | Bin 1976 -> 0 bytes website/pictures/hdmon-41-blue-yellow.png | Bin 1252 -> 0 bytes website/pictures/hdmon-41-purple-black.png | Bin 1230 -> 0 bytes website/pictures/hdmon-41.png | Bin 1172 -> 0 bytes website/pictures/pywmPhoto.png | Bin 9326 -> 0 bytes website/pictures/pywmdatetime-antialiased.png | Bin 1318 -> 0 bytes website/pictures/pywmdatetime-fonts.png | Bin 7035 -> 0 bytes website/pictures/pywmdatetime.png | Bin 753 -> 0 bytes website/pictures/pywmgeneric.png | Bin 850 -> 0 bytes website/pictures/pywmhdmon-taller_font.png | Bin 745 -> 0 bytes website/pictures/pywmhdmon.png | Bin 746 -> 0 bytes website/pictures/pywmseti.png | Bin 561 -> 0 bytes website/pictures/pywmsysmon.png | Bin 474 -> 0 bytes 50 files changed, 3853 deletions(-) delete mode 100644 CVSROOT/checkoutlist delete mode 100644 CVSROOT/commitinfo delete mode 100644 CVSROOT/config delete mode 100644 CVSROOT/cvswrappers delete mode 100644 CVSROOT/editinfo delete mode 100644 CVSROOT/loginfo delete mode 100644 CVSROOT/modules delete mode 100644 CVSROOT/notify delete mode 100644 CVSROOT/rcsinfo delete mode 100644 CVSROOT/taginfo delete mode 100644 CVSROOT/verifymsg rename README.txt => README.rst (100%) delete mode 100644 examples/README delete mode 100755 examples/pywmdatetime.py delete mode 100644 examples/pywmgeneric.py delete mode 100755 examples/pywmhdmon.py delete mode 100644 examples/pywmnop.py delete mode 100755 examples/pywmoonop.py delete mode 100644 examples/pywmphoto.py delete mode 100755 examples/pywmradio.py delete mode 100755 examples/pywmseti.py delete mode 100755 examples/pywmsysmon.py delete mode 100644 examples/pywmwet.py delete mode 100644 examples/sample.pyradiorc delete mode 100644 examples/sample.pywmdatetimerc delete mode 100644 examples/sample.pywmgenericrc delete mode 100644 examples/sample.pywmhdmonrc delete mode 100644 examples/sample.pywmsetirc delete mode 100644 pywmgeneric/README delete mode 100644 pywmgeneric/__init__.py delete mode 100644 website/index.html delete mode 100644 website/my_style.css delete mode 100644 website/pictures/angelico-mounted.png delete mode 100644 website/pictures/angelico-unmounted.png delete mode 100644 website/pictures/croese-mounted.png delete mode 100644 website/pictures/croese-vari.png delete mode 100644 website/pictures/generic-defaults.png delete mode 100644 website/pictures/generic-gray80-black.png delete mode 100644 website/pictures/hdmon-41-blue-yellow.png delete mode 100644 website/pictures/hdmon-41-purple-black.png delete mode 100644 website/pictures/hdmon-41.png delete mode 100644 website/pictures/pywmPhoto.png delete mode 100644 website/pictures/pywmdatetime-antialiased.png delete mode 100644 website/pictures/pywmdatetime-fonts.png delete mode 100644 website/pictures/pywmdatetime.png delete mode 100644 website/pictures/pywmgeneric.png delete mode 100644 website/pictures/pywmhdmon-taller_font.png delete mode 100644 website/pictures/pywmhdmon.png delete mode 100644 website/pictures/pywmseti.png delete mode 100644 website/pictures/pywmsysmon.png diff --git a/CVSROOT/checkoutlist b/CVSROOT/checkoutlist deleted file mode 100644 index 2921bff..0000000 --- a/CVSROOT/checkoutlist +++ /dev/null @@ -1,13 +0,0 @@ -# The "checkoutlist" file is used to support additional version controlled -# administrative files in $CVSROOT/CVSROOT, such as template files. -# -# The first entry on a line is a filename which will be checked out from -# the corresponding RCS file in the $CVSROOT/CVSROOT directory. -# The remainder of the line is an error message to use if the file cannot -# be checked out. -# -# File format: -# -# [][] -# -# comment lines begin with '#' diff --git a/CVSROOT/commitinfo b/CVSROOT/commitinfo deleted file mode 100644 index b19e7b7..0000000 --- a/CVSROOT/commitinfo +++ /dev/null @@ -1,15 +0,0 @@ -# The "commitinfo" file is used to control pre-commit checks. -# The filter on the right is invoked with the repository and a list -# of files to check. A non-zero exit of the filter program will -# cause the commit to be aborted. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being committed to, relative -# to the $CVSROOT. For the first match that is found, then the remainder -# of the line is the name of the filter to run. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/config b/CVSROOT/config deleted file mode 100644 index 92c150b..0000000 --- a/CVSROOT/config +++ /dev/null @@ -1,21 +0,0 @@ -# Set this to "no" if pserver shouldn't check system users/passwords -#SystemAuth=no - -# Put CVS lock files in this directory rather than directly in the repository. -#LockDir=/var/lock/cvs - -# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top -# level of the new working directory when using the `cvs checkout' -# command. -#TopLevelAdmin=no - -# Set `LogHistory' to `all' or `TOEFWUPCGMAR' to log all transactions to the -# history file, or a subset as needed (ie `TMAR' logs all write operations) -#LogHistory=TOEFWUPCGMAR - -# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg -# script to change the log message. Set it to `stat' to force CVS to verify# that the file has changed before reading it (this can take up to an extra -# second per directory being committed, so it is not recommended for large -# repositories. Set it to `never' (the previous CVS behavior) to prevent -# verifymsg scripts from changing the log message. -#RereadLogAfterVerify=always diff --git a/CVSROOT/cvswrappers b/CVSROOT/cvswrappers deleted file mode 100644 index e989b75..0000000 --- a/CVSROOT/cvswrappers +++ /dev/null @@ -1,19 +0,0 @@ -# This file affects handling of files based on their names. -# -# The -m option specifies whether CVS attempts to merge files. -# -# The -k option specifies keyword expansion (e.g. -kb for binary). -# -# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers) -# -# wildcard [option value][option value]... -# -# where option is one of -# -f from cvs filter value: path to filter -# -t to cvs filter value: path to filter -# -m update methodology value: MERGE or COPY -# -k expansion mode value: b, o, kkv, &c -# -# and value is a single-quote delimited value. -# For example: -#*.gif -k 'b' diff --git a/CVSROOT/editinfo b/CVSROOT/editinfo deleted file mode 100644 index d78886c..0000000 --- a/CVSROOT/editinfo +++ /dev/null @@ -1,21 +0,0 @@ -# The "editinfo" file is used to allow verification of logging -# information. It works best when a template (as specified in the -# rcsinfo file) is provided for the logging procedure. Given a -# template with locations for, a bug-id number, a list of people who -# reviewed the code before it can be checked in, and an external -# process to catalog the differences that were code reviewed, the -# following test can be applied to the code: -# -# Making sure that the entered bug-id number is correct. -# Validating that the code that was reviewed is indeed the code being -# checked in (using the bug-id number or a seperate review -# number to identify this particular code set.). -# -# If any of the above test failed, then the commit would be aborted. -# -# Actions such as mailing a copy of the report to each reviewer are -# better handled by an entry in the loginfo file. -# -# One thing that should be noted is the the ALL keyword is not -# supported. There can be only one entry that matches a given -# repository. diff --git a/CVSROOT/loginfo b/CVSROOT/loginfo deleted file mode 100644 index 537607d..0000000 --- a/CVSROOT/loginfo +++ /dev/null @@ -1,27 +0,0 @@ -# The "loginfo" file controls where "cvs commit" log information -# is sent. The first entry on a line is a regular expression which must match -# the directory that the change is being made to, relative to the -# $CVSROOT. If a match is found, then the remainder of the line is a filter -# program that should expect log information on its standard input. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name ALL appears as a regular expression it is always used -# in addition to the first matching regex or DEFAULT. -# -# You may specify a format string as part of the -# filter. The string is composed of a `%' followed -# by a single format character, or followed by a set of format -# characters surrounded by `{' and `}' as separators. The format -# characters are: -# -# s = file name -# V = old version number (pre-checkin) -# v = new version number (post-checkin) -# t = tag or branch name -# -# For example: -#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog -# or -#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog diff --git a/CVSROOT/modules b/CVSROOT/modules deleted file mode 100644 index cb9e9ef..0000000 --- a/CVSROOT/modules +++ /dev/null @@ -1,26 +0,0 @@ -# Three different line formats are valid: -# key -a aliases... -# key [options] directory -# key [options] directory files... -# -# Where "options" are composed of: -# -i prog Run "prog" on "cvs commit" from top-level of module. -# -o prog Run "prog" on "cvs checkout" of module. -# -e prog Run "prog" on "cvs export" of module. -# -t prog Run "prog" on "cvs rtag" of module. -# -u prog Run "prog" on "cvs update" of module. -# -d dir Place module in directory "dir" instead of module name. -# -l Top-level directory only -- do not recurse. -# -# NOTE: If you change any of the "Run" options above, you'll have to -# release and re-checkout any working directories of these modules. -# -# And "directory" is a path to a directory relative to $CVSROOT. -# -# The "-a" option specifies an alias. An alias is interpreted as if -# everything on the right of the "-a" had been typed on the command line. -# -# You can encode a module within a module by using the special '&' -# character to interpose another module into the current module. This -# can be useful for creating a module that consists of many directories -# spread out over the entire source repository. diff --git a/CVSROOT/notify b/CVSROOT/notify deleted file mode 100644 index 74ae6f9..0000000 --- a/CVSROOT/notify +++ /dev/null @@ -1,12 +0,0 @@ -# The "notify" file controls where notifications from watches set by -# "cvs watch add" or "cvs edit" are sent. The first entry on a line is -# a regular expression which is tested against the directory that the -# change is being made to, relative to the $CVSROOT. If it matches, -# then the remainder of the line is a filter program that should contain -# one occurrence of %s for the user to notify, and information on its -# standard input. -# -# "ALL" or "DEFAULT" can be used in place of the regular expression. -# -# For example: -#ALL mail -s "CVS notification" %s diff --git a/CVSROOT/rcsinfo b/CVSROOT/rcsinfo deleted file mode 100644 index 49e59f4..0000000 --- a/CVSROOT/rcsinfo +++ /dev/null @@ -1,13 +0,0 @@ -# The "rcsinfo" file is used to control templates with which the editor -# is invoked on commit and import. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being made to, relative to the -# $CVSROOT. For the first match that is found, then the remainder of the -# line is the name of the file that contains the template. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/taginfo b/CVSROOT/taginfo deleted file mode 100644 index 274a46d..0000000 --- a/CVSROOT/taginfo +++ /dev/null @@ -1,20 +0,0 @@ -# The "taginfo" file is used to control pre-tag checks. -# The filter on the right is invoked with the following arguments: -# -# $1 -- tagname -# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d -# $3 -- repository -# $4-> file revision [file revision ...] -# -# A non-zero exit of the filter program will cause the tag to be aborted. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being committed to, relative -# to the $CVSROOT. For the first match that is found, then the remainder -# of the line is the name of the filter to run. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/verifymsg b/CVSROOT/verifymsg deleted file mode 100644 index 86f747c..0000000 --- a/CVSROOT/verifymsg +++ /dev/null @@ -1,21 +0,0 @@ -# The "verifymsg" file is used to allow verification of logging -# information. It works best when a template (as specified in the -# rcsinfo file) is provided for the logging procedure. Given a -# template with locations for, a bug-id number, a list of people who -# reviewed the code before it can be checked in, and an external -# process to catalog the differences that were code reviewed, the -# following test can be applied to the code: -# -# Making sure that the entered bug-id number is correct. -# Validating that the code that was reviewed is indeed the code being -# checked in (using the bug-id number or a seperate review -# number to identify this particular code set.). -# -# If any of the above test failed, then the commit would be aborted. -# -# Actions such as mailing a copy of the report to each reviewer are -# better handled by an entry in the loginfo file. -# -# One thing that should be noted is the the ALL keyword is not -# supported. There can be only one entry that matches a given -# repository. diff --git a/README.txt b/README.rst similarity index 100% rename from README.txt rename to README.rst diff --git a/examples/README b/examples/README deleted file mode 100644 index efc5acd..0000000 --- a/examples/README +++ /dev/null @@ -1,97 +0,0 @@ -[Pywmdatetime] -Pywmdatetime is a WindowMaker dockapp for displaying time, date and -some other information. The colors and formats are easy to configure -through the configuration file or as command line arguments. Invoke -the program with --help or see the sample rc-file for more information. - -[Pywmgeneric] -Pywmgeneric is a dockapp with five entrys that display the first line of -output from an external program, the returned string from an python -method or an static string. Three mouse actions can be associated with -each displayed entry. - -[Pywmgeneric -- DETAILED] -Five different entries can be defined in pywmgeneric. Every entry can -have an action, an update_delay and up to three mouse actions associated -with it. Some additional options are also available. - -The associated action of an entry is executed with update_delay time -between executions. The output from the action is stored. If no special -display options are defined, the application will display the first line -of output from the action. If it does not fit in the window, it will -slowly scroll in the window. Clicking with the mouse on the text invokes -one of the mouse actions, depending on which button was pressed. The -action can be to execute an external program, to run a python method or -to update the text through performing the action associated with the -entry. The mouse actions can retreive the text genererated by the timed -action. - -Python methods that should be executed as actions should be defined in -the class UserMethods. Look in pywmgeneric.py, near the top, for this -class and the documentation of how these methods should be defined. -Note that the methods allready there only are samples and will probably -not work on your system. - -Other options in the configuration file include: -scroll = yes|no - en-/disable scrolling of the text when it doesn't fit -display = - display a static string instead of the first line of - the action-generated output. - -See the sample configuration file for examples and more information. -Note that this file is only for reference, it is the one I use. Things -will probably not work on your system if you do not change it. - -[Pywmgeneric -- USES] -This program is very generic (hence the name ;) ), the uses are many -since it is highly configurable. - -I use it for displaying my cpu and system temperatures. I just defined -methods for reading two files in the /proc filesystem on my system. - -I also use it for fetching headlines from a newspaper, displaying the -first headline fetched. If I click with my left button, all headlines -will appear in an xmessage. If I rightclick the headlines along with -summaries are displayed, and if I click with my middle button mozilla -will fire up showing the newspaper's website. - -I have an external program which displays what's currently on tv, -ideal for use with this program I thought! I modified it a bit so -it printed a summary line at the top, and voila I have all -currently running tv programs scrolling by in an dockapp. And clicking -on it shows me the details. - -You could use it as an application launcher, just display the name of -the applications and associate mouse actions to lauch them. The -xterm-entry in the sample shows this. - -You could probably come up with much more than this! - -[pywmhdmon] -pywmhdmon is a WindowMaker dockapp that displays the available space on -up to four of your filesystems. It also contains a bar showing the -current HD activity. It currently only works on system which has a -/proc/stat like file. The application is easy to configure, invoke it -with --help or see the sample rc-file for more information. - -[pywmhdmon -- BUGS] -The activity bar does not work with the proc filesystem that comes with -the 2.6 kernels. It is just a matter of rewriting the app to parse the -new format, but I'm low on time personally. - -[Pywmseti] -Pywmseti is an WindowMaker dockapp for monitoring your seti@home progress. -The application displays how many workunits you have done and the progress -on the current one. You start/stop the seti@home process by simply clicking -anywhere in the application. It also displays the time spent on the workunit -(or since you started the program if you restart it in the middle of a -workunit). Invoke the program with --help or see the sample rc-file for -more information about customization. - -[pywmsysmon] -pywmsysmon is a WindowMaker dockapp that displays your cpu and memory -usages. The upper graph shows your cpu usage history and the lower -"progress bar" shows your current memory usage excluding cached and -buffered data. This program currently only works on systems which got -the /proc/stat and /proc/meminfo files available. Invoke the program -with --help for information about customization. - diff --git a/examples/pywmdatetime.py b/examples/pywmdatetime.py deleted file mode 100755 index aee67bf..0000000 --- a/examples/pywmdatetime.py +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env python - -"""pywmdatetime.py - -WindowMaker dockapp that displays time, date, weekday and week number. - -Copyright (C) 2003 Kristoffer Erlandsson - -Licensed under the GNU General Public License. - - -Changes: -2003-09-01 Kristoffer Erlandsson -Fixed a bug where the week didn't update if we used %q style week numbering. - -2003-06-28 Kristoffer Erlandsson -Fixed a bug where a mouse click caused an infinite loop - -2003-06-26 Kristoffer Erlandsson -Fixed bug when longer strings didn't get cleared when shorter ones where -painted. Now only repaint the strings when they have changed. - -2003-06-24 Kristoffer Erlandsson -Added event handling for graceful shutdown - -2003-06-16 Kristoffer Erlandsson -First workingish version -""" - -import sys -import time -import os - -from wmdocklib import wmoo, readConfigFile - -width = 64 -height = 64 - -xOffset = 4 -yOffset = 4 - -patterns = [ -".+@@+.....#@...#@@#...#@@#....$@%...@@@@+..+=@%..+@@@@@..%@@+...&@@#.....", -"$@==@$...+@@..&@--@&.*@--@&...#@%..*@-%%*.$==-@&.*%%%@=.#@-=@*.*@=-@&....", -"&@**@&..#@@@..&@$.@%.&-..@%..*@@%..+@+....+@*.%*....+@*.%@.+@+.%@$.-%.*+.", -"%@..@%..#+%@.....$@%....+@#..--@%..&@=@#..%@$+$.....--..&@&%@$.%@..%@.%@.", -"%@..@%....%@.....%@*...%@-..*@$@%..%@%=@*.%@=@@*...*@&...=@@#..&@%&@@.*+.", -"%@..@%....%@....+@%....&-@+.=#.@%...*.$@%.%@%&@-...#@...#@&%@*..=@@@@....", -"%@..@%....%@...+@=$......-@.@-%@=&.....@%.%@..%@...=-...@%..@%...+*%@.&%.", -"&@**@&....%@..$@=$...&-..-@.@@@@@%.--.*@#.+@$.-@...@%...@-.$@%.$#*.=%.%@.", -"$@==@$....%@..#@-%%&.+@--@#....@%..%@-=@$.$@=-@#..+@+...#@-=@*.$@=-@+....", -".+@@+.....%@..@@@@@%..#@@#.....@%..$-@=+...+=@%$..+@+...$#@@&...+@@#.....", -] -palette = { - ".":"#181818", - "+":"#6E6E0F", - "@":"#FFFF00", - "#":"#A0A009", - "$":"#3B3B14", - "%":"#B9B907", - "&":"#87870C", - "*":"#545411", - "=":"#E6E602", - "-":"#CFCF04", - } - -timeDefaultFormat = '%H:%M:%S' -dateDefaultFormat = '%d-%m-%y' -dayDefaultFormat = '%A' -weekDefaultFormat = 'wk %q' # %q added by Kristoffer for different week calculation. - -defaultConfigFile = '~/.pywmdatetimerc' - -class Application(wmoo.Application): - - def __init__(self): - - from optparse import OptionParser - - parser = OptionParser() - parser.add_option('-a', '--antialiased', dest='antialiased', - action="store_true", default=False) - parser.add_option('-f', '--foreground', type='string', default='cyan3') - parser.add_option('-F', '--font', type='string', default='6x8orig') - parser.add_option('-b', '--background', type='string', default='black') - parser.add_option('-t', '--timeformat', type='string', default=timeDefaultFormat) - parser.add_option('-d', '--dateformat', default=dateDefaultFormat) - parser.add_option('-y', '--weekdayformat', default=dayDefaultFormat) - parser.add_option('-e', '--weekformat', default=weekDefaultFormat) - parser.add_option('--height', type='int', default=64) - parser.add_option('-r', '--rgbfile') - #parser.add_option('-c', '--configfile', default=defaultConfigFile) - parser.add_option('--debug', action='store_true', default=False) - - configFile = os.path.expanduser("~/.pywmdatetimerc") - # Merge the two configs, let the commandline options overwrite those in the - # configuration file. - config = readConfigFile(configFile, sys.stderr) - parser.set_defaults(**config) - - (options, args) = parser.parse_args() - - palette[0] = options.background - palette[2] = options.foreground - - self.hpad = hpad = (64 - options.height) / 2 - - if options.antialiased: - background = [((6,3+hpad),(57,19+hpad)), - ((3,22+hpad),(60,60-hpad))] - else: - background = [((3,3+hpad),(59,60-hpad))] - - wmoo.Application.__init__(self, - patterns=patterns, - font_name=options.font, - bg=0, fg=2, palette=palette, - background=background, - debug=options.debug) - - - if options.antialiased: - self.addWidget('date', wmoo.Label, orig=(4,24+hpad), size=(54,10), align=wmoo.CENTRE) - self.addWidget('day', wmoo.Label, orig=(4,36+hpad), size=(54,10), align=wmoo.CENTRE) - if 48+hpad <= 50: - self.addWidget('week', wmoo.Label, orig=(4,48), size=(54,10), align=wmoo.CENTRE) - else: - self.addWidget('time', wmoo.Label, orig=(4, 5+hpad), size=(54,10), align=wmoo.CENTRE) - self.addWidget('time2', wmoo.Label, orig=(4,16+hpad), size=(54,10), align=wmoo.CENTRE) - self.addWidget('date', wmoo.Label, orig=(4,27+hpad), size=(54,10), align=wmoo.CENTRE) - self.addWidget('day', wmoo.Label, orig=(4,38+hpad), size=(54,10), align=wmoo.CENTRE) - if 49+hpad <= 50: - self.addWidget('week', wmoo.Label, orig=(4,49+hpad), size=(54,10), align=wmoo.CENTRE) - - self.timeFmt = options.timeformat - self.dateFmt = options.dateformat - self.dayFmt = options.weekdayformat - self.weekFmt = options.weekformat - self.antialiased = options.antialiased - self.debug = options.debug - - self.recalcWeek = self.weekFmt.find('%q') + 1 # True if we found %q. - self.counter = -1 - self.lastStrs = [''] * 4 - - pass - - def calculateWeek(self, localTime): - """Calculate the week number as we do, for example in Sweden. - - That is, add one to the %W format if the year didn't start on a monday.""" - day = int(time.strftime('%j', localTime)) - weekDay = int(time.strftime('%w')) - 1 - if weekDay == -1: - weekDay = 6 - lastMonday = day - weekDay - if lastMonday % 7 == 0: - return int(time.strftime('%W')) - return int(time.strftime('%W')) + 1 - - def updateTimeString(self, s): - if self.antialiased: - x, y = 8, 6+self.hpad - for c in s: - charW = 7 - charX = (ord(c) - ord('0')) * 7 - if not c.isdigit(): - charX = 70 - charW = 3 - self.putPattern(charX, 0, charW, 10, x, y) - x += charW - else: - self['time'].setText(s) - - def update(self): - self.counter += 1 - lt = time.localtime() - timeStr = time.strftime(self.timeFmt, lt) - self.updateTimeString(timeStr) - self.lastStrs[0] = timeStr - if self.counter % 100 == 0: - # We only perform the date/week checks/updates once every 100th - # iteration. We will maybe lag behind a couple of seconds when - # switching, but switching occurs seldom and it will be alot of - # unnecessary checks :). - dateStr = time.strftime(self.dateFmt, lt) - newWeekFmt = self.weekFmt - if self.recalcWeek: - week = self.calculateWeek(lt) - newWeekFmt = self.weekFmt.replace('%q', str(week)) - weekStr = time.strftime(newWeekFmt, lt) - dayStr = time.strftime(self.dayFmt, lt) - if self.lastStrs[1] != dateStr: - self['date'].setText(dateStr) - self.lastStrs[1] = dateStr - if self.lastStrs[2] != dayStr: - self['day'].setText(dayStr) - self.lastStrs[2] = dayStr - if self.lastStrs[3] != weekStr: - if 'week' in self._widgets: - self['week'].setText(weekStr) - self.lastStrs[3] = weekStr - -if __name__ == '__main__': - app = Application() - app.run() diff --git a/examples/pywmgeneric.py b/examples/pywmgeneric.py deleted file mode 100644 index f2e9897..0000000 --- a/examples/pywmgeneric.py +++ /dev/null @@ -1,679 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -"""pywmgeneric.py - -WindowMaker dockapp to display the output from an external program, or the -string returned from a python function. Mouse actions can be associated with -the displayed text. - -Copyright (C) 2003 Kristoffer Erlandsson - -Licensed under the GNU General Public License. - - -Changes -2003-07-02 Kristoffer Erlandsson -Added support for up to 10 mouse buttons. -The char translation now handles both upper and lower case. - -2003-06-29 Kristoffer Erlandsson -Additional error checking around string interpolations from cfg file. - -2003-06-27 Kristoffer Erlandsson -First working version -""" - -usage = """pywmgeneric.py [options] -Available options are: - -h, --help print this help - -t, --text set the text color - -b, --background set the background color - -F, --font set the font name - -r, --rgbfile set the rgb file to get color codes from - -c, --configfile set the config file to use -""" - -import sys -import os -import time -import string -import ConfigParser -import getopt -import popen2 - -import wmdocklib - -prevStat = {'user':0, - 'nice':0, - 'sys':0, - 'idle':0, - 'total':0, - } -import re -cpuinfo = re.compile(r'^cpu[^ ]* +(?P[0-9]+) +(?P[0-9]+)' - r'+(?P[0-9]+) +(?P[0-9]+)') - -class UserMethods: - """Put methods that should be called when the action is method=... here. - - The action methods should return a function, which in turn returns - the string to be displayed (if no 'display =' exists) and stored - for later retreival. - - The mouse action methods gets the entry instance as an argument. Return - value doesn't matter. - - An instance of this class is created at initialization and passed to all - entries, so keep in mind that they share the same object. - - THE METHODS ALREADY HERE ARE JUST SAMPLES AND WILL PROBABLY NOT WORK - WITH YOUR SYSTEM. - """ - - userTicks = sysTicks = niceTicks = idleTicks = 0 - - def getCpuTemp(self): - def result(): - global prevStat - try: - f = file('/proc/stat', 'r') - except IOError: - return 'error' - - currStat = dict( - [(k, int(v)) - for (k,v) in cpuinfo.match(f.readline()).groupdict().items()] - ) - f.close() - - total = 0 - for k,v in currStat.items(): - total += v - currStat['total'] = total - totalTicks = (currStat['total'] - prevStat['total']) - - result = {} - if (totalTicks <= 0): - return '00/00/00' - - for k in prevStat: - result[k] = (100. * (currStat[k] - prevStat[k])) / totalTicks - prevStat = currStat - - return '%(user)02.f/%(sys)02.f/%(idle)02.f' % result - return result - - def getSysTemp(self): - try: - f = file('/proc/sys/dev/sensors/w83697hf-isa-0290/temp1', 'r') - except IOError: - return lambda: 'error' - temp = f.readline().split()[2] - f.close() - return lambda: 'sys: %s' % temp - - def ls(self): - return lambda: 'boh' - - def showDnWithoutDescs(self, entry): - """Strip descriptions from some text where the descs are indented. - - Display it in an xmessage. - """ - text = entry.getAllText() - s = '\n'.join([x for x in text.split('\n') if not x.startswith(' ')]) - os.system('xmessage "' + s.replace('"', r'\"') + '" &') - - def showTvWithoutDescs(self, entry): - """Strip descriptions from some text where the descs are indented. - - Display it in an xmessage. - """ - text = entry.getAllText() - s='\n'.join([x for x in - text.split('\n')[1:] if not x.startswith(' ')]) - s = s.replace('\n\n', '\n') - os.system('xmessage "' + s.replace('"', r'\"') + '" &') - -width = 64 -height = 64 - -xOffset = 4 -yOffset = 4 - -maxChars = 13 - -defaultConfigFile = '~/.pywmgenericrc' -defaultRGBFiles = ('/usr/share/X11/rgb.txt', '/usr/X11R6/lib/X11/rgb.txt') - -err = sys.stderr.write - -def addString(s, x, y): - """Convenience function around pwymhelpers.addString.""" - try: - wmdocklib.addString(s, x, y, xOffset, yOffset, - width, height) - except ValueError, e: - sys.stderr.write('Error when painting string:\n' + str(e) + '\n') - sys.exit(3) - -def clearLine(y): - """Clear a line of text at position y.""" - wmdocklib.copyXPMArea(0, 64+yOffset, - width - 2 * xOffset, char_height, - xOffset, y + yOffset) - -def getXY(line): - """Return the x and y positions to be used at line line.""" - return 0, line * (char_height + 3) + 1 - -def isTrue(s): - """Return true if the string s can be interpreted as a true value. - - Raises ValueError if we get a string we don't like. - """ - trueThings = ['on', 'yes', '1', 'true'] - falseThings = ['off', 'no', '0', 'false'] - if s in trueThings: - return 1 - elif s in falseThings: - return 0 - raise ValueError - - -class Entry: - def __init__(self, line, updateDelay, action, mouseActions, - userMethods, display=None, scrollText=1): - self._updateDelay = updateDelay - self._line = line - self._action = self._parseAction(action) - self._mouseActions = [self._parseAction(a) for a in mouseActions] - self._userMethods = userMethods - self._display = display - self._scrollText = scrollText - - self._glue = ' ... ' - self._scrollPos = 0 - self._tickCount = 0L - - self._runningProcs = [] - self._actionProc = None - self._getTextMethod = None - self._allText = '' - self._displayLine = '' - # Do one action when we start, so we are sure that one gets done even - # if we do not want any other updates. - self._doAction() - self._lastActionAt = time.time() - - def _parseAction(self, action): - """Parse an action string, return (, ). - - Or none if we get an empty action.""" - if action: - whatToDo = action.split()[0] - argStr = action[len(whatToDo):].lstrip() - return (whatToDo, argStr) - return None - - def _execExternal(self, command): - """Exec an external command in the background. - - Return the running process as created by Popen3().""" - proc = popen2.Popen3(command) - self._runningProcs.append(proc) - return proc - - def _doMouseAction(self, button): - """Perform the mouse action associated with a button.""" - if len(self._mouseActions) < button: - return # Just for safety, shouldn't happen. - item = self._mouseActions[button - 1] - if item: - # We have an action associated with the button. - action, arg = item - else: - # No action associated with the button. - return - if action == 'exec': - self._execExternal(self._expandStr(arg)) - elif action == 'method': - try: - method = getattr(self._userMethods, arg) - except AttributeError: - method = None - if method: - method(self) - else: - err("Warning: Method %s does not exist." % arg) - elif action == 'update': - self._doAction() - else: - err("Warning: Unknown mouse action: %s, ignoring.\n" % action) - - def _doAction(self): - """Perform the action associated with this entry.""" - if self._action is None: - return - action, arg = self._action - if action == 'exec': - if self._actionProc is None : - self._actionProc = self._execExternal(arg) - else: - if not self._actionProc in self._runningProcs: - # The action process since the last time is finished, we - # can start another one without risking that we get - # flooded by processes. - self._actionProc = self._execExternal(arg) - self._getTextMethod = self._readFromActionProc - elif action == 'method': - try: - method = getattr(self._userMethods, arg) - except AttributeError: - method = None - if method: - self._getTextMethod = method() - else: - err('Warning: method %s does not exist. Ignoring.\n' % arg) - else: - err("Warning: Unknown action: %s, ignoring.\n" % action) - - def _readFromActionProc(self): - """If our action process is ready, return the output. Otherwise None. - """ - if self._actionProc.poll() == -1: - # Wait until the process is ready before we really read the text. - return None - # fromchild.read() will return '' if we allready have read the output - # so there will be no harm in calling this method more times. - return self._actionProc.fromchild.read() - - def _reapZombies(self): - """Poll all running childs. This will reap all zombies.""" - i = 0 - for p in self._runningProcs: - val = p.poll() - if val != -1: - self._runningProcs.pop(i) - i += 1 - - def _updateText(self): - """Get the text, update the display if it has changed. - """ - text = '' - if self._getTextMethod: - text = self._getTextMethod() - # Only change the text if we get anything from the getTextMethod() - if text: - self._allText = text - if self._display is None: - # We have no display = in the config file, we want to - # display the first line of the output of the action. - if text: - displayLine = text.split(os.linesep)[0] - else: - displayLine = self._displayLine - else: - displayLine = self._display - if displayLine != self._displayLine: - # Line to display has changed, display the new one. - self._displayLine = displayLine - self._scrollPos = 0 - self.displayText(displayLine) - elif len(self._displayLine) > maxChars and self._scrollText: - # Line is the same and is longer than the display and we - # want to scroll it. - if self._tickCount % 2 == 0: - # Only scroll every third tick. - self._scrollAndDisplay() - - def _scrollAndDisplay(self): - """Scroll the text one step to the left and redisplay it. - - When reaching the end, paint number of spaces before scrolling in the - same line again from the right. - """ - - # increase the amount of scrolled chars by one, modulo the lenght. - # take the line, append to it some glue and a copy of the line - # again, drop as many characters as the updated scrollPos, display - # the resulting text. - self._scrollPos += 1 - self._scrollPos %= len(self._displayLine) + len(self._glue) - disp = self._displayLine + self._glue + self._displayLine - disp = disp[self._scrollPos:] - self.displayText(disp) - - def tick1(self): - """Do things that should be done often. - """ - self._tickCount += 1 - self._reapZombies() - self._updateText() - currTime = time.time() - if not self._updateDelay is None and \ - currTime - self._lastActionAt > self._updateDelay: - # We want to do this last in the tick so the command gets the time - # to finish before the next tick (if it's a fast one). - self._lastActionAt = currTime - self._doAction() - - def tick2(self): - """Do things that should be done a bit less often. - """ - pass - - def translateText(self, text): - """Translate chars that can't be painted in the app to something nicer. - - Or nothing if we can't come up with something good. Could be nice to - extend this function with chars more fitting for your language. - """ - fromChars = u'ñźńśćżłáéíóúàèìòùâêîôûäëïöüãẽĩõũ' - toChars = u'nznsczlaeiouaeiouaeiouaeiouaeiou' - for frm, to in zip(fromChars, toChars): - text = text.replace(frm, to) - text = text.replace(frm.upper(), to.upper()) - text = ''.join([i for i in text if 32 <= ord(i) < 128]) - return text - - def getAllText(self): - return self._allText - - def getDisplayedLine(self): - return self._displayLine - - def _expandStr(self, s): - """Expand s, which now should be a line from an on_mouseX field. - """ - try: - res = s % {'allText' : self._allText, - 'displayedLine' : self._displayLine, - 'allTextEscaped' : self._allText.replace('"', r'\"'), - 'allTextButFirstLine' : - '\n'.join(self._allText.split('\n')[1:]), - 'allTextButFirstLineEscaped' : - '\n'.join(self._allText.replace('"', '\"'). - split('\n')[1:])} - except (KeyError, TypeError, ValueError): - err( - "Warning: %s doesn't expand correctly. Ignoring interpolations.\n" - % s) - res = s - return res - - def displayText(self, text): - """Display text on the entry's line. - - Remove or translate characters that aren't supported. Truncate the text - to fit in the app. - """ - x, y = getXY(self._line) - clearLine(y) - addString(self.translateText(text)[:maxChars], x, y) - - def mouseClicked(self, button): - """A mouse button has been clicked, do things.""" - if 0 < button < 11: - self._doMouseAction(button) - -class PywmGeneric: - def __init__(self, config): - self._entrys = [] - line = 0 - um = UserMethods() - for c in config: - # Create our 5 entrys. - if not c: - self._entrys.append(None) - line += 1 - continue - delay = c.get('update_delay') - if not delay is None: - try: - delay = self.parseTimeStr(delay) - except ValueError: - err("Malformed update_delay in section %s. " - % str(i)) - err("Ignoring this section.\n") - self._entrys.append(None) - line += 1 - continue - action = c.get('action') - display = c.get('display') - if action is None and display is None: - err( - "Warning: No action or display in section %d, ignoring it.\n" - % i) - self._entrys.append(None) - else: - scroll = isTrue(c.get('scroll', '1')) - # Get the mouse actions. - mouseActions = [] - for i in range(10): - but = str(i + 1) - opt = 'on_mouse' + but - mouseActions.append(c.get(opt)) - self._entrys.append(Entry(line, delay, action, - mouseActions, um, display, scroll)) - line += 1 - self._setupMouseRegions() - - def _setupMouseRegions(self): - for i in range(5): - x, y = getXY(i) - if not self._entrys[i] is None: - wmdocklib.addMouseRegion(i, x + xOffset, y + yOffset, - width - 2 * xOffset, y + yOffset + char_height) - - def parseTimeStr(self, timeStr): - """Take a string on a form like 10h and return the number of seconds. - - Raise ValueError if timeStr is on a bad format. - """ - multipliers = {'s' : 1, 'm' : 60, 'h' : 3600} - timeStr = timeStr.strip() - if timeStr: - timeLetter = timeStr[-1] - multiplier = multipliers.get(timeLetter) - if not multiplier is None: - timeNum = float(timeStr[:-1].strip()) - numSecs = timeNum * multiplier - return numSecs - raise ValueError, 'Invalid literal' - - def _checkForEvents(self): - event = wmdocklib.getEvent() - while not event is None: - if event['type'] == 'destroynotify': - sys.exit(0) - elif event['type'] == 'buttonrelease': - region = wmdocklib.checkMouseRegion(event['x'], event['y']) - button = event['button'] - if region != -1: - if not self._entrys[region] is None: - self._entrys[region].mouseClicked(button) - event = wmdocklib.getEvent() - - def mainLoop(self): - counter = -1 - while 1: - counter += 1 - self._checkForEvents() - if counter % 2 == 0: - [e.tick1() for e in self._entrys if not e is None] - if counter % 20 == 0: - [e.tick2() for e in self._entrys if not e is None] - - if counter == 999999: - counter = -1 - wmdocklib.redraw() - time.sleep(0.5) - -def parseCommandLine(argv): - """Parse the commandline. Return a dictionary with options and values.""" - shorts = 'ht:b:r:c:F:' - longs = ['help', 'text=', 'background=', 'rgbfile=', 'configfile=', - 'font=', 'debug'] - try: - opts, nonOptArgs = getopt.getopt(argv[1:], shorts, longs) - except getopt.GetoptError, e: - err('Error when parsing commandline: ' + str(e) + '\n') - err(usage) - sys.exit(2) - d = {} - for o, a in opts: - if o in ('-h', '--help'): - sys.stdout.write(usage) - sys.exit(0) - if o in ('-t', '--text'): - d['text'] = a - if o in ('-b', '--background'): - d['background'] = a - if o in ('-F', '--font'): - d['font'] = a - if o in ('-r', '--rgbfile'): - d['rgbfile'] = a - if o in ('-c', '--configfile'): - d['configfile'] = a - if o in ('--debug'): - d['debug'] = True - return d - -def readConfigFile(fileName): - """Read the config file. - - Return a list with dictionaries with the options and values in sections - [0]-[4]. - """ - fileName = os.path.expanduser(fileName) - if not os.access(fileName, os.R_OK): - err("Can't read the configuration file %s.\n" % fileName) - # We can't do much without a configuration file - sys.exit(3) - cp = ConfigParser.ConfigParser() - try: - cp.read(fileName) - except ConfigParser.Error, e: - err("Error when reading configuration file:\n%s\n" % str(e)) - sys.exit(3) - l = [{}, {}, {}, {}, {}] - for i in range(5): - strI = str(i) - if cp.has_section(strI): - for o in cp.options(strI): - l[i][o] = cp.get(strI, o, raw=1) - return l - -background = \ -[ - ' ...............................................................................................', - ' .///..___..ooo..___..___.......................................................................', - ' .///..___..ooo..___..___.......................................................................', - ' .///..___..ooo..___..___.......................................................................', - ' .///.._________________________________________________________________________________________', - ' .///.._________________________________________________________________________________________', - ' .///.._________________________________________________________________________________________', - ' .///.._________________________________________________________________________________________', - ' .///.._________________________________________________________________________________________', - ' .///.._________________________________________________________________________________________', - ' .///.._________________________________________________________________________________________', - ' .///.._________________________________________________________________________________________', - ' .///..___..___..___..___.......................................................................', - ' .///..___..___..___..ooo.......................................................................', - ' .///..___..___..___..ooo.......................................................................', - ' .///..___..___..___..ooo.......................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...........................................................................................', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' ...............................................................................................', - ' ...............................................................................................', - ] - -def main(): - clConfig = parseCommandLine(sys.argv) - - palette = { - '.': '#0000FF', - 'o': '#C7C3C7', - 'O': '#86828E', - '+': '#EFF3EF', - '@': '#616161', - '#': '#9EA29E', - '$': '#414141', - } - - palette['o'] = clConfig.get('indicator', '#20b2aa') - palette['/'] = clConfig.get('graph', '#20b2aa') - palette['-'] = clConfig.get('graphbg', '#707070') - palette['_'] = clConfig.get('background', '#FFFFFF') - palette['%'] = clConfig.get('text', '#20B2AE') - - font = clConfig.get('font', '6x8') - - configFile = clConfig.get('configfile', defaultConfigFile) - if not configFile.count(os.sep): - configFile = os.sep.join(sys.argv[0].split(os.sep)[:-1]) + os.sep + configFile - configFile = os.path.expanduser(configFile) - config = readConfigFile(configFile) - try: - programName = sys.argv[0].split(os.sep)[-1] - except IndexError: - programName = '' - sys.argv[0] = programName - - global char_width, char_height - char_width, char_height = wmdocklib.initPixmap(#patterns=background, - font_name=font, - bg='_', fg='%', - palette=palette) - - wmdocklib.openXwindow(sys.argv, width, height) - pywmgeneric = PywmGeneric(config) - pywmgeneric.mainLoop() - -if __name__ == '__main__': - main() diff --git a/examples/pywmhdmon.py b/examples/pywmhdmon.py deleted file mode 100755 index 4df2383..0000000 --- a/examples/pywmhdmon.py +++ /dev/null @@ -1,541 +0,0 @@ -#!/usr/bin/env python - -"""pywmhdmon.py - -WindowMaker dockapp to monitor the free space on your partitions and -the disk activity. - -Copyright (C) 2003 Kristoffer Erlandsson - -Licensed under the GNU General Public License. - - -Changes - -2005-09-02 Mario Frasca - added -s option for skipping an amount of configuration items. - changed some single quotes to double quotes for use in emacs. - updated the rc sample file - -2004-07-16 Mario Frasca - recognizes unmounted partitions. - configurable mouse actions. - 'used' information for read-only media. - recognizes #-started numerical-coded colors. - -2003-09-01 Kristoffer Erlandsson -Fixed a bug where the numbers wouldn't show if they were between 1000 and 1024. - -2003-06-25 Kristoffer Erlandsson -Fixed a bug where a mouse click caused the app to enter an infinite loop - -2003-06-24 Kristoffer Erlandsson -Additional fine tuning - -2003-06-23 Kristoffer Erlandsson -First working version - -""" - -usage = """pywmhdmon.py [options] -Available options are: --h, --help print this help --t, --textcolor set the text color --f, --barfgcolor set the foregroundcolor of the act. bar --g, --barbgcolor set the background color of the act. bar --b, --background set the background color --F, --font set the font name --r, --rgbfile set the rgb file to get color codes from --c, --configfile set the config file to use --p, --procstat set the location of /proc/stat --s, --skipconf determines how many configuration items to skip -""" - -import sys -import time -import getopt -import os - -import wmdocklib - -width = 64 -height = 64 - -xOffset = 4 -yOffset = 5 - -graphStartX = 7 -graphStartY = 53 -graphHeight = 4 - -graphBgStartX = 72-64 -graphBgStartY = 53+64 - -graphLineStartX = 2 -graphLineStartY = 58+64 - -defaultConfigFile = os.environ['HOME']+'/.pywmhdmonrc' -defaultProcStat = '/proc/stat' -displayModes = ('bar', 'percent', 'free', 'used') -defaultMode = 'bar' - -hdmon = None - -class NotMounted(OSError): - pass - -class PywmHDMon: - def __init__(self, pathsToMonitor, procStat='/proc/stat', actMonEnabled=1, skipping=0): - self._pathsToMonitor = pathsToMonitor - self._actMonEnabled = actMonEnabled - self._skipping = skipping - self._lineCount = (height - yOffset*2 - 2) / (char_height+1) - - self._statFile = procStat - self._maxIODiff = 0 - self._lastIO = -1 - for i in range(max(self._lineCount, len(pathsToMonitor)-skipping)): - wmdocklib.addMouseRegion(i+1, 8, self.getY(i+1)+yOffset, - 58, self.getY(i+1)+char_height+yOffset) - - - def addString(self, s, x, y): - try: - wmdocklib.addString(s, x, y, xOffset, yOffset, width, height) - except ValueError, e: - sys.stderr.write('Error when painting string:\n' + str(e) + '\n') - sys.exit(3) - - def getHdInfo(self, path): - """Get the free and total space of the filesystem which path is on. - - Return a tuple with (, ) in bytes. Raise - OSError if we can't stat the path. Raise NotMounted if not mounted. - These operations are quite costly, not adviced to perform these checks - more than once every 10 seconds. - """ - - # check if is mounted <- st_dev(/mount/point) == st_dev(/mount) - if path is not '/': - statOwn = os.stat(path) - - # the following is a bit ugly: it removes the trailing - # dirname from the mount point. split by '/', leave the - # last string, join back, check for empty string. - statCnt = os.stat('/'.join(path.split('/')[:-1]) or '/') - if statOwn[2] == statCnt[2]: - raise NotMounted - stat = os.statvfs(path) - blockSize = stat.f_bsize - availableBlocks = stat.f_bavail - totalBlocks = stat.f_blocks - free = blockSize * availableBlocks - total = blockSize * totalBlocks - return (total, free) - - def paintGraph(self, percentFilled, x, y, w, thin=None): - """Paint a graph with percentFilled percent filled. - - Paint at position x, y and with width w. - if thin == 1, make it a thin line instead of a block. - """ - paintWidth = int(round(percentFilled/100.0 * w)) - if paintWidth > 0: - wmdocklib.copyXPMArea( - graphLineStartX, graphLineStartY, paintWidth, thin or graphHeight, - x + xOffset, y + yOffset) - if w - paintWidth > 0: - wmdocklib.copyXPMArea( - graphBgStartX, graphBgStartY, w - paintWidth, thin or graphHeight, - x + paintWidth + xOffset, y + yOffset) - - def getY(self, line): - "returns the y coordinate of the top line for the box" - interlinea = (height - yOffset*2 - 2 - self._lineCount * char_height) / (self._lineCount-1) - interlinea += char_height - lastBaseline = yOffset + self._lineCount * interlinea - from math import ceil - extraYOffset = int(ceil((height - yOffset - lastBaseline) / 2.0)) - return extraYOffset + (line - 1) * interlinea - - def paintLabel(self, line, label): - self.addString(label, 1, self.getY(line)) - - def paintHdData(self, line, data, mode): - total, free = data - xStart = (width*2)/5 - if total==0: - self.addString(' ', width-yOffset*2-5*char_width-1, self.getY(line)) - self.paintGraph(0, xStart, self.getY(line) + 4, - width - xOffset*2 - xStart - 2, - thin=1) - pass - elif mode == 'percent': - percent = (float(free) / float(total)) * 100.0 - percentStr = (str(int(round(percent))) + '%').rjust(5) - self.addString(percentStr, xStart, self.getY(line)) - elif mode == 'used': - totalStr = bytesToStr(total).rjust(5) - self.addString(totalStr, width-yOffset*2-5*char_width-1, self.getY(line)) - elif mode == 'free': - freeStr = bytesToStr(free).rjust(5) - self.addString(freeStr, width-yOffset*2-5*char_width, self.getY(line)) - elif mode == 'bar': - percentUsed = (float(total - free) / float(total)) * 100.0 - self.paintGraph(percentUsed, xStart, self.getY(line) + 2, - width - xOffset*2 - xStart - 2) - else: - sys.stderr.write('Unknown display mode: %s, ignoring data.\n' - % mode) - def getHdActivity(self): - """Return the current hd activity in percent. - - Return how many percent of the max achieved activity during the - program's lifetime the current activity is. However, every time - this method is called we decrease the max achieved activity a - little bit to get a bit less affected by spikes. I think the - interesting thing is to see if the hard drive is active, not - really exactly how active. - """ - - statFile = file(self._statFile, 'r') - diskIoStartTag = 'disk_io: ' - ioLine = None - for line in statFile: - if line.startswith(diskIoStartTag): - ioLine = line - statFile.close() - if ioLine is None: - # Can't get HD activity - sys.stderr.write("Can't get hd activity from %s\n" % - self._statFile) - return 0.0 - ioLine = ioLine[len(diskIoStartTag):] - disks = ioLine.split() - currIO = 0 - for disk in disks: - dataPart = disk.split(':')[1].strip(')(') - infos = dataPart.split(',') - blocksRead = long(infos[2]) - blocksWritten = long(infos[4]) - currIO += blocksRead + blocksWritten - if self._lastIO == -1: - self._lastIO = currIO - currDiff = currIO - self._lastIO - self._lastIO = currIO - if currDiff > self._maxIODiff: - self._maxIODiff = currDiff - if self._maxIODiff <= 0: - self._maxIODiff = 0 - return 0.0 - currAct = (float(currDiff) / float(self._maxIODiff)) * 100.0 - self._maxIODiff -= 1 # So spikes won't affect us too much. - return currAct - - def updateHdActivity(self): - currentAct = self.getHdActivity() - self.paintGraph(currentAct, 3, height - yOffset*2 - 3 - graphHeight, - width - 2 * xOffset - 6) - - def _checkEvents(self): - event = wmdocklib.getEvent() - while event is not None: - if event['type'] == 'destroynotify': - sys.exit(0) - elif event['type'] == 'buttonrelease': - area = wmdocklib.checkMouseRegion(event['x'],event['y']) - if area is not -1: - self.toggleMount(area-1+self._skipping) - event = wmdocklib.getEvent() - - def toggleMount(self, line): - label, path, mode, action = self._pathsToMonitor[line] - if action is None: - return - try: - self.getHdInfo(path) - mounted = True - except NotMounted: - mounted = False - except OSError, e: - return - if mounted: - if action == 'mount': - os.spawnvp(os.P_NOWAIT, 'umount', ['umount', path]) - elif action == 'eject': - os.spawnvp(os.P_WAIT, 'umount', ['umount', path]) - os.spawnvp(os.P_NOWAIT, 'eject', ['eject', path]) - else: - os.spawnvp(os.P_NOWAIT, 'mount', ['mount', path]) - - def updateMonitoredPaths(self): - index = 0 - pageoffset = self._skipping - for i in self._pathsToMonitor: - index += 1 - if index < pageoffset+1: - continue - if i is not None: - label, path, mode, action = i - self.paintLabel(index-pageoffset, label) - try: - hdData = self.getHdInfo(path) - except NotMounted: - hdData = (0, 0) - except OSError, e: - sys.stderr.write( - "Can't get hd data from %s: %s\n" % (path, str(e))) - hdData = (0, 0) - self.paintHdData(index-pageoffset, hdData, mode) - if index - pageoffset == self._lineCount: - break - - def mainLoop(self): - self.updateMonitoredPaths() - while 1: - self._checkEvents() - if self._actMonEnabled: - self.updateHdActivity() - wmdocklib.redraw() - time.sleep(0.1) - - -import signal -def handler(num, frame): - hdmon.updateMonitoredPaths() - signal.alarm(10) - -def parseCommandLine(argv): - """Parse the commandline. Return a dictionary with options and values.""" - shorts = 'ht:f:g:b:r:c:p:s:F:' - longs = ['help', 'textcolor=', 'background=', 'barfgcolor=', - 'rgbfile=', 'configfile=', 'barbgcolor=', 'procstat=', - 'skipconf=','font=', 'debug'] - try: - opts, nonOptArgs = getopt.getopt(argv[1:], shorts, longs) - except getopt.GetoptError, e: - sys.stderr.write('Error when parsing commandline: ' + str(e) + '\n') - sys.stderr.write(usage) - sys.exit(2) - d = {} - for o, a in opts: - if o in ('-h', '--help'): - sys.stdout.write(usage) - sys.exit(0) - if o in ('-t', '--textcolor'): - d['textcolor'] = a - if o in ('-b', '--background'): - d['background'] = a - if o in ('-r', '--rgbfile'): - d['rgbfile'] = a - if o in ('-c', '--configfile'): - d['configfile'] = a - if o in ('-g', '--barbgcolor'): - d['barbgcolor'] = a - if o in ('-F', '--font'): - d['font'] = a - if o in ('-f', '--barfgcolor'): - d['barfgcolor'] = a - if o in ('-p', '--procstat'): - d['procstat'] = a - if o in ('-s', '--skipconf'): - d['skipconf'] = a - if o in ('--debug'): - d['debug'] = True - return d - -def makeNumDigits(num, numDigits): - """Make a floating point number a certain number of digits, including - decimal. Return a string containing it. - """ - lenOfIntPart = len(str(int(num))) - if lenOfIntPart > numDigits: - # Can't convert a number to less digits then it's integer part... - return '' - decimalsNeeded = numDigits - lenOfIntPart - s = '%' + str(lenOfIntPart) + '.' + str(decimalsNeeded) + 'f' - s = s % round(num, decimalsNeeded) - return s - -def bytesToStr(bytes): - """Convert a number of bytes to a nice printable string. - - May raise ValueError if bytes can't be seen as an float. - """ - bytes = float(bytes) - kb = 1024 - mb = 1024 * 1024 - gb = 1024 * mb - tb = 1024 * gb - pb = 1024 * tb - if bytes < kb: - size = bytes - letter = 'B' - #return makeNumDigits(bytes, numDigits) + 'B' - elif bytes < mb: - size = bytes / kb - letter = 'k' - #return makeNumDigits(bytes/kb, numDigits) + 'k' - elif bytes < gb: - size = bytes / mb - letter = 'M' - #return makeNumDigits(bytes/mb, numDigits) + 'M' - elif bytes < tb: - size = bytes / gb - letter = 'G' - #return makeNumDigits(bytes/gb, numDigits) + 'G' - elif bytes < pb: - size = bytes / tb - letter = 'T' - #return makeNumDigits(bytes/tb, numDigits) + 'T' - else: - size = bytes / pb - letter = 'p' - #return makeNumDigits(bytes/pb, numDigits) + 'P' - if size >= 1000: - res = makeNumDigits(size, 4) - else: - res = makeNumDigits(size, 3) - res += letter - return res - - -def main(): - clConfig = parseCommandLine(sys.argv) - configFile = clConfig.get('configfile', defaultConfigFile) - configFile = os.path.expanduser(configFile) - fileConfig = wmdocklib.readConfigFile(configFile, sys.stderr) - config = fileConfig - for i in clConfig.iteritems(): - config[i[0]] = i[1] - - palette = {} - palette[0] = clConfig.get('background', 'black') - palette[2] = clConfig.get('textcolor', 'cyan3') - palette[9] = clConfig.get('barfgcolor', 'cyan') - palette[8] = clConfig.get('barbgcolor', 'cyan4') - palette[5] = clConfig.get('activitycolor', 'cyan2') - - font = clConfig.get('font', '6x8') - debug = clConfig.get('debug') - - global char_width, char_height - char_width, char_height = wmdocklib.initPixmap(patterns=patterns, - font_name=font, - palette=palette, - margin=3, - bg=0, fg=2, debug=debug) - - pathsToMonitor = [] - for i in range(1,1000): - labelStr = str(i) + '.label' - pathStr = str(i) + '.path' - modeStr = str(i) + '.displaymode' - actionStr = str(i) + '.action' - label = config.get(labelStr) - if not label: break - path = config.get(pathStr) - action = config.get(actionStr, 'fixed').lower().strip() - if action not in ['mount', 'eject']: - action = None - displayMode = config.get(modeStr, defaultMode) - if not displayMode in displayModes: - sys.stderr.write( - 'Unknown display mode: %s, using default.\n' % displayMode) - displayMode = defaultMode - takeChars = 3 - if char_width <= 5: - takeChars = 4 - pathsToMonitor.append((label[:takeChars], path, displayMode, action)) - procStat = config.get('procstat', defaultProcStat) - skipping = int(config.get('skipconf', 0)) - actMonEnabled = int(config.get('monitoring',0)) - if not os.access(procStat, os.R_OK): - sys.stderr.write( - "Can't read your procstat file, try setting it with -p. ") - sys.stderr.write("Disabling the HD activity bar.\n") - actMonEnabled = 0 - try: - programName = sys.argv[0].split(os.sep)[-1] - except IndexError: - programName = '' - sys.argv[0] = programName - wmdocklib.openXwindow(sys.argv, width, height) - - signal.signal(signal.SIGCHLD, handler) - signal.signal(signal.SIGALRM, handler) - signal.alarm(10) - - global hdmon - hdmon = PywmHDMon(pathsToMonitor, procStat, actMonEnabled, skipping) - hdmon.mainLoop() - -patterns = \ -['0000000000000000000000000000000000000000000000000000000000000000', - '0000000000000000000000000000000000000000000000000000000000000000', - '0099900555002220055500555000000000000000000000000000000000000000', - '0099900555002220055500555000000000000000000000000000000000000000', - '0099900555002220055500555000000000000000000000000000000000000000', - '0099900555005550055500555000000000000000000000000000000000000000', - '0099900555005550055500555000000000000000000000000000000000000000', - '0099900555005550055500555000000000000000000000000000000000000000', - '0099900555005550022200555000000000000000000000000000000000000000', - '0099900555005550022200555000000000000000000000000000000000000000', - '0099900555005550022200555000000000000000000000000000000000000000', - '0099900555005550055500555000000000000000000000000000000000000000', - '0099900555005550055500555000000000000000000000000000000000000000', - '0099900555005550055500555000000000000000000000000000000000000000', - '0099900555005550055500222000000000000000000000000000000000000000', - '0099900555005550055500222000000000000000000000000000000000000000', - '0099900555005550055500222000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099900088888888888888888888888888888888888888888888888888888888', - '0099900088888888888888888888888888888888888888888888888888888888', - '0099900088888888888888888888888888888888888888888888888888888888', - '0099900088888888888888888888888888888888888888888888888888888888', - '0099900000000000000000000000000000000000000000000000000000000000', - '0099999999999999999999999999999999999999999999999999999999999999', - '0099999999999999999999999999999999999999999999999999999999999999', - '0099999999999999999999999999999999999999999999999999999999999999', - '0099999999999999999999999999999999999999999999999999999999999999', - '0000000000000000000000000000000000000000000000000000000000000000', - '0000000000000000000000000000000000000000000000000000000000000000', - ] - -if __name__ == '__main__': - main() diff --git a/examples/pywmnop.py b/examples/pywmnop.py deleted file mode 100644 index 469e523..0000000 --- a/examples/pywmnop.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python - -"""pywmnop.py - -WindowMaker dockapp doing nothing - -Copyright (C) 2006 Mario Frasca - -Licensed under the GNU General Public License. -""" - -import sys, time -import wmdocklib - -def checkForEvents(): - event = wmdocklib.getEvent() - while not event is None: - if event['type'] == 'destroynotify': - sys.exit(0) - event = wmdocklib.getEvent() - -def mainLoop(): - while 1: - checkForEvents() - wmdocklib.redraw() - time.sleep(0.5) - -def main(): - wmdocklib.initPixmap() - wmdocklib.openXwindow(sys.argv, 64, 64) - - mainLoop() - -if __name__ == '__main__': - main() diff --git a/examples/pywmoonop.py b/examples/pywmoonop.py deleted file mode 100755 index a69adf6..0000000 --- a/examples/pywmoonop.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -"""pywmoonop.py - -object oriented WindowMaker dockapp doing nothing - -Copyright (C) 2007 Mario Frasca - -Licensed under the GNU General Public License. -""" - -from wmdocklib import wmoo -thisapp = wmoo.Application() - -if __name__ == '__main__': - thisapp.run() diff --git a/examples/pywmphoto.py b/examples/pywmphoto.py deleted file mode 100644 index c14687a..0000000 --- a/examples/pywmphoto.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python - -"""pywmphoto.py - -WindowMaker dockapp that displays a static xpm - -Copyright (C) 2006-2007 Mario Frasca - -Licensed under the GNU General Public License. - - -Changes: -2006-10-27 Mario Frasca -First workingish version - -2007-05-19 Mario Frasca -more compact form, based on wmdocklib.wmoo and optparse. -""" - -from wmdocklib import wmoo - -def main(): - - from optparse import OptionParser - - parser = OptionParser() - parser.add_option("-f", "--file", dest="filename", - help="read background from file", metavar="FILE") - parser.add_option("-d", "--debug", dest="debug", - action="store_true", default=False, - help="print the pixmap") - - (options, args) = parser.parse_args() - - app = wmoo.Application(background = options.filename, - margin = 3, - debug = options.debug) - - app.run() - -if __name__ == '__main__': - main() diff --git a/examples/pywmradio.py b/examples/pywmradio.py deleted file mode 100755 index 6733467..0000000 --- a/examples/pywmradio.py +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/env python - -"""pywmnop.py - -WindowMaker dockapp doing nothing - -Copyright (C) 2006 Mario Frasca - -Licensed under the GNU General Public License. -""" - -import sys, time -from wmdocklib import wmoo -devnull = file('/dev/null') - -class Application(wmoo.Application): - - def reset(self): - self._cacheLevel = -50 - self.child = None - self._paused = None - self._buffering = 0 - self._flash = 0 - self._muting = 0 - if 'pause' in self._widgets: - self['pause'].setPattern((11, 10)) - self.showCacheLevel() - - def __init__(self, *args, **kwargs): - wmoo.Application.__init__(self, *args, **kwargs) - self.radioList = [] - self.currentRadio = 0 - self._count = 0 - self._expectdying = 0 - - self.reset() - - self._buffered = '' - import re - self._feedback = re.compile(r'.+A:.*?% ([0-9\.]+)%') - - import fileinput, os - configfile = os.sep.join([os.environ['HOME'], '.pyradiorc']) - - import codecs - f = codecs.open(configfile, 'r', 'utf-8') - t = f.read() - f.close() - for i in t.split(u'\n'): - radiodef = i.split('\t') - radioname = radiodef[0].lower() - if len(radiodef) != 3 or i[0] == '#': - continue - if radioname == '': - globals()[radiodef[1]] = radiodef[2] - pass - else: - self.radioList.append( (radioname, radiodef[1], radiodef[2]) ) - - - def handler(self, num, frame): - if self._expectdying: - self._expectdying -= 1 - else: - self.reset() - self._flash = 4 - self._colour = 1 - - def startPlayer(self): - import os, subprocess, signal - commandline = [mplayer, - '-cache', self.radioList[self.currentRadio][2], - self.radioList[self.currentRadio][1] - ] - self.child = subprocess.Popen(commandline, - stdin =subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=devnull) - signal.signal(signal.SIGCHLD, self.handler) - self._flash = 0 - self._paused = False - self._buffered = '' - self._buffering = 1 - self._cacheLevel = 0 - import fcntl - flags = fcntl.fcntl(self.child.stdout, fcntl.F_GETFL) - fcntl.fcntl(self.child.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) - flags = fcntl.fcntl(self.child.stdin, fcntl.F_GETFL) - fcntl.fcntl(self.child.stdin, fcntl.F_SETFL, flags | os.O_NONBLOCK) - - def stopPlayer(self): - if self.child: - self.child.stdin.write('q') - self._expectdying += 1 - self.child = None - - def printevent(self, event): - print event - - def previousRadio(self, event): - #print 'in previousRadio' - if self.currentRadio == 0: self.currentRadio = len(self.radioList) - self.currentRadio -= 1 - self['name'].setText(self.radioList[self.currentRadio][0]) - if self.child: - self.stopPlayer() - self.startPlayer() - - def nextRadio(self, event): - #print 'in nextRadio' - self.currentRadio += 1 - if self.currentRadio == len(self.radioList): self.currentRadio = 0 - self['name'].setText(self.radioList[self.currentRadio][0]) - if self.child: - self.stopPlayer() - self.startPlayer() - - def playStream(self, event): - #print 'in playStream' - self.startPlayer() - - def stopStream(self, event): - #print 'in stopStream' - self.stopPlayer() - self.reset() - - def pauseStream(self, event): - #print 'in pauseStream' - if self.child and not self._buffering: - self.child.stdin.write(' ') - self._paused = not self._paused - if self._paused: - self._colour = 1 - return True - return False - - def muteStream(self, event): - #print 'in muteStream' - if self.child and self._buffering == 0: - self.child.stdin.write('m') - self['mute'].setPattern((33-11*self._muting, 0)) - self._muting = 1 - self._muting - - def showCacheLevel(self): - if self._buffering: - self._cacheLevel += 1 - if self._cacheLevel >= 25: - self._cacheLevel -= 25 - for i in range(-1, 25): - if abs(i - self._cacheLevel) <= 1: - self.putPattern(54, self._buffering, 5, 1, 54, 58-i) - else: - self.putPattern(54, 0, 5, 1, 54, 58-i) - else: - if self._flash: - colour = self._colour = 3 - self._colour - self._flash = max(0, self._flash - 1) - else: - colour = 2 - for i in range(-1, 25): - if (i*4 < self._cacheLevel) or self._flash: - self.putPattern(54, colour, 5, 1, 54, 58-i) - else: - self.putPattern(54, 0, 5, 1, 54, 58-i) - - def update(self): - self._count += 1 - if self._count <= 3: - return - if self._paused: - colour = self._colour = 4 - self._colour - self['pause'].setPattern((self._colour*11, 10)) - self._count = 0 - if self.child: - import select - [i, o, e] = select.select([self.child.stdout], [], [], 0) - if i: - line = self.child.stdout.read(102400) - self._buffered += line - npos = self._buffered.rfind('\n')+1 - rpos = self._buffered.rfind('\r')+1 - if npos != 0: - self._buffered = self._buffered[npos:] - if rpos != 0: - if self._buffered.startswith('Cache fill:'): - self._buffering = 2 - else: - match = self._feedback.match(self._buffered[rpos-90:rpos]) - if match: - self._buffering = 0 - self._cacheLevel = float(match.group(1)) - - self._buffered = self._buffered[rpos:] - if self.child or self._flash: - self.showCacheLevel() - -palette = { - '-': "#000000", - ".": "#868682", - "X": "#AEAEAA", - "o": "#F7F7F3", - "r": "#F73020", - "i": "#00F700", - } - -background = [ - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " X----------------------------------------------------------X ", - " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ", - " ", - " ", - " ", - " ", - " ......... ......... ......... XXXXXX. ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " X----- ", - " X----- ", - " X----- ", - " X----- ", - " X.-----.. ", - " X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " ......... ......... ......... X----- ", - " X----- ", - " .----- ", - " ", - " ", - " ", - " ", - " ", - ] - -patterns = [ - "XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX ----- ", - "X-------- X-------- X-------- X-------- rrrrr ", - "X-o------ X-----o-- X-----o-- X----rr-- iiiii ", - "X-o--oo-- X-oo--o-- X----oo-- X----rr-- ", - "X-o-ooo-- X-ooo-o-- X-ooXoo-- X-oorro-- ", - "X-ooooo-- X-ooooo-- X-ooXoo-- X-ooroo-- ", - "X-o-ooo-- X-ooo-o-- X-ooXoo-- X-orroo-- ", - "X-o--oo-- X-oo--o-- X----oo-- X-rr-oo-- ", - "X-o------ X-----o-- X-----o-- X-rr--o-- ", - "X-------- X-------- X-------- X-------- ", - "XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX ", - "X-------- X-------- X-------- X-------- ", - "X-------- X-------- X-------- X-------- ", - "X-oo----- X-oo-oo-- X-ooooo-- X-rr-rr-- ", - "X-oooo--- X-oo-oo-- X-ooooo-- X-rr-rr-- ", - "X-ooooo-- X-oo-oo-- X-ooooo-- X-rr-rr-- ", - "X-oooo--- X-oo-oo-- X-ooooo-- X-rr-rr-- ", - "X-oo----- X-oo-oo-- X-ooooo-- X-rr-rr-- ", - "X-------- X-------- X-------- X-------- ", - "X-------- X-------- X-------- X-------- ", - ] - - -def main(): - - global char_width, char_height, maxCharsPerLine, antialiased - app = Application(font_name='5x8', - margin = 3, - bg=0, fg=2, palette = palette, - background = background, - patterns = patterns) - # maxCharsPerLine = (width-2*xOffset) / char width - app.addWidget('name', wmoo.Label, - (5, 16), (54, 10), app.radioList[app.currentRadio][0]) - - app.addWidget('prev', wmoo.Button, ( 6,31), (9, 10), app.previousRadio, pattern=(0,0)) - app.addWidget('next', wmoo.Button, (21,31), (9, 10), app.nextRadio, pattern=(11,0)) - app.addWidget('mute', wmoo.Button, (36,31), (9, 10), app.muteStream, pattern=(22,0)) - - app.addWidget('play', wmoo.Button, ( 6,47), (9, 10), app.playStream, pattern=(0,10)) - app.addWidget('pause',wmoo.Button, (21,47), (9, 10), app.pauseStream, pattern=(11,10)) - app.addWidget('stop', wmoo.Button, (36,47), (9, 10), app.stopStream, pattern=(22,10)) - - app.addCallback(app.previousRadio, 'keypress', key='k') - app.addCallback(app.nextRadio, 'keypress', key='j') - app.addCallback(app.muteStream, 'keypress', key='m') - app.addCallback(app.playStream, 'keypress', key='p') - app.addCallback(app.pauseStream, 'keypress', key=' ') - app.addCallback(app.stopStream, 'keypress', key='q') - - app.run() - -if __name__ == '__main__': - main() diff --git a/examples/pywmseti.py b/examples/pywmseti.py deleted file mode 100755 index a490baf..0000000 --- a/examples/pywmseti.py +++ /dev/null @@ -1,502 +0,0 @@ -#!/usr/bin/env python - -"""pywmseti.py - -WindowMaker dockapp to monitor the progress of your seti@home. - -Copyright (C) 2003 Kristoffer Erlandsson - -Licensed under the GNU General Public License. - - -Changes - -2003-06-24 Kristoffer Erlandsson -Added event handling for graceful shutdown - -2003-06-17 Kristoffer Erlandsson -First workingish version - -""" -usage = """pywmseti.py [options] -Available options are: --h, --help print this help --t, --textcolor set the text color --p, --progressbarcolor set the color of the progress bar --g, --barbgcolor set the background color of the progress bar --i, --indicatorcolor set the color of the running indicator --b, --background set the background color --d, --setidir set the directory where seti@home resides --n, --nice set the nice value to run seti@home with --r, --rgbfile set the rgb file to get color codes from --c, --configfile set the config file to use -""" - -import sys -import time -import getopt -import os - -import wmdocklib - -width = 64 -height = 64 - -xOffset = 4 -yOffset = 4 - -graphStartX = 7 -graphStartY = 53 -graphLength = 50 -graphHeight = 4 - -graphBgStartX = 72 -graphBgStartY = 53 - -graphLineStartX = 66 -graphLineStartY = 58 - -runningIndX = 71 -runningIndY = 1 -runningIndWidth = 3 -runningIndHeight = 15 -numRunningInds = 4 - -defaultConfigFile = '~/.pywmsetirc' -defaultRGBFiles = ['/usr/lib/X11/rgb.txt', '/usr/X11R6/lib/X11/rgb.txt'] - -stateFileName = 'state.sah' -uinfoFileName = 'user_info.sah' -pidFileName = 'pid.sah' -execFileName = 'setiathome' - -class PywmSeti: - def __init__(self, statePath, uinfoPath, pidPath, execCmd): - self._statePath = statePath - self._uinfoPath = uinfoPath - self._pidPath = pidPath - self._execCmd = execCmd - self._currentRunningInd = 0 - self._lastTime = time.time() - self._lastNumResults = -1 - self._progress = 0 - - def addString(self, s, x, y): - try: - wmdocklib.addString(s, x, y, digits, - xOffset, yOffset, width, height) - except ValueError, e: - sys.stderr.write('Error when painting string:\n' + str(e) + '\n') - sys.exit(3) - - def getCenterStartPos(self, s): - return wmdocklib.getCenterStartPos(s, width, xOffset) - - def getVertSpacing(self, numLines, margin): - return wmdocklib.getVertSpacing(numLines, margin, height, yOffset) - - def getProgress(self, lines): - """Return the progess of the current workunit. - - Supply the lines of the statefile as argument. - """ - for line in lines: - if line.startswith('prog='): - try: - progress = float(line.split('=')[-1]) - except ValueError: - progress = 0 - return progress - return 0 - - def getNumResults(self, lines): - """Return the number of results produced. - - Supply the lines in the user info file as argument. - """ - for line in lines: - if line.startswith('nresults='): - try: - results = int(line.split('=')[-1]) - except ValueError: - pass - else: - return results - sys.stderr.write( - "Error when reading uinfo file! Can't get number of results.\n") - return -1 - - def pidIsRunning(self, pid): - """Determine if the process with PID pid is running. - - Return 1 if it is running. - Return 0 if it is not running. - Return -1 if we do not have permission to signal the process - This could be slightly non-portal, but I can not find any better - way to do it. - """ - try: - os.kill(pid, 0) - except OSError, e: - if e.errno == 1: - return -1 - return 0 - return 1 - - def openFileRead(self, fileName): - try: - f = file(fileName, 'r') - except IOError, e: - sys.stderr.write('Error when opening %s: %s\n' % (fileName, str(e))) - return None - return f - - - def paintCurrentRunningIndicator(self): - """Paint the running indicator. - """ - indX = runningIndX + self._currentRunningInd * \ - (runningIndWidth + 2) - indY = runningIndY - w = runningIndWidth - h = runningIndHeight - targX = width - xOffset - w - 5 - targY = yOffset + 5 - wmdocklib.copyXPMArea(indX, indY, w, h, targX, targY) - - def updateRunning(self): - """Update the information regarding if we got seti@home running or not. - - Return a tuple with (running, startStopenabled). - startStopEnabled is 1 if we own the process and got the permissions - to start and stop it, or if there is no process running. - """ - pidFile = self.openFileRead(self._pidPath) - if pidFile is None: - sys.stderr.write("Can't read pid file") - self._running = 0 - self._startStopEnabled = 0 - return - try: - self._pid = int(pidFile.read().strip()) - except ValueError: - sys.stderr.write("Can't get pid from %s.\n" % self._pidPath) - self._running = 0 - self._startStopEnabled = 0 - return - pidFile.close() - self._running = self.pidIsRunning(self._pid) - if self._running == -1 and self._startStopEnabled: - sys.stderr.write( - "An other seti@home process which you don't own is running.\n") - sys.stderr.write( - "Starting and stopping of the process is disabled.\n") - self._startStopenabled = 0 - if self._running == -1: - self._running = 1 - else: - # If no process is running (we could have stopped the one - # running from an other process), enable starting and stopping. - self._startStopEnabled = 1 - if self._running: - self._currentRunningInd = (self._currentRunningInd - 1) \ - % numRunningInds - else: - self._currentRunningInd = 0 - self.paintCurrentRunningIndicator() - - def updateProgress(self): - """Update the progress on the current workunit.""" - stateFile = self.openFileRead(self._statePath) - if stateFile is None: - # Can't open file, probably in progress of gettin a new workunit. - progress = 0 - else: - progress = self.getProgress(stateFile.readlines()) - stateFile.close() - self._progress = progress - percent = int(progress * 100.0) - graphSize = int(round(progress * graphLength)) - wmdocklib.copyXPMArea( - graphLineStartX, graphLineStartY, graphSize, graphHeight, - graphStartX, graphStartY) - wmdocklib.copyXPMArea( - graphBgStartX, graphBgStartY, graphLength - graphSize, graphHeight, - graphStartX + graphSize, graphStartY) - self.addString((str(percent) + '%').ljust(4), 4, 32) - - def updateNumResults(self): - """Update the number of workunits done.""" - uinfoFile = self.openFileRead(self._uinfoPath) - numResults = self.getNumResults(uinfoFile.readlines()) - if self._lastNumResults == -1: - self._lastNumResults = numResults - if numResults != self._lastNumResults and self._progress < 0.03: - # If we just got a new number of results and the progress of the - # current workunit is under 3%, assume we started working on a new - # workunit. The times this could be missleading is if we have an - # other seti@home process running on an other computer, but this is - # accurate enough I think. - self.nextWorkUnitStarted() - self._lastNumResults = numResults - uinfoFile.close() - self.addString(str(numResults)[:7], 4, 4) - - def updateTime(self): - """Update the time line. - - We display the time that we have been on the current work unit, since - either the last one was done or since we started the program. - """ - timeSpent = time.time() - self._lastTime - hours = int(timeSpent / 3600) - mins = int((timeSpent - hours * 3600) / 60) - hours = str(hours)[:3] - mins = str(mins).zfill(2) - s = (hours + ':' + mins).ljust(6) - self.addString(s, 4, 18) - - def nextWorkUnitStarted(self): - self._lastTime = time.time() - - def handleMouseClick(self, region): - if region == 0: - if self._startStopEnabled: - if self._running: - try: - os.kill(self._pid, 15) - except OSError, e: - sys.stderr.write( - "Error when ending process: "+str(e)+'\n') - else: - os.system(self._execCmd) # Use fork instead? - - def _checkForEvents(self): - """Check for, and handle, X events.""" - event = wmdocklib.getEvent() - while not event is None: - if event['type'] == 'buttonrelease': - region = wmdocklib.checkMouseRegion(event['x'], - event['y']) - self.handleMouseClick(region) - elif event['type'] == 'destroynotify': - sys.exit(0) - event = wmdocklib.getEvent() - - def mainLoop(self): - counter = -1 - self._startStopEnabled = 1 - while 1: - counter += 1 - self._checkForEvents() - if counter % 10 == 0: - self.updateRunning() - if counter % 100 == 0: - self.updateProgress() - self.updateNumResults() - self.updateTime() - if counter == 999999: - counter = -1 - wmdocklib.redraw() - time.sleep(0.1) - - -def parseCommandLine(argv): - """Parse the commandline. Return a dictionary with options and values.""" - shorts = 'ht:b:n:d:r:c:p:g:i:' - longs = ['help', 'textcolor=', 'background=', 'setidir=', 'nice=', - 'rgbfile=', 'configfile=', 'progressbarcolor=', 'barbgcolor=', - 'indicatorcolor='] - try: - opts, nonOptArgs = getopt.getopt(argv[1:], shorts, longs) - except getopt.GetoptError, e: - sys.stderr.write('Error when parsing commandline: ' + str(e) + '\n') - sys.stderr.write(usage) - sys.exit(2) - d = {} - for o, a in opts: - if o in ('-h', '--help'): - sys.stdout.write(usage) - sys.exit(0) - if o in ('-t', '--textcolor'): - d['textcolor'] = a - if o in ('-b', '--background'): - d['background'] = a - if o in ('-d', '--setidir'): - d['setidir'] = a - if o in ('-n', '--nice'): - d['nice'] = a - if o in ('-r', '--rgbfile'): - d['rgbfile'] = a - if o in ('-c', '--configfile'): - d['configfile'] = a - if o in ('-p', '--progressbarcolor'): - d['progressbarcolor'] = a - if o in ('-g', '--barbgcolor'): - d['barbgcolor'] = a - if o in ('-i', '--indicatorcolor'): - d['indicatorcolor'] = a - return d - -def parseColors(defaultRGBFileNames, config, xpm): - rgbFileName = '' - for fn in defaultRGBFileNames: - if os.access(fn, os.R_OK): - rgbFileName = fn - break - rgbFileName = config.get('rgbfile', rgbFileName) - useColors = 1 - if not os.access(rgbFileName, os.R_OK): - sys.stderr.write( - "Can't read the RGB file, try setting it differently using -r,\n") - sys.stderr.write( - "Ignoring your color settings, using the defaults.\n") - useColors = 0 - if useColors: - # Colors is a list with (, ) pairs. - colors = (('indicatorcolor', 'indicator'), - ('progressbarcolor', 'graph'), - ('barbgcolor', 'graphbg'), - ('textcolor', 'text'), - ('background', 'background')) - for key, value in colors: - col = config.get(key) - if not col is None: - code = wmdocklib.getColorCode(col, rgbFileName) - if code is None: - sys.stderr.write('Bad colorcode for %s, ignoring.\n' % key) - else: - wmdocklib.setColor(xpm, value, code) - -palette = { - ' ': '#208120812081', - '.': '#00000000FFFF', - 'o': '#C71BC30BC71B', - 'O': '#861782078E38', - '+': '#EFBEF3CEEFBE', - '@': '#618561856185', - '#': '#9E79A2899E79', - '$': '#410341034103', - 'o': '#2020b2b2aaaa', - '/': '#2020b2b2aaaa', - '-': '#707070707070', - '_': '#000000000000', - '%': '#2081B2CAAEBA', -} - -background = \ -[' ...............................................................................................', - ' .///..___..ooo..___..___.......................................................................', - ' .///..___..ooo..___..___.......................................................................', - ' .///..___..ooo..___..___.......................................................................', - ' .///..___..___..___..___.......................................................................', - ' .///..___..___..___..___.......................................................................', - ' .///..___..___..___..___.......................................................................', - ' .///..___..___..ooo..___.......................................................................', - ' .///..___..___..ooo..___.......................................................................', - ' .///..___..___..ooo..___.......................................................................', - ' .///..___..___..___..___.......................................................................', - ' .///..___..___..___..___.......................................................................', - ' .///..___..___..___..___.......................................................................', - ' .///..___..___..___..ooo.......................................................................', - ' .///..___..___..___..ooo.......................................................................', - ' .///..___..___..___..ooo.......................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...........................................................................................', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...........................................................................................', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' ...............................................................................................', - ' ...............................................................................................', - ] - -def main(): - clConfig = parseCommandLine(sys.argv) - configFile = clConfig.get('configfile', defaultConfigFile) - configFile = os.path.expanduser(configFile) - fileConfig = wmdocklib.readConfigFile(configFile, sys.stderr) - # Merge the two configs, let the commandline options overwrite those in the - # configuration file. - config = fileConfig - for i in clConfig.iteritems(): - config[i[0]] = i[1] - # Get the configurations - setiDir = config.get('setidir') - if setiDir is None: - sys.stderr.write( - 'You have to supply a directory where seti@home resides. Either in\n') - sys.stderr.write( - 'the configuration file or with -d/--setidir.\n') - sys.exit(3) - setiDir = os.path.expanduser(setiDir) - try: - os.chdir(setiDir) - except OSError, e: - sys.stderr.write('Error when accessing seti directory: %s\n' % str(e)) - sys.exit(4) - statePath = os.path.join(setiDir, stateFileName) - uinfoPath = os.path.join(setiDir, uinfoFileName) - pidPath = os.path.join(setiDir, pidFileName) - execPath = os.path.join(setiDir, execFileName) - niceVal = config.get('nice') - if niceVal is None: - execCmd = execPath - else: - execCmd = execPath + ' -nice %s' % niceVal + '&' - try: - programName = sys.argv[0].split(os.sep)[-1] - except IndexError: - programName = '' - sys.argv[0] = programName - wmdocklib.initPixmap(background, - palette=palette) - wmdocklib.openXwindow(sys.argv, width, height) - wmdocklib.addMouseRegion(0, xOffset, yOffset, width - 2 * xOffset, - height - 2 * yOffset) - pwms = PywmSeti(statePath, uinfoPath, pidPath, execCmd) - pwms.mainLoop() - - -if __name__ == '__main__': - main() diff --git a/examples/pywmsysmon.py b/examples/pywmsysmon.py deleted file mode 100755 index 8a83531..0000000 --- a/examples/pywmsysmon.py +++ /dev/null @@ -1,397 +0,0 @@ -#! /usr/bin/env python - -"""pywmsysmon.py - -WindowMaker system monitor dockapp written in Python. It displays your CPU -usage and your available/used memory. - -Copyright (C) 2003 Kristoffer Erlandsson - -Licensed under the GNU General Public License. - -Changes -2003-06-28 Kristoffer Erlandsson -Fixed a bug which caused infinite loop if the mouse was clicked - -2003-06-24 Kristoffer Erlandsson -First working version -""" -usage="""pywmsysmon.py [options] -Available options are: --h, --help print this help --f, --barfgcolor set the foreground color of the memory bar --g, --barbgcolor set the background color of the memory bar --b, --background set the background color --p, --graphforeground set the cpu graph foreground color --a, --graphbackground set the cpu graph background color --r, --rgbfile set the rgb file to get color codes from --s, --procstat set the location of /proc/stat --m, --procmeminfo set the location of /proc/meminfo --i, --ignorenice ignore nice valued cpu usage --u, --updatedelay delay (in seconds) between cpu graph updates -""" - -import sys -import time -import getopt -import os - -import wmdocklib - -width = 64 -height = 64 - -xOffset = 4 -yOffset = 4 - -hGraphStartX = 7 -hGraphStartY = 53 -hGraphHeight = 4 -hGraphWidth = width - xOffset * 2 - 6 - -hGraphBgStartX = 72 -hGraphBgStartY = 53 - -hGraphLineStartX = 66 -hGraphLineStartY = 58 - -vGraphStartX = 7 -vGraphStartY = 7 -vGraphHeight = 43 -vGraphWidth = 50 - -vGraphLineStartX = 95 -vGraphLineStartY = 1 - -vGraphBgStartX = 97 -vGraphBgStartY = 1 - -defaultConfigFile = '~/.pywmhdmonrc' -defaultRGBFiles = ('/usr/lib/X11/rgb.txt', '/usr/X11R6/lib/X11/rgb.txt') -defaultProcStat = '/proc/stat' -defaultProcMeminfo = '/proc/meminfo' - -class PywmSysMon: - def __init__(self, procMeminfo, procStat, ignoreNice=0, updateDelay=10): - self._procStat = procStat - self._procMeminfo = procMeminfo - self._ignoreNice = ignoreNice - - self._lastUsed = 0 - self._lastTotal = 0 - - self._usageHistory = [0.0] * vGraphWidth - - self._cpuUpdateDelay = updateDelay - self._memUpdateDelay = 30 - - def addUsageToHist(self, cpuUsage): - self._usageHistory = self._usageHistory[1:] - self._usageHistory.append(cpuUsage) - - def getMemInfo(self): - """Get memory information. - - Return a tuple with (total_mem, used_mem, buffered_mem, cached_mem). - """ - try: - meminfoFile = file(self._procMeminfo, 'r') - except IOError, e: - sys.stderr.write("Can't open meminfo file: %s.\n" % str(e)) - sys.exit(2) - total = used = free = shared = buffers = cached = theLine = None - for line in meminfoFile: - if line.startswith('Mem:'): - theLine = line - break - if line.startswith('MemTotal:'): - total = long(line.split()[1]) - if line.startswith('MemFree:'): - free = long(line.split()[1]) - if line.startswith('Buffers:'): - buffers = long(line.split()[1]) - if line.startswith('Cached:'): - cached = long(line.split()[1]) - if free and total: - used = total - free - if theLine is not None: - parts = [long(x) for x in theLine.split()[1]] - total, used, free, shared, buffers, cached = parts[:6] - if None in [total, used, buffers, cached]: - sys.stderr.write("Can't find memory information in %s.\n" % - self._procMeminfo) - sys.exit(4) - return (total, used, buffers, cached) - - def freeMem(self, memData): - """Take a tuple as returned from getMemInfo and return the free mem. - """ - total, used, buffers, cached = memData - reallyUsed = used - buffers - cached - free = total - reallyUsed - return free - - def getCPUUsage(self): - """Get the current CPU usage. - - Only works for systems where this can be found in a /proc/stat like - file. Return the usage in percent. - """ - try: - statFile = file(self._procStat, 'r') - except IOError, e: - sys.stderr.write("Can't open statfile: %s.\n" % str(e)) - sys.exit(2) - line = statFile.readline() - statFile.close() - cpu, nice, system, idle = [long(x) for x in line.split()[1:]][:4] - used = cpu + system - if not self._ignoreNice: - used += nice - total = cpu + nice + system + idle - if total - self._lastTotal <= 0 or self._lastTotal == 0: - cpuUsage = 0.0 - else: - cpuUsage = 100.0 * (float(used - self._lastUsed) / float(total - - self._lastTotal)) - self._lastUsed = used - self._lastTotal = total - return cpuUsage - - def addString(self, s, x, y): - try: - wmdocklib.addString(s, x, y, digits, xOffset, yOffset, width, height) - except ValueError, e: - sys.stderr.write('Error when painting string:\n' + str(e) + '\n') - sys.exit(3) - - def paintGraph(self, percentFilled, x, y, w): - """Paint a graph with percentFilled percent filled. - - Paint at position x, y and with width w. - """ - paintWidth = int(round(percentFilled/100.0 * w)) - if paintWidth > 0: - wmdocklib.copyXPMArea( - hGraphLineStartX, hGraphLineStartY, paintWidth, hGraphHeight, - x, y) - if w - paintWidth > 0: - wmdocklib.copyXPMArea( - hGraphBgStartX, hGraphBgStartY, w - paintWidth, hGraphHeight, - x + paintWidth, y) - - def drawVertLine(self, sourceX, sourceY, targX, targY, length): - """Draw a vertical line. - """ - if length > 0: - wmdocklib.copyXPMArea(sourceX, sourceY, 1, length, targX, targY) - - def drawCPUUsageHistory(self): - """Draw the complete CPU usage graph according to what's in the history. - """ - count = 0 - for histItem in self._usageHistory: - lengthFilled = int(round(vGraphHeight * (histItem/100.0))) - lengthNotFilled = vGraphHeight - lengthFilled - self.drawVertLine(vGraphBgStartX, vGraphBgStartY, - vGraphStartX + count, vGraphStartY, - lengthNotFilled) - self.drawVertLine(vGraphLineStartX, vGraphLineStartY, - vGraphStartX + count, - vGraphStartY + lengthNotFilled, lengthFilled) - count += 1 - - def updateCPUInfo(self): - """Update the current cpu usage graph.""" - currentUsage = self.getCPUUsage() - self.addUsageToHist(currentUsage) - self.drawCPUUsageHistory() - - def updateMemInfo(self): - """Update the current memory usage graph.""" - memInfo = self.getMemInfo() - total = memInfo[0] - free = self.freeMem(memInfo) - percentUsed = 100.0 * (float(total - free) / float(total)) - self.paintGraph(percentUsed, hGraphStartX, hGraphStartY, hGraphWidth) - - def _checkForEvents(self): - event = wmdocklib.getEvent() - while not event is None: - if event['type'] == 'destroynotify': - sys.exit(0) - event = wmdocklib.getEvent() - - def mainLoop(self): - counter = -1 - while 1: - counter += 1 - self._checkForEvents() - if counter % self._cpuUpdateDelay == 0: - self.updateCPUInfo() - if counter % self._memUpdateDelay == 0: - self.updateMemInfo() - if counter == 999999: - counter = -1 - wmdocklib.redraw() - time.sleep(0.1) - -def parseCommandLine(argv): - """Parse the commandline. Return a dictionary with options and values.""" - shorts = 'hf:g:b:p:a:r:s:m:iu:' - longs = ['help=', 'barbgcolor=', 'barfgcolor=', 'background=', - 'graphforeground=', 'graphbackground=', 'rgbfile=', 'procstat=', - 'procmeminfo=', 'ignorenice', 'updatedelay='] - try: - opts, nonOptArgs = getopt.getopt(argv[1:], shorts, longs) - except getopt.GetoptError, e: - sys.stderr.write('Error when parsing commandline: ' + str(e) + '\n') - sys.stderr.write(usage) - sys.exit(2) - d = {} - for o, a in opts: - if o in ('-h', '--help'): - sys.stdout.write(usage) - sys.exit(0) - if o in ('-b', '--background'): - d['background'] = a - if o in ('-r', '--rgbfile'): - d['rgbfile'] = a - if o in ('-g', '--barbgcolor'): - d['barbgcolor'] = a - if o in ('-f', '--barfgcolor'): - d['barfgcolor'] = a - if o in ('-s', '--procstat'): - d['procstat'] = a - if o in ('-p', '--graphforeground'): - d['graphforeground'] = a - if o in ('-a', '--graphbackground'): - d['graphbackground'] = a - if o in ('-m', '--procmeminfo'): - d['procmeminfo'] = a - if o in ('-i', '--ignorenice'): - d['ignorenice'] = 1 - if o in ('-u', '--updatedelay'): - try: - d['updatedelay'] = int(a) * 10 - except ValueError: - sys.stderr.write( - "Value for updatedelay has to be an integer.\n") - sys.exit(2) - return d - -background = \ -[' ...............................................................................................', - ' .///..___..ooo..___..___......|.I..............................................................', - ' .///..___..ooo..___..___......|.I..............................................................', - ' .///..___..ooo..___..___......|.I..............................................................', - ' .///..___..___..___..___......|.I..............................................................', - ' .///..___..___..___..___......|.I..............................................................', - ' .///..___..___..___..___......|.I..............................................................', - ' .///..___..___..ooo..___......|.I..............................................................', - ' .///..___..___..ooo..___......|.I..............................................................', - ' .///..___..___..ooo..___......|.I..............................................................', - ' .///..___..___..___..___......|.I..............................................................', - ' .///..___..___..___..___......|.I..............................................................', - ' .///..___..___..___..___......|.I..............................................................', - ' .///..___..___..___..ooo......|.I..............................................................', - ' .///..___..___..___..ooo......|.I..............................................................', - ' .///..___..___..___..ooo......|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///..........................|.I..............................................................', - ' .///...........................................................................................', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...-------------------------------------------------------------------------------------...', - ' .///...........................................................................................', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' .///////////////////////////////////////////////////////////////////////////////////////////...', - ' ...............................................................................................', - ' ...............................................................................................', - ] - -def main(): - config = parseCommandLine(sys.argv) - procStat = config.get('procstat', defaultProcStat) - if not os.access(procStat, os.R_OK): - sys.stderr.write( - "Can't read your procstat file, try setting it with -s.\n") - sys.exit(4) - procMeminfo = config.get('procmeminfo', defaultProcMeminfo) - if not os.access(procMeminfo, os.R_OK): - sys.stderr.write( - "Can't read your procmeminfo file, try setting it with -m.\n") - sys.exit(4) - ignoreNice = config.get('ignorenice', 0) - updateDelay = config.get('updatedelay', 30) - try: - programName = sys.argv[0].split(os.sep)[-1] - except IndexError: - programName = '' - sys.argv[0] = programName - - palette = { - ' ': '#208120812081', - '.': '#00000000FFFF', - 'o': '#C71BC30BC71B', - 'O': '#861782078E38', - '+': '#EFBEF3CEEFBE', - '@': '#618561856185', - '#': '#9E79A2899E79', - '$': '#410341034103', - 'o': '#2020b2b2aaaa', - } - #palette['o'] = config.get('indicator', '#2020b2b2aaaa') - palette['/'] = config.get('barfgcolor', '#2020b2b2aaaa') - palette['-'] = config.get('barbgcolor', '#707070707070') - palette['|'] = config.get('graphforeground', '#2020b2b2aaaa') - palette['I'] = config.get('graphbackground', '#707070707070') - palette['_'] = config.get('background', '#000000000000') - palette['%'] = config.get('foreground', '#2081B2CAAEBA') - - wmdocklib.initPixmap(background, palette=palette) - wmdocklib.openXwindow(sys.argv, width, height) - pywmsysmon = PywmSysMon(procMeminfo, procStat, ignoreNice, updateDelay) - pywmsysmon.mainLoop() - - - -if __name__ == '__main__': - main() diff --git a/examples/pywmwet.py b/examples/pywmwet.py deleted file mode 100644 index b5a2da0..0000000 --- a/examples/pywmwet.py +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/env python -"""pywmwet.py -WindowMaker dockapp that tracks a Wolf:ET server and displays following info: -->Map Name --># of Allies --># of Axis --># of Spectators (if server using 'P' cvar - -Copyright (C) 2007 Nathan Lundquist -Licensed under the GNU General Public License. -Changes: -2007-01-16 Nate Lundquist -First attempt -""" - -import sys, getopt, os -import socket -import wmdocklib -import time, datetime - -DEFAULT_PORT = 27960 -DEFAULT_INTERVAL = 60 #seconds -WIDTH = 64 -HEIGHT = 64 -XOFFSET = 4 -YOFFSET = 4 -MARGIN = 1 -LINE_SPACING = 4 - -usage = '''\ -pywmwet.py [options] -Available options are: --h, --help Print this help text --s, --server Server to track --p, --port Server port [default: 27960] --u, --update-interval Delay between updates [default: 60 sec] -''' - - -def parse_command_line(argv): - shorts = 'hs:p:u:' - longs = ['help', 'server=', 'port=', 'update-interval='] - - try: - opts, nonOptArgs = getopt.getopt(argv[1:], shorts, longs) - except getopt.GetoptError, e: - print 'Error parsing commandline: ' + str(e) - print usage - sys.exit(2) - d = {} - for o, a in opts: - if o in ('-h', '--help'): - print usage - sys.exit(0) - if o in ('-s', '--server'): - d['server'] = a - if o in ('-p', '--port'): - d['port'] = int(a) - else: - d['port'] = DEFAULT_PORT - if o in ('-u', '--update-interval'): - d['update-interval'] = int(a) - else: - d['update-interval'] = DEFAULT_INTERVAL - return d - -def query_server(server, port): - try: - query = '\xFF\xFF\xFF\xFF\x02getstatus\x0a\x00' - addr = (server, port) - sockobj = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sockobj.settimeout(4.0) - sockobj.connect(addr) - sockobj.send(query) - data = sockobj.recv(4096) - data = data[18:] - sockobj.shutdown(0) - sockobj.close() - #print 'query success' - #print data - return data - except socket.error: - #print 'query failure' - return False - -def get_map(data): - data = data.split('\\') - i = data.index('mapname') - return ' '.join(data[i+1].split('_')).title() - -def get_num_allies(data): - data = data.split('\\') - try: #servers using older cvar - i = data.index('Players_Allies') - allies = data[i+1] - return len(allies.split()) - except ValueError: #possibly newer server using 'P' cvar - try: - #3 - Spectator, 2 - Allies, 1 - Axis - i = data.index('P') - slots = data[i+1] - allies = 0 - for slot in slots: - if slot == '2': - allies += 1 - return allies - except ValueError: #no players connected? - return 0 - -def get_num_axis(data): - data = data.split('\\') - try: #server using old cvar - i = data.index('Players_Axis') - axis = data[i+1] - return len(axis.split()) - except ValueError: #possible new cvar - try: - #3 - Spectator, 2 - Allies, 1 - Axis - i = data.index('P') - slots = data[i+1] - axis = 0 - for slot in slots: - if slot == '1': - axis += 1 - return axis - except ValueError: #no players - return 0 - -def get_num_spectators(data): - #This will only work with servers that use the newer 'P' cvar - data = data.split('\\') - try: - #3 - Spectator, 2 - Allies, 1 - Axis - i = data.index('P') - slots = data[i+1] - spec = 0 - for slot in slots: - if slot == '3': - spec += 1 - return spec - except ValueError: #check if old cvars in use - if 'Players_Axis' in data or 'Players_Allies' in data: - #old cvars in use, so we don't know how many spectators there are - return '??' - else: #no players - return 0 - -def get_players(data): - players = [] - player_data = data.strip().split('\n')[1:] - for player_line in player_data: - player = strip_name(player_line.split('"')[1]) - players.append(player) - return players - -def scroll_players(players): - pass - -def strip_name(name): - stripped_name = '' - skip_next = False - for x in range(len(name)): - if name[x] != '^' and skip_next != True: - stripped_name += name[x] - elif name[x] == '^': - skip_next = True - continue - skip_next = False - return stripped_name - - -def scroll_text(s, y, speed): - #not sure if this is the best way to do this... - cen_pos = get_center(s) - end_pos = (cen_pos *2) - (MARGIN * 2) - 64 - for x in range(WIDTH, end_pos, -1): - add_string(s, x, y) - wmdocklib.redraw() - time.sleep(speed) - -def get_center(s): - return wmdocklib.getCenterStartPos(s, WIDTH, XOFFSET) - -def add_string(s, x, y): - return wmdocklib.addString(s, x, y, XOFFSET, YOFFSET, WIDTH, HEIGHT) - -def get_spacing(line_no): - if line_no == 1: - return MARGIN - else: - # 1 + (4) + 4 - return MARGIN + (char_height * (line_no - 1)) + LINE_SPACING * (line_no - 1) - -def check_for_events(): - event = wmdocklib.getEvent() - while not event is None: - if event['type'] == 'destroynotify': - sys.exit(0) - event = wmdocklib.getEvent() - -def main_loop(server, port, update_interval): - dif = datetime.timedelta(seconds=update_interval) - last_updated = datetime.datetime.now() - just_started = True - while 1: - check_for_events() - now = datetime.datetime.now() - if now > (last_updated + dif) or just_started == True: - data = query_server(server, port) - if not data: - add_string('Server', get_center('Server'), get_spacing(1)) - add_string('Not', get_center('Not'), get_spacing(2)) - add_string('Found', get_center('Found'), get_spacing(3)) - just_started = False - else: - mapname = get_map(data) - num_allies = get_num_allies(data) - num_axis = get_num_axis(data) - num_specs = get_num_spectators(data) - last_updated = datetime.datetime.now() - just_started = False - - if data: - add_string(('Allies:%s' % str(num_allies)), MARGIN, get_spacing(2) + 5) - add_string(('Axis:%s' % str(num_axis)), MARGIN, get_spacing(3) + 5) - add_string(('Spec:%s' % str(num_specs)), MARGIN, get_spacing(4) + 5) - - #mapname last in case it has to scroll - if get_center(mapname) < MARGIN: - scroll_text(mapname, get_spacing(1), 0.04) - else: - add_string(mapname, get_center(mapname), get_spacing(1)) - - wmdocklib.redraw() - time.sleep(0.1) - -def main(): - clConfig = parse_command_line(sys.argv) - try: - program_name = sys.argv[0].split(os.sep)[-1] - except IndexError: - program_name = '' - - if not clConfig.has_key('server'): - print '\nYou must supply a server using the -s/--server option.\n' - print 'Use -h flag to see more options.' - sys.exit(2) - - global char_width, char_height - char_width, char_height = wmdocklib.initPixmap(font_name='5x7', fg=3) - wmdocklib.openXwindow(sys.argv, 64, 64) - - try: - main_loop(clConfig['server'], clConfig['port'], clConfig['update-interval']) - except KeyboardInterrupt: - print 'Goodbye.' - sys.exit(0) - -if __name__ == '__main__': - main() - - diff --git a/examples/sample.pyradiorc b/examples/sample.pyradiorc deleted file mode 100644 index 2b0a06a..0000000 --- a/examples/sample.pyradiorc +++ /dev/null @@ -1,18 +0,0 @@ - mplayer /usr/bin/mplayer - dumpdir /home/mario -rai1 rtsp://live.media.rai.it/broadcast/radiouno.rm 48 -rai2 rtsp://live.media.rai.it/broadcast/radiodue.rm 48 -rai3tre rtsp://live.media.rai.it/broadcast/radiotre.rm 96 -nos1 http://livemedia.omroep.nl/radio1-breed 128 -nos4 http://livemedia.omroep.nl/radio4-breed 128 -rne1 mms://a729.l830022151.c8300.e.lm.akamaistream.net/D/729/8300/v0001/reflector:22151 128 -rne3 mms://a1830.l830120550.c8301.e.lm.akamaistream.net/D/1830/8301/v0001/reflector:20550 128 -rzeszów http://live.radio.rzeszow.pl:8000/hi 128 -gdańsk http://www.radio.gdansk.pl/audio/radio_gdansk_low.asx 128 -kielce http://gra.radio.kielce.com.pl:8000/listen.pls 128 -kraków http://emiter.radio-krakow.pl:8080/ramgen/encoder/krakow.rm 48 -bialystok rtsp://194.187.119.2/encoder/radio.rm 48 -bbcws rtsp://rmlive.bbc.co.uk/bbc-rbs/rmlive/ev7/live24/worldservice/liveinfent.ra 256 -bbc3 rtsp://rmlive.bbc.co.uk/bbc-rbs/rmlive/ev7/live24/radio3/live/r3_dsat_g2.ra 256 -bbc4 rtsp://rmlive.bbc.co.uk/bbc-rbs/rmlive/ev7/live24/radio4/live/r4_dsat_g2.ra 256 - diff --git a/examples/sample.pywmdatetimerc b/examples/sample.pywmdatetimerc deleted file mode 100644 index 98e55bc..0000000 --- a/examples/sample.pywmdatetimerc +++ /dev/null @@ -1,42 +0,0 @@ -[DEFAULT] -# The formats are the same as Python's strftime accept, but one format is -# added. %q now means the week-number with monday as the start of the week and -# the first day of the year is allways in week 1. We calculate like that for -# example here in Sweden. -# -# Taken from the Python manual: -# %a Locale's abbreviated weekday name. -# %A Locale's full weekday name. -# %b Locale's abbreviated month name. -# %B Locale's full month name. -# %c Locale's appropriate date and time representation. -# %d Day of the month as a decimal number [01,31]. -# %H Hour (24-hour clock) as a decimal number [00,23]. -# %I Hour (12-hour clock) as a decimal number [01,12]. -# %j Day of the year as a decimal number [001,366]. -# %m Month as a decimal number [01,12]. -# %M Minute as a decimal number [00,59]. -# %p Locale's equivalent of either AM or PM. -# %S Second as a decimal number [00,61]. -# %U Week number of the year (Sunday as the first day of the week) as a -# decimal number [00,53]. All days in a new year preceding the first -# Sunday are considered to be in week 0. -# %w Weekday as a decimal number [0(Sunday),6]. -# %W Week number of the year (Monday as the first day of the week) as a -# decimal number [00,53]. All days in a new year preceding the first -# Monday are considered to be in week 0. -# %x Locale's appropriate date representation. -# %X Locale's appropriate time representation. -# %y Year without century as a decimal number [00,99]. -# %Y Year with century as a decimal number. -# %Z Time zone name (or by no characters if no time zone exists). -# %% A literal "%" character. - -background=black -foreground=light sea green -timeformat=%H:%M:%S -dateformat=%d-%m-%y -weekdayformat=%A -weekformat=wk %q -#rgbfile=/usr/lib/X11/rgb.txt - diff --git a/examples/sample.pywmgenericrc b/examples/sample.pywmgenericrc deleted file mode 100644 index 8116077..0000000 --- a/examples/sample.pywmgenericrc +++ /dev/null @@ -1,69 +0,0 @@ -# Sample configuration file for pywmgeneric.py. -# -# THIS IS ONLY A SAMPLE. IT WILL MOST CERTAIN NOT WORK ON YOUR SYSTEM SINCE -# CUSTOM PROGRAMS ARE USED IN HERE. ONLY USE THIS AS AN REFERENCE. -# -# Available actions are: -# * method - Call a method defined in the class UserMethods. See the -# source file for more information -# * exec - Execute an external command -# -# Available mouse actions are: -# * method - Same as above, see the source file for more information. -# * exec - Same as above -# * update - Update the data through running the action. -# -# Other options: -# * scroll = yes|no - en-/disable scrolling of the text if it doens't fit. -# * display = - display a static string instead of the first line of -# the action-generated output. -# * update_delay = - the time to elapse between performing the -# action -# -# %(allText)s expands to all the text collected by the action. -# %(displayedLine)s expands to the line currently displayed in the app. This -# may show more than actually displayed since it gets the -# entire line, which may be truncated before display. -# %(allTextEscaped)s expands to the same as %(allText)s but with all ":s -# escaped to \". Great to use when passing the text as a -# command line argument to something. -# %(allTextButFirstLine)s expands to all text but leaves out the first line. -# Useful if your program for example prints a summary -# first. -# %(allTextButFirstLineEscaped)s is a combination of the two above. -# - -[0] -action = method getCpuTemp -update_delay = 10s -on_mouse1 = exec sensors | xmessage -file - -on_mouse3 = update -scroll = no - -[1] -action = method getSysTemp -update_delay = 10s -on_mouse1 = exec sensors | xmessage -file - -on_mouse3 = update -scroll = no - -[2] -action = exec tvcatcher.py -s -d -on_mouse1 = method showTvWithoutDescs -on_mouse2 = exec mozilla http://tvprogram.nu -on_mouse3 = exec xmessage "%(allTextButFirstLineEscaped)s" -update_delay = 5m -scroll = yes - -[3] -display = xterm -on_mouse1 = exec xterm - -[4] -action = exec dnheadlinecatcher.py -d -on_mouse1 = method showDnWithoutDescs -on_mouse2 = exec mozilla http://www.dn.se -on_mouse3 = exec xmessage "%(allTextEscaped)s" -update_delay = 0.5h -scroll = yes - diff --git a/examples/sample.pywmhdmonrc b/examples/sample.pywmhdmonrc deleted file mode 100644 index a21246d..0000000 --- a/examples/sample.pywmhdmonrc +++ /dev/null @@ -1,50 +0,0 @@ -[DEFAULT] - -# Displaymodes are used, free, percent or bar, displays the used size, -# free size, free percent and a bar representing space, respectively. - -1.label=/ -1.path=/ -#1.displaymode=free - -2.label=usr -2.path=/usr -#2.displaymode=free - -3.label=home -3.path=/home -#3.displaymode=free - -4.label=cd -4.path=/mnt/cd -4.displaymode=used -4.action=eject - -5.label=jr -5.path=/mnt/jr -5.displaymode=used -5.action=eject - -6.label=sm -6.path=/mnt/sm -6.displaymode=free -6.action=mount - -7.label=cf -7.path=/mnt/cf -7.displaymode=free -7.action=mount - -8.label=flo -8.path=/mnt/flo -8.displaymode=free -8.action=mount - -textcolor=light sea green -background=black -barfgcolor=light sea green -barbgcolor=grey45 -monitoring=0 - -#rgbfile=/usr/lib/X11/rgb.txt - diff --git a/examples/sample.pywmsetirc b/examples/sample.pywmsetirc deleted file mode 100644 index da86ee4..0000000 --- a/examples/sample.pywmsetirc +++ /dev/null @@ -1,12 +0,0 @@ -[DEFAULT] -setidir=/home/erl/setiathome -# Nice value to start the seti@home process with on click. -nice=19 -textcolor=light sea green -progressbarcolor=light sea green -barbgcolor=grey45 -indicatorcolor=light sea green -background=black - -#rgbfile=/usr/lib/X11/rgb.txt - diff --git a/pywmgeneric/README b/pywmgeneric/README deleted file mode 100644 index e7ed501..0000000 --- a/pywmgeneric/README +++ /dev/null @@ -1,15 +0,0 @@ -[wmdocklib.WHAT] -Pywmgeneral is a python module that will help you develope WindowMaker -dockapps in python. It is mostly a wrapper around the functions from the -popular wmgeneral.c, but some new functions are added too. - -It also contains the Python written module pywmhelpers.py which contains -functions to aid the development of wm dockapps. This module contains python -functions that wrap up the functions which the extension module provides. -They ease up argument passing and give nicer return values. Some additional -functions, like help for handling a simple configuration file is also -available. This module is better documented than the pywmgeneral. It is -adviced to only use pywmhelpers and not touch the pywmgeneral module -directly at all. For information about how to use the module, see the -documentation in pywmhelpers.py. It is also possible to import it in the -interactive interpreter and issue 'help(wmdocklib)'. diff --git a/pywmgeneric/__init__.py b/pywmgeneric/__init__.py deleted file mode 100644 index 800f115..0000000 --- a/pywmgeneric/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from pywmgeneral import * -from pywmhelpers import * diff --git a/website/index.html b/website/index.html deleted file mode 100644 index 71382f3..0000000 --- a/website/index.html +++ /dev/null @@ -1,259 +0,0 @@ - - -pywmdockapps - WindowMaker dockapps written in Python - - - -

pywmdockapps - WindowMaker dockapps written in Python

- -

What is this place?

- -

pywmdockapps is the place to be if you are interested in WindowMaker, dockapps and Python. -

- -

-WindowMaker dockapps are graphical applications fitting in a 64x64 tile. -they can work in WindowMaker or any other window manager which can handle -WindowMaker style dockapps; typically: Gome or fvwm. -

- -

-pywmdockapps is a sourceforge hosted project containing a Python library --wmdocklib- and a small collection of rather usable examples. -

- -

although some of the included examples are untested, some others are used -and maintained by the project coordinator. non eof them comes with any -guarantee: they may work well, not work at all, set your computer in flames. -even though no such event has yet been reported, you have been warned. the -ones Mario Frasca uses all the time are pywmdatetime (removed wmCalClock in -its favour) and pywmhdmon. -

- -

-The example dockapps aim at simplicity and consistency. they are as similar -as possible to each other and with no excessive graphics. Since they are -written in Python, it shouldn't be too hard to change something you do not -like about them. if you do modify things according to your needs and tastes -or if you simply try things out, please share your opinions/changes with the -community, by sending a comment, suggestion, patch (highly appreciated), or -just drop a note to say that you have tried it. see contact information at -the bottom of this page.

- -

you may also consider filing a bug -or change -request... if your request comes with a diff file, chances are that it -will be processed quickly (a matter of 3/5 days). -

- -
- -

News

- -

2006-10-26

- -

released a few constraints. the font can be -antialiased (the colour is interpreted as levels of gray and the resulting -effect is an interpolation between background and text-foreground); -the set of patterns and the character set may be each reasonable size; -some of the programs accept a --debug option, in which case they also -output the xpm to stdout; clashes in symbols used in character definition -xpm and patterns are resolved by the library. the ' ' (space) is still -reserved for the transparency; all 0..9,a..f are still reserved for -'built in' colours.

- -

2006-10-22

- -

radically restyled the initialization of the xpm. the -three parts of which it is composed (drawing area, patterns, charset) are -now one on top of the other. the client application does not need take care -of making the three components of equal width nor of any specific length: -it's the library fixing and keeping track of this kind of things. -

- -

the 'background' parameter for the initialization -function can be a static pixel map, (in this case the space character is -reserved for specifying transparency), or can be left blank (then the -pixel map is constructed with 'margin' transparent pixels all around) -or you may give a list of 'viewports': rectangular holes you want to -dig in the otherwise transparent pixel map.

- -

use the initialization interactively and give -'debug=True' to see the constructed xpm. you may save it in a file and -view it with your favourite graphics viewer. there are versions of emacs -(e.g.: CVS Emacs on Mac OS X) where you can view a buffer 'graphically' -just by hitting C-c C-c.

- -

2006-10-13

-

we are now at version 1.11. the library can be -built/installed/distributed using the standard distutils library. -do

-
python setup.py build
-sudo python setup.py install
- -

additional fonts can be installed. have a look at the -ones defined in the wmdocklib directory. the constraints are: the name must -contain an indication of the size of the character cell (something like -6x8); only the ASCII characters 32-127 can be defined; the width of the xpm -must be 128 pixels; in the xpm the two characters ' '(space) and '%' are -reserved for background and foreground. -

-

once you have added your own font, redo the intallation -procedure.

- -

2005-09-05

-

coordination taken over by Mario Frasca. project accepted in sourceforge.

- -

2004-07-15

-

Minor feature enhancement/bug fix in pywmhdmon.

-

2003-09-01

-

Some bugfixes in pywmdatetime and pywmhdmon.

-

2003-07-02

-

Pywmgeneric now has support for up to ten mouse buttons.

-

2003-06-28

-

Fixed a bug in three of the applications where a mouse click caused the app to -hang.

-

2003-06-27

-

Added a new dockapp, pywmgeneric.

-

2003-06-24

-

Added a new dockapp, pywmsysmon.

-

2003-06-23

-

Added a new dockapp, pywmhdmon.

-

2003-06-17

-

Added a new dockapp, pywmseti.

-

2003-06-16

-

Added a new dockapp, pywmdatetime.

-

2003-06-13

-

Kristoffer Erlandsson starts the project, creating the file pywmgeneral.c. Thanks to Martijn Pieterse for the original wmgeneral.c

-
- -

wmdocklib

-

wmdocklib is a library that makes it possible to write WindowMaker -dockapps in Python. Quite a bit of the -code is taken from wmgeneral.c and Kristoffer says he just provided Python -wrappers around those functions. The library also contains a Python part -above the wrappers that ease up argument passing and return values. Also -some other usable methods are provided there. -

-
- -

Pywmdatetime

-pywmdatetime -pywmdatetime -pywmdatetime -

Pywmdatetime is a dockapp that displays the current time, date, weekday -and week number. Formats and colours and font are easily configured. The -application contains an antialiased font for digits, which is used if the -option '-a' is used.

-

Changes:

-

2003-09-01

-

Fixed a bug where the week didn't update if we used %q style week numbering.

-

2003-06-28

-

Fixed a bug where a mouse click caused an infinite loop.

-

2003-06-26

-

Fixed the bug where longer strings didn't get cleared when shorter ones where -painted. -

-
- -

Pywmhdmon

-pywmhdmon -pywmhdmon -pywmhdmon -pywmhdmon -pywmhdmon -pywmhdmon -pywmhdmon -

Pywmhdmon is a dockapp that monitors the free space of up to five of your -filesystems (per instance). the fifth line can be set to contain a little -bar that displays the current hard drive activity.

-

the configuration file can contain more than 5 entries, the '-s' option -is then used to skip the correct amount of entries in each activation of the -program.

-

Changes:

-

2006-10-12

-

each mount point can be associated to an 'action'. this -action can be 'mount' or 'eject'. clicking on a mount point with action -'mount' will toggle mounting it. 'eject' is the same, but after unmounting, -ejection will be attempted. -

2004-07-15

-

Added a patch from Mario Frasca (Thanks!) which prevents the app from showing -the data from the host file system if there is no filesystem mounted at the -given point.

-

2003-09-01

-

Fixed a bug where the numbers weren't displayed if they were between 1000 and 1024.

-

2003-06-28

-

Fixed a bug where a mouse click caused an infinite loop. -

-
- -

pywmPhoto

-pywmPhoto -

this program was born because I did not manage to get wmPhoto working on -my computer at work and because I wanted to document the process of starting -a completely new program using the wmdocklib library. -

-

pywmPhoto has not that much funcionality as wmPhoto: it just shows a -single static xpm, nothing more. there are limitations on the xpm that can -be shown: it may not use the ' ' (space) as a symbol for coding colours, it -must use one character to code each colour. use imagemagik's convert with -parameters: -depth 256 -colors 80, then make sure that the space is not -being used (it is necessary for transparency).

-
- -

Pywmseti

-pywmseti -

Pywmseti is a dockapp that monitors your SETI@home progress. It displays -how many workunits you have done and the progress on the current one. You can -start and stop the current process by clicking anywhere within the window.

-
- -

Pywmsysmon

-pywmsysmon -

Pywmsysmon is a dockapp that displays your current CPU and memory usage. It -has a graph displaying the history of the CPU usage and a bar to display the -current amount of memory in use.

-

Changes:

-

2003-06-28

-

Fixed a bug where a mouse click caused an infinite loop. -

-
- -

Pywmgeneric

-pywmgeneric -pywmgeneric -pywmgeneric -

Pywmgeneric is a dockapp that displays the first line of output from an -external program, the returned string from an python method or an static -string. Up to ten mouse actions can be associated with every displayed entry. -

-

Changes:

-

2003-07-02

-

Support for up to ten mouse buttons added. Some additionaly -fine tuning. -

-
- -

download

- -

all released files can be found here.

- -

not yet released versions can be downloaded through cvs.

- -

Contact

-

Is there anything you wonder about these programs? Any thoughts, -comments, suggestions, bug reports or anything else? Don't hesitate to -contact the developers of this project. have a look at the main page for this -project.

- - - diff --git a/website/my_style.css b/website/my_style.css deleted file mode 100644 index 115e70a..0000000 --- a/website/my_style.css +++ /dev/null @@ -1,74 +0,0 @@ -body { - font-size: 12px; color: #000000; margin-left: 10%; margin-right: 10%; - background: #FFFFFF; - font-family: verdana, helvetica, arial, sans-serif; -} -body.blank { - font-size: 12px; - margin: 0; -} -body.menu { - font-size: 12px; margin-top: 7px; margin-left: 10%; margin-right: 10%; - font-family: verdana, helvetica, arial, sans-serif; -} -form { - margin: 0px -} -body a:link { - color: #002090 -} -body a:visited { - color: #002090 -} -body a:hover { - color: #300020; - background-color: #c0f0f0; -} -body a.menu { - margin-right: 15px; text-decoration: none; font-size: 12px; -} -a.bm { - margin-left: 20px -} -td.name { - width: 80px -} - -ul.noblob { - list-style-type: none; - margin-top: 10px; - margin-bottom: 10px; -} -h1 { - font-size: 20px; - margin-top: 20px; - margin-bottom: 10px; - margin-left: -15px; - font-family: verdana, helvetica, arial, sans-serif; -} -h3 { - font-size: 14px; - font-family: verdana, helvetica, arial, sans-serif; - margin: 0px; -} - -p { - font-size: 12px; -} - -td.listitem { - width: 140px -} - -p.newsdate { - margin-top: 12px; - margin-bottom: 0; - font-weight: bold; -} - -p.newstext { - margin-bottom: 12px; - margin-top: 0; - margin-left: 24px -} - diff --git a/website/pictures/angelico-mounted.png b/website/pictures/angelico-mounted.png deleted file mode 100644 index 085c41de6a4ec6e3d911d586f4e80ddb1e5756a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGH$wj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&kwOi=WHFGCuc>0|Nsiqo<2wNXEUlvo7*B8}P7B*4muH zn3l{PmfYYoxh|kpB*c8_mQ5#rE?(r}@jhiXGw1x`vT3iM^-Qm92>Ac;-fWK8ep_W0 z25+6~HoFroHl!|RowMxi%)*>^2R43*ay#Ml>pFwmCHo}-S-$z|o7b;x>zsPW?X}>g z{haw_4o~f_%yfS3+M4pR^Nwm{O0{`y$ay91wT0fNiuTwqei3-6i^Zy9hBog_o~beQ zUpSR6?_hpqd*PwbeCbP0l+XkKGIouV diff --git a/website/pictures/angelico-unmounted.png b/website/pictures/angelico-unmounted.png deleted file mode 100644 index 44956c03f87980deb9162701a4a12da13410ba68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGH$wj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&kwOi=WHV!m#k|bfC~5PZ!6KjC*fq-R5mJ;Bobw8o7yK zvmxu6V+=FZ{$@?%iWcbb`d?3faiyfd%&qY?jur=7*;S~6~a+akcg z^RcWq`SLc=;BTglhYj{#Dm}_~W##otPGVQqGfM>i=V^`6|5|2ZJu^#XG&+A(`i9qu^yjK%-} diff --git a/website/pictures/croese-mounted.png b/website/pictures/croese-mounted.png deleted file mode 100644 index 8f354f0484fe8fe3bb0bfbc9eb0c72200fc56eb2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1134 zcmV-!1d;oRP){sCu9Hs1N%ut zK~#9!?Okn>vmgxC4yUNc=-E8Q_G%u3y@v0PeQgmEBpMJ%GUH5jx2_2f`FIHK_L!>}p<1j|EBpa4)2EC!7XUCTPC-s%BVqyxa(Uj=~90okD6m4Vw2r)law7W#&m zrf2s#fVI}s7v%vELoCZMyj~3UFGM}O-{G}+{v<=z{(cM*=)Ela@4a5%YujfITigJA zS7!sc2hagDsqjgO>FN%CgErX%-T^>38-xzNKiju+4*B`HPp5gN@Bs1#|8D{e@StS=Vv_rcT@qmAfP3I9aRAcGDTEBF4z?S!u3`nNVq5f z1PMfae?ox!LkUb^sPhRXu(=B9fCxf)fNsmaCtd~$5ko?_dmf`okIJXgU1%;PoLY-_ zS_*EZ?*@Kz>MloAX|pae;kkWa^yC4eYXPy@o&tuJ1k(@lh!m-v3U-;XBqOyx(@X1D z0Tq0h1MCt(D6VtF$FXw41=A0+N8=^YIt=S-tzEaz|LdfV4`1KyT%O)$5GsDSlT-qO zL{M;901+fjZ)jl=>SM& z#Qa*hfv(wY@B&-uKkL#0xpQuOwz|FoS!D&30Mrcie+Kr;B_JA;IPK(goKSqtDS4`T!q zl$23B9u-jUbqx<7*kZ0!~oXA+61QG82}PP-fnN; zcksvK93WS2z>y7eRRP%SW6R1jRzF}ESWf_;OOe|X=yD*(NuWx1#FroLMQ;z6<^dqR z#cmH*N#OxXm0YoGIF|IBP69LP*+{Ec&<{|>)-X;=^a>Sxmg?oEh?$SA-@_eilkEQe zj^7+5V9Kmbek0nA7FO2H$^UeFssBOj;qn0AHfbC12>vzfoO&HQ#|~@l?srq~zdvFwvW&j>9J$KC zgV~iLlmxW4WVL1Qkp%!PEGoHs0;M1& diff --git a/website/pictures/croese-vari.png b/website/pictures/croese-vari.png deleted file mode 100644 index 4f885ee2c7fbbba811cc0625eee9c53ea2e1e3bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11593 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 D80{&< diff --git a/website/pictures/generic-defaults.png b/website/pictures/generic-defaults.png deleted file mode 100644 index 0394d1b957152714d33a07d69dd5c2541b3ca4b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2087 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 KMNUMnLSTXyB&;t0 diff --git a/website/pictures/hdmon-41-blue-yellow.png b/website/pictures/hdmon-41-blue-yellow.png deleted file mode 100644 index e44cb333bc9633e313c6c2f8889e38e1193e94f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1252 zcmV00009a7bBm0000; z0000;07l7cJ^%m&d`Uz>RA}DaT3w6ORv3O}n9J<^1;IZc2woJyPi!fsMexE+6hRgY z)uOOnDTRWxw0Pm5^$Q8IBFIkmMn-UMoBajSTD2oo-Bs&HX%}&JM6Yss@lH<8oSbAb z+1Y&TOBhbx$;b1aJnzYK-jfRO6bWp3c>@DujDaDt0WcQZh&y@spV9?8oz5XsuK@sV z4MRU&H1v$IR;vY|Hni_&XE(NPw~B_I8d3l=$^fROl29yDbKQks7w%FF)x5!^H2x4u z8~`;GIiP7Pyxr?frHgKbupMi8K=%X zkptB0o>!?>$AV(5tn^9DAOtWwyOA0^YwPtc&xZmUz2QJPu)I9oy4|8bG;PJUtvh$V zXt(uVZz6pRm9gNQiTsE86be+DZ-(Kt+j>Slnbradv7ikAy54pi0|0e@-Z-NJ;1mkf z6ab*vG^RFS z4mmY#g>Ny=?C^8iy!q$j>o*^+UUdKlFwX~=q4BE|Rb6xl3^y$w& zKY;Kkgh4qS@0^=6Ez1UA7@_Vz+rV0wFXlLAnL;Asa5hU$!kvrkq^vY34>2w^! zwylhz_XA+!C?v>h$1yywqU-H$x9)ir!Y4WDRqZ&2W!aWxlk6jBh7tI*fBEYD-!FTY zF5jg5pv0BZ*Yl9jnOPElee(O=pYHEJfp7v8-y$glpYD>FOYY1n0t6G9GCl-h6dFXY z>ut}gP_lNrb<=DDFwLf@@M4_V1;F*&v*+)gJ%9Jhg&Ucr;8>FQtK;A8*u4+ykU~*n zE}=8K066BwrMHVqZ_k~-&ff!~Pz&oe?v#$C-OMOt9s73M&M!e#328=?T+GFdo}*H- zkxcvvl{tYzs`*S3F&E=pYYXPUd<}&Emt4%{JNXo5WCDfgwMv6JmuN~cCmoq_Fu~aK z_{o2NJ^A-+c13azsNN*$1(T=6+b%&D?IV`;ZtneQtH2i z&Y@+$fHe0XzPSJ3#g9K-`FIC`I8&Wk1(-4<0_gdCM-uRHqAW zkrYBI-L^{om*S4=VvS6>z+swAu`;LYZA2(Mv8%!>voY6^%6`dfffD{c=HLHV`t9E0 z=^xJLUT+&|Mt0z!wQ2KqD67-uuytFVE{pMzv&Jdpx(j)u8YzN4h5XVYWArU-W?v1D z=N3S%)9KJx)a658KH{tFe{VuwEi~nEdjJ3c4s=CWbYpLAZDnqB0C;y~b!~8t1?l|& O000000009a7bBm0000; z0000;07l7cJ^%m&W=TXrRA}DaS}||hKoovhECf)INXDS#7o?-7uIbQjo~lZ5B_a`Z z;t%u}M9Ne_Rhp8q5^bo|C6(H$o0p=}#o1~FwM!ByRWNK^hX;@I`Rv#PY@7$O&JSaM z@BH1n&+nWX3>ag;7%%{kHyDHQhnn&R0As$58_yEv5~gWBeey_2D0;@&@$oSLq!DZT z_|qIu9RYf506?00di3G}Of1E1m(WUwoiE>hU<}HHFf49V;f!vALUd1-Nhn0W4M*41 z&M5h~q23UKNTK2A8bN22{NC9*AIwr2Q7FA23hBS^&EYKj`+}qSa+d(DIUj$PM0prJjVYjwcwxjFJnT(^5a|mnm=}eNeoMCs^fme|bPh+?^!0H@huqX!uF-Mps z6B!|Pk7mJ%xMPuhgjsQ;mu4ZUQ_X5em(_@&j{{(Q7UJZ!n$>ix&>fuYovrIu0r3e= zoT}BVwo^RVDITEgLuZ5$j471*^Vh~2OMd?`xSl7G9=cVim3l#((SR=Ed38OAnDcQi+W68U6H1H0#az4(pYqZo zvK*5-Ni?aL6ON2H7`{5~pb*l!eo?NKdKo2e*saQ1!?0VZ+t8_7h00n(I8ulqd}VGo z)X{zvN{V?_rxPLOZq7nWZu}aVgF+Q!=3)WOqn9sm zB*i=zIA+sr?vZ^m-DZ># scHo%+000hjMObuWZ*6U5Zgc>6cVu;KaE=A({Qv*}07*qoM6N<$g8mykGynhq diff --git a/website/pictures/hdmon-41.png b/website/pictures/hdmon-41.png deleted file mode 100644 index a0e950292233884e1b60502f93aec9b4f2352463..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1172 zcmV;F1Z(?=P)00009a7bBm0000; z0000;07l7cJ^%m&EJ;K`RA}DaT1|`7Kp1|u^prm%NcSL;6%=hn@#0~@m4XO*P+U;< z(h7^x*269cey|6R9z52AhxFhG={4fVs$I}UVcieWqgHR@VWu;a$t0WfBTe?*rA*$* z$Ma5}dGpMh%=G(|QcwyCz}%n|{7*E^4S>?f#=d7sa*1BAck#m6LQc_BO55!=fFi^C zy!~Q~r%nMqYXB&Uk*-$HAty!%dHL!!i=i+e44pQrWF~GxLC`&4W}uMlv@F@~_ooeY zpBMrZvMdg|--qk^g2|Ez3Kb_sAv%sTuCD5yr6mynYZO8$}?V{U7zdw8oGcyy9KvD?QHwP*ebh~K`<0$wg zg|sPP+i)BJeE73!3WcbjLd_;hr7T025tu0?(6isnPT~P=iiRwjRnWcw2BazI6v~T* zQm9;p=gI$anL8~@{zo`d!!KyF_v7F0-ru#gXS~Pr0LW<|WQFQvo2s+X;G3x!A!PC9 za{2T;3|R;;ry!%V(Lk#O0F{c~wX!l1>;o|;FqdP>*ADFnzhad34X$C*+DA`AHoU3oE)dx|=G z+eWh~H|ur&t17$*XKDdZRZgoE>U7ZQ=(}qkwrO;x7r{ZHP#_D1iMg20)B=#DMU6t; zE=nb?4lE0ZQf_Vs5I7&ydn0V>wIeLZTVPoVI7W!N}b6W%JkP&7Ui)Pk0X#XH2LeQnzV) zrZ|rYA(yY*Iy!d-W(wuR!mHDH5OXoIP_`{R3)!~hz3WElHa75VIff}@q``wsqfmS? zHx1A#`j8hKIWeWQsJ-AAPPb_*=|ty=UklVCV6^XT?0(wVY2JIxJB*b%E&XfjcXc1_ z5UrRO-x*o!;qS;CN8V8NvxA_*Q!gJpq*gQQznISb%6^hG>mRq)KWyD?Jm5W=Zd0eGrts8T zA3P-DJVsHNr0hosS*Tt+JbN5b)#+?oIE65jZW~emCBNcpsHO>*#c3 zxsG*dML01?s;Y}Vk8mPMEzpmjV}ASo+naY^m+#!4_K+qpLdg8W)kBAm!Calrg&o|| zVouCZohF1#8&#qRL>3xQhHlxdc$`^?K|p>inV4AMs80A61T9-HsCxVE_OC m4s=CWbYpLAZDnqB0C;y~b!~8t1?l|&0000L>>Q diff --git a/website/pictures/pywmPhoto.png b/website/pictures/pywmPhoto.png deleted file mode 100644 index 0ff61cbf40fa194c1db705a080daae428e47ded7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9326 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 cdCaPGqsIDiIs5;+BNR~0Jy)nDgXcg diff --git a/website/pictures/pywmdatetime-antialiased.png b/website/pictures/pywmdatetime-antialiased.png deleted file mode 100644 index 9c4b16628da4c7c48fe887ab51ab7d28c6119448..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1318 zcmV+>1=;$EP)00009a7bBm0000; z0000;07l7cJ^%m&zDYzuRA}DaTF;9VM;LvM9X1mL5%#d-C9rp~8TaPgf(v49!a|}j z2U*Yv84v=({sUgezsXtie9TYKfohS2M=WBnuvPM(|w(Cxmg zR{NC1;ltbQc3D}g^kX%lfq6@))tV(B{4b5h!PV6%R%|v8(9RYXdH}lJ5`e|U|C-GW zU9HlO)nsYu9i0~QBGBRy=v~MUn(zIH1F}wl>vnmvyyDm`$!;-H4*{^XG~g z5O&6$0ECl*H2^yANfJ;QG#Z;x^j24^gxRE0**)70~~uR_2d z=|6jax60NRL(JG{r5RKchdpbh2F+W;Xb7f<`U*5CCe`hBimpxB?Zf@Km7y9Kr z3jvr`AuskH5nlaTB*Z3{4k|yD=Az7rXJ&3}?pNZkmym2A{9-P8xyssjlou-MM#g8S z3viK9u^*m=xT9%-z)6U^-4qMljm#_|dD|aMWU=o_- z@7t;fr0n$X_aEo>Z8&omK#-;>{TFrd*cVUuDtrJe%^6w-F0w=b000hjMObuWZ*6U5 cZgc>6cVu;KaE=A({Qv*}07*qoM6N<$f_G$eTL1t6 diff --git a/website/pictures/pywmdatetime-fonts.png b/website/pictures/pywmdatetime-fonts.png deleted file mode 100644 index ac2dffc093fea6a506a94d042dbb6d3c37dc88e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7035 zcmXY01y~f{*IpC^kDXnZ1wmR`8YPunQY06UUMZy!Sfsx7 z_x+!FCZ0QI?%X+Z&w1bX+$0?>RYH6kd;kDIsP;lh4*h8$)vr$@Fg zRh0nu|F)v;iVRH4W3Lw`z5u`z@_#!PATJ+?X~gwY(^STt$0vS5_H=A4PzC^?#Zyyy zZVa{tLME+DO-zOPc0WS%GN<^SY zl+#%H{%e%j0t5q|kznIR19HX&NjLsy8f6Yx59mxQES#KL|6fxq=4n!8(vu)C4i1iF zc=LwW+r7((FNLUn!A+n8fF+e2kuWJ505!+>5Q{0Sjt=um3GdBJ?#%R zz08|#3lzs~PkU|%*esaic4_(u{)mCQah~?20~9*m3|@cgn4gJO-lKOeY@G(0-VBEj zwVr82Wa|bOK+AP+n$FGep)yTgkcnPxYR6)SfSR|jwF3E zVp0<_zr8%mucc9i)zT!yRXAs=eh^TX|2BSZkI&6ZFU}k}4pkIZ6&}>yLoQ6&O#15S zt3!^vWO|fSLK+=9Fy~B_X(vY?%UF^D6$HuMAI4Gql-W3}6bH9+2?CW25LC=# zDKaL9rkXnRefWh*C{9zJ%*eb1dlIOk^T;t}{B4?`y7~(@g4W-~ z0!kh`EWC0>qT91UFSHMx_eh`Y@F2!vX;W%66Q=>tJtySwH!K3-cG;PCLQKivRQHe4HYg$+Fwc#%+Ainc63Og z!{h*8^|fUkGzW&qyQhvBU|!P__jG~FHjh0&c-wAam8w{)CU9EX4(@T9@<2zyH2tdD z0lPNk)L6T_U+HLway?|qD2m^#H6N#Cla~1rsUwu&3A?_>rcc{!ALI&>L6yk!-Z8nv zhOsILbbh4CQLqW~-T=71+$re@YV#lOP0k=ieXT@F1$U+88!5C$PQM1>$We@c!~yM2 zYE@3wUfOPkjQ_-;<}r>M8dAy3&Ndy>4$un;(oKRJeypgg<7AX!?xF-o%^yWi~-+q@WDJ^n~8ya(|pCW??VZ_O1AbF?c-p%ohMj4S(Vp;dLbyom7> z54K2hnx&HR$hBU(*3yj+D}~DLObiD%N9?N$9&2Z3z4j-6Gom0>)A22}r@uI#R(XW_ z&h`157SC(g*$X`_B&{``KU~<@aCFnPXiEPcqSdnZs9ER-&wF)b;U0&^2f5OM83NWf ztVmg8$_muwr{7)u868i)6+GpH1i(0%mB4I-72nVDSwbK=cMxf7IiY~qWXa%21}@B` zK8s)qYi*9&NO?SI!TfAv6oRnxYaQQz@px+IuS|0_7ds|j^am#rvZx-!tod$wIIshr z**CCbr3{rOKJliYywZ7N6?L|wy(1$ha^;{#K?-_Y?6oNK=5>8k*;*n|r7%g#(8k3v zzFEG6LrTPD=UQ=lJBXK;7fe9sW5D}2?#VAoE2Q=v+hc$Ev?fMIAPgS!8PC-%Cf|$< z!UE96CPgtSb)2UA6eh^sA5}08P0$LJaBRz{l$Mg?z>`x_8bdD+GmovypMjknLUQx-kotuDfubV%}1V7~nG7Y(037ndq zj()}%b$#?j{^V+JrlQejOI_8v!41h5wj;eZC3`rYD{S2AO8MY5fC>{QNUO*d!7!h{ ze_UGH+Df{*z?d%941ZhaLp4vkSN&!*cVC$12VEb0lIF%eiX{Xsn6?sG&=V5jFZ9_U|v!7?|y`U@R%3E7dMBzzCEVO&EZ*A*sDm>X03 z^=9P4`N*OZ7$Sg^^7k^PW@b}JWDfeULjIN$Qf~<(mcJ3$x!UW#Ts9USSON}~;=->lHV!_mX_aNpHRMVM@=@`c zW}X2@E<5Z;$nvH9@lhxgXM9=&?_cw?1)R7qd-xjZjHE7`vM)vzgtRhExd=NxvOX^Du5vFla2F6=KfK9s-N zAYR-qGC`#Vq?R){m8cFkIgB;fA&A`9dMr*tRkzl$Hj>Ghjk^AR2F9@_zhNa!e_w1@ z_8j2W43Zw2B~h7`48qHh4AL0ddK!#y&?A{%&9Qu}xzyckdS2@PvFdXz_T47g%t4la zqg`Q>otU1eRn*abig|88v4=2;Y!L2*65?~qtJ_# z7#?KHT6d^;&w1UeJ$mHKOw9E3bSx>hMy9-H>R(=XC)_ttNrKF_9i&MZ%jpOUv*@fBpd72#t(*lRAH0S5dpesv5mW`%7R{B_z`$5y8jukXo$&P_P4@f9?GcK3+V0X5-uElS zG*0=t$mD2d_$?Pw?OjX`-fPxmMkVz|D08v*Uy^K7``&6uub8398CABHwY88(>5}fZ z7p+5_sc9N@b#>?;Yj^R4v|>dqEfkofrp!U15FRdT+XxH^4Hb0y2ClXGLjR-9qkmxm zn3tEQV`T-$kjq^1w~*tEMM>B1*2|rN{FXr*I9&X7A3i*)?>fa7b6<%1_>pga?MtB+ zm9fKk1K4RhFayD3{+XoLnuNax%{*UcmSAKRPFWa!0XpoywA6IB3_DTgvFOOW4W`}u z<1+nyCjYk->l(K}> zj1W1s_MLW;lw_csJke)DJUceKBuZNDF8u6m5u@eHq>1CxO(_M&RMj~o*Mi0L?4hHo z+D}^zhpPBpUp$uFHqVvhBMeSdR#iP$RD7saCrX3Io#94~=GV>zbPrfR&jAWlJJng7Db?v@sXojXBNZGxcTG+cyVS&P}YZJ3ApIq|m!w=lh2>H9$ zzB}JGFcZD9zFzhDb1VQO3EuktVlxm7R$?T1AsB}72o#gd%`Mn9aU)8AiY}q~5V>=V zg+%0?%;?xyT24-a)BE7~Zx36mx2kmcGt(R=-|ud>N8Eb8Cow0<6PvK~YH>rc#NtWyzg zEFCX|GFFiZsbsd(H9Yy6~2+{gMcYFD&Duyat&O(O%?x#DTC zJRAM`wlL}saYr=RH5Pa8TyP;Zx=1&Tfv-)+z5=$b9Yjr$G zJAdPmG zfMSMLWK5!CZa~0E6URuBxqN<*Kje%YGi%ttIOpIh*@?p-$*H3-dm^eV2EI(Znpz+p zFyj6YMV<|o+F=6d4ELHH6u%pJ{6n-S`vD8~RAS<=GkB^YG2X-qA)0meRV{cr=r+P& z+3(?_3kJYrSW!zE1zG*{P?G-kaH>GN$>dDx$zy(vA@$TH-1-7>O0T^e2lQ$9=Zy|p z5)Q6FurP3fn>sU-aiQ&j)qy;Ki9*4}T;O3K02e`BIKeD;%x9$tax?L_fFXlKOeqjRqj108_R!Y?+2 z0SJtmG*a>)fx%$Kot^qn63{ot|87*rsNh3uNf+PV z-l9*(_%|-E8!>o;?!-$RqOA&hqOG7eS$4xil~m0j?IP?Pk%{wn#cHnOb^mkW6Y% zj~oFpafQ+V1_w^h&h$GfH9_rZSc*DFJ#<+y$UGf-xTLlc5YIr-`?OEs5hmR zpdnq{@xf$rvU*VW>NuX0Fpldih48^e+1{^QN83ZtRX(}!$oo(cn!)vT#`uJU#;~i? zSR?)~Jn&~`79UqsN=)r{GQnMzsU~i7>=~zXr-`*o`qgZeoVf<0_Gad--JPaLPlMp8 z`7W`jb}-K9LJ2)LMFXTU@}U{GSC2_cTk;3zP4k}jVq>LN z{f%>o&06Q7lBO?Sr$-0VCal+08bIdNf@@{C6PbeI1{ulD=RDE^AoS5qoY>$ zRHVs_SK-BP=z`LcWKdp2n@T3Rn-fc32byN5LAKVlp@2PO$KheKz0A|f*1x&_;JQiB zd$l3o!xo1$7)@aaN+5_@KN?=U&Q^M0UBS#>r3`9W8f*GSowtJLx}(i3*#yRq^SV7p z>c{=WaLyDApgv$@V>ABj#q@63!Q-LlK#G$#=cE7AK_O?p^PmAKl6l$^Xhw;8>= zncj!OOOem&AT3j_mNUFzE_-;qjY?t?^&mHj;H_>iDFmGC7@h$nM0f0`jK;?IgMo5{O(uG2y)`Q8EfLZF+ z0Du49owMS$HYyDLOnYJfi#87wq|&#rVEmx*55%{cI1!Te{pTs}e zjQ&Z|xcRT_WfF&}XJIjv3K^;~xor)@0`Lqoen<@sr?IFCV94VWYQFV(vsZHio7$0o z$*ZfY1>EL&C@3kJ`1y(H;fOH$h`jG#zecs;)^|=Ml+%J?;-gC*-=Zo;Yo=cRS617S z($Y6^r1e_ZJPER`$)_K*70k@a!VH*6UY;R1I5?xa;7rYBKIR#oHeJWAFZk32!G#+h%XF-gM%2-$-%)9g+O`7Mk6PBrAL;w-^azA zG*%woX7(qRqX}U`sIap7GL2L69MvUO@f=cR-OB}Q0lb_soOl-io+Y!+C+Gri~;^wvXn8PWtwpyg90W(X8TmQzfUTKIT1Pps!gTYg)(a{+GSd zNh6qGoE+0|*eYiaI#|w=T#0R>QV~hc`w&D~+UGRL0VZ-2i?{9jw%fh5EWw2{0S<^JBmW4`);jz|IbBE`Ol>0&h76ucNdivtx;$~)2 z1e#f1+bXz(SHx2@VH3+713W)(Jo??(SY2J99IvqY`d+DPTP3j>qG1IW>89!)goz%0 zxsL#l*K|?yn#N*8CIS$(c6ad!y(530>$C5Vv`El=Cx(F>T86M=EUou4Nf?!~iMiQ+ z{ubD+%_1GI!6l%zgdVo+df)W1s;U>0+%VjE}f5%WLg?W^gltMt}tx_X-J-_D~-EO;-ty zETp|CSksnu2E*YR94GRy*Dw)MTv^F+a*L58WNQ-z($s(k-yJP6OZ6U4X-dh55RtP9 zh~;Q3V)T0kYc8CNi%TH#F3kM1*Xv(@QmFa==`)Pqy)X6`_f;pHJM4vq-DS;diKl+d zu|d6UC*Fxq&N^Teg!SZmSu}>1ONz3?>11a>#~?6R0}qw)RJ-ZPmLJxH?SQela6S&p zn2f(@t?_YgG%z>&Ws5(`+oWkT}d<+RNq23bs?NzCa z;F(Sn0fNrfVdfmaxvZ81g&UaLFqJ2ad~CC`zPRD62^@PdVk6RC&Qeh$xTyqB(^vQo z+F;{_FR2IHDDJ2Tv+k6!sp%cQkuv-l7*Dm7`(%pNgT>8ppNBeQ_t&p~(hR_e;hyM$ z=_gfrHe|vDSMGfpLr+bB+E>Rm@thzQts#NUw~Jq22J9CVxyad7*c3C?^KLP9t4FA8 z1;i85=X6opsMqe6)$wKBG$ol>M&6!Ns0hZvAur(P#oTe=EK9M+w4g%!)eQv`+EPy8 z$qxc58fOzWUG}5>^Je>Fn{TUlU%bqo6C3+YZ5hP0wdHrZ&{3V!+LxW~@7#>z_iL83 z>tu*FsZMse^!rdkg8rVsW*JO3G*lWx*kz$`xSg{z-aGME+l(f?FI%R*|Kxk6Vqa@Y zp<81DgQ4A*S~$0^t!_4{&3oVJEsH!MFn${skX8^ko-xjYQICLz@aq7+GSTBS?=LmO4*@XibBAx z26=q65>Se8Vnm{yJ*5ixDIa`%{htMVrau7zXFz-_kR~6WUR+EPUkl6F(U$!GRS%cE z4VDZ>ywpK15XO@Cxv1mDm452KP6oX5EYV){>Vq8Rdg0pI+FGkE%PIo7sr0hRfvdr) zSte4_(&Sshl5&1%FQ|kH#Ad+T=Yvc#0+r0G16$8H?0)*C;(Wgug!Mu$@UQ>yJ+~pD zVc+n~>gxM5h-OGm^S5tW7LLJZ6XK1*XO3QB|67IO6lP6khSVC{&@hxH8;sx;>7q~X zPl2b`f9z(V1WRYr=`Hg=KbK+B?+lfZj2c`#OWLO?S$>BTS)p3^gKY>giWyFw8O;KuuXo>7#;m^#1`4 CmX44B diff --git a/website/pictures/pywmdatetime.png b/website/pictures/pywmdatetime.png deleted file mode 100644 index 4be0250b86c314894f1bcd29db40dc8486e6b23b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 753 zcmV00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3x@yz3yA>@!>Zi?000McNliru(*_t8Iu?sX`WpZM0)9zE zK~#7F?N(b(12GI_5eMN!d~!%WIT1H0MnTlSM&M(jh7!UuZpmO%c`TuL6&)hO~}gK zO~6z^LlBDi7I0>{Gv0!oz)E#A))cwl5lYilkc;QLD6=hf*L4(UmfCS7{jWwSCDb5C zrZE*<5W{pCrMA;MLT0^okOtkxN=;QA(8v@CMt@WY`o3&qId|jF@_I_7^}Q|Fdj@VB z-2v+>fdfUlsmk;n*u6%>)n*?WMYOc4qsUpTZ##C4;-{t^@gPDdsWR*Iu-G`;bQ}Sj z@NY(lTjBD-p)zGIVH?XmrvJNVz_jteawac5CPq^0f!M>^vwy!MWEt13-zy2TTt^Y* z2A!}}eIV;Ghf)j@rauEKfkBf4x6^kZe#q?p!sp3lzR`TEAF=wGDYaubK==yrp!VMa zKa7|U85Y50#N`@sBI_t}#11TQ%y&0JC^HL49o^*JJy}^mjIw8nb=@l7JaM%IM zOs?g?;$;yN)LaKk^Odra5i&iarP_7GLw1u6c+#8$l0iKb(ddH?maGX7mU-7?C$DDdQHzSA>Kr|T1(zv7ZciW-+ua8+IMWb;a3+COFB?b5 z168jUkb-ptox6=4@XGx*T+YocFw&OEdd#)e?L1cF88|P1UP~*1-U{~er|-bkE!10$ j5&Y>puo4(CHth2gE%Ah2Vkmvj00000NkvXXu0mjf(eX@m diff --git a/website/pictures/pywmgeneric.png b/website/pictures/pywmgeneric.png deleted file mode 100644 index e570b2bebfef8b1c1f85c5e596cba6b2059e460a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 850 zcmV-Y1FigtP)00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3x@yz3yA>@!>Zi?000McNliru(*_$94-Ca8x>o=I0^dnQ zK~#7F?Ur3q+&~P3;}i$UiSm$x<{>BICL1N9J{n1k{J+|-20r@)pR|BwS@iK?ZQa|`U!gZA;3NO>=Qp!|{`pHE4R^%;LdGVlG)f(1 zmO42~L(Gm1SU?s63396CE|}`V&R&p#G8}Z&_=;CZ`*V9R9?0W4Wt|Sc6BVxz1*y?b zrcv2Or!x@`C&V7hsA*To)XN09ja6imR6GIeSnJRMkT`I_R}EEmaz=v4Dq+!o3fDif zFuo%mr|rNI#a1~^-#}dAur$7}tg?CY2IH*;^oo_rukQaJDf;MkjtZREfVn#bWsYac zIQi5?S%4t$F~*!PcZIBP9fo(Whz~{)=P)NGmko`|-usYvg|rUO*Fl=Ok($`av@2va z%_?h?R6K!PLiCS@|T3CZ(wDKdGYCh!&Vt5Bg%LC zJ&xgI$@Y6u=*I@kp>moV9K*aM00bci1{{!Vcn>NvSIF{hN}1E_hr|=;6k2jh zQ0rbLD7kN6pA!99?Za&Cz&@$xsGh!oVu^We+1i;MmMbqYQUW9nsx$Ky8U_^ zb4whnO>4l@9N$B6g_t7u0i>)F+IUnud9P22od(;MoxB6>ywiwpuFy2q1BFh10#^eE c-j*`eU)2tPrc{;poB#j-07*qoM6N<$g33RD761SM diff --git a/website/pictures/pywmhdmon-taller_font.png b/website/pictures/pywmhdmon-taller_font.png deleted file mode 100644 index 9da5a282627e0107ae8b924e3a8ec90ef5342437..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 745 zcmV00009a7bBm000XU z000XU0RWnu7ytkO2XskIMF-Xj7YQXV!#?yR0007rNklF9HDYkwX7o8+sz@`yPNuj(ykd`*U9#dfBi7XuSa( z4yf%KhT-#Tlrc2md8tWY9DrZ4PYGWr;u3h30Xfoo#x%PZL=vfj(C1%PNB-P z5R3r2ZqID^A@M^lDiU&Wll%$7n|%#8>AIR1XzPODvxU5fUN+UMU?V)-!< zTRpOE_7qwK!g47zCW-j&>ejYfQHUH0S%Y2eZYD?}Ybxq4#bF91nNw6XDGCWcg+hPI zw%bz?g}AA?#-$Rr5WNhj)vyc~kp^(B9 zaz&`QLvXcfK`j)dkc-K?vnlQ2&8JYMz7W$wrmaQrwid-aU+C`o<*nsNWe%%=`Y0r} zSOP8-6OEhAGE#Fj?zB6lZr$|86Qht<0zGntSQkf+n0=NyBQvcbvu9Z@Swl0&uFP|% zmn~K9=vw{WB^$!9^#RAy@;mQ2?!E1;eDfkn00000NkvXXu0mjfV-8Qc diff --git a/website/pictures/pywmhdmon.png b/website/pictures/pywmhdmon.png deleted file mode 100644 index 39810220d1a1a392c39753ab33671a2bac179048..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 746 zcmV00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3x@yz3yA>@!>Zi?000McNliru(*_t8IyoSe$3g%A0(VJ7 zK~#7F?OD-n>o5$giw@F>`q@P?M;7U4C+a3C3l@iqNXoPY%Tb`>;ekFMk4H*O19Z9F zZZ9MMypC-C&--lP>=S%r1Ix1TU=f=x9MsY{ljStPLbgl>fe#_W1cMn7<*a5s z=@rUP$Yo;c{FcFJuFOF$KsU>|Lda|hY%w4(ROo{sICB(dgcDD`LSid(da{|&a zi}GM9Ld7eqz(_%^Jg#QVuM(B%b$NC24z&09j19=%;9tvxc>ki9^(_ZBG+;7f=Tk`D z;gd%)5hEuPu$v4&;;dFb>I$tEjvQ~r{S(-#lHq60#N_~VhtjD5t_?#)+Yv|cDC?*z zRG5n%#a84jN-1#v1R%;&DKhJisv!UGR#1I7iOS8d647LO;V17vdz-^I;4Crk&At_6 z1(~rcVmTSaIWhiYfxa$;oSZFCM$K{*vA9-d&(C;;q)W8!p8o0qAbpjYAwbPF$qLbuM+N9I)Yty;E29v z14m4Ci{|hr;D3x>E|)D+=)}EVueQ?gComhZhuRmJzlr00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3x@yz3yA>@!>Zi?000McNliru(*_t904*LRr*QxP0lrB@ zK~#7F?O0K61R)5mO%Ku&^`}X1H5b{>y+J>Fi{4~PV?t0IoMlvW!+cDXL3r>$-3|M` zzpVVct_=Pky9Z#+;2Q-HLZH)W$Fy&~gsf?D2CNxKnm7aVe!u;Gd_`d#!<*{BS1zFn z7sqHEVQ_;|09+d+Xe(OBDSSeI#f6=O%lANqfip=xqoYedrT55!6aZZ>phPu6=g9qa z`LmZ0&rp`;Y|8a}O9H)D_+6-Xx(oJ~?*R{>!0J$uGcYvW1!vMpobB;=;!-n5Iv_9V z)3r^;QUKrpK_JjLK)ImP1YgximmZ+uRS{fNs4&2-j|9iPb4eElxSM{GhXa5fz<%fl z>%8Sk37x^pb)p2`1M1Chqvy%)qxoH+9;*JhmvID9iNpylM-|&00000NkvXXu0mjf*1q&{ diff --git a/website/pictures/pywmsysmon.png b/website/pictures/pywmsysmon.png deleted file mode 100644 index 8d9da6b4564ca88e67c953c25596648628504971..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 474 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGH$wj^(N7l!{JxM1({$v_d#0*}aI z1_thSAns)3J-q5JP>{XE)7O>#GMj`rlknT38xaf)jOm^(jv*C{Z=+809x~uj?QopY ztSoHc<^ED;jsSB(%G#iilUzlf!mp2JJ}fjU6WZT@IT)yJx9Az z#PRX|)ngy`KIPcD?PYQci_i5^q4nx7e#bRGKdRDYk~(o>Aseqf(<~tsXQrn{N$e+YGwS>bw9RLF z+NS$Pp^>$5)%4pI40|{|m>eR09#iCeQqH=LMc80Q!VRI%?7|)W-#Y*IG~Cc_oMst# zsarMqwrSq_M-7s_A5QYWVX+BR`ynE5p`%poqGsT%a~tP|IVdz92$vPzqA2&{y%;Jq-yhFqdyPYqC1YRe gXTAvzuO+J(#d&R|>vu=&0>%P^r>mdKI;Vst0LY@f_5c6?