]> git.parisson.com Git - telecaster-cgi.git/commitdiff
Add acpi tools, make temp oddcast config
authoryomguy <yomguy@parisson.com>
Mon, 20 Oct 2008 11:45:05 +0000 (11:45 +0000)
committeryomguy <yomguy@parisson.com>
Mon, 20 Oct 2008 11:45:05 +0000 (11:45 +0000)
css/telecaster.css
etc/telecaster_mp3.cfg
telecaster.py
tools/acpi.py

index 97917e1fc0dcfca3aa07368fb36783cd759386ca..f0a874a1c82bf7d4f073f09d4e4987602906ece0 100644 (file)
@@ -1,29 +1,68 @@
 
-div#header { background-color: #030250;
+div.header { background-color: #030250;
              color: #FFFFFF;
             padding: 0.5em;
             line-height: 10px;
+         font: 0.8125em/1em Verdana, sans-serif;
+         font-size: 1em;
 
 }
 
-div#bg { background-color: #030250;
+div.bg { background-color: #FFFFFF;
          color: #FFFFFF;
 }
-div#main { background-color: #FFFFFF;
-           color: #000033;
+
+div.main {
+       clear: both;
+       width: 50%;
+       display: block;
+       background-color: transparent;
+       color: #000033;
           padding:1em;
-          margin: 0;
+       position: relative;
+       font: 0.8125em/1em Verdana, sans-serif;
 }
-div#tools { background-color: #030250;
+
+
+div.tools { background-color: #030250;
             color: #FFFFFF;
+        font-size: 1em;
            border: 1px solid #FFFFFF;
            padding:0.5em;
            margin: 0;
 }
-div#colophon { background-color: #FFFFFF;
+
+div.colophon { background-color: #FFFFFF;
          color: #000033;
         font-size: 80%;
      float: right;
+     font: 0.8125em/1em Verdana, sans-serif;
+}
+
+div.title { background-color: #030250;
+             color: #FFFFFF;
+         padding: 0.5em;
+         line-height: 10px;
+         font: 0.8125em/1em Verdana, sans-serif;
 }
 
+div.hardware {     clear: both;
+    font: 0.8125em/1em Verdana, sans-serif;
+    font-size: 1em;
+    position: absolute;
+    right: 1em;
+    text-align: left;
+    margin-top: 10px;
+    border: 1px dotted #999;
+    padding: 6px;
+    background-color: #eee;
+    display: block;
+}
+
+div.form { background-color: #FFFFFF;
+       float: left;
+       color: #000033;
+       padding:1em;
+       margin: 0;
+}
 
index ed72e65b0ec5e16b5398d73df47b2abd9233dcb6..a12c9a5c5a670a2d0520848a9ff36b45fbd38ec1 100644 (file)
@@ -1,7 +1,7 @@
 Server=localhost
 Port=8000
 ServerPassword=source2parisson
-ServerMountpoint=/Pre-Barreau_-_ICP_-_CRFPA_-_Droit_administratif_Corrections.mp3
+ServerMountpoint=/Pre-Barreau_-_ICP_-_AE_-_Adm_Correction.mp3
 ServerPublic=0
 AutomaticReconnectSecs=10
 Encode=MP3 Lame
@@ -13,8 +13,8 @@ ServerType=Icecast2
 ExternalFile=/tmp/test
 #YP Settings
 ServerStreamURL=http://www.pre-barreau.com
-ServerName=Pre-Barreau_-_ICP_-_CRFPA_-_Droit_administratif_Corrections
-ServerDescription=Pre-Barreau_-_ICP_-_CRFPA_-_Droit_administratif_Corrections_-_2_-_MARINHO_A._-_1er_cours
+ServerName=Pre-Barreau_-_ICP_-_AE_-_Adm_Correction
+ServerDescription=Pre-Barreau_-_ICP_-_AE_-_Adm_Correction_-_3_-_GIUSTINIANI_G._-_2e_cours
 ServerGenre=Teaching
 #Advanced Settings
 LogLevel=1
index 46f686e6eabe8a2ddd1a9baf7b4d25f62862eb30..471492cc43bc56452396b4c9d221aa3594607b27 100755 (executable)
@@ -3,7 +3,7 @@
 """
    telecaster
 
-   Copyright (c) 2006-2007 Guillaume Pellerin <yomguy@altern.org>
+   Copyright (c) 2006-2008 Guillaume Pellerin <yomguy@parisson.org>
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -20,7 +20,8 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 """
 
-version = '0.3.4'
+version = '0.3.5'
+# Only for Unix and Linux systems
 
 import os
 import cgi
@@ -33,6 +34,7 @@ import string
 import signal
 import unicodedata
 from tools import *
+from tempfile import NamedTemporaryFile
 from mutagen.oggvorbis import OggVorbis
 from mutagen.id3 import ID3, TIT2, TP1, TAL, TDA, TCO, COM
 cgitb.enable()
@@ -61,7 +63,7 @@ class Station(Conference):
         self.date = datetime.datetime.now().strftime("%Y")
         self.time = datetime.datetime.now().strftime("%x-%X")
         self.time1 = self.time.replace('/','_')
-       self.time2 = self.time1.replace(':','_')
+        self.time2 = self.time1.replace(':','_')
                self.time = self.time2.replace(' ','_')
         self.conf = xml2dict(conf_file)
         self.conf = self.conf['telecaster']
@@ -88,7 +90,8 @@ class Station(Conference):
         self.uid = os.getuid()
         self.odd_pid = get_pid('^oddcastv3 -n [^LIVE]', self.uid)
         self.rip_pid = get_pid('streamripper ' + self.url + self.mount_point, self.uid)
-        self.new_title = clean_string('_-_'.join(self.server_name)+'_-_'+self.professor+'_-_'+self.comment)
+        self.new_title = clean_string('_-_'.join(self.server_name)+'_-_'+self.session+'_-_'+self.professor+'_-_'+self.comment)
+        self.short_title = clean_string('_-_'.join(self.conference)+'_-_'+self.session+'_-_'+self.professor+'_-_'+self.comment)
         self.genre = 'Vocal'
         self.encoder = 'TeleCaster by Parisson'
         self.rsync_host = self.conf['server']['rsync_host']
