[Sugar-devel] [PATCH Log 1/2] pep8-ized logcollect.py
Manuel Kaufmann
humitos at gmail.com
Thu May 10 17:46:00 EDT 2012
Passed pep8.py script to remove a lot of trailling whitespaces and
things related.
Signed-off-by: Manuel Kaufmann <humitos at gmail.com>
---
logcollect.py | 278 ++++++++++++++++++++++++++++++---------------------------
1 files changed, 146 insertions(+), 132 deletions(-)
diff --git a/logcollect.py b/logcollect.py
index 82c1bba..956cc24 100644
--- a/logcollect.py
+++ b/logcollect.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2007, Pascal Scheffers <pascal at scheffers.net>
+# Copyright (C) 2007, Pascal Scheffers <pascal at scheffers.net>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
@@ -33,7 +33,7 @@
# ** ...
# * Installed packages list
# * All relevant log files (all of them, at first)
-#
+#
# The report is output as a tarfile
#
# This file has two modes:
@@ -78,32 +78,32 @@ class MachineProperties:
return '#/etc/issue not found'
# Needed, because we want to default to the first non blank line:
- first_line = ''
+ first_line = ''
for line in self.__read_file('/etc/issue').splitlines():
if line.lower().find('olpc build') > -1:
- return line
+ return line
if first_line == '':
- first_line=line
+ first_line = line
return first_line
def uptime(self):
for line in self.__read_file('/proc/uptime').splitlines():
if line != '':
- return line
+ return line
return ''
def loadavg(self):
for line in self.__read_file('/proc/loadavg').splitlines():
if line != '':
- return line
+ return line
return ''
def kernel_version(self):
for line in self.__read_file('/proc/version').splitlines():
if line != '':
- return line
+ return line
return ''
def memfree(self):
@@ -126,11 +126,11 @@ class MachineProperties:
v = self.__read_file(mfg_path)
# Remove trailing 0 character, if any:
- if v != '' and ord(v[len(v)-1]) == 0:
- v = v[:len(v)-1]
-
+ if v != '' and ord(v[len(v) - 1]) == 0:
+ v = v[:len(v) - 1]
+
return v
-
+
def laptop_serial_number(self):
return self._mfg_data('SN')
@@ -141,9 +141,8 @@ class MachineProperties:
s = self._mfg_data('SG')[0:1]
if s == '':
return ''
-
+
return '%02X' % ord(self._mfg_data('SG')[0:1])
-
def laptop_uuid(self):
return self._mfg_data('U#')
@@ -165,18 +164,18 @@ class MachineProperties:
def laptop_localization(self):
return self._mfg_data('LO')
-
+
def _battery_info(self, item):
""" from /sys/class/power-supply/olpc-battery/ """
root = '/sys/class/power_supply/olpc-battery/'
- if not os.path.exists(root+item):
+ if not os.path.exists(root + item):
return ''
-
- return self.__read_file(root+item).strip()
+
+ return self.__read_file(root + item).strip()
def battery_serial_number(self):
return self._battery_info('serial_number')
-
+
def battery_capacity(self):
return self._battery_info('capacity') + ' ' + \
self._battery_info('capacity_level')
@@ -184,61 +183,60 @@ class MachineProperties:
def battery_info(self):
#Should be just:
#return self._battery_info('uevent')
-
+
#But because of a bug in the kernel, that has trash, lets filter:
- bi = ''
+ bi = ''
for line in self._battery_info('uevent').splitlines():
if line.startswith('POWER_'):
bi += line + '\n'
-
+
return bi
-
+
def disksize(self, path):
return os.statvfs(path).f_bsize * os.statvfs(path).f_blocks
-
+
def diskfree(self, path):
return os.statvfs(path).f_bsize * os.statvfs(path).f_bavail
-
+
def _read_popen(self, cmd):
p = os.popen(cmd)
s = ''
try:
for line in p:
- s += line
+ s += line
finally:
- p.close()
-
+ p.close()
+
return s
-
- def ifconfig(self):
+
+ def ifconfig(self):
return self._read_popen('/sbin/ifconfig')
-
- def route_n(self):
+
+ def route_n(self):
return self._read_popen('/sbin/route -n')
-
+
def df_a(self):
return self._read_popen('/bin/df -a')
-
+
def ps_auxfwww(self):
return self._read_popen('/bin/ps auxfwww')
-
+
def usr_bin_free(self):
return self._read_popen('/usr/bin/free')
def top(self):
return self._read_popen('/usr/bin/top -bn2')
-
- def installed_activities(self):
- s = ''
+
+ def installed_activities(self):
+ s = ''
for path in glob.glob('/usr/share/activities/*.activity'):
s += os.path.basename(path) + '\n'
for path in glob.glob('/home/olpc/Activities/*'):
s += '~' + os.path.basename(path) + '\n'
-
+
return s
-
-
+
class LogCollect:
"""Collect XO logfiles and machine metadata for reporting to OLPC
@@ -248,80 +246,86 @@ class LogCollect:
self._mp = MachineProperties()
def write_logs(self, archive='', logbytes=15360):
- """Write a zipfile containing the tails of the logfiles and machine info of the XO
-
+ """Write a zipfile containing the tails of the logfiles and
+ machine info of the XO
+
Arguments:
archive - Specifies the location where to store the data
defaults to /dev/shm/logs-<xo-serial>.zip
-
+
logbytes - Maximum number of bytes to read from each log file.
0 means complete logfiles, not just the tail
-1 means only save machine info, no logs
"""
#This function is crammed with try...except to make sure we get as much
#data as possible, if anything fails.
-
- if archive=='':
+
+ if archive == '':
archive = '/dev/shm/logs.zip'
try:
#With serial number is more convenient, but might fail for some
#Unknown reason...
- archive = '/dev/shm/logs-%s.zip' % self._mp.laptop_serial_number()
+ archive = '/dev/shm/logs-%s.zip' % \
+ self._mp.laptop_serial_number()
except Exception:
pass
-
+
z = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED)
-
- try:
- try:
+
+ try:
+ try:
z.writestr('info.txt', self.laptop_info())
except Exception, e:
z.writestr('info.txt',
"logcollect: could not add info.txt: %s" % e)
-
- if logbytes > -1:
+ if logbytes > -1:
# Include some log files from /var/log.
- for fn in ['dmesg', 'messages', 'cron', 'maillog','rpmpkgs',
+ for fn in ['dmesg', 'messages', 'cron', 'maillog', 'rpmpkgs',
'Xorg.0.log', 'spooler']:
try:
- if os.access('/var/log/'+fn, os.F_OK):
+ if os.access('/var/log/' + fn, os.F_OK):
if logbytes == 0:
- z.write('/var/log/'+fn, 'var-log/'+fn)
+ z.write('/var/log/' + fn, 'var-log/' + fn)
else:
- z.writestr('var-log/'+fn,
- self.file_tail('/var/log/'+fn, logbytes))
+ z.writestr('var-log/' + fn,
+ self.file_tail('/var/log/' + fn,
+ logbytes))
except Exception, e:
- z.writestr('var-log/'+fn,
- "logcollect: could not add %s: %s" % (fn, e))
-
+ z.writestr('var-log/' + fn,
+ "logcollect: could not add %s: %s" % \
+ (fn, e))
+
# Include all current ones from sugar/logs
for path in glob.glob('/home/olpc/.sugar/default/logs/*.log'):
try:
if os.access(path, os.F_OK):
if logbytes == 0:
- z.write(path, 'sugar-logs/'+os.path.basename(path))
+ z.write(path, 'sugar-logs/' + \
+ os.path.basename(path))
else:
- z.writestr('sugar-logs/'+os.path.basename(path),
+ z.writestr('sugar-logs/' + \
+ os.path.basename(path),
self.file_tail(path, logbytes))
except Exception, e:
- z.writestr('sugar-logs/'+fn,
- "logcollect: could not add %s: %s" % (fn, e))
- try:
+ z.writestr('sugar-logs/' + fn,
+ "logcollect: could not add %s: %s" % \
+ (fn, e))
+ try:
z.write('/etc/resolv.conf')
except Exception, e:
z.writestr('/etc/resolv.conf',
"logcollect: could not add resolv.conf: %s" % e)
-
+
except Exception, e:
- print 'While creating zip archive: %s' % e
-
- z.close()
-
+ print 'While creating zip archive: %s' % e
+
+ z.close()
+
return archive
def file_tail(self, filename, tailbytes):
"""Read the tail (end) of the file
-
+
Arguments:
filename The name of the file to read
tailbytes Number of bytes to include or 0 for entire file
@@ -332,35 +336,35 @@ class LogCollect:
f = open(filename)
try:
fsize = os.stat(filename).st_size
-
+
if tailbytes > 0 and fsize > tailbytes:
f.seek(-tailbytes, 2)
-
+
data = f.read()
finally:
f.close()
- return data
-
+ return data
def make_report(self, target='stdout'):
"""Create the report
Arguments:
- target - where to save the logs, a path or stdout
+ target - where to save the logs, a path or stdout
"""
li = self.laptop_info()
for k, v in li.iteritems():
- print k + ': ' +v
-
+ print k + ': ' + v
+
print self._mp.battery_info()
def laptop_info(self):
- """Return a string with laptop serial, battery type, build, memory info, etc."""
+ """Return a string with laptop serial, battery type, build,
+ memory info, etc."""
- s = ''
+ s = ''
try:
# Do not include UUID!
s += 'laptop-info-version: 1.0\n'
@@ -368,48 +372,60 @@ class LogCollect:
s += 'date: %s' % time.strftime("%a, %d %b %Y %H:%M:%S +0000",
time.gmtime())
s += 'memfree: %s\n' % self._mp.memfree()
- s += 'disksize: %s MB\n' % ( self._mp.disksize('/') / (1024*1024) )
- s += 'diskfree: %s MB\n' % ( self._mp.diskfree('/') / (1024*1024) )
+ s += 'disksize: %s MB\n' % \
+ (self._mp.disksize('/') / (1024 * 1024))
+ s += 'diskfree: %s MB\n' % \
+ (self._mp.diskfree('/') / (1024 * 1024))
s += 'olpc_build: %s\n' % self._mp.olpc_build()
s += 'kernel_version: %s\n' % self._mp.kernel_version()
s += 'uptime: %s\n' % self._mp.uptime()
- s += 'loadavg: %s\n' % self._mp.loadavg()
+ s += 'loadavg: %s\n' % self._mp.loadavg()
s += 'serial-number: %s\n' % self._mp.laptop_serial_number()
- s += 'motherboard-number: %s\n' % self._mp.laptop_motherboard_number()
- s += 'board-revision: %s\n' % self._mp.laptop_board_revision()
- s += 'keyboard: %s\n' % self._mp.laptop_keyboard()
- s += 'wireless_mac: %s\n' % self._mp.laptop_wireless_mac()
- s += 'firmware: %s\n' % self._mp.laptop_bios_version()
+ s += 'motherboard-number: %s\n' % \
+ self._mp.laptop_motherboard_number()
+ s += 'board-revision: %s\n' % \
+ self._mp.laptop_board_revision()
+ s += 'keyboard: %s\n' % \
+ self._mp.laptop_keyboard()
+ s += 'wireless_mac: %s\n' % \
+ self._mp.laptop_wireless_mac()
+ s += 'firmware: %s\n' % \
+ self._mp.laptop_bios_version()
s += 'country: %s\n' % self._mp.laptop_country()
s += 'localization: %s\n' % self._mp.laptop_localization()
-
+
s += self._mp.battery_info()
-
+
s += "\n[/sbin/ifconfig]\n%s\n" % self._mp.ifconfig()
s += "\n[/sbin/route -n]\n%s\n" % self._mp.route_n()
-
- s += '\n[Installed Activities]\n%s\n' % self._mp.installed_activities()
-
+
+ s += '\n[Installed Activities]\n%s\n' % \
+ self._mp.installed_activities()
+
s += '\n[df -a]\n%s\n' % self._mp.df_a()
s += '\n[ps auxwww]\n%s\n' % self._mp.ps_auxfwww()
s += '\n[free]\n%s\n' % self._mp.usr_bin_free()
s += '\n[top -bn2]\n%s\n' % self._mp.top()
except Exception, e:
s += '\nException while building info:\n%s\n' % e
-
+
return s
+
class LogSend:
-
# post_multipart and encode_multipart_formdata have been taken from
- # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306
+ # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306
def post_multipart(self, host, selector, fields, files):
"""
Post fields and files to an http host as multipart/form-data.
- fields is a sequence of (name, value) elements for regular form fields.
- files is a sequence of (name, filename, value) elements for data to be uploaded as files
- Return the server's response page.
+ fields is a sequence of (name, value) elements for regular
+ form fields.
+
+ files is a sequence of (name, filename, value) elements for
+ data to be uploaded as files Return the server's response
+ page.
"""
+
content_type, body = self.encode_multipart_formdata(fields, files)
h = httplib.HTTP(host)
h.putrequest('POST', selector)
@@ -420,13 +436,16 @@ class LogSend:
h.send(body)
errcode, errmsg, headers = h.getreply()
return h.file.read()
-
+
def encode_multipart_formdata(self, fields, files):
"""
fields is a sequence of (name, value) elements for regular form fields.
- files is a sequence of (name, filename, value) elements for data to be uploaded as files
- Return (content_type, body) ready for httplib.HTTP instance
+
+ files is a sequence of (name, filename, value) elements for
+ data to be uploaded as files Return (content_type, body) ready
+ for httplib.HTTP instance
"""
+
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
@@ -437,7 +456,8 @@ class LogSend:
L.append(value)
for (key, filename, value) in files:
L.append('--' + BOUNDARY)
- L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
+ L.append('Content-Disposition: form-data; name="%s"; '
+ 'filename="%s"' % (key, filename))
L.append('Content-Type: %s' % self.get_content_type(filename))
L.append('')
L.append(value)
@@ -446,7 +466,7 @@ class LogSend:
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
-
+
def read_file(self, filename):
"""Read the entire contents of a file and return it as a string"""
@@ -462,11 +482,11 @@ class LogSend:
def get_content_type(self, filename):
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
-
+
def http_post_logs(self, url, archive):
#host, selector, fields, files
files = ('logs', os.path.basename(archive), self.read_file(archive)),
-
+
# Client= olpc will make the server return just "OK" or "FAIL"
fields = ('client', 'xo'),
urlparts = urlparse.urlsplit(url)
@@ -475,29 +495,28 @@ class LogSend:
print r
return (r == 'OK')
-
# This script is dual-mode, it can be used as a command line tool and as
-# a library.
+# a library.
if sys.argv[0].endswith('logcollect.py') or \
sys.argv[0].endswith('logcollect'):
print 'log-collect utility 1.0'
-
+
lc = LogCollect()
ls = LogSend()
logs = ''
mode = 'http'
-
- if len(sys.argv)==1:
+
+ if len(sys.argv) == 1:
print """logcollect.py - send your XO logs to OLPC
-
+
Usage:
logcollect.py http://server.name/submit.php
- submit logs to a server
-
+
logcollect.py file:/media/xxxx-yyyy/mylog.zip
- save the zip file on a USB device or SD card
-
+
logcollect.py all file:/media/xxxx-yyyy/mylog.zip
- Save to zip file and include ALL logs
@@ -510,35 +529,33 @@ Usage:
If you specify 'all' or 'none' you must specify http or file as well.
"""
sys.exit()
-
-
- logbytes = 15360
- if len(sys.argv)>1:
- mode = sys.argv[len(sys.argv)-1]
+
+ logbytes = 15360
+ if len(sys.argv) > 1:
+ mode = sys.argv[len(sys.argv) - 1]
if sys.argv[1] == 'all':
logbytes = 0
if sys.argv[1] == 'none':
logbytes = -1
-
if mode.startswith('file'):
# file://
logs = mode[5:]
-
+
#if mode.lower().startswith('http'):
# pass
#else if mode.lower().startswith('usb'):
# pass
#else if mode.lower().startswith('sd'):
# pass
-
+
logs = lc.write_logs(logs, logbytes)
print 'Logs saved in %s' % logs
-
+
sent_ok = False
- if len(sys.argv)>1:
- mode = sys.argv[len(sys.argv)-1]
-
+ if len(sys.argv) > 1:
+ mode = sys.argv[len(sys.argv) - 1]
+
if mode.startswith('http'):
print "Trying to send the logs using HTTP (web)"
if len(mode) == 4:
@@ -546,16 +563,13 @@ Usage:
sys.exit(1)
else:
url = mode
-
+
if ls.http_post_logs(url, logs):
print "Logs were sent."
- sent_ok = True
+ sent_ok = True
else:
print "FAILED to send logs."
-
if sent_ok:
os.remove(logs)
print "Logs were sent, tempfile deleted."
-
-
--
1.7.7.6
More information about the Sugar-devel
mailing list