"""
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
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
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()
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']
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']
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()
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')
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']
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> 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+" © <span>"+date+"</span> <a href=\"http://parisson.com\">Parisson</a>. Tous droits réservés."
+ print "<div class=\"colophon\">"
+ print "TeleCaster "+version+" © <span>"+date+"</span> <a href=\"http://parisson.com\">Parisson SARL</a>. Tous droits réservés."
print "</div>"
def footer(self):
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écharge"
+ #elif self.power_state == 1:
+ #batt_info = "chargé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 %</span>'
+ else:
+ percent = self.acpi.percent()
+ if percent < 10:
+ batt_charge = '<span style=\"color: red\">'+str(percent)+' %</span>'
+ else:
+ batt_charge = '<span style=\"color: green\">'+str(percent)+' %</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é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é batterie :</td>"
+ print "<td>%s</td></tr>" % batt_charge
+ #print "<tr><td>Estimation duré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>"
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 écouter le flux continu 24/24 en direct</a></h5>"
print '<hr>'
print "<h5><a href=\""+self.url+"/media/\">Cliquez ici pour accéder aux archives</a></h5>"
print "<h5><a href=\""+self.url+"/backup/\">Cliquez ici pour accé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>"
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>"
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:
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 é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\">"
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()
'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) != []:
##
## $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
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