@@ -100,6 +103,7 @@ class Station(Conference):
             os.makedirs(self.raw_dir)
 
     def set_oddcast_conf(self):
+        oddconf_temp = NamedTemporaryFile(suffix='.cfg')
         oddconf = open(self.odd_conf_file,'r')
         lines = oddconf.readlines()
         oddconf.close()
@@ -123,17 +127,17 @@ class Station(Conference):
 
             else:
                 newlines.append(line)
-                
-        oddconf = open(self.odd_conf_file,'w')
-        oddconf.writelines(newlines)
-        oddconf.close()
+
+        oddconf_temp_file = open(oddconf_temp.name,'w')
+        oddconf_temp_file.writelines(newlines)
+        self.odd_conf = oddconf_temp.name
 
     def start_oddcast(self):
-        command = 'oddcastv3 -n "'+clean_string(self.conference)[0:16]+'" -c '+self.odd_conf_file+ \
+        command = 'oddcastv3 -n "'+clean_string(self.conference)[0:16]+'" -c '+self.odd_conf+ \
                   ' alsa_pcm:capture_1 > /dev/null &'
         os.system(command)
         self.set_lock()
-        time.sleep(1)
+        time.sleep(0.1)
 
     def set_lock(self):
         lock = open(self.lock_file,'w')
@@ -273,10 +277,19 @@ class WebView:
     def __init__(self, school_file):
         self.conf = xml2dict(school_file)
         self.conf = self.conf['telecaster']
-       self.interface = 'eth1'
-       self.ip = get_ip_address(self.interface)
+        self.interfaces = ['eth0', 'eth1', 'eth2']
+        ip = ''
+        for interface in self.interfaces:
+            try:
+                ip = get_ip_address(interface)
+                if ip:
+                    self.ip = ip
+                break
+            except:
+                self.ip = 'localhost'
         self.url = 'http://' + self.ip
         self.port = self.conf['port']
+        self.acpi = acpi.Acpi()
         self.format = self.conf['format']
         self.title = self.conf['title']
         self.departments = self.conf['department']
@@ -326,15 +339,15 @@ class WebView:
         print "</HEAD>\n"
         
         print "<BODY BGCOLOR =\"#FFFFFF\">"
-        print "<div id=\"bg\">"
-        print "<div id=\"header\">"
+        print "<div class=\"bg\">"
+        print "<div class=\"header\">"
         print "<H3>&nbsp;TeleCaster - L'enregistrement et la diffusion audio en direct par internet</H3>"
         print "</div>"
 
     def colophon(self):
         date = datetime.datetime.now().strftime("%Y")
-        print "<div id=\"colophon\">"
-        print "TeleCaster "+version+" &copy; <span>"+date+"</span>&nbsp;<a href=\"http://parisson.com\">Parisson</a>. Tous droits r&eacute;serv&eacute;s."
+        print "<div class=\"colophon\">"
+        print "TeleCaster "+version+" &copy; <span>"+date+"</span>&nbsp;<a href=\"http://parisson.com\">Parisson SARL</a>. Tous droits r&eacute;serv&eacute;s."
         print "</div>"
             
     def footer(self):
@@ -342,12 +355,66 @@ class WebView:
         print "</BODY>"
         print "</HTML>"
 
+    def hardware_data(self):
+        self.acpi.update()
+        self.power_state = self.acpi.charging_state()
+        if self.power_state == 0:
+            power_info = "<span style=\"color: red\">batterie</span>"
+        elif self.power_state == 1 or self.power_state == 2:
+            power_info = "<span style=\"color: green\">secteur</span>"
+        else:
+            power_info = ""
+            
+        #if self.power_state == 0:
+            #batt_info = "en d&eacute;charge"
+        #elif self.power_state == 1:
+            #batt_info = "charg&eacute;e"
+        #elif self.power_state == 2:
+            #batt_info = "en charge"
+        #else:
+            #batt_info = ""
+
+        if self.acpi.percent() == 127:
+            batt_charge = '<span style=\"color: green\">100 &#37;</span>'
+        else:
+            percent = self.acpi.percent()
+            if percent < 10:
+                batt_charge = '<span style=\"color: red\">'+str(percent)+' &#37;</span>'
+            else:
+                batt_charge = '<span style=\"color: green\">'+str(percent)+' &#37;</span>'
+
+        if self.ip == 'localhost':
+            ip_info = '<span style=\"color: red\">'+self.ip+'</span>'
+        else:
+            ip_info = '<span style=\"color: green\">'+self.ip+'</span>'
+        
+        print "<div class=\"hardware\">"
+        print "<div class=\"title\">Informations mat&eacute;rielles</div>"
+        print "<table>"
+        print "<tr><td>Alimentation :</td>"
+        print "<td>%s</td></tr>" % power_info
+        #print "<tr><td>Etat batterie :</td>"
+        #print "<td>%s</td></tr>" % batt_info
+        print "<tr><td>Capacit&eacute; batterie :</td>"
+        print "<td>%s</td></tr>" % batt_charge
+        #print "<tr><td>Estimation dur&eacute;e batterie :</td>"
+        #print "<td>%s</td></tr>" % self.acpi.estimated_lifetime()
+        print "<tr><td>Temp core 1 :</td>"
+        print "<td>%s</td></tr>" % self.acpi.temperature(0)
+        print "<tr><td>Address IP :</td>"
+        print "<td>%s</td></tr>" % ip_info
+        print "</table>"
+        print "</div>"
+        
+
     def start_form(self, message=''):
         self.refresh = False
         self.header()
