From: yomguy Date: Tue, 21 Oct 2008 12:12:54 +0000 (+0000) Subject: Split classes, fix some styles X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=c31e09e46f12eec40f4cbd26a64a5d68644584fc;p=telecaster-cgi.git Split classes, fix some styles --- diff --git a/css/telecaster.css b/css/telecaster.css index d66634d..481a464 100644 --- a/css/telecaster.css +++ b/css/telecaster.css @@ -18,14 +18,14 @@ div.main { display: block; background-color: transparent; color: #000033; - padding:1em; + padding: 1em; position: relative; font: 0.8125em/1em Verdana, sans-serif; } div.tools { background-color: #030250; - color: #FFFFFF; + color: #FFFFFF; font-size: 1em; border: 1px solid #FFFFFF; padding:0.5em; @@ -34,9 +34,10 @@ div.tools { background-color: #030250; } div.colophon { background-color: #FFFFFF; - color: #000033; + color: #000033; font-size: 80%; - float: right; + float: left; + padding: 0px 0px 0px 1em; font: 0.8125em/1em Verdana, sans-serif; } diff --git a/station.py b/station.py new file mode 100644 index 0000000..6452fe6 --- /dev/null +++ b/station.py @@ -0,0 +1,266 @@ +#!/usr/bin/python +# *-* coding: utf-8 *-* +""" + telecaster + + Copyright (c) 2006-2008 Guillaume Pellerin + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +""" + +import os +import shutil +import datetime +import time +import codecs +import string +import signal +import unicodedata +from tools import * +from mutagen.oggvorbis import OggVorbis +from mutagen.id3 import ID3, TIT2, TP1, TAL, TDA, TCO, COM + +class Conference: + """A conference object including metadata""" + + def __init__(self, dict): + self.title = dict['title'] + self.department = dict['department'] + self.conference = dict['conference'] + self.session = dict['session'] + self.professor = dict['professor'] + self.comment = dict['comment'] + + def get_info(self): + return self.title, self.department, self.conference, self.session, self.professor, self.comment + + +class Station(Conference): + """Control the Oddcastv3-jack thread which send audio data to the icecast server + and the Streamripper thread which write audio on the hard disk""" + + def __init__(self, conf_file, conference_dict, lock_file): + Conference.__init__(self, conference_dict) + 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.time = self.time2.replace(' ','_') + self.conf = xml2dict(conf_file) + self.conf = self.conf['telecaster'] + self.root_dir = self.conf['server']['root_dir'] + self.media_dir = self.conf['media']['dir'] + self.host = self.conf['server']['host'] + self.port = self.conf['server']['port'] + self.password = self.conf['server']['sourcepassword'] + self.url = 'http://'+self.host+':'+self.port + self.odd_conf_file = self.conf['server']['odd_conf_file'] + self.bitrate = '64' + self.format = self.conf['media']['format'] + self.description = [self.title, self.department, self.conference, self.session, self.professor, self.comment] + self.server_name = [self.title, self.department, self.conference] + self.ServerDescription = clean_string('_-_'.join(self.description)) + self.ServerName = clean_string('_-_'.join(self.server_name)) + self.mount_point = '/' + clean_string(self.title) + '_-_' + \ + clean_string(self.department) + '_-_' + \ + clean_string(self.conference)+'.'+self.format + self.lock_file = self.root_dir + os.sep + self.conf['server']['lock_file'] + self.filename = self.ServerDescription + '_-_' + self.time + '.' + self.format + self.output_dir = self.media_dir + os.sep + self.department + os.sep + self.date + self.file_dir = self.output_dir + os.sep + self.ServerName + 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.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'] + self.record = str_to_bool(self.conf['media']['record']) + self.raw_dir = self.conf['media']['raw_dir'] + if not os.path.exists(self.media_dir): + os.makedirs(self.media_dir) + if not os.path.exists(self.raw_dir): + 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() + newlines = [] + for line in lines: + if 'ServerDescription' in line.split('='): + newlines.append('ServerDescription=' + \ + self.ServerDescription.replace(' ','_') + '\n') + + elif 'ServerName' in line.split('='): + newlines.append('ServerName=' + self.ServerName + '\n') + + elif 'ServerMountpoint' in line.split('='): + newlines.append('ServerMountpoint=' + self.mount_point + '\n') + + elif 'ServerPassword' in line.split('='): + newlines.append('ServerPassword=' + self.password + '\n') + + elif 'SaveDirectory' in line.split('='): + newlines.append('SaveDirectory=' + self.raw_dir + '\n') + + else: + newlines.append(line) + + odd_conf_file = 'etc/'+self.title+'.cfg' + oddconf = open(odd_conf_file,'w') + oddconf.writelines(newlines) + oddconf.close() + self.odd_conf = self.odd_conf_file + + def start_oddcast(self): + 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(0.1) + + def set_lock(self): + lock = open(self.lock_file,'w') + lock_text = clean_string('_*_'.join(self.description)) + lock_text = lock_text.replace('\n','') + lock.write(lock_text) + lock.close() + + def del_lock(self): + os.remove(self.lock_file) + + def start_rip(self): + if not os.path.exists(self.output_dir): + os.makedirs(self.output_dir) + command = 'streamripper ' + self.url + self.mount_point + \ + ' -d '+self.output_dir+' -D "%S" -s -t --quiet > /dev/null &' + os.system(command) + time.sleep(1) + + def stop_oddcast(self): + if len(self.odd_pid) != 0: + os.system('kill -9 '+self.odd_pid[0]) + + def stop_rip(self): + if len(self.rip_pid) != 0: + os.system('kill -9 ' + self.rip_pid[0]) + time.sleep(1) + date = datetime.datetime.now().strftime("%Y") + if os.path.exists(self.file_dir) and os.path.exists(self.file_dir + os.sep + 'incomplete'): + shutil.copy(self.file_dir+os.sep+'incomplete'+os.sep+' - .'+self.format, self.file_dir+os.sep) + os.rename(self.file_dir+os.sep+' - .'+self.format, self.file_dir+os.sep+self.filename) + shutil.rmtree(self.file_dir+os.sep+'incomplete'+os.sep) + + def mp3_convert(self): + os.system('oggdec -o - '+ self.file_dir+os.sep+self.filename+' | lame -S -m m -h -b '+ self.bitrate + \ + ' --add-id3v2 --tt "'+ self.new_title + '" --ta "'+self.professor+'" --tl "'+self.title+'" --ty "'+self.date+ \ + '" --tg "'+self.genre+'" - ' + self.file_dir+os.sep+self.ServerDescription + '.mp3 &') + + def write_tags_ogg(self): + file = self.file_dir + os.sep + self.filename + if os.path.exists(file): + audio = OggVorbis(file) + audio['TITLE'] = self.new_title + audio['ARTIST'] = self.professor + audio['ALBUM'] = self.title + audio['DATE'] = self.date + audio['GENRE'] = self.genre + audio['SOURCE'] = self.title + audio['ENCODER'] = self.encoder + audio['COMMENT'] = self.comment + audio.save() + + def write_tags_mp3(self): + file = self.file_dir + os.sep + self.filename + if os.path.exists(file): + os.system('mp3info -t "a" -a "a" '+file) + audio = ID3(file) + #tag = tags.__dict__['TITLE'] + audio.add(TIT2(encoding=3, text=self.new_title)) + #tag = tags.__dict__['ARTIST'] + audio.add(TP1(encoding=3, text=self.professor)) + #tag = tags.__dict__['ALBUM'] + audio.add(TAL(encoding=3, text=self.title)) + #tag = tags.__dict__['DATE'] + audio.add(TDA(encoding=3, text=self.date)) + #tag = tags.__dict__['GENRE'] + audio.add(TCO(encoding=3, text=self.genre)) + #tag = tags.__dict__['COMMENT'] + #audio.add(COM(encoding=3, text=self.comment)) + audio.save() + time.sleep(1) + + def start(self): + self.set_lock() + self.set_oddcast_conf() + self.start_oddcast() + self.start_rip() + + def stop(self): + self.stop_rip() + self.stop_oddcast() + if self.format == 'ogg': + self.write_tags_ogg() + elif self.format == 'mp3': + self.write_tags_mp3() + self.del_lock() + #self.mp3_convert() + #self.rsync_out() + + def start_mp3cast(self): + item_id = item_id + source = source + metadata = metadata + args = get_args(options) + ext = get_file_extension() + args = ' '.join(args) + command = 'sox "%s" -q -w -r 44100 -t wav -c2 - | lame %s -' % (source, args) + # Processing (streaming + cache writing) + stream = self.core_process(self.command,self.buffer_size,self.dest) + for chunk in stream: + yield chunk + + def core_process(self, command, buffer_size, dest): + """Encode and stream audio data through a generator""" + __chunk = 0 + file_out = open(dest,'w') + try: + proc = subprocess.Popen(command, + shell = True, + bufsize = buffer_size, + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + close_fds = True) + except: + raise ExportProcessError('Command failure:', command, proc) + # Core processing + while True: + __chunk = proc.stdout.read(buffer_size) + status = proc.poll() + if status != None and status != 0: + raise ExportProcessError('Command failure:', command, proc) + if len(__chunk) == 0: + break + yield __chunk + file_out.write(__chunk) + file_out.close() + + def rsync_out(self): + local_uname = os.uname() + hostname = local_uname[1] + os.system('rsync -a '+self.media_dir+os.sep+' '+self.rsync_host+':'+os.sep+hostname+os.sep) diff --git a/telecaster.py b/telecaster.py index 0741eae..5df32d8 100755 --- a/telecaster.py +++ b/telecaster.py @@ -34,502 +34,12 @@ import string import signal import unicodedata from tools import * -from cgi import FieldStorage -from tempfile import NamedTemporaryFile +from webview import * +from station import * from mutagen.oggvorbis import OggVorbis from mutagen.id3 import ID3, TIT2, TP1, TAL, TDA, TCO, COM cgitb.enable() -class Conference: - """A conference object including metadata""" - - def __init__(self, dict): - self.title = dict['title'] - self.department = dict['department'] - self.conference = dict['conference'] - self.session = dict['session'] - self.professor = dict['professor'] - self.comment = dict['comment'] - - def get_info(self): - return self.title, self.department, self.conference, self.session, self.professor, self.comment - - -class Station(Conference): - """Control the Oddcastv3-jack thread which send audio data to the icecast server - and the Streamripper thread which write audio on the hard disk""" - - def __init__(self, conf_file, conference_dict, lock_file): - Conference.__init__(self, conference_dict) - 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.time = self.time2.replace(' ','_') - self.conf = xml2dict(conf_file) - self.conf = self.conf['telecaster'] - self.root_dir = self.conf['server']['root_dir'] - self.media_dir = self.conf['media']['dir'] - self.host = self.conf['server']['host'] - self.port = self.conf['server']['port'] - self.password = self.conf['server']['sourcepassword'] - self.url = 'http://'+self.host+':'+self.port - self.odd_conf_file = self.conf['server']['odd_conf_file'] - self.bitrate = '64' - self.format = self.conf['media']['format'] - self.description = [self.title, self.department, self.conference, self.session, self.professor, self.comment] - self.server_name = [self.title, self.department, self.conference] - self.ServerDescription = clean_string('_-_'.join(self.description)) - self.ServerName = clean_string('_-_'.join(self.server_name)) - self.mount_point = '/' + clean_string(self.title) + '_-_' + \ - clean_string(self.department) + '_-_' + \ - clean_string(self.conference)+'.'+self.format - self.lock_file = self.root_dir + os.sep + self.conf['server']['lock_file'] - self.filename = self.ServerDescription + '_-_' + self.time + '.' + self.format - self.output_dir = self.media_dir + os.sep + self.department + os.sep + self.date - self.file_dir = self.output_dir + os.sep + self.ServerName - 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.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'] - self.record = str_to_bool(self.conf['media']['record']) - self.raw_dir = self.conf['media']['raw_dir'] - if not os.path.exists(self.media_dir): - os.makedirs(self.media_dir) - if not os.path.exists(self.raw_dir): - 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() - newlines = [] - for line in lines: - if 'ServerDescription' in line.split('='): - newlines.append('ServerDescription=' + \ - self.ServerDescription.replace(' ','_') + '\n') - - elif 'ServerName' in line.split('='): - newlines.append('ServerName=' + self.ServerName + '\n') - - elif 'ServerMountpoint' in line.split('='): - newlines.append('ServerMountpoint=' + self.mount_point + '\n') - - elif 'ServerPassword' in line.split('='): - newlines.append('ServerPassword=' + self.password + '\n') - - elif 'SaveDirectory' in line.split('='): - newlines.append('SaveDirectory=' + self.raw_dir + '\n') - - else: - newlines.append(line) - - oddconf = open(self.odd_conf_file,'w') - oddconf.writelines(newlines) - oddconf.close() - self.odd_conf = self.odd_conf_file - - def start_oddcast(self): - 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(0.1) - - def set_lock(self): - lock = open(self.lock_file,'w') - lock_text = clean_string('_*_'.join(self.description)) - lock_text = lock_text.replace('\n','') - lock.write(lock_text) - lock.close() - - def del_lock(self): - os.remove(self.lock_file) - - def start_rip(self): - if not os.path.exists(self.output_dir): - os.makedirs(self.output_dir) - command = 'streamripper ' + self.url + self.mount_point + \ - ' -d '+self.output_dir+' -D "%S" -s -t --quiet > /dev/null &' - os.system(command) - time.sleep(1) - - def stop_oddcast(self): - if len(self.odd_pid) != 0: - os.system('kill -9 '+self.odd_pid[0]) - - def stop_rip(self): - if len(self.rip_pid) != 0: - os.system('kill -9 ' + self.rip_pid[0]) - time.sleep(1) - date = datetime.datetime.now().strftime("%Y") - if os.path.exists(self.file_dir) and os.path.exists(self.file_dir + os.sep + 'incomplete'): - shutil.copy(self.file_dir+os.sep+'incomplete'+os.sep+' - .'+self.format, self.file_dir+os.sep) - os.rename(self.file_dir+os.sep+' - .'+self.format, self.file_dir+os.sep+self.filename) - shutil.rmtree(self.file_dir+os.sep+'incomplete'+os.sep) - - def mp3_convert(self): - os.system('oggdec -o - '+ self.file_dir+os.sep+self.filename+' | lame -S -m m -h -b '+ self.bitrate + \ - ' --add-id3v2 --tt "'+ self.new_title + '" --ta "'+self.professor+'" --tl "'+self.title+'" --ty "'+self.date+ \ - '" --tg "'+self.genre+'" - ' + self.file_dir+os.sep+self.ServerDescription + '.mp3 &') - - def write_tags_ogg(self): - file = self.file_dir + os.sep + self.filename - if os.path.exists(file): - audio = OggVorbis(file) - audio['TITLE'] = self.new_title - audio['ARTIST'] = self.professor - audio['ALBUM'] = self.title - audio['DATE'] = self.date - audio['GENRE'] = self.genre - audio['SOURCE'] = self.title - audio['ENCODER'] = self.encoder - audio['COMMENT'] = self.comment - audio.save() - - def write_tags_mp3(self): - file = self.file_dir + os.sep + self.filename - if os.path.exists(file): - os.system('mp3info -t "a" -a "a" '+file) - audio = ID3(file) - #tag = tags.__dict__['TITLE'] - audio.add(TIT2(encoding=3, text=self.new_title)) - #tag = tags.__dict__['ARTIST'] - audio.add(TP1(encoding=3, text=self.professor)) - #tag = tags.__dict__['ALBUM'] - audio.add(TAL(encoding=3, text=self.title)) - #tag = tags.__dict__['DATE'] - audio.add(TDA(encoding=3, text=self.date)) - #tag = tags.__dict__['GENRE'] - audio.add(TCO(encoding=3, text=self.genre)) - #tag = tags.__dict__['COMMENT'] - #audio.add(COM(encoding=3, text=self.comment)) - audio.save() - time.sleep(2) - - def start(self): - self.set_lock() - self.set_oddcast_conf() - self.start_oddcast() - self.start_rip() - - def stop(self): - self.stop_rip() - self.stop_oddcast() - if self.format == 'ogg': - self.write_tags_ogg() - elif self.format == 'mp3': - self.write_tags_mp3() - self.del_lock() - #self.mp3_convert() - #self.rsync_out() - - def start_mp3cast(self): - item_id = item_id - source = source - metadata = metadata - args = get_args(options) - ext = get_file_extension() - args = ' '.join(args) - command = 'sox "%s" -q -w -r 44100 -t wav -c2 - | lame %s -' % (source, args) - # Processing (streaming + cache writing) - stream = self.core_process(self.command,self.buffer_size,self.dest) - for chunk in stream: - yield chunk - - def core_process(self, command, buffer_size, dest): - """Encode and stream audio data through a generator""" - __chunk = 0 - file_out = open(dest,'w') - try: - proc = subprocess.Popen(command, - shell = True, - bufsize = buffer_size, - stdin = subprocess.PIPE, - stdout = subprocess.PIPE, - close_fds = True) - except: - raise ExportProcessError('Command failure:', command, proc) - # Core processing - while True: - __chunk = proc.stdout.read(buffer_size) - status = proc.poll() - if status != None and status != 0: - raise ExportProcessError('Command failure:', command, proc) - if len(__chunk) == 0: - break - yield __chunk - file_out.write(__chunk) - file_out.close() - - def rsync_out(self): - local_uname = os.uname() - hostname = local_uname[1] - os.system('rsync -a '+self.media_dir+os.sep+' '+self.rsync_host+':'+os.sep+hostname+os.sep) - - -class WebView(FieldStorage): - """Gives the web CGI frontend""" - - def __init__(self, school_file): - FieldStorage.__init__(self) - self.conf = xml2dict(school_file) - self.conf = self.conf['telecaster'] - 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'] - self.professors = self.conf['professor'] - self.comments = self.conf['comment'] - #print self.departments - #self.conferences = self.conf['department']['conferences'] - self.len_departments = len(self.departments) - self.len_professors = len(self.professors) - self.conference_nb_max = 40 - self.professor_nb_max = 40 - self.refresh = False - - def header(self): - # Required header that tells the browser how to render the HTML. - print "Content-Type: text/html\n\n" - print "" - print "" - print "TeleCaster - "+self.title+"" - print "" - print '' - if self.refresh: - print "" - print "\n" - - print "" - print "
" - print "
" - print "

 TeleCaster - L'enregistrement et la diffusion audio en direct par internet

" - print "
" - - def colophon(self): - date = datetime.datetime.now().strftime("%Y") - print "
" - print "TeleCaster "+version+" © "+date+" Parisson SARL. Tous droits réservés." - print "
" - - def footer(self): - print "
" - print "" - print "" - - def hardware_data(self): - self.acpi.update() - self.power_state = self.acpi.charging_state() - if self.power_state == 0: - power_info = "batterie" - elif self.power_state == 1 or self.power_state == 2: - power_info = "secteur" - 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 = '100 %' - else: - percent = self.acpi.percent() - if percent < 10: - batt_charge = ''+str(percent)+' %' - else: - batt_charge = ''+str(percent)+' %' - - if self.ip == 'localhost': - ip_info = ''+self.ip+'' - else: - ip_info = ''+self.ip+'' - - print "
" - print "
Informations matérielles
" - print "" - print "" - print "" % power_info - #print "" - #print "" % batt_info - print "" - print "" % batt_charge - #print "" - #print "" % self.acpi.estimated_lifetime() - try: - print "" % self.acpi.temperature(0) - except: - pass - try: - print "" % self.acpi.temperature(1) - except: - pass - print "" - print "" % ip_info - print "
Alimentation :%s
Etat batterie :%s
Capacité batterie :%s
Estimation durée batterie :%s
Temp core 1 :%s
Temp core 2 :%s
Address IP :%s
" - print "
" - - - def start_form(self, message=''): - self.refresh = False - self.header() - self.hardware_data() - print "
" - print "
" - #print "
"+message+"
" - #print "
Attention, il est important de remplir tous les champs, y compris le commentaire !
" - print "
" - print "" - print "" - print "" - print "" - - print "" - print "" - - print "" - - print "" - print "" - - print "" - print "" - print "
Titre :"+self.title+"
Département :
Conférence :
Session :
Professeur :
Commentaire :
" - print "
" - - #print "
Cliquez ici pour écouter le flux continu 24/24 en direct
" - - print "
" - print "
" - print "
" - #print "" - print "" - print "\"\"/Archives" - print "\"\"/Corbeille" - #print "" - print "
" - print "
" - print "
" - self.colophon() - self.footer() - - def encode_form(self, message=''): - self.header() - print "
" - print "
"+message+"
" - print "
ENCODAGE EN COURS !
" - print "
" - self.colophon() - self.footer() - - def stop_form(self, conference_dict, writing, casting): - """Stop page""" - department = conference_dict['department'] - conference = conference_dict['conference'] - session = conference_dict['session'] - professor = conference_dict['professor'] - comment = conference_dict['comment'] - self.refresh = True - self.header() - self.hardware_data() - print "
" - print "" - print "" - print "" - print "" - print "" - print "" - print "" - print "
Titre :"+self.title+"
Département :"+department+"
Conference :"+conference+"
Session :"+session+"
Professeur :"+professor+"
Commentaire :"+comment+"
" - #print "
Cliquez ici pour écouter cette formation en direct
" - print "
" - print "
" - print "
" - print "
" - if writing: - print "" - - #print "" - #print "" - print "
" - print "
" - print "
" - self.colophon() - self.footer() - class TeleCaster: """Manage the calls of Station and Webview to get the network and diff --git a/webview.py b/webview.py new file mode 100644 index 0000000..498b062 --- /dev/null +++ b/webview.py @@ -0,0 +1,296 @@ +#!/usr/bin/python +# *-* coding: utf-8 *-* +""" + telecaster + + Copyright (c) 2006-2008 Guillaume Pellerin + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +""" + +version = '0.3.5' +# Only for Unix and Linux systems + +import os +import cgi +import cgitb +import shutil +import datetime +import time +import codecs +import string +import signal +import unicodedata +from tools import * +from cgi import FieldStorage +cgitb.enable() + +class WebView(FieldStorage): + """Gives the web CGI frontend""" + + def __init__(self, school_file): + FieldStorage.__init__(self) + self.conf = xml2dict(school_file) + self.conf = self.conf['telecaster'] + 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'] + self.professors = self.conf['professor'] + self.comments = self.conf['comment'] + #print self.departments + #self.conferences = self.conf['department']['conferences'] + self.len_departments = len(self.departments) + self.len_professors = len(self.professors) + self.conference_nb_max = 40 + self.professor_nb_max = 40 + self.refresh = False + + def header(self): + # Required header that tells the browser how to render the HTML. + print "Content-Type: text/html\n\n" + print "" + print "" + print "TeleCaster - "+self.title+"" + print "" + print '' + if self.refresh: + print "" + print "\n" + + print "" + print "
" + print "
" + print "

 TeleCaster - L'enregistrement et la diffusion audio en direct par internet

" + print "
" + + def colophon(self): + date = datetime.datetime.now().strftime("%Y") + print "
" + print "TeleCaster "+version+" © "+date+" Parisson SARL. Tous droits réservés." + print "
" + + def footer(self): + print "
" + print "" + print "" + + def hardware_data(self): + self.acpi.update() + self.power_state = self.acpi.charging_state() + if self.power_state == 0: + power_info = "batterie" + elif self.power_state == 1 or self.power_state == 2: + power_info = "secteur" + 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 = '100 %' + else: + percent = self.acpi.percent() + if percent < 10: + batt_charge = ''+str(percent)+' %' + else: + batt_charge = ''+str(percent)+' %' + + if self.ip == 'localhost': + ip_info = ''+self.ip+'' + else: + ip_info = ''+self.ip+'' + + print "
" + print "
Informations matérielles
" + print "" + print "" + print "" % power_info + #print "" + #print "" % batt_info + print "" + print "" % batt_charge + #print "" + #print "" % self.acpi.estimated_lifetime() + try: + print "" % self.acpi.temperature(0) + except: + pass + try: + print "" % self.acpi.temperature(1) + except: + pass + print "" + print "" % ip_info + print "
Alimentation :%s
Etat batterie :%s
Capacité batterie :%s
Estimation durée batterie :%s
Temp core 1 :%s
Temp core 2 :%s
Address IP :%s
" + print "
" + + + def start_form(self, message=''): + self.refresh = False + self.header() + self.hardware_data() + print "
" + print "
" + #print "
"+message+"
" + #print "
Attention, il est important de remplir tous les champs, y compris le commentaire !
" + print "
" + print "" + print "" + print "" + print "" + + print "" + print "" + + print "" + + print "" + print "" + + print "" + print "" + print "
Titre :"+self.title+"
Département :
Conférence :
Session :
Professeur :
Commentaire :
" + print "
" + + #print "
Cliquez ici pour écouter le flux continu 24/24 en direct
" + + print "
" + print "
" + print "
" + #print "" + print "" + print "\"\"/Archives" + print "\"\"/Corbeille" + #print "" + print "
" + print "
" + print "
" + self.colophon() + self.footer() + + def encode_form(self, message=''): + self.header() + print "
" + print "
"+message+"
" + print "
ENCODAGE EN COURS !
" + print "
" + self.colophon() + self.footer() + + def stop_form(self, conference_dict, writing, casting): + """Stop page""" + department = conference_dict['department'] + conference = conference_dict['conference'] + session = conference_dict['session'] + professor = conference_dict['professor'] + comment = conference_dict['comment'] + self.refresh = True + self.header() + self.hardware_data() + print "
" + print "" + print "" + print "" + print "" + print "" + print "" + print "" + print "
Titre :"+self.title+"
Département :"+department+"
Conference :"+conference+"
Session :"+session+"
Professeur :"+professor+"
Commentaire :"+comment+"
" + #print "
Cliquez ici pour écouter cette formation en direct
" + print "
" + print "
" + print "
" + print "
" + if writing: + print "" + + #print "" + #print "" + print "
" + print "
" + print "
" + self.colophon() + self.footer() +