--- /dev/null
++---------------------------------------------------------
+| CRFPA
++---------------------------------------------------------
+Liberté publiques - Cours
+Note de synthèse - Corrections
+Droit civil - Cours
+Droit civil - Corrections
+Procédure administrative et contentieuse - Cours
+Procédure administrative et contentieuse - Corrections
+Procédure civile - Cours
+Procédure civile - Corrections
+Procédure pénale - Cours
+Procédure pénale - Corrections
+Droit commercial des affaires - Cours
+Droit commercial des affaires - Corrections
+Droit communautaire et européen - Cours
+Droit communautaire et européen - Corrections
+Droit fiscal - Cours
+Droit fiscal - Corrections
+Droit pénal - Cours
+Droit pénal - Corrections
+Droit de la famille et des personnes - Cours
+Droit de la famille et des personnes - Corrections
+Droit patrimonial - Cours
+Droit patrimonial - Corrections
+Droit du travail - Cours
+Droit du travail - Corrections
+Droit administratif - Cours
+Droit administratif - Corrections
+Droit public des activités économiques - Cours
+Droit public des activités économiques - Corrections
+Droit international privé - Cours
+Droit international privé - Corrections
+Procédures collectives et sûretés - Cours
+Procédures collectives et sûretés - Corrections
+Procédure communautaire - Cours
+Procédures civile d'exécution - Cours
+Comptabilité privée - Cours
+Finances publiques - Cours
+TEST
++---------------------------------------------------------
+| AE
++---------------------------------------------------------
+Administratif_Cours
+Adm_Correction
+Civil_Correction
+Commercial_Correctio
+Commercial_Cours
+Deontologie_Cours
+Droit civil - Cours
+Methodo_Oraux
+Penal_Correction
+Penal_Cours
+Procedures_Cours
+Reunion_info
+Social_Corrections
+Social_Cours
+REUNION
+TEST
--- /dev/null
+CRFPA
+AE
+ENM
+FJP
--- /dev/null
+Server=localhost
+Port=8000
+ServerPassword=streampreb
+ServerMountpoint=/Pre-barreau_-_Augustins_-_AE_-_TEST.ogg
+ServerPublic=0
+AutomaticReconnectSecs=10
+Encode=OggVorbis
+BitrateNominal=512
+NumberChannels=1
+OggQuality=1
+Samplerate=44100
+ServerType=Icecast2
+ExternalFile=/home/pre-barreau/augustins/audio/
+#YP Settings
+ServerStreamURL=http://www.pre-barreau.com
+ServerName=Pre-barreau_-_Augustins_-_AE_-_TEST_-_7
+ServerDescription=Pre-barreau_-_Augustins_-_AE_-_TEST_-_7_-_GP_-_test
+ServerGenre=Teaching
+#Advanced Settings
+LogLevel=1
+LogFile=oddcastv3.log
+SaveAsWAV=0
+OutputControl=SERVER,GENERAL,OUTPUT
+
--- /dev/null
+
+div#header { background-color: #030250;
+ color: #FFFFFF;
+ padding: 0.5em;
+ line-height: 10px;
+
+}
+
+div#bg { background-color: #030250;
+ color: #FFFFFF;
+}
+div#main { background-color: #FFFFFF;
+ color: #000033;
+ padding:1em;
+ margin: 0;
+}
+div#tools { background-color: #030250;
+ color: #FFFFFF;
+ border: 1px solid #FFFFFF;
+ padding:0.5em;
+ margin: 0;
+}
+div#colophon { background-color: #FFFFFF;
+ color: #000033;
+ font-size: 80%;
+}
+
+
--- /dev/null
+#!/usr/bin/python
+# *-* coding: utf-8 *-*
+"""
+ teleoddcast
+
+ Copyright (c) 2006-2007 Guillaume Pellerin <yomguy@altern.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
+ 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.2'
+
+import os
+import cgi
+import shutil
+import datetime
+import time
+from mutagen.oggvorbis import OggVorbis
+
+def get_pid(proc,uid):
+ """Get a process pid filtered by arguments and uid"""
+ (list1, list2) = os.popen4('pgrep -f -U '+str(uid)+' '+'"'+proc+'"')
+ pids = list2.readlines()
+ if pids != '':
+ for pid in pids:
+ index = pids.index(pid)
+ pids[index] = pid[:-1]
+ return pids
+
+
+def get_lines(file):
+ """Get lines from a file"""
+ fic = open(file,'r')
+ lines = fic.readlines()
+ fic.close()
+ return lines
+
+def clean_string(string):
+ """removes blank spaces and accents"""
+ string = string.replace(' ','_')
+ string = string.replace('é','e')
+ string = string.replace('è','e')
+ return string
+
+def start_stream(odd_conf_file, lock_file, media_dir, title, department, course, session, professor, comment):
+ oddconf = open(odd_conf_file,'r')
+ params = oddconf.readlines()
+ oddconf.close()
+ newlines = []
+ for line in params:
+ if 'ServerDescription' in line.split('='):
+ ServerDescription = title+'_-_'+department+'_-_'+course+'_-_'+session+'_-_'+professor+'_-_'+comment
+ ServerDescription = ServerDescription.replace(' ','_')
+ newlines.append('ServerDescription='+ServerDescription+'\n')
+ elif 'ServerName' in line.split('='):
+ ServerName=title+'_-_'+department+'_-_'+course+'_-_'+session
+ ServerName=clean_string(ServerName)
+ newlines.append('ServerName='+ServerName+'\n')
+ elif 'ServerMountpoint' in line.split('='):
+ mount_point = '/'+clean_string(title)+'_-_'+clean_string(department)+'_-_'+clean_string(course)+'.ogg'
+ newlines.append('ServerMountpoint='+mount_point+'\n')
+ else:
+ newlines.append(line)
+ oddconf = open(odd_conf_file,'w')
+ oddconf.writelines(newlines)
+ oddconf.close()
+ os.system('oddcastv3 -n "'+clean_string(course)+'" -c '+odd_conf_file+ \
+ ' alsa_pcm:capture_1 alsa_pcm:capture_2 > /dev/null &')
+ lock = open(lock_file,'w')
+ lock_text = clean_string(title+'_*_'+department+'_*_'+course+'_*_'+session+'_*_'+professor+'_*_'+comment)
+ lock_text = lock_text.replace('\n','')
+ lock.write(lock_text)
+ lock.close()
+ time.sleep(1)
+ return mount_point
+
+def start_rip(url, mount_point, media_dir, department):
+ output_dir = media_dir+os.sep+department+os.sep
+ #print mount_point
+ if not os.path.exists(output_dir):
+ os.mkdir(output_dir)
+ os.system('streamripper '+url+mount_point+' -d '+output_dir+' -D "%S" -s -t --quiet > /dev/null &')
+
+def stop_oddcast(pid):
+ os.system('kill -9 '+pid)
+
+def rm_lockfile(lock_file):
+ os.system('rm '+lock_file)
+
+def stop_rip(pid,media_dir,title,department,course,session,professor,comment):
+ os.system('kill -9 '+pid)
+ time.sleep(1)
+ date = datetime.datetime.now().strftime("%Y")
+ filename = clean_string(title+'_-_'+department+'_-_'+course+'_-_'+session+'_-_'+date+'_-_'+professor+'_-_'+comment+'.ogg')
+ dirname = media_dir + os.sep + department + os.sep + clean_string(title+'_-_'+department+'_-_'+course+'_-_'+session)
+ if os.path.exists(dirname) and os.path.exists(dirname+os.sep+'incomplete'):
+ shutil.move(dirname+os.sep+'incomplete'+os.sep+' - .ogg',dirname+os.sep)
+ shutil.rmtree(dirname+os.sep+'incomplete'+os.sep)
+ os.rename(dirname+os.sep+' - .ogg',dirname+os.sep+filename)
+
+def get_params_from_lock(lock_file):
+ lockfile = open(lock_file,'r')
+ params = lockfile.readline()
+ params_ok = params.split('_*_')
+ lockfile.close()
+ return params_ok
+
+def write_tags(media_dir,title,department,course,session,professor,comment):
+ date = datetime.datetime.now().strftime("%Y")
+ filename = clean_string(title+'_-_'+department+'_-_'+course+'_-_'+session+'_-_'+date+'_-_'+professor+'_-_'+comment+'.ogg')
+ new_title = clean_string(title+'_-_'+department+'_-_'+course+'_-_'+session)
+ dirname = media_dir + os.sep + department + os.sep + new_title
+ if os.path.exists(dirname+os.sep+filename):
+ audio = OggVorbis(dirname+os.sep+filename)
+ audio['TITLE'] = new_title
+ audio['ARTIST'] = professor
+ audio['ALBUM'] = title
+ audio['DATE'] = date
+ audio['GENRE'] = 'Vocal'
+ audio['SOURCE'] = title
+ audio['ENCODER'] = 'TeleOddCast by Parisson'
+ audio['COMMENT'] = comment
+ audio.save()
+
+# Required header that tells the browser how to render the HTML.
+print "Content-Type: text/html\n\n"
+
+def header(title):
+ print "<HTML>"
+ print "<HEAD>"
+ print "\t<TITLE>"+title+"</TITLE>"
+ print "<link href=\"teleoddcast.css\" rel=\"stylesheet\" type=\"text/css\">"
+ print "</HEAD>"
+ print "<BODY BGCOLOR =\"#FFFFFF\">"
+ print "<div id=\"bg\">"
+ print "<div id=\"header\">"
+ print "\t<H3> TeleOddCast - L'enregistrement et la diffusion audio en direct par internet</H3>"
+ print "</div>"
+
+def colophon():
+ print "<div id=\"colophon\">"
+ print "TeleOddCast "+version+" © <span>2007</span> <a href=\"http://parisson.com\">Parisson</a>. Tous droits réservés."
+ print "</div>"
+
+def footer():
+ print "</div>"
+ print "</BODY>"
+ print "</HTML>"
+
+
+
+def start_form(title, departments, courses):
+ header(title)
+ print "<div id=\"main\">"
+ print "<h5><a href=\"http://augustins.pre-barreau.com:8000/crfpa.pre-barreau.com_live.ogg.m3u\">Cliquez ici pour écouter le flux continu 24/24 en direct</a></h5>"
+ print "\t<TABLE BORDER = 0>"
+ print "\t\t<FORM METHOD = post ACTION = \"teleoddcast.py\">"
+ print "\t\t<TR><TH align=\"left\">Titre :</TH><TD>"+title+"</TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Département :</TH><TD><select name=\"department\">"
+ for department in departments:
+ print "<option value=\""+department+"\">"+department+"</option>"
+ print "</select></TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Intitulé du cours :</TH><TD><select name=\"course\">"
+ for course in courses:
+ print "<option value=\""+course+"\">"+course+"</option>"
+ print "</select></TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Session :</TH><TD><select name=\"session\">"
+ for i in range(1,21):
+ print "<option value=\""+str(i)+"\">"+str(i)+"</option>"
+ print "</select></TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Professeur :</TH><TD><INPUT type = text name = \"professor\"></TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Commentaire :</TH><TD><INPUT type = text name = \"comment\"></TD></TR>"
+ print "\t</TABLE>"
+ print "\t<h5><span style=\"color: red\">Attention, il est important de remplir tous les champs, y compris le commentaire !</span></h5>"
+ print "</div>"
+ print "<div id=\"tools\">"
+ print "\t<INPUT TYPE = hidden NAME = \"action\" VALUE = \"start\">"
+ print "\t<INPUT TYPE = submit VALUE = \"Start\">"
+ print "\t</FORM>"
+ print "</div>"
+ colophon()
+ footer()
+
+
+def stop_form(url,title, department, course, session, professor, comment):
+ """Stop page"""
+ header(title)
+ print "<div id=\"main\">"
+ print "\t<h4><span style=\"color: red\">Cette formation est en cours de diffusion :</span></h4>"
+ print "<hr>"
+ print "\t<TABLE BORDER = 0>"
+ print "\t\t<FORM METHOD = post ACTION = \"teleoddcast.py\">"
+ print "\t\t<TR><TH align=\"left\">Titre :</TH><TD>"+title+"</TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Département :</TH><TD>"+department+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Intitulé du cours :</TH><TD>"+course+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Session :</TH><TD>"+session+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Professeur :</TH><TD>"+professor+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Commentaire :</TH><TD>"+comment+"</TD><TR>"
+ print "\t</TABLE>"
+ print "<hr>"
+ print "<h5><a href=\""+url+"/"+clean_string(title)+"_-_"+clean_string(department)+"_-_"+clean_string(course)+".ogg.m3u\">Cliquez ici pour écouter cette formation en direct</a></h5>"
+ print "</div>"
+ print "<div id=\"tools\">"
+ print "\t<INPUT TYPE = hidden NAME = \"action\" VALUE = \"stop\">"
+ print "\t<INPUT TYPE = submit VALUE = \"Stop\">"
+ print "\t</FORM>"
+ print "</div>"
+ colophon()
+ footer()
+
+def main():
+ """Main function"""
+ title = 'Pre-barreau - Augustins'
+ root_dir = '/var/www/cgi-bin/'
+ media_dir = root_dir + 'media/'
+ server = 'augustins.pre-barreau.com'
+ port = '8000'
+ url = 'http://'+server+':'+port
+ uid = os.getuid()
+
+ departments = get_lines(root_dir+'pre-barreau_departments.txt')
+ courses = get_lines(root_dir+'pre-barreau_courses.txt')
+ odd_conf_file = root_dir+'teleoddcast.cfg'
+
+ oddcast_pid = get_pid('^oddcastv3 -n [^LIVE]',uid)
+ lock_file = root_dir+'teleoddcast.lock'
+
+ form = cgi.FieldStorage()
+
+ if oddcast_pid == [] and form.has_key("action") and \
+ form.has_key("department") and form.has_key("course") and form.has_key("professor") \
+ and form.has_key("comment") and form["action"].value == "start":
+
+ mount_point = start_stream(odd_conf_file, lock_file, media_dir, title,
+ form["department"].value, form["course"].value,
+ form["session"].value, form["professor"].value,
+ form["comment"].value)
+
+ department = form["department"].value
+ start_rip(url,mount_point,media_dir,department)
+
+ stop_form(url,title,
+ form["department"].value, form["course"].value,
+ form["session"].value, form["professor"].value,
+ form["comment"].value)
+
+ elif oddcast_pid != [] and os.path.exists(lock_file) and not form.has_key("action"):
+
+ title,department,course,session,professor,comment = get_params_from_lock(lock_file)
+ stop_form(url,title,department,course,session,professor,comment)
+
+ elif oddcast_pid != [] and form.has_key("action") and form["action"].value == "stop":
+
+ if os.path.exists(lock_file):
+ title,department,course,session,professor,comment = get_params_from_lock(lock_file)
+
+ stop_oddcast(oddcast_pid[0])
+ mount_point = '/'+clean_string(title)+'_-_'+clean_string(department)+'_-_'+clean_string(course)+'.ogg'
+ #print mount_point
+ streamripper_pid = get_pid('streamripper '+url+mount_point,uid)
+
+ if streamripper_pid != []:
+ stop_rip(streamripper_pid[0],media_dir,title,department,course,session,professor,comment)
+ write_tags(media_dir,title,department,course,session,professor,comment)
+
+ rm_lockfile(lock_file)
+
+ start_form(title, departments, courses)
+
+ elif oddcast_pid == []:
+ start_form(title, departments, courses)
+
+# Call main function.
+main()
+
--- /dev/null
+#!/usr/bin/python
+# *-* coding: utf-8 *-*
+"""
+ teleoddcast
+
+ Copyright (c) 2006-2007 Guillaume Pellerin <yomguy@altern.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
+ 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.2.1'
+
+import os
+import cgi
+import shutil
+import datetime
+import time
+from mutagen.oggvorbis import OggVorbis
+
+def get_pid(proc,uid):
+ """Get a process pid filtered by arguments and uid"""
+ (list1, list2) = os.popen4('pgrep -f -U '+str(uid)+' '+'"'+proc+'"')
+ pids = list2.readlines()
+ if pids != '':
+ for pid in pids:
+ index = pids.index(pid)
+ pids[index] = pid[:-1]
+ return pids
+
+
+def get_lines(file):
+ """Get lines from a file"""
+ fic = open(file,'r')
+ lines = fic.readlines()
+ fic.close()
+ return lines
+
+def clean_string(string):
+ """removes blank spaces and accents"""
+ string = string.replace(' ','_')
+ string = string.replace('é','e')
+ string = string.replace('è','e')
+ return string
+
+def start_stream(odd_conf_file, lock_file, media_dir, title, category, course, session, professor, comment):
+ oddconf = open(odd_conf_file,'r')
+ params = oddconf.readlines()
+ oddconf.close()
+ newlines = []
+ for line in params:
+ if 'ServerDescription' in line.split('='):
+ ServerDescription = title+'_-_'+category+'_-_'+course+'_-_'+session+'_-_'+professor+'_-_'+comment
+ ServerDescription = ServerDescription.replace(' ','_')
+ newlines.append('ServerDescription='+ServerDescription+'\n')
+ elif 'ServerName' in line.split('='):
+ ServerName=title+'_-_'+category+'_-_'+course+'_-_'+session
+ ServerName=clean_string(ServerName)
+ newlines.append('ServerName='+ServerName+'\n')
+ elif 'ServerMountpoint' in line.split('='):
+ mount_point = '/'+clean_string(title)+'_-_'+clean_string(category)+'_-_'+clean_string(course)+'.ogg'
+ newlines.append('ServerMountpoint='+mount_point+'\n')
+ else:
+ newlines.append(line)
+ oddconf = open(odd_conf_file,'w')
+ oddconf.writelines(newlines)
+ oddconf.close()
+ os.system('oddcastv3 -n "'+clean_string(course)+'" -c '+odd_conf_file+ \
+ ' alsa_pcm:capture_1 alsa_pcm:capture_2 > /dev/null &')
+ lock = open(lock_file,'w')
+ lock_text = clean_string(title+'_*_'+category+'_*_'+course+'_*_'+session+'_*_'+professor+'_*_'+comment)
+ lock_text = lock_text.replace('\n','')
+ lock.write(lock_text)
+ lock.close()
+ time.sleep(1)
+ return mount_point
+
+def start_rip(url, mount_point, media_dir, category):
+ output_dir = media_dir+os.sep+category+os.sep
+ #print mount_point
+ if not os.path.exists(output_dir):
+ os.mkdir(output_dir)
+ os.system('streamripper '+url+mount_point+' -d '+output_dir+' -D "%S" -s -t --quiet > /dev/null &')
+
+def stop_oddcast(pid):
+ os.system('kill -9 '+pid)
+
+def rm_lockfile(lock_file):
+ os.system('rm '+lock_file)
+
+def stop_rip(pid,media_dir,title,category,course,session,professor,comment):
+ os.system('kill -9 '+pid)
+ time.sleep(1)
+ date = datetime.datetime.now().strftime("%Y")
+ filename = clean_string(title+'_-_'+category+'_-_'+course+'_-_'+session+'_-_'+date+'_-_'+professor+'_-_'+comment+'.ogg')
+ dirname = media_dir + os.sep + category + os.sep + clean_string(title+'_-_'+category+'_-_'+course+'_-_'+session)
+ if os.path.exists(dirname) and os.path.exists(dirname+os.sep+'incomplete'):
+ shutil.move(dirname+os.sep+'incomplete'+os.sep+' - .ogg',dirname+os.sep)
+ shutil.rmtree(dirname+os.sep+'incomplete'+os.sep)
+ os.rename(dirname+os.sep+' - .ogg',dirname+os.sep+filename)
+
+def get_params_from_lock(lock_file):
+ lockfile = open(lock_file,'r')
+ params = lockfile.readline()
+ params_ok = params.split('_*_')
+ lockfile.close()
+ return params_ok
+
+def write_tags(media_dir,title,category,course,session,professor,comment):
+ date = datetime.datetime.now().strftime("%Y")
+ filename = clean_string(title+'_-_'+category+'_-_'+course+'_-_'+session+'_-_'+date+'_-_'+professor+'_-_'+comment+'.ogg')
+ new_title = clean_string(title+'_-_'+category+'_-_'+course+'_-_'+session)
+ dirname = media_dir + os.sep + category + os.sep + new_title
+ if os.path.exists(dirname+os.sep+filename):
+ audio = OggVorbis(dirname+os.sep+filename)
+ audio['TITLE'] = new_title
+ audio['ARTIST'] = professor
+ audio['ALBUM'] = title
+ audio['DATE'] = date
+ audio['GENRE'] = 'Vocal'
+ audio['SOURCE'] = title
+ audio['ENCODER'] = 'TeleOddCast by Parisson'
+ audio['COMMENT'] = comment
+ audio.save()
+
+def get_def_tags(doc):
+ for tag in doc.documentElement.getElementsByTagName('category') :
+ name = tag.getAttribute('name')
+ value = typeToolBox.cast(tag.getAttribute('value'), tag.getAttribute('type'))
+ tags.__dict__[name] = value
+ for opt in doc.documentElement.getElementsByTagName('opt') :
+ name = opt.getAttribute('name')
+ value = typeToolBox.cast(opt.getAttribute('value'), opt.getAttribute('type'))
+ options.__dict__[name] = value
+
+
+# Required header that tells the browser how to render the HTML.
+print "Content-Type: text/html\n\n"
+
+def header(title):
+ print "<HTML>"
+ print "<HEAD>"
+ print "\t<TITLE>"+title+"</TITLE>"
+ print "<link href=\"teleoddcast.css\" rel=\"stylesheet\" type=\"text/css\">"
+ print "</HEAD>"
+ print "<BODY BGCOLOR =\"#FFFFFF\">"
+ print "<div id=\"bg\">"
+ print "<div id=\"header\">"
+ print "\t<H3> TeleOddCast - L'enregistrement et la diffusion audio en direct par internet</H3>"
+ print "</div>"
+
+def colophon():
+ print "<div id=\"colophon\">"
+ print "TeleOddCast "+version+" © <span>2007</span> <a href=\"http://parisson.com\">Parisson</a>. Tous droits réservés."
+ print "</div>"
+
+def footer():
+ print "</div>"
+ print "</BODY>"
+ print "</HTML>"
+
+
+
+def start_form(title, categories, courses):
+ header(title)
+ print "<div id=\"main\">"
+ print "<h5><a href=\"http://augustins.pre-barreau.com:8000/crfpa.pre-barreau.com_live.ogg.m3u\">Cliquez ici pour écouter le flux continu 24/24 en direct</a></h5>"
+ print "\t<TABLE BORDER = 0>"
+ print "\t\t<FORM METHOD = post ACTION = \"teleoddcast.py\">"
+ print "\t\t<TR><TH align=\"left\">Titre :</TH><TD>"+title+"</TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Département :</TH><TD><select name=\"category\">"
+ for category in categories:
+ print "<option value=\""+category+"\">"+category+"</option>"
+ print "</select></TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Intitulé du cours :</TH><TD><select name=\"course\">"
+ for course in courses:
+ print "<option value=\""+course+"\">"+course+"</option>"
+ print "</select></TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Session :</TH><TD><select name=\"session\">"
+ for i in range(1,21):
+ print "<option value=\""+str(i)+"\">"+str(i)+"</option>"
+ print "</select></TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Professeur :</TH><TD><INPUT type = text name = \"professor\"></TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Commentaire :</TH><TD><INPUT type = text name = \"comment\"></TD></TR>"
+ print "\t</TABLE>"
+ print "\t<h5><span style=\"color: red\">Attention, il est important de remplir tous les champs, y compris le commentaire !</span></h5>"
+ print "</div>"
+ print "<div id=\"tools\">"
+ print "\t<INPUT TYPE = hidden NAME = \"action\" VALUE = \"start\">"
+ print "\t<INPUT TYPE = submit VALUE = \"Start\">"
+ print "\t</FORM>"
+ print "</div>"
+ colophon()
+ footer()
+
+
+def stop_form(url,title, category, course, session, professor, comment):
+ """Stop page"""
+ header(title)
+ print "<div id=\"main\">"
+ print "\t<h4><span style=\"color: red\">Cette formation est en cours de diffusion :</span></h4>"
+ print "<hr>"
+ print "\t<TABLE BORDER = 0>"
+ print "\t\t<FORM METHOD = post ACTION = \"teleoddcast.py\">"
+ print "\t\t<TR><TH align=\"left\">Titre :</TH><TD>"+title+"</TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Département :</TH><TD>"+category+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Intitulé du cours :</TH><TD>"+course+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Session :</TH><TD>"+session+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Professeur :</TH><TD>"+professor+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Commentaire :</TH><TD>"+comment+"</TD><TR>"
+ print "\t</TABLE>"
+ print "<hr>"
+ print "<h5><a href=\""+url+"/"+clean_string(title)+"_-_"+clean_string(category)+"_-_"+clean_string(course)+".ogg.m3u\">Cliquez ici pour écouter cette formation en direct</a></h5>"
+ print "</div>"
+ print "<div id=\"tools\">"
+ print "\t<INPUT TYPE = hidden NAME = \"action\" VALUE = \"stop\">"
+ print "\t<INPUT TYPE = submit VALUE = \"Stop\">"
+ print "\t</FORM>"
+ print "</div>"
+ colophon()
+ footer()
+
+def main():
+ """Main function"""
+ title = 'Pre-barreau - Augustins'
+ root_dir = '/var/www/cgi-bin/'
+ media_dir = root_dir + 'media/'
+ server = 'augustins.pre-barreau.com'
+ port = '8000'
+ url = 'http://'+server+':'+port
+ uid = os.getuid()
+
+ xml_conf_file = root_dir+'pre-barreau.xml'
+ categories = get_lines(root_dir+'pre-barreau_categories.txt')
+ courses = get_lines(root_dir+'pre-barreau_courses.txt')
+ odd_conf_file = root_dir+'teleoddcast.cfg'
+ lock_file = root_dir+'teleoddcast.lock'
+ oddcast_pid = get_pid('^oddcastv3 -n [^LIVE]',uid)
+
+ doc = xml.dom.minidom.parse(xml_conf_file)
+ tag_tools.get_def_tags(doc)
+
+ form = cgi.FieldStorage()
+
+ if oddcast_pid == [] and form.has_key("action") and \
+ form.has_key("category") and form.has_key("course") and form.has_key("professor") \
+ and form.has_key("comment") and form["action"].value == "start":
+
+ mount_point = start_stream(odd_conf_file, lock_file, media_dir, title,
+ form["category"].value, form["course"].value,
+ form["session"].value, form["professor"].value,
+ form["comment"].value)
+
+ category = form["category"].value
+ start_rip(url,mount_point,media_dir,category)
+
+ stop_form(url,title,
+ form["category"].value, form["course"].value,
+ form["session"].value, form["professor"].value,
+ form["comment"].value)
+
+ elif oddcast_pid != [] and os.path.exists(lock_file) and not form.has_key("action"):
+
+ title,category,course,session,professor,comment = get_params_from_lock(lock_file)
+ stop_form(url,title,category,course,session,professor,comment)
+
+ elif oddcast_pid != [] and form.has_key("action") and form["action"].value == "stop":
+
+ if os.path.exists(lock_file):
+ title,category,course,session,professor,comment = get_params_from_lock(lock_file)
+
+ stop_oddcast(oddcast_pid[0])
+ mount_point = '/'+clean_string(title)+'_-_'+clean_string(category)+'_-_'+clean_string(course)+'.ogg'
+ #print mount_point
+ streamripper_pid = get_pid('streamripper '+url+mount_point,uid)
+
+ if streamripper_pid != []:
+ stop_rip(streamripper_pid[0],media_dir,title,category,course,session,professor,comment)
+ write_tags(media_dir,title,category,course,session,professor,comment)
+
+ rm_lockfile(lock_file)
+
+ start_form(title, categories, courses)
+
+ elif oddcast_pid == []:
+ start_form(title, categories, courses)
+
+# Call main function.
+main()
+
--- /dev/null
+#!/usr/bin/python
+# *-* coding: utf-8 *-*
+"""
+ teleoddcast
+
+ Copyright (c) 2006-2007 Guillaume Pellerin <yomguy@altern.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
+ 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.2'
+
+import os
+import cgi
+import shutil
+import datetime
+import time
+from mutagen.oggvorbis import OggVorbis
+
+def get_pid(proc,uid):
+ """Get a process pid filtered by arguments and uid"""
+ (list1, list2) = os.popen4('pgrep -f -U '+str(uid)+' '+'"'+proc+'"')
+ pids = list2.readlines()
+ if pids != '':
+ for pid in pids:
+ index = pids.index(pid)
+ pids[index] = pid[:-1]
+ return pids
+
+
+def get_lines(file):
+ """Get lines from a file"""
+ fic = open(file,'r')
+ lines = fic.readlines()
+ fic.close()
+ return lines
+
+def clean_string(string):
+ """removes blank spaces and accents"""
+ string = string.replace(' ','_')
+ string = string.replace('é','e')
+ string = string.replace('è','e')
+ return string
+
+def start_stream(odd_conf_file, lock_file, media_dir, title, department, course, session, professor, comment):
+ oddconf = open(odd_conf_file,'r')
+ params = oddconf.readlines()
+ oddconf.close()
+ newlines = []
+ for line in params:
+ if 'ServerDescription' in line.split('='):
+ ServerDescription = title+'_-_'+department+'_-_'+course+'_-_'+session+'_-_'+professor+'_-_'+comment
+ ServerDescription = ServerDescription.replace(' ','_')
+ newlines.append('ServerDescription='+ServerDescription+'\n')
+ elif 'ServerName' in line.split('='):
+ ServerName=title+'_-_'+department+'_-_'+course+'_-_'+session
+ ServerName=clean_string(ServerName)
+ newlines.append('ServerName='+ServerName+'\n')
+ elif 'ServerMountpoint' in line.split('='):
+ mount_point = '/'+clean_string(title)+'_-_'+clean_string(department)+'_-_'+clean_string(course)+'.ogg'
+ newlines.append('ServerMountpoint='+mount_point+'\n')
+ else:
+ newlines.append(line)
+ oddconf = open(odd_conf_file,'w')
+ oddconf.writelines(newlines)
+ oddconf.close()
+ os.system('oddcastv3 -n "'+clean_string(course)+'" -c '+odd_conf_file+ \
+ ' alsa_pcm:capture_1 alsa_pcm:capture_2 > /dev/null &')
+ lock = open(lock_file,'w')
+ lock_text = clean_string(title+'_*_'+department+'_*_'+course+'_*_'+session+'_*_'+professor+'_*_'+comment)
+ lock_text = lock_text.replace('\n','')
+ lock.write(lock_text)
+ lock.close()
+ time.sleep(1)
+ return mount_point
+
+def start_rip(url, mount_point, media_dir, department):
+ output_dir = media_dir+os.sep+department+os.sep
+ #print mount_point
+ if not os.path.exists(output_dir):
+ os.mkdir(output_dir)
+ os.system('streamripper '+url+mount_point+' -d '+output_dir+' -D "%S" -s -t --quiet > /dev/null &')
+
+def stop_oddcast(pid):
+ os.system('kill -9 '+pid)
+
+def rm_lockfile(lock_file):
+ os.system('rm '+lock_file)
+
+def stop_rip(pid,media_dir,title,department,course,session,professor,comment):
+ os.system('kill -9 '+pid)
+ time.sleep(1)
+ date = datetime.datetime.now().strftime("%Y")
+ filename = clean_string(title+'_-_'+department+'_-_'+course+'_-_'+session+'_-_'+date+'_-_'+professor+'_-_'+comment+'.ogg')
+ dirname = media_dir + os.sep + department + os.sep + clean_string(title+'_-_'+department+'_-_'+course+'_-_'+session)
+ if os.path.exists(dirname) and os.path.exists(dirname+os.sep+'incomplete'):
+ shutil.move(dirname+os.sep+'incomplete'+os.sep+' - .ogg',dirname+os.sep)
+ shutil.rmtree(dirname+os.sep+'incomplete'+os.sep)
+ os.rename(dirname+os.sep+' - .ogg',dirname+os.sep+filename)
+
+def get_params_from_lock(lock_file):
+ lockfile = open(lock_file,'r')
+ params = lockfile.readline()
+ params_ok = params.split('_*_')
+ lockfile.close()
+ return params_ok
+
+def write_tags(media_dir,title,department,course,session,professor,comment):
+ date = datetime.datetime.now().strftime("%Y")
+ filename = clean_string(title+'_-_'+department+'_-_'+course+'_-_'+session+'_-_'+date+'_-_'+professor+'_-_'+comment+'.ogg')
+ new_title = clean_string(title+'_-_'+department+'_-_'+course+'_-_'+session)
+ dirname = media_dir + os.sep + department + os.sep + new_title
+ if os.path.exists(dirname+os.sep+filename):
+ audio = OggVorbis(dirname+os.sep+filename)
+ audio['TITLE'] = new_title
+ audio['ARTIST'] = professor
+ audio['ALBUM'] = title
+ audio['DATE'] = date
+ audio['GENRE'] = 'Vocal'
+ audio['SOURCE'] = title
+ audio['ENCODER'] = 'TeleOddCast by Parisson'
+ audio['COMMENT'] = comment
+ audio.save()
+
+# Required header that tells the browser how to render the HTML.
+print "Content-Type: text/html\n\n"
+
+def header(title):
+ print "<HTML>"
+ print "<HEAD>"
+ print "\t<TITLE>"+title+"</TITLE>"
+ print "<link href=\"teleoddcast.css\" rel=\"stylesheet\" type=\"text/css\">"
+ print "</HEAD>"
+ print "<BODY BGCOLOR =\"#FFFFFF\">"
+ print "<div id=\"bg\">"
+ print "<div id=\"header\">"
+ print "\t<H3> TeleOddCast - L'enregistrement et la diffusion audio en direct par internet</H3>"
+ print "</div>"
+
+def colophon():
+ print "<div id=\"colophon\">"
+ print "TeleOddCast "+version+" © <span>2007</span> <a href=\"http://parisson.com\">Parisson</a>. Tous droits réservés."
+ print "</div>"
+
+def footer():
+ print "</div>"
+ print "</BODY>"
+ print "</HTML>"
+
+
+
+def start_form(title, departments, courses):
+ header(title)
+ for department in departments:
+ print "<div id=\"main\">"
+ print "<h5><a href=\"http://augustins.pre-barreau.com:8000/crfpa.pre-barreau.com_live.ogg.m3u\">Cliquez ici pour écouter le flux continu 24/24 en direct</a></h5>"
+ print "\t<TABLE BORDER = 0>"
+ print "\t\t<FORM METHOD = post ACTION = \"teleoddcast.py\">"
+ print "\t\t<TR><TH align=\"left\">Titre :</TH><TD>"+title+"</TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Département :</TH><TD>"+department+"</TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Intitulé du cours :</TH><TD><select name=\"course\">"
+ for course in courses:
+ print "<option value=\""+course+"\">"+course+"</option>"
+ print "</select></TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Session :</TH><TD><select name=\"session\">"
+ for i in range(1,21):
+ print "<option value=\""+str(i)+"\">"+str(i)+"</option>"
+ print "</select></TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Professeur :</TH><TD><INPUT type = text name = \"professor\"></TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Commentaire :</TH><TD><INPUT type = text name = \"comment\"></TD></TR>"
+ print "\t</TABLE>"
+ print "\t<h5><span style=\"color: red\">Attention, il est important de remplir tous les champs, y compris le commentaire !</span></h5>"
+ print "</div>"
+ print "<div id=\"tools\">"
+ print "\t<INPUT TYPE = hidden NAME = \"action\" VALUE = \"start\">"
+ print "\t<INPUT TYPE = submit VALUE = \"Start\">"
+ print "\t</FORM>"
+ print "</div>"
+ colophon()
+ footer()
+
+
+def stop_form(url,title, department, course, session, professor, comment):
+ """Stop page"""
+ header(title)
+ print "<div id=\"main\">"
+ print "\t<h4><span style=\"color: red\">Cette formation est en cours de diffusion :</span></h4>"
+ print "<hr>"
+ print "\t<TABLE BORDER = 0>"
+ print "\t\t<FORM METHOD = post ACTION = \"teleoddcast.py\">"
+ print "\t\t<TR><TH align=\"left\">Titre :</TH><TD>"+title+"</TD></TR>"
+ print "\t\t<TR><TH align=\"left\">Département :</TH><TD>"+department+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Intitulé du cours :</TH><TD>"+course+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Session :</TH><TD>"+session+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Professeur :</TH><TD>"+professor+"</TD><TR>"
+ print "\t\t<TR><TH align=\"left\">Commentaire :</TH><TD>"+comment+"</TD><TR>"
+ print "\t</TABLE>"
+ print "<hr>"
+ print "<h5><a href=\""+url+"/"+clean_string(title)+"_-_"+clean_string(department)+"_-_"+clean_string(course)+".ogg.m3u\">Cliquez ici pour écouter cette formation en direct</a></h5>"
+ print "</div>"
+ print "<div id=\"tools\">"
+ print "\t<INPUT TYPE = hidden NAME = \"action\" VALUE = \"stop\">"
+ print "\t<INPUT TYPE = submit VALUE = \"Stop\">"
+ print "\t</FORM>"
+ print "</div>"
+ colophon()
+ footer()
+
+class School:
+ """
+ a School object
+ """
+
+ def __init__(self):
+ self.metadata = {}
+
+ def set_metadata(self, metadata):
+ self.metadata = metadata
+
+ def get_metadata(self):
+ return self.metadata
+
+ def
+
+ def set_tag_values(self, tag, values):
+ for values in courses
+ self.metadata
+
+
+ def add_to_dict(dict,tag,value):
+ """
+ Return a dictionary with the value added to the existing tag
+ """
+ tags = dict[tag]
+ tags= tags.append(value)
+ dict[tag] = tags
+ return dict
+
+
+def main():
+ """Main function"""
+ title = 'Pre-barreau - Augustins'
+ root_dir = '/var/www/cgi-bin/'
+ media_dir = root_dir + 'media/'
+ server = 'augustins.pre-barreau.com'
+ port = '8000'
+ url = 'http://'+server+':'+port
+ uid = os.getuid()
+ metadata = {'departments':'' , 'courses':'', 'sessions':'', 'professor':'', 'comment':''}
+
+
+ departments = get_lines(root_dir+'pre-barreau_departments.txt')
+ for dep in departments:
+ add_to_dict(metadata,
+ courses = get_lines(root_dir+'pre-barreau_courses.txt')
+ odd_conf_file = root_dir+'teleoddcast.cfg'
+
+ oddcast_pid = get_pid('^oddcastv3 -n [^LIVE]',uid)
+ lock_file = root_dir+'teleoddcast.lock'
+
+ form = cgi.FieldStorage()
+
+ if oddcast_pid == [] and form.has_key("action") and \
+ form.has_key("course") and form.has_key("professor") \
+ and form.has_key("comment") and form["action"].value == "start":
+
+ mount_point = start_stream(odd_conf_file, lock_file, media_dir, title,
+ form["department"].value, form["course"].value,
+ form["session"].value, form["professor"].value,
+ form["comment"].value)
+
+ department = form["department"].value
+ start_rip(url,mount_point,media_dir,department)
+
+ stop_form(url,title,
+ form["department"].value, form["course"].value,
+ form["session"].value, form["professor"].value,
+ form["comment"].value)
+
+ elif oddcast_pid != [] and os.path.exists(lock_file) and not form.has_key("action"):
+
+ title,department,course,session,professor,comment = get_params_from_lock(lock_file)
+ stop_form(url,title,department,course,session,professor,comment)
+
+ elif oddcast_pid != [] and form.has_key("action") and form["action"].value == "stop":
+
+ if os.path.exists(lock_file):
+ title,department,course,session,professor,comment = get_params_from_lock(lock_file)
+
+ stop_oddcast(oddcast_pid[0])
+ mount_point = '/'+clean_string(title)+'_-_'+clean_string(department)+'_-_'+clean_string(course)+'.ogg'
+ #print mount_point
+ streamripper_pid = get_pid('streamripper '+url+mount_point,uid)
+
+ if streamripper_pid != []:
+ stop_rip(streamripper_pid[0],media_dir,title,department,course,session,professor,comment)
+ write_tags(media_dir,title,department,course,session,professor,comment)
+
+ rm_lockfile(lock_file)
+
+ start_form(title, departments, courses)
+
+ elif oddcast_pid == []:
+ start_form(title, departments, courses)
+
+# Call main function.
+main()
+