-        print "<div id=\"main\">"
-        print "<h5><span style=\"color: red\">"+message+"</span></h5>"
-        print "<h5><span style=\"color: red\">Attention, il est important de remplir tous les champs, y compris le commentaire !</span></h5>"
+        self.hardware_data()
+        print "<div class=\"main\">"
+        #print "<h5><span style=\"color: red\">"+message+"</span></h5>"
+        #print "<h5><span style=\"color: red\">Attention, il est important de remplir tous les champs, y compris le commentaire !</span></h5>"
+        print "<div \class=\"form\">"
         print "<TABLE BORDER = 0>"
         print "<FORM method=POST ACTION=\""+self.url+"/telecaster/telecaster.py\" name=\"formulaire\">"
         print "<TR><TH align=\"left\">Titre :</TH><TD>"+self.title+"</TD></TR>"
@@ -383,14 +450,16 @@ class WebView:
         for comment in self.comments:
             print "<option value=\""+comment['text']+"\">"+comment['text']+"</option>"
         print "</select></TD></TR>"
-        
+       
         print "</TABLE>"
+        print "</div>"
+        
         #print "<h5><a href=\""+self.url+":"+self.port+"/augustins.pre-barreau.com_live."+self.format+".m3u\">Cliquez ici pour &eacute;couter le flux continu 24/24 en direct</a></h5>"
         print '<hr>'
         print "<h5><a href=\""+self.url+"/media/\">Cliquez ici pour acc&eacute;der aux archives</a></h5>"
         print "<h5><a href=\""+self.url+"/backup/\">Cliquez ici pour acc&eacute;der aux archives de secours</a></h5>"
         print "</div>"
-        print "<div id=\"tools\">"
+        print "<div class=\"tools\">"
         print "<INPUT TYPE = hidden NAME = \"action\" VALUE = \"start\">"
         print "<INPUT TYPE = submit VALUE = \"Enregistrer\">"
         print "</FORM>"
@@ -400,7 +469,7 @@ class WebView:
 
     def encode_form(self, message=''):
         self.header()
-        print "<div id=\"main\">"
+        print "<div class=\"main\">"
         print "<h5><span style=\"color: red\">"+message+"</span></h5>"
         print "<h5><span style=\"color: red\">ENCODAGE EN COURS !</span></h5>"
         print "</div>"
@@ -414,9 +483,10 @@ class WebView:
         session = conference_dict['session']
         professor = conference_dict['professor']
         comment = conference_dict['comment']
-        self.refresh = False
+        self.refresh = True
         self.header()
-        print "<div id=\"main\">"
+        self.hardware_data()
+        print "<div class=\"main\">"
         
         print "<hr>"
         if writing:
@@ -440,7 +510,7 @@ class WebView:
         print "<hr>"
         print "<h5><a href=\""+self.url+":"+self.port+"/"+clean_string(self.title)+"_-_"+clean_string(department)+"_-_"+clean_string(conference)+"."+self.format+".m3u\">Cliquez ici pour &eacute;couter cette formation en direct</a></h5>"
         print "</div>"
-        print "<div id=\"tools\">"
+        print "<div class=\"tools\">"
         print "<FORM METHOD = post ACTION = \""+self.url+"/telecaster/telecaster.py\">"
         print "<INPUT TYPE = hidden NAME = \"action\" VALUE = \"stop\">"
         print "<INPUT TYPE = submit VALUE = \"STOP\">"
@@ -463,7 +533,6 @@ class TeleCaster:
         self.title = self.conf['infos']['name']
         self.root_dir = self.conf['server']['root_dir']
         self.lock_file = self.root_dir + os.sep + self.conf['server']['lock_file']
-        self.odd_conf_file = self.conf['server']['lock_file']
         self.title = self.conf['infos']['name']
         self.uid = os.getuid()
 
@@ -491,7 +560,7 @@ class TeleCaster:
                         'session': form["session"].value,
                         'professor': form["professor"].value,
                         'comment': form["comment"].value}
-
+            
             s = Station(self.conf_file, self.conference_dict, self.lock_file)
             s.start()
             if get_pid('^oddcastv3 -n [^LIVE]', self.uid) != []:
index 4cb3db5fd2e8e95d3c63d629b640b3deb58c0e25..9d1b6ca94405e6257c648752d87eb2a9bb999c33 100644 (file)
@@ -2,9 +2,10 @@
 ##
 ## $Id: acpi.py,v 1.23 2003/12/15 20:04:09 riemer Exp $
 ##
-## Copyright (C) 2002-2003 Tilo Riemer <riemer@lincvs.org>,
+## Copyright (C) 2002-2008 Tilo Riemer <riemer@lincvs.org>,
 ##                         Luc Sorgue  <luc.sorgue@laposte.net> and
-##                         Rds <rds@rdsarts.com>
+##                         Rds <rds@rdsarts.com> and
+##                         Guillaume Pellerin <yomguy@parisson.com>
 ## All rights reserved. 
 ##
 ## Redistribution and use in source and binary forms, with or without
@@ -60,494 +61,495 @@ ERR_CONFIGURATION_CHANGED = -5   #reload module? or function reconfigure?
 ERR_NOT_ALLOWED           = -6   #access for some resource not allowed --> better idea?
 
 class AcpiError(Exception):
-       """ACPI exceptions"""
+    """ACPI exceptions"""
 
-       def __init__(self, errno):
-               self.errno = errno
+    def __init__(self, errno):
+        self.errno = errno
 
-       def __str__(self):
-               if self.errno == ERR_GENERIC:
-                       return "Any ACPI error occured."
-               elif self.errno == ERR_NO_DEVICE:
-                       return "ACPI is not configured on this host."
-               elif self.errno == ERR_NOT_IMPLEMENTED:
-                       return "No implementation for this operating system."
-               elif self.errno == ERR_NO_LOW_LEVEL:
-                       return "Acpi_lowlevel module not found."
-               elif self.errno == ERR_CONFIGURATION_CHANGED:
-                       return "ACPI configuartion has been changed."
-               else:
-                       return "Unknown error occured."
+    def __str__(self):
+        if self.errno == ERR_GENERIC:
+            return "Any ACPI error occured."
+        elif self.errno == ERR_NO_DEVICE:
+            return "ACPI is not configured on this host."
+        elif self.errno == ERR_NOT_IMPLEMENTED:
+            return "No implementation for this operating system."
+        elif self.errno == ERR_NO_LOW_LEVEL:
+            return "Acpi_lowlevel module not found."
+        elif self.errno == ERR_CONFIGURATION_CHANGED:
+            return "ACPI configuartion has been changed."
+        else:
+            return "Unknown error occured."
 
 
 
 # interface ###################################################################
 
 class Acpi:
