mirror of
https://github.com/gryf/wmdocklib.git
synced 2025-12-19 12:28:10 +01:00
1569327 release 1.1 is broken
trying to clean up things. wmdocklib now contains the modules to install. examples all the scripts. only pywmhdmon.py has been tested.
This commit is contained in:
374
examples/pywmdatetime.py
Executable file
374
examples/pywmdatetime.py
Executable file
@@ -0,0 +1,374 @@
|
||||
#!/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
|
||||
"""
|
||||
usage = """pywmdatetime.py [options]
|
||||
Available options are:
|
||||
-h, --help print this help
|
||||
-f, --foreground <color> set the foreground color
|
||||
-b, --background <color> set the background color
|
||||
-t, --timeformat <format> set the time format
|
||||
-d, --dateformat <format> set the date format
|
||||
-y, --weekdayformat <format> set the weekday format
|
||||
-e, --weekformat <format> set the week format
|
||||
-r, --rgbfile <file> set the rgb file to get color codes from
|
||||
-c, --configfile <file> set the config file to use
|
||||
|
||||
The formats are the same as Python's strftime() accept. See the sample
|
||||
rc-file for more information about this.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
import getopt
|
||||
import os
|
||||
|
||||
from pywmgeneral import pywmhelpers
|
||||
|
||||
width = 64
|
||||
height = 64
|
||||
|
||||
lettersStartX = 0
|
||||
lettersStartY = 74
|
||||
letterWidth = 6
|
||||
letterHeight = 8
|
||||
|
||||
digitsStartX = 0
|
||||
digitsStartY = 64
|
||||
digitWidth = 6
|
||||
digitHeight = 8
|
||||
|
||||
xOffset = 4
|
||||
yOffset = 4
|
||||
|
||||
letters = 'abcdefghijklmnopqrstuvwxyz'
|
||||
digits = '0123456789:/- '
|
||||
|
||||
timeDefaultFormat = '%H:%M:%S'
|
||||
dateDefaultFormat = '%d-%m-%y'
|
||||
dayDefaultFormat = '%A'
|
||||
weekDefaultFormat = 'wk %q' # %q added by me for different week calculation.
|
||||
|
||||
defaultConfigFile = '~/.pywmdatetimerc'
|
||||
defaultRGBFiles = ['/usr/lib/X11/rgb.txt', '/usr/X11R6/lib/X11/rgb.txt']
|
||||
maxCharsPerLine = 9
|
||||
|
||||
def addString(s, x, y):
|
||||
try:
|
||||
pywmhelpers.addString(s, x, y, letterWidth, letterHeight, lettersStartX,
|
||||
lettersStartY, letters, digitWidth, digitHeight,
|
||||
digitsStartX, digitsStartY, digits, 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.'''
|
||||
pywmhelpers.copyXPMArea(73, yOffset, width - 2 * xOffset, letterHeight,
|
||||
xOffset, y + yOffset)
|
||||
|
||||
def getCenterStartPos(s):
|
||||
return pywmhelpers.getCenterStartPos(s, letterWidth, width, xOffset)
|
||||
|
||||
def getVertSpacing(numLines, margin):
|
||||
return pywmhelpers.getVertSpacing(numLines, margin, height, letterHeight,
|
||||
yOffset)
|
||||
|
||||
def calculateWeek(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 parseCommandLine(argv):
|
||||
'''Parse the commandline. Return a dictionary with options and values.'''
|
||||
shorts = 'hf:b:t:d:e:y:r:c:'
|
||||
longs = ['help', 'foreground=', 'background=', 'timeformat=', 'dateformat=',
|
||||
'weekdayformat=', 'weekformat=', 'rgbfile=', 'configfile=']
|
||||
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 ('-f', '--foreground'):
|
||||
d['foreground'] = a
|
||||
if o in ('-b', '--background'):
|
||||
d['background'] = a
|
||||
if o in ('-t', '--timeformat'):
|
||||
d['timeformat'] = a
|
||||
if o in ('-d', '--dateformat'):
|
||||
d['dateformat'] = a
|
||||
if o in ('-y', '--weekdayformat'):
|
||||
d['weekdayformat'] = a
|
||||
if o in ('-e', '--weekformat'):
|
||||
d['weekformat'] = a
|
||||
if o in ('-r', '--rgbfile'):
|
||||
d['rgbfile'] = a
|
||||
if o in ('-c', '--configfile'):
|
||||
d['configfile'] = a
|
||||
return d
|
||||
|
||||
def checkForEvents():
|
||||
event = pywmhelpers.getEvent()
|
||||
while not event is None:
|
||||
if event['type'] == 'destroynotify':
|
||||
sys.exit(0)
|
||||
event = pywmhelpers.getEvent()
|
||||
|
||||
def mainLoop(timeFmt, dateFmt, dayFmt, weekFmt):
|
||||
recalcWeek = weekFmt.find('%q') + 1 # True if we found %q.
|
||||
counter = -1
|
||||
lastStrs = [''] * 4
|
||||
while 1:
|
||||
counter += 1
|
||||
checkForEvents()
|
||||
lt = time.localtime()
|
||||
timeStr = time.strftime(timeFmt, lt)[:maxCharsPerLine]
|
||||
margin = 3
|
||||
spacing = getVertSpacing(4, margin)
|
||||
timeX = getCenterStartPos(timeStr)
|
||||
if lastStrs[0] != timeStr:
|
||||
clearLine(margin)
|
||||
addString(timeStr, timeX, margin)
|
||||
lastStrs[0] = timeStr
|
||||
if 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(dateFmt, lt)[:maxCharsPerLine]
|
||||
if recalcWeek:
|
||||
week = calculateWeek(lt)
|
||||
newWeekFmt = weekFmt.replace('%q', str(week))
|
||||
weekStr = time.strftime(newWeekFmt, lt)[:maxCharsPerLine]
|
||||
dayStr = time.strftime(dayFmt, lt)[:maxCharsPerLine]
|
||||
dateX = getCenterStartPos(dateStr)
|
||||
weekX = getCenterStartPos(weekStr)
|
||||
dayX = getCenterStartPos(dayStr)
|
||||
if lastStrs[1] != dateStr:
|
||||
clearLine(margin + spacing + letterWidth)
|
||||
addString(dateStr, dateX, margin + spacing + letterWidth)
|
||||
lastStrs[1] = dateStr
|
||||
if lastStrs[2] != dayStr:
|
||||
clearLine(margin + 2 * (spacing + letterWidth))
|
||||
addString(dayStr, dayX, margin + 2 * (spacing + letterWidth))
|
||||
lastStrs[2] = dayStr
|
||||
if lastStrs[3] != weekStr:
|
||||
clearLine(margin + 3 * (spacing + letterWidth))
|
||||
addString(weekStr, weekX, margin + 3 * (spacing + letterWidth))
|
||||
lastStrs[3] = weekStr
|
||||
if counter == 999999:
|
||||
counter = -1
|
||||
pywmhelpers.redraw()
|
||||
time.sleep(0.1)
|
||||
|
||||
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 (<config_key>, <xpm-key>) pairs.
|
||||
colors = (('foreground', 'text'),
|
||||
('background', 'background'))
|
||||
for key, value in colors:
|
||||
col = config.get(key)
|
||||
if not col is None:
|
||||
code = pywmhelpers.getColorCode(col, rgbFileName)
|
||||
if code is None:
|
||||
sys.stderr.write('Bad colorcode for %s, ignoring.\n' % key)
|
||||
else:
|
||||
pywmhelpers.setColor(xpm, value, code)
|
||||
|
||||
def main():
|
||||
clConfig = parseCommandLine(sys.argv)
|
||||
configFile = clConfig.get('configfile', defaultConfigFile)
|
||||
configFile = os.path.expanduser(configFile)
|
||||
fileConfig = pywmhelpers.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]
|
||||
|
||||
parseColors(defaultRGBFiles, config, xpm)
|
||||
pywmhelpers.setDefaultPixmap(xpm)
|
||||
timeFmt = config.get('timeformat', timeDefaultFormat)
|
||||
dateFmt = config.get('dateformat', dateDefaultFormat)
|
||||
dayFmt = config.get('weekdayformat', dayDefaultFormat)
|
||||
weekFmt = config.get('weekformat', weekDefaultFormat)
|
||||
# openXwindow sets the window title to the program name. If we get the
|
||||
# program name with a path, split it so we only name the window with the
|
||||
# filename.
|
||||
try:
|
||||
programName = sys.argv[0].split(os.sep)[-1]
|
||||
except IndexError: # Should only happen when using the interpreter.
|
||||
programName = ''
|
||||
sys.argv[0] = programName
|
||||
pywmhelpers.openXwindow(sys.argv, width, height)
|
||||
mainLoop(timeFmt, dateFmt, dayFmt, weekFmt)
|
||||
|
||||
xpm = \
|
||||
['160 100 11 1',
|
||||
' \tc #208120812081',
|
||||
'.\tc #00000000FFFF',
|
||||
'o\tc #C71BC30BC71B',
|
||||
'O\tc #861782078E38',
|
||||
'+\tc #EFBEF3CEEFBE',
|
||||
'@\tc #618561856185',
|
||||
'#\tc #9E79A2899E79',
|
||||
'$\tc #410341034103',
|
||||
'/\tc #2020b2b2aaaa s graph',
|
||||
'X\tc #000000000000 s background',
|
||||
'%\tc #2081B2CAAEBA s text',
|
||||
' ................................................................................................',
|
||||
' ..///...........................................................................................',
|
||||
' ..///...........................................................................................',
|
||||
' ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...............................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...............................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...............................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...............................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...............................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...............................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...............................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...............................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ..///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' ..///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' ................................................................................................',
|
||||
' ................................................................................................',
|
||||
' ................................................................................................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%%%%%XXX%XXX%%%%%X%%%%%X%XXX%X%%%%%X%%%%%X%%%%%X%%%%%X%%%%%XXXXXXXXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XX%%XXXXXXX%XXXXX%X%XXX%X%XXXXX%XXXXXXXXX%X%XXX%X%XXX%XX%%XXXXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXXXXXX%XXXXX%X%XXX%X%XXXXX%XXXXXXXXX%X%XXX%X%XXX%XX%%XXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%%%%%XX%%%%X%%%%%X%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XXXXXXXXX%XXX%%%%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%XXXXXXXXX%XXXXX%XXXXX%X%XXX%XXXXX%X%XXX%XXXXX%XXXXXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%XXXXXXXXX%XXXXX%XXXXX%X%XXX%XXXXX%X%XXX%XXXXX%XX%%XXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%%%%%XX%%%XX%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XX%%XXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'................................................................................................................................................................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
'XX%%%XX%%%%XXX%%%%X%%%%XX%%%%XX%%%%%X%%%%%X%XXX%XXX%XXXXXXX%X%XXX%X%XXXXX%XXX%X%%%%XX%%%%%X%%%%%X%%%%%X%%%%%X%%%%%X%%%%%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%%%%%XXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXXXX%XXX%XXX%XXXXXXX%X%XXX%X%XXXXX%%X%%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%XXXXXXX%XXX%XXX%X%XXX%X%XXX%X%XXX%X%XXX%XXXXX%XXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXXXX%XXX%XXX%XXXXXXX%X%XX%XX%XXXXX%X%X%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%XXXXXXX%XXX%XXX%X%XXX%X%XXX%XX%X%XX%XXX%XXXX%XXXXX',
|
||||
'X%%%%%X%%%%XX%XXXXX%XXX%X%%%%XX%%%%XX%X%%%X%%%%%XXX%XXXXXXX%X%%%XXX%XXXXX%XXX%X%XXX%X%XXX%X%%%%%X%%XX%X%%%%XX%%%%%XXX%XXX%XXX%X%XXX%X%XXX%XXX%XXX%%%%%XXX%XXXXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXX%X%XXX%XXX%XXXXXXX%X%XX%XX%XXXXX%XXX%X%XXX%X%XXX%X%XXXXX%X%X%X%XXX%XXXXX%XXX%XXX%XXX%X%XXX%X%X%X%XX%X%XXXXXX%XX%XXXXXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXX%X%XXX%XXX%XXX%XXX%X%XXX%X%XXXXX%XXX%X%XXX%X%XXX%X%XXXXX%XX%%X%XXX%XXXXX%XXX%XXX%XXX%X%XXX%X%%X%%X%XXX%XXXXX%X%XXXXXXXX',
|
||||
'X%XXX%X%%%%XXX%%%%X%%%%XX%%%%XX%XXXXX%%%%%X%XXX%XXX%XXXX%%%XX%XXX%X%%%%XX%XXX%X%XXX%X%%%%%X%XXXXX%%%%%X%XXX%X%%%%%XXX%XXXX%%%%XX%%%XX%XXX%X%XXX%X%%%%%X%%%%%XXXX',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................']
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
747
examples/pywmgeneric.py
Normal file
747
examples/pywmgeneric.py
Normal file
@@ -0,0 +1,747 @@
|
||||
#!/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 <color> set the text color
|
||||
-b, --background <color> set the background color
|
||||
-r, --rgbfile <file> set the rgb file to get color codes from
|
||||
-c, --configfile <file> set the config file to use
|
||||
'''
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import string
|
||||
import ConfigParser
|
||||
import getopt
|
||||
import popen2
|
||||
|
||||
from pywmgeneral import pywmhelpers
|
||||
|
||||
prevStat = {'user':0,
|
||||
'nice':0,
|
||||
'sys':0,
|
||||
'idle':0,
|
||||
'total':0,
|
||||
}
|
||||
import re
|
||||
cpuinfo = re.compile(r'^cpu[^ ]* +(?P<user>[0-9]+) +(?P<nice>[0-9]+)'
|
||||
r'+(?P<sys>[0-9]+) +(?P<idle>[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 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
|
||||
|
||||
lettersStartX = 0
|
||||
lettersStartY = 74
|
||||
letterWidth = 6
|
||||
letterHeight = 8
|
||||
|
||||
digitsStartX = 0
|
||||
digitsStartY = 64
|
||||
digitWidth = 6
|
||||
digitHeight = 8
|
||||
|
||||
letters = 'abcdefghijklmnopqrstuvwxyz'
|
||||
digits = '0123456789:/-%. '
|
||||
|
||||
maxChars = 9
|
||||
|
||||
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:
|
||||
pywmhelpers.addString(s, x, y, letterWidth, letterHeight, lettersStartX,
|
||||
lettersStartY, letters, digitWidth, digitHeight,
|
||||
digitsStartX, digitsStartY, digits, 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.'''
|
||||
pywmhelpers.copyXPMArea(72, yOffset, width - 2 * xOffset, letterHeight,
|
||||
xOffset, y + yOffset)
|
||||
|
||||
def getXY(line):
|
||||
'''Return the x and y positions to be used at line line.'''
|
||||
return 0, line * (letterHeight + 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._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 (<action>, <argument string>).
|
||||
|
||||
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.
|
||||
'''
|
||||
if self._scrollPos >= \
|
||||
len(self._displayLine) + (maxChars - 4):
|
||||
self._scrollPos = 0
|
||||
self.displayText(self._displayLine)
|
||||
elif self._scrollPos >= len(self._displayLine) - 3:
|
||||
self._scrollPos += 1
|
||||
disp = self._displayLine[self._scrollPos:] + \
|
||||
' ' * (maxChars - 3)
|
||||
diff = self._scrollPos - len(self._displayLine)
|
||||
if diff > 0:
|
||||
disp = disp[diff:]
|
||||
disp += self._displayLine
|
||||
self.displayText(disp)
|
||||
else:
|
||||
self._scrollPos += 1
|
||||
self.displayText(
|
||||
self._displayLine[self._scrollPos:])
|
||||
|
||||
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 = 'áéíóúàèìòùâêîôûäëïöü'
|
||||
toChars = 'aeiouaeiouaeiouaeiou'
|
||||
deleteChars = []
|
||||
for c in text.lower():
|
||||
if not (c in letters or c in digits or c in fromChars):
|
||||
deleteChars.append(c)
|
||||
deleteChars = ''.join(deleteChars)
|
||||
trans = string.maketrans(fromChars, toChars)
|
||||
text = string.translate(text.lower(), trans, deleteChars)
|
||||
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:
|
||||
pywmhelpers.addMouseRegion(i, x + xOffset, y + yOffset,
|
||||
width - 2 * xOffset, y + yOffset + letterHeight)
|
||||
|
||||
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 = pywmhelpers.getEvent()
|
||||
while not event is None:
|
||||
if event['type'] == 'destroynotify':
|
||||
sys.exit(0)
|
||||
elif event['type'] == 'buttonrelease':
|
||||
region = pywmhelpers.checkMouseRegion(event['x'], event['y'])
|
||||
button = event['button']
|
||||
if region != -1:
|
||||
if not self._entrys[region] is None:
|
||||
self._entrys[region].mouseClicked(button)
|
||||
event = pywmhelpers.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
|
||||
pywmhelpers.redraw()
|
||||
time.sleep(0.5)
|
||||
|
||||
def parseCommandLine(argv):
|
||||
'''Parse the commandline. Return a dictionary with options and values.'''
|
||||
shorts = 'ht:b:r:c:'
|
||||
longs = ['help', 'text=', 'background=', 'rgbfile=', 'configfile=']
|
||||
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['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
|
||||
return d
|
||||
|
||||
def parseColors(defaultRGBFileList, config, xpm):
|
||||
rgbFileName = ''
|
||||
for fn in defaultRGBFileList:
|
||||
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):
|
||||
err(
|
||||
"Can't read the RGB file, try setting it differently using -r,\n")
|
||||
err(
|
||||
"Ignoring your color settings, using the defaults.\n")
|
||||
useColors = 0
|
||||
if useColors:
|
||||
# Colors is a list with (<config_key>, <xpm-key>) pairs.
|
||||
colors = (('barfgcolor', 'graph'),
|
||||
('barbgcolor', 'graphbg'),
|
||||
('textcolor', 'text'),
|
||||
('background', 'background'))
|
||||
for key, value in colors:
|
||||
col = config.get(key)
|
||||
if not col is None:
|
||||
code = pywmhelpers.getColorCode(col, rgbFileName)
|
||||
if code is None:
|
||||
err('Bad colorcode for %s, ignoring.\n' % key)
|
||||
else:
|
||||
pywmhelpers.setColor(xpm, value, code)
|
||||
|
||||
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
|
||||
|
||||
|
||||
def main():
|
||||
clConfig = parseCommandLine(sys.argv)
|
||||
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)
|
||||
parseColors(defaultRGBFiles, clConfig, xpm)
|
||||
try:
|
||||
programName = sys.argv[0].split(os.sep)[-1]
|
||||
except IndexError:
|
||||
programName = ''
|
||||
sys.argv[0] = programName
|
||||
pywmhelpers.setDefaultPixmap(xpm)
|
||||
pywmhelpers.openXwindow(sys.argv, width, height)
|
||||
pywmgeneric = PywmGeneric(config)
|
||||
pywmgeneric.mainLoop()
|
||||
|
||||
xpm = \
|
||||
['160 100 13 1',
|
||||
' \tc #208120812081',
|
||||
'.\tc #00000000FFFF',
|
||||
'o\tc #C71BC30BC71B',
|
||||
'O\tc #861782078E38',
|
||||
'+\tc #EFBEF3CEEFBE',
|
||||
'@\tc #618561856185',
|
||||
'#\tc #9E79A2899E79',
|
||||
'$\tc #410341034103',
|
||||
'o\tc #2020b2b2aaaa s indicator',
|
||||
'/\tc #2020b2b2aaaa s graph',
|
||||
'-\tc #707070707070 s graphbg',
|
||||
'X\tc #000000000000 s background',
|
||||
'%\tc #2081B2CAAEBA s text',
|
||||
' ...............................................................................................',
|
||||
' .///..XXX..ooo..XXX..XXX.......................................................................',
|
||||
' .///..XXX..ooo..XXX..XXX.......................................................................',
|
||||
' .///..XXX..ooo..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' ...............................................................................................',
|
||||
' ...............................................................................................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%%%%%XXX%XXX%%%%%X%%%%%X%XXX%X%%%%%X%%%%%X%%%%%X%%%%%X%%%%%XXXXXXXXXX%XXXXXXXXXX%X%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XX%%XXXXXXX%XXXXX%X%XXX%X%XXXXX%XXXXXXXXX%X%XXX%X%XXX%XX%%XXXXXX%XXXXXXXXXXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXXXXXX%XXXXX%X%XXX%X%XXXXX%XXXXXXXXX%X%XXX%X%XXX%XX%%XXXXX%%XXXXXXXXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%%%%%XX%%%%X%%%%%X%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XXXXXXXXX%XXX%%%%%XXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%XXXXXXXXX%XXXXX%XXXXX%X%XXX%XXXXX%X%XXX%XXXXX%XXXXXXXX%%XXXXXXXXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%XXXXXXXXX%XXXXX%XXXXX%X%XXX%XXXXX%X%XXX%XXXXX%XX%%XXXX%XXXXXXXXXXXX%XXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%%%%%XX%%%XX%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XX%%XXXX%XXXXXXXXXXXX%X%XXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'................................................................................................................................................................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
'XX%%%XX%%%%XXX%%%%X%%%%XX%%%%XX%%%%%X%%%%%X%XXX%XXX%XXXXXXX%X%XXX%X%XXXXX%XXX%X%%%%XX%%%%%X%%%%%X%%%%%X%%%%%X%%%%%X%%%%%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%%%%%XXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXXXX%XXX%XXX%XXXXXXX%X%XXX%X%XXXXX%%X%%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%XXXXXXX%XXX%XXX%X%XXX%X%XXX%X%XXX%X%XXX%XXXXX%XXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXXXX%XXX%XXX%XXXXXXX%X%XX%XX%XXXXX%X%X%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%XXXXXXX%XXX%XXX%X%XXX%X%XXX%XX%X%XX%XXX%XXXX%XXXXX',
|
||||
'X%%%%%X%%%%XX%XXXXX%XXX%X%%%%XX%%%%XX%X%%%X%%%%%XXX%XXXXXXX%X%%%XXX%XXXXX%XXX%X%XXX%X%XXX%X%%%%%X%%XX%X%%%%XX%%%%%XXX%XXX%XXX%X%XXX%X%XXX%XXX%XXX%%%%%XXX%XXXXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXX%X%XXX%XXX%XXXXXXX%X%XX%XX%XXXXX%XXX%X%XXX%X%XXX%X%XXXXX%X%X%X%XXX%XXXXX%XXX%XXX%XXX%X%XXX%X%X%X%XX%X%XXXXXX%XX%XXXXXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXX%X%XXX%XXX%XXX%XXX%X%XXX%X%XXXXX%XXX%X%XXX%X%XXX%X%XXXXX%XX%%X%XXX%XXXXX%XXX%XXX%XXX%X%XXX%X%%X%%X%XXX%XXXXX%X%XXXXXXXX',
|
||||
'X%XXX%X%%%%XXX%%%%X%%%%XX%%%%XX%XXXXX%%%%%X%XXX%XXX%XXXX%%%XX%XXX%X%%%%XX%XXX%X%XXX%X%%%%%X%XXXXX%%%%%X%XXX%X%%%%%XXX%XXXX%%%%XX%%%XX%XXX%X%XXX%X%%%%%X%%%%%XXXX',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................']
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
589
examples/pywmhdmon.py
Executable file
589
examples/pywmhdmon.py
Executable file
@@ -0,0 +1,589 @@
|
||||
#!/usr/bin/env python2.3
|
||||
|
||||
"""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 <color> set the text color
|
||||
-f, --barfgcolor <color> set the foregroundcolor of the act. bar
|
||||
-g, --barbgcolor <color> set the background color of the act. bar
|
||||
-b, --background <color> set the background color
|
||||
-r, --rgbfile <file> set the rgb file to get color codes from
|
||||
-c, --configfile <file> set the config file to use
|
||||
-p, --procstat <file> set the location of /proc/stat
|
||||
-s, --skipconf <num> determines how many configuration items to skip
|
||||
'''
|
||||
|
||||
import sys
|
||||
import time
|
||||
import getopt
|
||||
import os
|
||||
|
||||
import wmdocklib
|
||||
|
||||
width = 64
|
||||
height = 64
|
||||
|
||||
xOffset = 4
|
||||
yOffset = 4
|
||||
|
||||
lettersStartX = 0
|
||||
lettersStartY = 74
|
||||
letterWidth = 6
|
||||
letterHeight = 8
|
||||
|
||||
digitsStartX = 0
|
||||
digitsStartY = 64
|
||||
digitWidth = 6
|
||||
digitHeight = 8
|
||||
|
||||
graphStartX = 7
|
||||
graphStartY = 53
|
||||
graphHeight = 4
|
||||
|
||||
graphBgStartX = 72
|
||||
graphBgStartY = 53
|
||||
|
||||
graphLineStartX = 66
|
||||
graphLineStartY = 58
|
||||
|
||||
letters = 'abcdefghijklmnopqrstuvwxyz'
|
||||
digits = '0123456789:/-%. '
|
||||
|
||||
defaultConfigFile = os.environ['HOME']+'/.pywmhdmonrc'
|
||||
defaultRGBFiles = ('/usr/lib/X11/rgb.txt', '/usr/X11R6/lib/X11/rgb.txt')
|
||||
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._statFile = procStat
|
||||
self._maxIODiff = 0
|
||||
self._lastIO = -1
|
||||
|
||||
def addString(self, s, x, y):
|
||||
try:
|
||||
wmdocklib.addString(s, x, y, letterWidth, letterHeight,
|
||||
lettersStartX, lettersStartY, letters, digitWidth,
|
||||
digitHeight, digitsStartX, digitsStartY, digits,
|
||||
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 (<total space>, <free space>) 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):
|
||||
return 2 + (line - 1) * (letterHeight + 3)
|
||||
|
||||
def paintLabel(self, line, label):
|
||||
self.addString(label, 1, self.getY(line))
|
||||
|
||||
def paintHdData(self, line, data, mode):
|
||||
total, free = data
|
||||
xStart = width - xOffset - 6 * letterWidth - 1
|
||||
if total==0:
|
||||
self.addString(' ', xStart, 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, xStart, self.getY(line))
|
||||
elif mode == 'free':
|
||||
freeStr = bytesToStr(free).rjust(5)
|
||||
self.addString(freeStr, xStart, 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:
|
||||
action = self._pathsToMonitor[area-1+self._skipping][3]
|
||||
if action:
|
||||
os.spawnvp(os.P_NOWAIT, action[0], action)
|
||||
event = wmdocklib.getEvent()
|
||||
|
||||
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 == 5:
|
||||
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:'
|
||||
longs = ['help', 'textcolor=', 'background=', 'barfgcolor=',
|
||||
'rgbfile=', 'configfile=', 'barbgcolor=', 'procstat=',
|
||||
'skipconf=']
|
||||
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', '--barfgcolor'):
|
||||
d['barfgcolor'] = a
|
||||
if o in ('-p', '--procstat'):
|
||||
d['procstat'] = a
|
||||
if o in ('-s', '--skipconf'):
|
||||
d['skipconf'] = a
|
||||
return d
|
||||
|
||||
def parseColors(defaultRGBFileList, config, xpm):
|
||||
rgbFileName = ''
|
||||
for fn in defaultRGBFileList:
|
||||
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 (<config_key>, <xpm-key>) pairs.
|
||||
colors = (('barfgcolor', 'graph'),
|
||||
('barbgcolor', 'graphbg'),
|
||||
('textcolor', 'text'),
|
||||
('background', 'background'))
|
||||
for key, value in colors:
|
||||
col = config.get(key)
|
||||
if not col is None:
|
||||
if col[0] is '#': code=col
|
||||
else: 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)
|
||||
|
||||
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]
|
||||
parseColors(defaultRGBFiles, config, xpm)
|
||||
|
||||
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)
|
||||
if action: action=eval(action)
|
||||
displayMode = config.get(modeStr, defaultMode)
|
||||
if not displayMode in displayModes:
|
||||
sys.stderr.write(
|
||||
'Unknown display mode: %s, using default.\n' % displayMode)
|
||||
displayMode = defaultMode
|
||||
pathsToMonitor.append((label[:3], path, displayMode, action))
|
||||
wmdocklib.addMouseRegion(i,
|
||||
8, 8 + (i - 1) * (letterHeight + 3),
|
||||
58, 4 + i * (letterHeight + 3))
|
||||
procStat = config.get('procstat', defaultProcStat)
|
||||
skipping = int(config.get('skipconf', 0))
|
||||
actMonEnabled = int(config.get('monitoring'))
|
||||
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.setDefaultPixmap(xpm)
|
||||
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()
|
||||
|
||||
|
||||
xpm = \
|
||||
['160 100 13 1',
|
||||
' \tc #208120812081',
|
||||
'.\tc #00000000FFFF',
|
||||
'o\tc #C71BC30BC71B',
|
||||
'O\tc #861782078E38',
|
||||
'+\tc #EFBEF3CEEFBE',
|
||||
'@\tc #618561856185',
|
||||
'#\tc #9E79A2899E79',
|
||||
'$\tc #410341034103',
|
||||
'o\tc #2020b2b2aaaa s indicator',
|
||||
'/\tc #2020b2b2aaaa s graph',
|
||||
'-\tc #707070707070 s graphbg',
|
||||
'X\tc #000000000000 s background',
|
||||
'%\tc #2081B2CAAEBA s text',
|
||||
' ...............................................................................................',
|
||||
' .///..XXX..ooo..XXX..XXX.......................................................................',
|
||||
' .///..XXX..ooo..XXX..XXX.......................................................................',
|
||||
' .///..XXX..ooo..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..ooo..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..ooo..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..ooo..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' ...............................................................................................',
|
||||
' ...............................................................................................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%%%%%XXX%XXX%%%%%X%%%%%X%XXX%X%%%%%X%%%%%X%%%%%X%%%%%X%%%%%XXXXXXXXXX%XXXXXXXXXX%X%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XX%%XXXXXXX%XXXXX%X%XXX%X%XXXXX%XXXXXXXXX%X%XXX%X%XXX%XX%%XXXXXX%XXXXXXXXXXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXXXXXX%XXXXX%X%XXX%X%XXXXX%XXXXXXXXX%X%XXX%X%XXX%XX%%XXXXX%%XXXXXXXXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%%%%%XX%%%%X%%%%%X%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XXXXXXXXX%XXX%%%%%XXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%XXXXXXXXX%XXXXX%XXXXX%X%XXX%XXXXX%X%XXX%XXXXX%XXXXXXXX%%XXXXXXXXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%XXXXXXXXX%XXXXX%XXXXX%X%XXX%XXXXX%X%XXX%XXXXX%XX%%XXXX%XXXXXXXXXXXX%XXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%%%%%XX%%%XX%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XX%%XXXX%XXXXXXXXXXXX%X%XXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'................................................................................................................................................................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
'XX%%%XX%%%%XXX%%%%X%%%%XX%%%%XX%%%%%X%%%%%X%XXX%XXX%XXXXXXX%X%XXX%X%XXXXX%XXX%X%%%%XX%%%%%X%%%%%X%%%%%X%%%%%X%%%%%X%%%%%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%%%%%XXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXXXX%XXX%XXX%XXXXXXX%X%XXX%X%XXXXX%%X%%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%XXXXXXX%XXX%XXX%X%XXX%X%XXX%X%XXX%X%XXX%XXXXX%XXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXXXX%XXX%XXX%XXXXXXX%X%XX%XX%XXXXX%X%X%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%XXXXXXX%XXX%XXX%X%XXX%X%XXX%XX%X%XX%XXX%XXXX%XXXXX',
|
||||
'X%%%%%X%%%%XX%XXXXX%XXX%X%%%%XX%%%%XX%X%%%X%%%%%XXX%XXXXXXX%X%%%XXX%XXXXX%XXX%X%XXX%X%XXX%X%%%%%X%%XX%X%%%%XX%%%%%XXX%XXX%XXX%X%XXX%X%XXX%XXX%XXX%%%%%XXX%XXXXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXX%X%XXX%XXX%XXXXXXX%X%XX%XX%XXXXX%XXX%X%XXX%X%XXX%X%XXXXX%X%X%X%XXX%XXXXX%XXX%XXX%XXX%X%XXX%X%X%X%XX%X%XXXXXX%XX%XXXXXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXX%X%XXX%XXX%XXX%XXX%X%XXX%X%XXXXX%XXX%X%XXX%X%XXX%X%XXXXX%XX%%X%XXX%XXXXX%XXX%XXX%XXX%X%XXX%X%%X%%X%XXX%XXXXX%X%XXXXXXXX',
|
||||
'X%XXX%X%%%%XXX%%%%X%%%%XX%%%%XX%XXXXX%%%%%X%XXX%XXX%XXXX%%%XX%XXX%X%%%%XX%XXX%X%XXX%X%%%%%X%XXXXX%%%%%X%XXX%X%%%%%XXX%XXXX%%%%XX%%%XX%XXX%X%XXX%X%%%%%X%%%%%XXXX',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................']
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
551
examples/pywmseti.py
Executable file
551
examples/pywmseti.py
Executable file
@@ -0,0 +1,551 @@
|
||||
#!/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 <color> set the text color
|
||||
-p, --progressbarcolor <color> set the color of the progress bar
|
||||
-g, --barbgcolor <color> set the background color of the progress bar
|
||||
-i, --indicatorcolor <color> set the color of the running indicator
|
||||
-b, --background <color> set the background color
|
||||
-d, --setidir <directory> set the directory where seti@home resides
|
||||
-n, --nice <value> set the nice value to run seti@home with
|
||||
-r, --rgbfile <file> set the rgb file to get color codes from
|
||||
-c, --configfile <file> set the config file to use
|
||||
'''
|
||||
|
||||
import sys
|
||||
import time
|
||||
import getopt
|
||||
import os
|
||||
|
||||
from pywmgeneral import pywmhelpers
|
||||
|
||||
width = 64
|
||||
height = 64
|
||||
|
||||
xOffset = 4
|
||||
yOffset = 4
|
||||
|
||||
lettersStartX = 0
|
||||
lettersStartY = 74
|
||||
letterWidth = 6
|
||||
letterHeight = 8
|
||||
|
||||
digitsStartX = 0
|
||||
digitsStartY = 64
|
||||
digitWidth = 6
|
||||
digitHeight = 8
|
||||
|
||||
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
|
||||
|
||||
letters = 'abcdefghijklmnopqrstuvwxyz'
|
||||
digits = '0123456789:/-% '
|
||||
|
||||
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:
|
||||
pywmhelpers.addString(s, x, y, letterWidth, letterHeight,
|
||||
lettersStartX, lettersStartY, letters, digitWidth,
|
||||
digitHeight, digitsStartX, digitsStartY, 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 pywmhelpers.getCenterStartPos(s, letterWidth, width, xOffset)
|
||||
|
||||
def getVertSpacing(self, numLines, margin):
|
||||
return pywmhelpers.getVertSpacing(numLines, margin, height,
|
||||
letterHeight, 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
|
||||
pywmhelpers.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))
|
||||
pywmhelpers.copyXPMArea(
|
||||
graphLineStartX, graphLineStartY, graphSize, graphHeight,
|
||||
graphStartX, graphStartY)
|
||||
pywmhelpers.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 = pywmhelpers.getEvent()
|
||||
while not event is None:
|
||||
if event['type'] == 'buttonrelease':
|
||||
region = pywmhelpers.checkMouseRegion(event['x'],
|
||||
event['y'])
|
||||
self.handleMouseClick(region)
|
||||
elif event['type'] == 'destroynotify':
|
||||
sys.exit(0)
|
||||
event = pywmhelpers.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
|
||||
pywmhelpers.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 (<config_key>, <xpm-key>) 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 = pywmhelpers.getColorCode(col, rgbFileName)
|
||||
if code is None:
|
||||
sys.stderr.write('Bad colorcode for %s, ignoring.\n' % key)
|
||||
else:
|
||||
pywmhelpers.setColor(xpm, value, code)
|
||||
|
||||
def main():
|
||||
clConfig = parseCommandLine(sys.argv)
|
||||
configFile = clConfig.get('configfile', defaultConfigFile)
|
||||
configFile = os.path.expanduser(configFile)
|
||||
fileConfig = pywmhelpers.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
|
||||
parseColors(defaultRGBFiles, config, xpm)
|
||||
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
|
||||
pywmhelpers.setDefaultPixmap(xpm)
|
||||
pywmhelpers.openXwindow(sys.argv, width, height)
|
||||
pywmhelpers.addMouseRegion(0, xOffset, yOffset, width - 2 * xOffset,
|
||||
height - 2 * yOffset)
|
||||
pwms = PywmSeti(statePath, uinfoPath, pidPath, execCmd)
|
||||
pwms.mainLoop()
|
||||
|
||||
xpm = \
|
||||
['160 100 13 1',
|
||||
' \tc #208120812081',
|
||||
'.\tc #00000000FFFF',
|
||||
'o\tc #C71BC30BC71B',
|
||||
'O\tc #861782078E38',
|
||||
'+\tc #EFBEF3CEEFBE',
|
||||
'@\tc #618561856185',
|
||||
'#\tc #9E79A2899E79',
|
||||
'$\tc #410341034103',
|
||||
'o\tc #2020b2b2aaaa s indicator',
|
||||
'/\tc #2020b2b2aaaa s graph',
|
||||
'-\tc #707070707070 s graphbg',
|
||||
'X\tc #000000000000 s background',
|
||||
'%\tc #2081B2CAAEBA s text',
|
||||
' ...............................................................................................',
|
||||
' .///..XXX..ooo..XXX..XXX.......................................................................',
|
||||
' .///..XXX..ooo..XXX..XXX.......................................................................',
|
||||
' .///..XXX..ooo..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..ooo..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..ooo..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..ooo..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo.......................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' ...............................................................................................',
|
||||
' ...............................................................................................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%%%%%XXX%XXX%%%%%X%%%%%X%XXX%X%%%%%X%%%%%X%%%%%X%%%%%X%%%%%XXXXXXXXXX%XXXXXXXXXX%X%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XX%%XXXXXXX%XXXXX%X%XXX%X%XXXXX%XXXXXXXXX%X%XXX%X%XXX%XX%%XXXXXX%XXXXXXXXXXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXXXXXX%XXXXX%X%XXX%X%XXXXX%XXXXXXXXX%X%XXX%X%XXX%XX%%XXXXX%%XXXXXXXXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%%%%%XX%%%%X%%%%%X%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XXXXXXXXX%XXX%%%%%XXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%XXXXXXXXX%XXXXX%XXXXX%X%XXX%XXXXX%X%XXX%XXXXX%XXXXXXXX%%XXXXXXXXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%XXXXXXXXX%XXXXX%XXXXX%X%XXX%XXXXX%X%XXX%XXXXX%XX%%XXXX%XXXXXXXXXXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%%%%%XX%%%XX%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XX%%XXXX%XXXXXXXXXXXX%X%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'................................................................................................................................................................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
'XX%%%XX%%%%XXX%%%%X%%%%XX%%%%XX%%%%%X%%%%%X%XXX%XXX%XXXXXXX%X%XXX%X%XXXXX%XXX%X%%%%XX%%%%%X%%%%%X%%%%%X%%%%%X%%%%%X%%%%%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%%%%%XXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXXXX%XXX%XXX%XXXXXXX%X%XXX%X%XXXXX%%X%%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%XXXXXXX%XXX%XXX%X%XXX%X%XXX%X%XXX%X%XXX%XXXXX%XXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXXXX%XXX%XXX%XXXXXXX%X%XX%XX%XXXXX%X%X%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%XXXXXXX%XXX%XXX%X%XXX%X%XXX%XX%X%XX%XXX%XXXX%XXXXX',
|
||||
'X%%%%%X%%%%XX%XXXXX%XXX%X%%%%XX%%%%XX%X%%%X%%%%%XXX%XXXXXXX%X%%%XXX%XXXXX%XXX%X%XXX%X%XXX%X%%%%%X%%XX%X%%%%XX%%%%%XXX%XXX%XXX%X%XXX%X%XXX%XXX%XXX%%%%%XXX%XXXXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXX%X%XXX%XXX%XXXXXXX%X%XX%XX%XXXXX%XXX%X%XXX%X%XXX%X%XXXXX%X%X%X%XXX%XXXXX%XXX%XXX%XXX%X%XXX%X%X%X%XX%X%XXXXXX%XX%XXXXXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXX%X%XXX%XXX%XXX%XXX%X%XXX%X%XXXXX%XXX%X%XXX%X%XXX%X%XXXXX%XX%%X%XXX%XXXXX%XXX%XXX%XXX%X%XXX%X%%X%%X%XXX%XXXXX%X%XXXXXXXX',
|
||||
'X%XXX%X%%%%XXX%%%%X%%%%XX%%%%XX%XXXXX%%%%%X%XXX%XXX%XXXX%%%XX%XXX%X%%%%XX%XXX%X%XXX%X%%%%%X%XXXXX%%%%%X%XXX%X%%%%%XXX%XXXX%%%%XX%%%XX%XXX%X%XXX%X%%%%%X%%%%%XXXX',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................']
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
465
examples/pywmsysmon.py
Executable file
465
examples/pywmsysmon.py
Executable file
@@ -0,0 +1,465 @@
|
||||
#! /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 <color> set the foreground color of the memory bar
|
||||
-g, --barbgcolor <color> set the background color of the memory bar
|
||||
-b, --background <color> set the background color
|
||||
-p, --graphforeground <color> set the cpu graph foreground color
|
||||
-a, --graphbackground <color> set the cpu graph background color
|
||||
-r, --rgbfile <file> set the rgb file to get color codes from
|
||||
-s, --procstat <file> set the location of /proc/stat
|
||||
-m, --procmeminfo <file> set the location of /proc/meminfo
|
||||
-i, --ignorenice ignore nice valued cpu usage
|
||||
-u, --updatedelay <value> delay (in seconds) between cpu graph updates
|
||||
'''
|
||||
|
||||
import sys
|
||||
import time
|
||||
import getopt
|
||||
import os
|
||||
|
||||
from pywmgeneral import pywmhelpers
|
||||
|
||||
width = 64
|
||||
height = 64
|
||||
|
||||
xOffset = 4
|
||||
yOffset = 4
|
||||
|
||||
lettersStartX = 0
|
||||
lettersStartY = 74
|
||||
letterWidth = 6
|
||||
letterHeight = 8
|
||||
|
||||
digitsStartX = 0
|
||||
digitsStartY = 64
|
||||
digitWidth = 6
|
||||
digitHeight = 8
|
||||
|
||||
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
|
||||
|
||||
letters = 'abcdefghijklmnopqrstuvwxyz'
|
||||
digits = '0123456789:/-%. '
|
||||
|
||||
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)
|
||||
theLine = None
|
||||
for line in meminfoFile:
|
||||
if line.startswith('Mem:'):
|
||||
theLine = line
|
||||
if theLine is None:
|
||||
sys.stderr.write("Can't find memory information in %s.\n" %
|
||||
self._procMeminfo)
|
||||
sys.exit(4)
|
||||
parts = [long(x) for x in theLine.split()[1:]]
|
||||
total, used, free, shared, buffers, cached = parts
|
||||
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:]]
|
||||
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:
|
||||
pywmhelpers.addString(s, x, y, letterWidth, letterHeight,
|
||||
lettersStartX, lettersStartY, letters, digitWidth,
|
||||
digitHeight, digitsStartX, digitsStartY, 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:
|
||||
pywmhelpers.copyXPMArea(
|
||||
hGraphLineStartX, hGraphLineStartY, paintWidth, hGraphHeight,
|
||||
x, y)
|
||||
if w - paintWidth > 0:
|
||||
pywmhelpers.copyXPMArea(
|
||||
hGraphBgStartX, hGraphBgStartY, w - paintWidth, hGraphHeight,
|
||||
x + paintWidth, y)
|
||||
|
||||
def drawVertLine(self, sourceX, sourceY, targX, targY, length):
|
||||
'''Draw a vertical line.
|
||||
'''
|
||||
if length > 0:
|
||||
pywmhelpers.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 = pywmhelpers.getEvent()
|
||||
while not event is None:
|
||||
if event['type'] == 'destroynotify':
|
||||
sys.exit(0)
|
||||
event = pywmhelpers.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
|
||||
pywmhelpers.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
|
||||
|
||||
def parseColors(defaultRGBFileList, config, xpm):
|
||||
rgbFileName = ''
|
||||
for fn in defaultRGBFileList:
|
||||
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 (<config_key>, <xpm-key>) pairs.
|
||||
colors = (('barfgcolor', 'graph'),
|
||||
('barbgcolor', 'graphbg'),
|
||||
('background', 'background'),
|
||||
('graphforeground', 'vgraph'),
|
||||
('graphbackground', 'vgraphbg'))
|
||||
for key, value in colors:
|
||||
col = config.get(key)
|
||||
if not col is None:
|
||||
code = pywmhelpers.getColorCode(col, rgbFileName)
|
||||
if code is None:
|
||||
sys.stderr.write('Bad colorcode for %s, ignoring.\n' % key)
|
||||
else:
|
||||
pywmhelpers.setColor(xpm, value, code)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
config = parseCommandLine(sys.argv)
|
||||
parseColors(defaultRGBFiles, config, xpm)
|
||||
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
|
||||
pywmhelpers.setDefaultPixmap(xpm)
|
||||
pywmhelpers.openXwindow(sys.argv, width, height)
|
||||
pywmsysmon = PywmSysMon(procMeminfo, procStat, ignoreNice, updateDelay)
|
||||
pywmsysmon.mainLoop()
|
||||
|
||||
|
||||
xpm = \
|
||||
['160 100 15 1',
|
||||
' \tc #208120812081',
|
||||
'.\tc #00000000FFFF',
|
||||
'o\tc #C71BC30BC71B',
|
||||
'O\tc #861782078E38',
|
||||
'+\tc #EFBEF3CEEFBE',
|
||||
'@\tc #618561856185',
|
||||
'#\tc #9E79A2899E79',
|
||||
'$\tc #410341034103',
|
||||
'o\tc #2020b2b2aaaa s indicator',
|
||||
'/\tc #2020b2b2aaaa s graph',
|
||||
'-\tc #707070707070 s graphbg',
|
||||
'|\tc #2020b2b2aaaa s vgraph',
|
||||
'I\tc #707070707070 s vgraphbg',
|
||||
'X\tc #000000000000 s background',
|
||||
'%\tc #2081B2CAAEBA s text',
|
||||
' ...............................................................................................',
|
||||
' .///..XXX..ooo..XXX..XXX......|.I..............................................................',
|
||||
' .///..XXX..ooo..XXX..XXX......|.I..............................................................',
|
||||
' .///..XXX..ooo..XXX..XXX......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..ooo..XXX......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..ooo..XXX......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..ooo..XXX......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..XXX......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..XXX..XXX..XXX..ooo......|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///..........................|.I..............................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...-------------------------------------------------------------------------------------...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///...........................................................................................',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' .///////////////////////////////////////////////////////////////////////////////////////////...',
|
||||
' ...............................................................................................',
|
||||
' ...............................................................................................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%%%%%XXX%XXX%%%%%X%%%%%X%XXX%X%%%%%X%%%%%X%%%%%X%%%%%X%%%%%XXXXXXXXXX%XXXXXXXXXX%X%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XX%%XXXXXXX%XXXXX%X%XXX%X%XXXXX%XXXXXXXXX%X%XXX%X%XXX%XX%%XXXXXX%XXXXXXXXXXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXXXXXX%XXXXX%X%XXX%X%XXXXX%XXXXXXXXX%X%XXX%X%XXX%XX%%XXXXX%%XXXXXXXXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%%%%%XX%%%%X%%%%%X%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XXXXXXXXX%XXX%%%%%XXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%XXXXXXXXX%XXXXX%XXXXX%X%XXX%XXXXX%X%XXX%XXXXX%XXXXXXXX%%XXXXXXXXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%XXX%XXX%XXX%XXXXXXXXX%XXXXX%XXXXX%X%XXX%XXXXX%X%XXX%XXXXX%XX%%XXXX%XXXXXXXXXXXX%XXXXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'X%%%%%XX%%%XX%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XXXXX%X%%%%%X%%%%%XX%%XXXX%XXXXXXXXXXXX%X%XXX%%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................',
|
||||
'................................................................................................................................................................',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
'XX%%%XX%%%%XXX%%%%X%%%%XX%%%%XX%%%%%X%%%%%X%XXX%XXX%XXXXXXX%X%XXX%X%XXXXX%XXX%X%%%%XX%%%%%X%%%%%X%%%%%X%%%%%X%%%%%X%%%%%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%%%%%XXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXXXX%XXX%XXX%XXXXXXX%X%XXX%X%XXXXX%%X%%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%XXXXXXX%XXX%XXX%X%XXX%X%XXX%X%XXX%X%XXX%XXXXX%XXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXXXX%XXX%XXX%XXXXXXX%X%XX%XX%XXXXX%X%X%X%XXX%X%XXX%X%XXX%X%XXX%X%XXX%X%XXXXXXX%XXX%XXX%X%XXX%X%XXX%XX%X%XX%XXX%XXXX%XXXXX',
|
||||
'X%%%%%X%%%%XX%XXXXX%XXX%X%%%%XX%%%%XX%X%%%X%%%%%XXX%XXXXXXX%X%%%XXX%XXXXX%XXX%X%XXX%X%XXX%X%%%%%X%%XX%X%%%%XX%%%%%XXX%XXX%XXX%X%XXX%X%XXX%XXX%XXX%%%%%XXX%XXXXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXX%X%XXX%XXX%XXXXXXX%X%XX%XX%XXXXX%XXX%X%XXX%X%XXX%X%XXXXX%X%X%X%XXX%XXXXX%XXX%XXX%XXX%X%XXX%X%X%X%XX%X%XXXXXX%XX%XXXXXXX',
|
||||
'X%XXX%X%XXX%X%XXXXX%XXX%X%XXXXX%XXXXX%XXX%X%XXX%XXX%XXX%XXX%X%XXX%X%XXXXX%XXX%X%XXX%X%XXX%X%XXXXX%XX%%X%XXX%XXXXX%XXX%XXX%XXX%X%XXX%X%%X%%X%XXX%XXXXX%X%XXXXXXXX',
|
||||
'X%XXX%X%%%%XXX%%%%X%%%%XX%%%%XX%XXXXX%%%%%X%XXX%XXX%XXXX%%%XX%XXX%X%%%%XX%XXX%X%XXX%X%%%%%X%XXXXX%%%%%X%XXX%X%%%%%XXX%XXXX%%%%XX%%%XX%XXX%X%XXX%X%%%%%X%%%%%XXXX',
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................',
|
||||
'................................................................................................................................................................']
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
42
examples/sample.pywmdatetimerc
Normal file
42
examples/sample.pywmdatetimerc
Normal file
@@ -0,0 +1,42 @@
|
||||
[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
|
||||
|
||||
69
examples/sample.pywmgenericrc
Normal file
69
examples/sample.pywmgenericrc
Normal file
@@ -0,0 +1,69 @@
|
||||
# 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 <method> - Call a method defined in the class UserMethods. See the
|
||||
# source file for more information
|
||||
# * exec <command> - Execute an external command
|
||||
#
|
||||
# Available mouse actions are:
|
||||
# * method <method> - Same as above, see the source file for more information.
|
||||
# * exec <command> - 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 = <text> - display a static string instead of the first line of
|
||||
# the action-generated output.
|
||||
# * update_delay = <number><s|m|h> - 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
|
||||
|
||||
50
examples/sample.pywmhdmonrc
Normal file
50
examples/sample.pywmhdmonrc
Normal file
@@ -0,0 +1,50 @@
|
||||
[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=['/home/mario/bin/tmount', '/mnt/cd', 'eject']
|
||||
|
||||
5.label=jr
|
||||
5.path=/mnt/jr
|
||||
5.displaymode=used
|
||||
5.action=['/home/mario/bin/tmount', '/mnt/jr', 'eject']
|
||||
|
||||
6.label=sm
|
||||
6.path=/mnt/sm
|
||||
6.displaymode=free
|
||||
6.action=['/home/mario/bin/tmount', '/mnt/sm']
|
||||
|
||||
7.label=cf
|
||||
7.path=/mnt/cf
|
||||
7.displaymode=free
|
||||
7.action=['/home/mario/bin/tmount', '/mnt/cf']
|
||||
|
||||
8.label=flo
|
||||
8.path=/mnt/flo
|
||||
8.displaymode=free
|
||||
8.action=['/home/mario/bin/tmount', '/mnt/flo']
|
||||
|
||||
textcolor=light sea green
|
||||
background=black
|
||||
barfgcolor=light sea green
|
||||
barbgcolor=grey45
|
||||
monitoring=0
|
||||
|
||||
#rgbfile=/usr/lib/X11/rgb.txt
|
||||
|
||||
12
examples/sample.pywmsetirc
Normal file
12
examples/sample.pywmsetirc
Normal file
@@ -0,0 +1,12 @@
|
||||
[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
|
||||
|
||||
35
examples/tmount
Normal file
35
examples/tmount
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
# tmount - toggle mount / eject
|
||||
#
|
||||
# usage: tmount mountpoint ejectable
|
||||
#
|
||||
# parameter mountpoint: the mount point, without trailing '/'
|
||||
# ejectable: not empty indicates that the media is software ejectable
|
||||
# action: if the indicated file system is not mounted, mounts it
|
||||
# otherwise unmounts it
|
||||
# if mounting fails or when unmounting, ejects software ejectable
|
||||
# media.
|
||||
|
||||
if [ "$2" == "" ]; then eject=echo
|
||||
else eject=eject
|
||||
fi
|
||||
|
||||
mountpointIndicated=$1
|
||||
mountpointFound=`df $1 | tail -1 | cut -d% -f2`
|
||||
|
||||
if [ $mountpointIndicated = $mountpointFound ]
|
||||
then
|
||||
|
||||
umount $mountpointIndicated
|
||||
$eject $mountpointIndicated
|
||||
|
||||
else
|
||||
|
||||
# my smartmedia does not mount correctly after a media change
|
||||
# second try always succeeds. ask me why! if neither mount
|
||||
# attempt succeeds, then attempt ejecting ejectable media
|
||||
|
||||
mount $mountpointIndicated || mount $mountpointIndicated || $eject $mountpointIndicated
|
||||
|
||||
fi
|
||||
Reference in New Issue
Block a user