-       """Interface class for ACPI"""
-       
-       def __init__(self):
-               res = sys.platform
-               if res.find("freebsd4") > -1:
-                       self.acpi = None #throw exception
-                       raise AcpiError, ERR_NOT_IMPLEMENTED
-
-               elif res.find("netbsd1") > -1:
-                       self.acpi = None #throw exception
-                       raise AcpiError, ERR_NOT_IMPLEMENTED
-               
-               elif res.find("linux2") > -1:
-                       self.acpi = AcpiLinux()
-                       
-               elif res.find("linux") > -1:
-                       #some systems return linux instead of linux2. We should
-                       #show a warning or check by ourselves for Linux2
-                       self.acpi = AcpiLinux()
-                       
-               else:
-                       self.acpi = None #throw exception (os unknown)
-                       raise AcpiError, ERR_NOT_IMPLEMENTED
-               
-
-       def identity(self):
-               """Returns the identity of this module"""
-               return "acpi.py"
-               
-       def version(self):
-               """Returns the version of this module"""
-               return VERSION
-               
-       def update(self):
-               """Updates the ACPI state"""
-               self.acpi.update()
-
-       def percent(self):
-               """Returns percentage capacity of all batteries"""
-               return self.acpi.percent()
-
-       def capacity(self):
-               """Returns capacity of all batteries (in mWh)"""
-               return self.acpi.capacity()
-
-       def nb_of_batteries(self):
-               """Returns the number of batteries"""
-               return self.acpi.nb_of_batteries()
-
-       def charging_state(self):
-               """Returns ac state (off-/online/charging)"""
-               return self.acpi.charging_state()
-       
-       def estimated_lifetime(self):
-               """Returns Estimated Lifetime as real number"""
-               return self.acpi.estimated_lifetime()
-
-       def temperature(self, idx):
-               """Returns Processor Temperature"""
-               return self.acpi.temperature(idx)
-
-       def fan_state(self, idx):
-               """Returns fan states"""
-               return self.acpi.fan_state(idx)
+    """Interface class for ACPI"""
+    
+    def __init__(self):
+        res = sys.platform
+        if res.find("freebsd4") > -1:
+            self.acpi = None #throw exception
+            raise AcpiError, ERR_NOT_IMPLEMENTED
+
+        elif res.find("netbsd1") > -1:
+            self.acpi = None #throw exception
+            raise AcpiError, ERR_NOT_IMPLEMENTED
+        
+        elif res.find("linux2") > -1:
+            self.acpi = AcpiLinux()
+            
+        elif res.find("linux") > -1:
+            #some systems return linux instead of linux2. We should
+            #show a warning or check by ourselves for Linux2
+            self.acpi = AcpiLinux()
+            
+        else:
+            self.acpi = None #throw exception (os unknown)
+            raise AcpiError, ERR_NOT_IMPLEMENTED
+        
+
+    def identity(self):
+        """Returns the identity of this module"""
+        return "acpi.py"
+        
+    def version(self):
+        """Returns the version of this module"""
+        return VERSION
+        
+    def update(self):
+        """Updates the ACPI state"""
+        self.acpi.update()
+
+    def percent(self):
+        """Returns percentage capacity of all batteries"""
+        return self.acpi.percent()
+
+    def capacity(self):
+        """Returns capacity of all batteries (in mWh)"""
+        return self.acpi.capacity()
+
+    def nb_of_batteries(self):
+        """Returns the number of batteries"""
+        return self.acpi.nb_of_batteries()
+
+    def charging_state(self):
+        """Returns ac state (off-/online/charging)"""
+        return self.acpi.charging_state()
+    
+    def estimated_lifetime(self):
+        """Returns Estimated Lifetime as real number"""
+        return self.acpi.estimated_lifetime()
+
+    def temperature(self, idx):
+        """Returns Processor Temperature"""
+        return self.acpi.temperature(idx)
+
+    def fan_state(self, idx):
+        """Returns fan states"""
+        return self.acpi.fan_state(idx)
 
 
 #unfinished: don't use it or better send us improvements ;-)
-       def frequency(self, idx):
-               """ Return  the frequency of the processor"""
-               return self.acpi.frequency(idx)
+    def frequency(self, idx):
+        """ Return  the frequency of the processor"""
+        return self.acpi.frequency(idx)
 
-       def performance_states(self, idx):
-               """ Return a list of available frequencies for the proc """
-               return self.acpi.performance_states(idx)
+    def performance_states(self, idx):
+        """ Return a list of available frequencies for the proc """
+        return self.acpi.performance_states(idx)
 
-       def set_frequency(self, f):
-               """ Set the processor frequency - Warning ! Needs root privileges to work """
-               return self.acpi.set_frequency(f)
+    def set_frequency(self, f):
+        """ Set the processor frequency - Warning ! Needs root privileges to work """
+        return self.acpi.set_frequency(f)
 
 
 
 # implementation for Linux ####################################################
 
 class AcpiLinux:
-       def __init__(self):
-               """init ACPI class and check for any ACPI features in /proc/acpi/"""
+    def __init__(self):
+        """init ACPI class and check for any ACPI features in /proc/acpi/"""
 
-               #we read all acpi stuff from here
-               self.proc_acpi_dir = "/proc/acpi"
-               #self.proc_acpi_dir = "/home/riemer/main/ACPI/proc/acpi"
-               
-               self.init_batteries()
-               self.init_fans()
-               #self.init_processors()
-               self.init_temperatures()
-               
-               self.update()
+        #we read all acpi stuff from here
+        self.proc_acpi_dir = "/proc/acpi"
+        #self.proc_acpi_dir = "/home/riemer/main/ACPI/proc/acpi"
+        
+        self.init_batteries()
+        self.init_fans()
+        #self.init_processors()
+        self.init_temperatures()
+        
+        self.update()
 
 
-       def update(self):
-               """Read current states of supported acpi components"""
+    def update(self):
+        """Read current states of supported acpi components"""
 
-               self.update_batteries()
-               self.update_fans()
-               #self.update_processors()
-               self.update_temperatures()
+        self.update_batteries()
+        self.update_fans()
+        #self.update_processors()
+        self.update_temperatures()
 
-        # battery related functions
-       def init_batteries(self):
-               """Checks for and initializes the batteries"""
+    # battery related functions
+    def init_batteries(self):
+        """Checks for and initializes the batteries"""
 
-               self.proc_battery_dir = self.proc_acpi_dir + "/battery"
+        self.proc_battery_dir = self.proc_acpi_dir + "/battery"
 
                 # empty lists implies no battery, no capacity etc.
-               self.design_capacity = {}
-               self.life_capacity = {}
-               self.present_rate = {}
-
-               # empty list of battery sub directories; implies no batteries available
-               self.battery_dir_entries = []
-
-               try:
-                       battery_dir_entries = os.listdir(self.proc_battery_dir)
-               except OSError:
-                       self.ac_line_state = ONLINE  # no batteries: we assume that a cable is plugged in ;-)
-                       return   #nothing more to do
-                       
-
-               try:
-                       for i in battery_dir_entries:
-                               mode = os.stat(self.proc_battery_dir + "/" + i)[stat.ST_MODE]
-                               if stat.S_ISDIR(mode):
-                                       self.battery_dir_entries.append(i)
-               except OSError:
-                       # the battery module is not correctly loaded, or is broken.
-                       # currently self.battery_dir_entries has no batteries or only
-                       # the batteries which we could stat
-                       # because the appended dirs should be okay we do not return here
-                       pass
-               
-               self.ac_line_state = OFFLINE
+        self.design_capacity = {}
+        self.life_capacity = {}
+        self.present_rate = {}
+
+        # empty list of battery sub directories; implies no batteries available
+        self.battery_dir_entries = []
+
+        try:
+            battery_dir_entries = os.listdir(self.proc_battery_dir)
+        except OSError:
+            self.ac_line_state = ONLINE  # no batteries: we assume that a cable is plugged in ;-)
+            return   #nothing more to do
+            
+
+        try:
+            for i in battery_dir_entries:
+                mode = os.stat(self.proc_battery_dir + "/" + i)[stat.ST_MODE]
+                if stat.S_ISDIR(mode):
+                    self.battery_dir_entries.append(i)
+        except OSError:
+            # the battery module is not correctly loaded, or is broken.
+            # currently self.battery_dir_entries has no batteries or only
+            # the batteries which we could stat
+            # because the appended dirs should be okay we do not return here
+            pass
+        
+        self.ac_line_state = OFFLINE
 
 #later: the newer acpi versions seems to generate always two BAT dirs...
 #check info for present: no
-               try:
-                       for i in self.battery_dir_entries:
-                               #print self.proc_battery_dir + "/" + i + "/info"
-                               info_file = open(self.proc_battery_dir + "/" + i + "/info")
-                               line = info_file.readline()
-                       
-                               while len(line) != 0:
-                                       if line.find("last full capacity:") == 0:
-                                               cap = line.split(":")[1].strip()
-                                               try:
-                                                       self.design_capacity[i] = int(cap.split("m")[0].strip())
-                                               except ValueError:
-                                                       #no value --> conversion to int failed
-                                                       self.design_capacity[i] = 0
-                                                       
-                                       line = info_file.readline()
-                               info_file.close()
-               except IOError:
-                       #print "No batt info found."
-                       # the battery module is not correctly loaded... the file info should exist.
-                       # wipe out all lists --> no battery infos
-                       self.battery_dir_entries = []
-                       self.design_capacity = {}
-                       self.life_capacity = {}
-                       self.present_rate = {}
-
-
-       def update_batteries(self):
-               """Read current state of batteries"""
-
-               try:
-                       for i in self.battery_dir_entries:
-                               state_file = open(self.proc_battery_dir + "/" + i + "/state")
-                               line = state_file.readline()
-
-                               while len(line) != 0:
-                                       if line.find("remaining capacity") == 0:
-                                               cap = line.split(":")[1].strip()
-                                               try:
-                                                       self.life_capacity[i] = int(cap.split("m")[0].strip())
-                                               except ValueError:
-                                                       self.life_capacity[i] = 0
+        try:
+            for i in self.battery_dir_entries:
+                #print self.proc_battery_dir + "/" + i + "/info"
+                info_file = open(self.proc_battery_dir + "/" + i + "/info")
+                line = info_file.readline()
+            
+                while len(line) != 0:
+                    if line.find("last full capacity:") == 0:
+                        cap = line.split(":")[1].strip()
+                        try:
+                            self.design_capacity[i] = int(cap.split("m")[0].strip())
+                        except ValueError:
+                            #no value --> conversion to int failed
+                            self.design_capacity[i] = 0
+                            
+                    line = info_file.readline()
+                info_file.close()
+        except IOError:
+            #print "No batt info found."
+            # the battery module is not correctly loaded... the file info should exist.
+            # wipe out all lists --> no battery infos
+            self.battery_dir_entries = []
+            self.design_capacity = {}
+            self.life_capacity = {}
+            self.present_rate = {}
+
+
+    def update_batteries(self):
+        """Read current state of batteries"""
+
+        try:
+            for i in self.battery_dir_entries:
+                state_file = open(self.proc_battery_dir + "/" + i + "/state")
+                line = state_file.readline()
+
+                while len(line) != 0:
+                    if line.find("remaining capacity") == 0:
+                        cap = line.split(":")[1].strip()
+                        try:
+                            self.life_capacity[i] = int(cap.split("m")[0].strip())
+                        except ValueError:
+                            self.life_capacity[i] = 0
 
 # it's possible that in battery/*/info the charging state is unknown
 # --> then we must check ac_state...
 # iterating over all batteries this way is not smart. better implementation needed
 # better are funcs for capacity, acstate and prrate
 
-                                       # a little bit tricky... if loading of ac driver fails, we cant use info
-                                       # from /proc/ac_*/...
-                                       # if information in /proc/acpi/battery/*/state is wrong we had to
-                                       # track the capacity history.
-                                       # I assume that all battery state files get the same state.
-                                       if line.find("charging state") == 0:
-                                               state = line.split(":")[1].strip()
-                                               if state == "discharging":
-                                                       self.ac_line_state = OFFLINE
-                                               elif state == "charging":
-                                                       self.ac_line_state = CHARGING
-                                               else:
-                                                       self.ac_line_state = ONLINE
-
-                                       # Read the present energy consumption to 
-                                       # estimate life time 
-
-                                       if line.find("present rate:") == 0:
-                                               try:
-                                                       pr_rate = float(line.split(":")[1].strip().split("m")[0].strip())
-                                               except ValueError:
-                                                       pr_rate = 0
-                                                       
-                                               self.present_rate[i] = pr_rate
-
-                                       line = state_file.readline()
-                               state_file.close()
-               except IOError:
-                       raise AcpiError, ERR_CONFIGURATION_CHANGED 
-
-                       # maybe we should restart init_batteries instead of generating an error ?
-                       # the user may have unplugged the battery.
-                       #init_batteries()
-                       # I prefer raising an exception because we would run into a recursion of
-                       # member funcs what is not a good idea.
-                       # the case that this error occurs should be very rare
-                       
-
-       def init_temperatures(self):
-               """Initializes temperature stuff"""
-
-               self.proc_thermal_dir = self.proc_acpi_dir + "/thermal_zone"
-
-               # empty list implies no thermal feature supported
-               self.temperatures = {}
-
-               # empty list of thermal sub directories; implies no thermal infos available
-               self.thermal_dir_entries = []
-
-               try:
-                       thermal_dir_entries = os.listdir(self.proc_thermal_dir)
-               except OSError:
-                       return   #nothing more to do
-
-               try:
-                       for i in thermal_dir_entries:
-                               mode = os.stat(self.proc_thermal_dir + "/" + i)[stat.ST_MODE]
-                               if stat.S_ISDIR(mode):
-                                       self.thermal_dir_entries.append(i)
-               except OSError:
-                       # the thermal module is not correctly loaded, or is broken.
-                       # because the appended dirs should be okay we do not return here
-                       pass
-
-
-       def update_temperatures(self):
-               """Read current temperatures"""
-
-               try:
-                       for i in self.thermal_dir_entries:
-                               file = open(self.proc_thermal_dir + "/" + i + "/temperature")
-                               line = file.readline()
-                               while len(line) != 0:
-                                       if line.find("temperature") == 0:
-                                               self.temperatures[i] = line.split(":")[1].strip()
-                                       line = file.readline()
-                               file.close()
-               except IOError:
-                       raise AcpiError,ERR_CONFIGURATION_CHANGED
-
-                       
-       def init_fans(self):
-               """Initialize fans"""
-
-               self.proc_fan_dir = self.proc_acpi_dir + "/fan"
-
-               self.fans = {}
-
-               # empty list of fan sub directories; implies no fan infos available
-               self.fan_dir_entries = []
-
-               try:
-                       fan_dir_entries = os.listdir(self.proc_fan_dir)
-               except OSError:
-                       return   #nothing more to do
-
-               try:
-                       for i in fan_dir_entries:
-                               mode = os.stat(self.proc_fan_dir + "/" + i)[stat.ST_MODE]
-                               if stat.S_ISDIR(mode):
-                                       self.fan_dir_entries.append(i)
-               except OSError:
-                       # the fan module is not correctly loaded, or is broken.
-                       # because the appended dirs should be okay we do not return here
-                       pass
-               
-
-       def update_fans(self):
-               """Read current state of fans"""
-               
-               try:
-                       for i in self.fan_dir_entries:
-                               file = open(self.proc_fan_dir + "/" + i + "/state")
-                               line = file.readline()
-                               while len(line) != 0:
-                                       if line.find("status") == 0:
-                                               if line.split(":")[1].strip() == 'on':
-                                                       self.fans[i] = FAN_ON
-                                               else:
-                                                       self.fans[i] = FAN_OFF
-                                       line = file.readline()
-                               file.close()
-               except IOError:
-                       raise AcpiError,ERR_CONFIGURATION_CHANGED
-
-
-       def init_processors(self):
-               """Initialize processors"""
-
-               self.proc_processor_dir = self.proc_acpi_dir + "/processor"
+                    # a little bit tricky... if loading of ac driver fails, we cant use info
+                    # from /proc/ac_*/...
+                    # if information in /proc/acpi/battery/*/state is wrong we had to
+                    # track the capacity history.
+                    # I assume that all battery state files get the same state.
+                    if line.find("charging state") == 0:
+                        state = line.split(":")[1].strip()
+                        if state == "discharging":
+                            self.ac_line_state = OFFLINE
+                        elif state == "charging":
+                            self.ac_line_state = CHARGING
+                        else:
+                            self.ac_line_state = ONLINE
+
+                    # Read the present energy consumption to 
+                    # estimate life time 
+
+                    if line.find("present rate:") == 0:
+                        try:
+                            pr_rate = float(line.split(":")[1].strip().split("m")[0].strip())
+                        except ValueError:
+                            pr_rate = 0
+                            
+                        self.present_rate[i] = pr_rate
+
+                    line = state_file.readline()
+                state_file.close()
+        except IOError:
+            raise AcpiError, ERR_CONFIGURATION_CHANGED 
+
+            # maybe we should restart init_batteries instead of generating an error ?
+            # the user may have unplugged the battery.
+            #init_batteries()
+            # I prefer raising an exception because we would run into a recursion of
+            # member funcs what is not a good idea.
+            # the case that this error occurs should be very rare
+            
+
+    def init_temperatures(self):
+        """Initializes temperature stuff"""
+
+        self.proc_thermal_dir = self.proc_acpi_dir + "/thermal_zone"
+
+        # empty list implies no thermal feature supported
+        self.temperatures = {}
+
+        # empty list of thermal sub directories; implies no thermal infos available
+        self.thermal_dir_entries = []
+
+        try:
+            thermal_dir_entries = os.listdir(self.proc_thermal_dir)
+            #thermal_dir_entries.append('')
+        except OSError:
+            return   #nothing more to do
+
+        try:
+            for i in thermal_dir_entries:
+                mode = os.stat(self.proc_thermal_dir + "/" + i)[stat.ST_MODE]
+                if stat.S_ISDIR(mode):
+                    self.thermal_dir_entries.append(i)
+        except OSError:
+            # the thermal module is not correctly loaded, or is broken.
+            # because the appended dirs should be okay we do not return here
+            pass
+
+
+    def update_temperatures(self):
+        """Read current temperatures"""
+
+        try:
+            for i in self.thermal_dir_entries:
+                file = open(self.proc_thermal_dir + "/" + i + "/temperature")
+                line = file.readline()
+                while len(line) != 0:
+                    if line.find("temperature") == 0:
+                        self.temperatures[i] = line.split(":")[1].strip()
+                    line = file.readline()
+                file.close()
+        except IOError:
+            raise AcpiError,ERR_CONFIGURATION_CHANGED
+
+            
+    def init_fans(self):
+        """Initialize fans"""
+
+        self.proc_fan_dir = self.proc_acpi_dir + "/fan"
+
+        self.fans = {}
+
+        # empty list of fan sub directories; implies no fan infos available
+        self.fan_dir_entries = []
+
+        try:
+            fan_dir_entries = os.listdir(self.proc_fan_dir)
+        except OSError:
+            return   #nothing more to do
+
+        try:
+            for i in fan_dir_entries:
+                mode = os.stat(self.proc_fan_dir + "/" + i)[stat.ST_MODE]
+                if stat.S_ISDIR(mode):
+                    self.fan_dir_entries.append(i)
+        except OSError:
+            # the fan module is not correctly loaded, or is broken.
+            # because the appended dirs should be okay we do not return here
+            pass
+        
+
+    def update_fans(self):
+        """Read current state of fans"""
+        
+        try:
+            for i in self.fan_dir_entries:
+                file = open(self.proc_fan_dir + "/" + i + "/state")
+                line = file.readline()
+                while len(line) != 0:
+                    if line.find("status") == 0:
+                        if line.split(":")[1].strip() == 'on':
+                            self.fans[i] = FAN_ON
+                        else:
+                            self.fans[i] = FAN_OFF
+                    line = file.readline()
+                file.close()
+        except IOError:
+            raise AcpiError,ERR_CONFIGURATION_CHANGED
+
+
+    def init_processors(self):
+        """Initialize processors"""
+
+        self.proc_processor_dir = self.proc_acpi_dir + "/processor"
 
 # TODO: adapt it for multiple CPUs --> we need a matrix instead of a vector!!!
-               self.perf_states = {}   #empty list implies no processor support
-
-               # empty list of processor sub directories; implies no processor infos available
-               self.processor_dir_entries = []
-
-               try:
-                       processor_dir_entries = os.listdir(self.proc_processor_dir)
-               except OSError:
-                       return   #nothing more to do
-
-               try:
-                       for i in processor_dir_entries:
-                               mode = os.stat(self.proc_processor_dir + "/" + i)[stat.ST_MODE]
-                               if stat.S_ISDIR(mode):
-                                       self.processor_dir_entries.append(i)
-               except OSError:
-                       # the processor module is not correctly loaded, or is broken.
-                       # because the appended dirs should be okay we do not return here
-                       pass
-
-               try:
-                       for i in self.processor_dir_entries:
-                               file = open(self.proc_processor_dir + "/" + i + "/performance")
-                               line = file.readline()
-                               while(len(line)!=0):
-                                       if line.find("MHz") > -1:
-                                               state = line.split(":")[0].strip().split("P")[-1]
-                                               freq = line.split(":")[1].split(",")[0].strip()
-                                               self.perf_states[freq] = state
-                                       line = file.readline()
-                               file.close()
-               except IOError:
-                       self.processor_dir_entries = []
-                       self.perf_states = {}   #reset list --> should we throw an exception? No!
-                       return
-                       
-
-       def update_processors(self):
-               """Read current state of processors"""
-
-               try:
-                       for i in self.processor_dir_entries:
-                               file = open(self.proc_processor_dir + "/" + i + "/performance")
-                               line = file.readline()
-
-                               while(len(line)!=0):
-                                       if line.find("*") > -1:
-                                               self.freq = line.split(":")[1].strip().split(",")[0]
-                                       line = f.readline()
-                               file.close()
-               except IOError:
-                       raise AcpiError,ERR_CONFIGURATION_CHANGED
-
-
-       def percent(self):
-               """Returns percentage capacity of all batteries"""
-
-               life_capacity = 0
-               design_capacity = 0
-               for i,c in self.life_capacity.items():
-                       life_capacity = life_capacity + c
-                       design_capacity = design_capacity + self.design_capacity[i]
-
-               if design_capacity == 0:
-                       return 0
-               
-               # should we use try catch instead of the check above?
-               return (life_capacity * 100) / design_capacity
-
-
-       def capacity(self):
-               """Returns capacity of all batteries"""
-               capacity = 0
-               for i,c in self.life_capacity.items():
-                       capacity = capacity + c
-               return capacity
-
-
-       def nb_of_batteries(self):
-               #returns the number of batteries
-               #if it returns 0, maybe ACPI is not available or 
-               #battery driver is not loaded
-               return len(self.battery_dir_entries)
-
-               
-       def charging_state(self):
-               return self.ac_line_state
-
-
-       def estimated_lifetime(self):
-
-               # what should we return if state==charging?
-               # it's not clean to return a time in one case and any
-               # English string in another case.
-               # The user can check for ac-state before call this func
-               time = 0
-               for batt,life_capacity in self.life_capacity.items():
-                       if self.present_rate[batt] > 0:
-                               time = time + life_capacity/self.present_rate[batt]
-               return time
-
-
-       # we need funcs like max_temperature and average_temperature
-       def temperature(self, idx):
-               #print self.temperatures
-               #print self.thermal_dir_entries[idx]
-               return self.temperatures(self.thermal_dir_entries(idx))
-
-
-       def fan_state(self, idx):
-               #print self.fans
-               return self.fans[self.fan_dir_entries[idx]]
-
-
-       def performance_states(self, idx):
-               return self.perf_states[idx].keys()
+        self.perf_states = {}   #empty list implies no processor support
+
+        # empty list of processor sub directories; implies no processor infos available
+        self.processor_dir_entries = []
+
+        try:
+            processor_dir_entries = os.listdir(self.proc_processor_dir)
+        except OSError:
+            return   #nothing more to do
+
+        try:
+            for i in processor_dir_entries:
+                mode = os.stat(self.proc_processor_dir + "/" + i)[stat.ST_MODE]
+                if stat.S_ISDIR(mode):
+                    self.processor_dir_entries.append(i)
+        except OSError:
+            # the processor module is not correctly loaded, or is broken.
+            # because the appended dirs should be okay we do not return here
+            pass
+
+        try:
+            for i in self.processor_dir_entries:
+                file = open(self.proc_processor_dir + "/" + i + "/performance")
+                line = file.readline()
+                while(len(line)!=0):
+                    if line.find("MHz") > -1:
+                        state = line.split(":")[0].strip().split("P")[-1]
+                        freq = line.split(":")[1].split(",")[0].strip()
+                        self.perf_states[freq] = state
+                    line = file.readline()
+                file.close()
+        except IOError:
+            self.processor_dir_entries = []
+            self.perf_states = {}   #reset list --> should we throw an exception? No!
+            return
+            
+
+    def update_processors(self):
+        """Read current state of processors"""
+
+        try:
+            for i in self.processor_dir_entries:
+                file = open(self.proc_processor_dir + "/" + i + "/performance")
+                line = file.readline()
+
+                while(len(line)!=0):
+                    if line.find("*") > -1:
+                        self.freq = line.split(":")[1].strip().split(",")[0]
+                    line = f.readline()
+                file.close()
+        except IOError:
+            raise AcpiError,ERR_CONFIGURATION_CHANGED
+
+
+    def percent(self):
+        """Returns percentage capacity of all batteries"""
+
+        life_capacity = 0
+        design_capacity = 0
+        for i,c in self.life_capacity.items():
+            life_capacity = life_capacity + c
+            design_capacity = design_capacity + self.design_capacity[i]
+
+        if design_capacity == 0:
+            return 0
+        
+        # should we use try catch instead of the check above?
+        return (life_capacity * 100) / design_capacity
+
+
+    def capacity(self):
+        """Returns capacity of all batteries"""
+        capacity = 0
+        for i,c in self.life_capacity.items():
+            capacity = capacity + c
+        return capacity
+
+
+    def nb_of_batteries(self):
+        #returns the number of batteries
+        #if it returns 0, maybe ACPI is not available or 
+        #battery driver is not loaded
+        return len(self.battery_dir_entries)
+
+        
+    def charging_state(self):
+        return self.ac_line_state
+
+
+    def estimated_lifetime(self):
+
+        # what should we return if state==charging?
+        # it's not clean to return a time in one case and any
+        # English string in another case.
+        # The user can check for ac-state before call this func
+        time = 0
+        for batt,life_capacity in self.life_capacity.items():
+            if self.present_rate[batt] > 0:
+                time = time + life_capacity/self.present_rate[batt]
+        return time
+
+
+    # we need funcs like max_temperature and average_temperature
+    def temperature(self, idx):
+        #print self.temperatures
+        #print self.thermal_dir_entries[idx]
+        return self.temperatures[self.thermal_dir_entries[idx]]
+
+
+    def fan_state(self, idx):
+        #print self.fans
+        return self.fans[self.fan_dir_entries[idx]]
+
+
+    def performance_states(self, idx):
+        return self.perf_states[idx].keys()
 
 
-       def frequency(self, idx):
-               #print self.freq
-               return self.freq[idx]
+    def frequency(self, idx):
+        #print self.freq
+        return self.freq[idx]
 
 
 # TODO: adapt it for multiple CPUs
-       def set_frequency(self, f):
-       #I think we should throw exceptions if someone goes wrong here
-       
-               if self.perf_states.has_key(f):
-                       state = self.perf_states[f]
-                       try:
-                               pr = os.listdir("/proc/acpi/processor")[0]
-                       except OSError:
-                               raise AcpiError, ERR_NOT_ALLOWED
-
-                       try:                            
-                               f = open("/proc/acpi/processor/"+pr+"/performance","w")
-                       except IOError:
-                               raise AcpiError, ERR_NOT_ALLOWED
-                               
-                       f.write(state)
-                       f.close()
-               else:
-                       raise AcpiError, ERR_NOT_ALLOWED
+    def set_frequency(self, f):
+    #I think we should throw exceptions if someone goes wrong here
+    
+        if self.perf_states.has_key(f):
+            state = self.perf_states[f]
+            try:
+                pr = os.listdir("/proc/acpi/processor")[0]
+            except OSError:
+                raise AcpiError, ERR_NOT_ALLOWED
+
+            try:                
+                f = open("/proc/acpi/processor/"+pr+"/performance","w")
+            except IOError:
+                raise AcpiError, ERR_NOT_ALLOWED
+                
+            f.write(state)
+            f.close()
+        else:
+            raise AcpiError, ERR_NOT_ALLOWED