]> git.parisson.com Git - telecaster-cgi.git/commitdiff
- cleanup various infos
authoryomguy <yomguy@parisson.com>
Fri, 17 Sep 2010 18:49:30 +0000 (18:49 +0000)
committeryomguy <yomguy@parisson.com>
Fri, 17 Sep 2010 18:49:30 +0000 (18:49 +0000)
- CHANGE conf to get old session parameters (sessions.xml not needed anymore)
- cleanup vebview
- fix deefuzzer bug when no network
- BUG: page reload after starting (even when all processes are starting well)

INSTALL
conf/etc/telecaster/telecaster.xml
install.py
station.py
telecaster.py
tools/__init__.py
tools/tools.py
webview.py

diff --git a/INSTALL b/INSTALL
index 85f986ab27e959227c40d813b9aa5c21c48d58bc..14b2c1dc4195ea17e7559ee466c0a542fde108ee 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -22,6 +22,8 @@ $ sudo aptitude install python python-dev python-xml python-libxml2 python-setup
                         icecast2 apache2 apache2-suexec jackd libjack-dev vorbis-tools procps meterbridge fluxbox \
                         vnc4server vncviewer swh-plugins jack-rack libshout3 libshout3-dev libmad0-dev libogg-dev g++
 
+On Debian Squeeze or recent Ubuntu, change libjack-dev to libjack-jackd2-dev
+
 Optional::
 
 $ sudo aptitude install libfaac-dev libmp3lame-dev libflac-dev 
index 2bcd696a5e41330de1f53214b4c35077c8b322ac..c3c1d4eaa3def8f220de0fe99d65b41e37d63504 100644 (file)
@@ -3,19 +3,11 @@
         <short_name>Pre-Barreau</short_name>
         <name>Pre-Barreau</name>
         <description>La preparation au Barreau de Paris</description>
-        <url>http:///telecaster-04.parisson.com</url>
+        <url>telecaster-04.parisson.com</url>
         <genre>Vocal</genre>
-    </infos>
-    <server>
-        <host>stream.parisson.com</host>
-        <port>8000</port>
-        <sourcepassword>source2parisson</sourcepassword>
-        <public>0</public>
-        <deefuzzer_default_conf>/etc/telecaster/deefuzzer.xml</deefuzzer_default_conf>
-        <rss>
-            <dir>/var/www/rss/</dir>
-        </rss>
-    </server>
+    <deefuzzer>
+       <conf>/etc/telecaster/deefuzzer.xml</conf>
+    </deefuzzer>
     <media>
         <record>true</record>
         <play_dir>/home/prebarreau/media</play_dir>
         <name>jack_rack:out_1</name>
         </input>
     </jack>
+
+    <department>
+        <name>CRFPA</name>
+        <conferences>
+          <conference>
+            <name>Droit_administratif_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_administratif_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_des_obligations_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_des_obligations_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_commercial_des_affaires_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_commercial_des_affaires_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_communautaire_et_europeen_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_communautaire_et_europeen_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_de_la_famille_et_des_personnes_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_de_la_famille_et_des_personnes_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_du_travail_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_du_travail_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_fiscal_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_fiscal_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_international_prive_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_international_prive_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_patrimonial_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_patrimonial_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_public_des_activites_economiques_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_public_des_activites_economiques_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_penal_Corrections</name>
+          </conference>
+          <conference>
+            <name>Droit_penal_Cours</name>
+          </conference>
+          <conference>
+            <name>Droit_Libertes_publiques_Cours</name>
+          </conference>
+          <conference>
+            <name>Note_de_synthese_Corrections</name>
+          </conference>
+          <conference>
+            <name>Procedure_administrative_et_contentieuse_Corrections</name>
+          </conference>
+          <conference>
+            <name>Procedure_administrative_et_contentieuse_Cours</name>
+          </conference>
+          <conference>
+            <name>Procedure_civile_Corrections</name>
+          </conference>
+          <conference>
+            <name>Procedure_civile_Cours</name>
+          </conference>
+          <conference>
+            <name>Procedures_collectives_et_suretes_Corrections</name>
+          </conference>
+          <conference>
+            <name>Procedures_collectives_et_suretes_Cours</name>
+          </conference>
+          <conference>
+            <name>Procedure_penale_Corrections</name>
+          </conference>
+          <conference>
+            <name>Procedure_penale_Cours</name>
+          </conference>
+          <conference>
+            <name>TEST</name>
+          </conference>
+        </conferences>
+        
+    </department>
+
+    <department>
+        <name>AE</name>
+        <conferences>
+            <conference>
+                <name>Administratif_Cours</name>
+            </conference>
+            <conference>
+                <name>Adm_Correction</name>
+            </conference>
+            <conference>
+                <name>Civil_Correction</name>
+            </conference>
+            <conference>
+                <name>Commercial_Correctio</name>
+            </conference>
+            <conference>
+                <name>Commercial_Cours</name>
+            </conference>
+            <conference>
+                <name>Deontologie_Cours</name>
+            </conference>
+            <conference>
+                <name>Droit civil - Cours</name>
+            </conference>
+            <conference>
+                <name>Methodo_Oraux</name>
+            </conference>
+            <conference>
+                <name>Penal_Correction</name>
+            </conference>
+            <conference>
+                <name>Penal_Cours</name>
+            </conference>
+            <conference>
+                <name>Procedures_Cours</name>
+            </conference>
+            <conference>
+                <name>Reunion_info</name>
+            </conference>
+            <conference>
+                <name>Social_Corrections</name>
+            </conference>
+            <conference>
+                <name>Social_Cours</name>
+            </conference>
+            <conference>
+                <name>REUNION</name>
+            </conference>
+            <conference>
+                <name>TEST</name>
+            </conference>
+        </conferences>
+    </department>
+
+    <department>
+        <name>ENM</name>
+        <conferences>
+            <conference>
+                <name>TEST</name>
+            </conference>
+            <conference>
+                <name>REUNION</name>
+            </conference>
+        </conferences>
+    </department>
+                
+
+    <department>
+        <name>FJP</name>
+        <conferences>
+            <conference>
+                <name>Actualisation</name>
+            </conference> 
+            <conference>
+                <name>TEST</name>
+            </conference>
+            <conference>
+                <name>REUNION</name>
+            </conference>
+        </conferences>
+    </department>
+
+        <professor>
+            <name>MARINHO A.</name>
+        </professor>
+        <professor>
+            <name>GIUSTINIANI G.</name>
+        </professor>
+        <professor>
+            <name>BOFFA R.</name>
+        </professor>
+        <professor>
+            <name>MEUNIER J.</name>
+        </professor>
+        <professor>
+            <name>THERY C.</name>
+        </professor>
+        <professor>
+            <name>JLB</name>
+        </professor>
+        <professor>
+            <name>AZZI T.</name>
+        </professor>
+        <professor>
+            <name>ETIENNEY A.</name>
+        </professor>
+        <professor>
+            <name>MARKUS J.</name>
+        </professor>
+        <professor>
+            <name>ANDREU L.</name>
+        </professor>
+        <professor>
+            <name>ROUMIER W.</name>
+        </professor>
+        <professor>
+            <name>HAIK R.</name>
+        </professor>
+        <professor>
+            <name>POISSON S.</name>
+        </professor>
+        <professor>
+            <name>CARTIER-BRESSON A.</name>
+        </professor>
+        <professor>
+            <name>MBONGO P.</name>
+        </professor>
+        <professor>
+            <name>MATHONNET P.</name>
+        </professor>
+        <professor>
+            <name>FOULQUIER N.</name>
+        </professor>
+        <professor>
+            <name>RILOV. F</name>
+        </professor>
+        <professor>
+            <name>JEANSEN E.</name>
+        </professor>
+        <professor>
+            <name>LA J.</name>
+        </professor>
+        <professor>
+            <name>MECARELLI G.</name>
+        </professor>
+        <professor>
+            <name>COLLET M.</name>
+        </professor>
+        <professor>
+            <name>GILBERT S.</name>
+        </professor>
+        <professor>
+            <name>VIAL C.</name>
+        </professor>
+        <professor>
+            <name>PAGNERRE E.</name>
+        </professor>
+        <professor>
+            <name>PANOU C.</name>
+        </professor>
+        <professor>
+            <name>GILBERT S.</name>
+        </professor>
+        <professor>
+            <name>ROBBE S.</name>
+        </professor>
+
+
+        <comment><text>1ere_sem</text></comment>
+        <comment><text>2e_sem</text></comment>
+        <comment><text>3e_sem</text></comment>
+        <comment><text>4e_sem</text></comment>
+        <comment><text>5e_sem</text></comment>
+        <comment><text>6e_sem</text></comment>
+        <comment><text>7e_sem</text></comment>
+        <comment><text>8e_sem</text></comment>
+        <comment><text>9e_sem</text></comment>
+        <comment><text>10e_sem</text></comment>
+        <comment><text>11e_sem</text></comment>
+        <comment><text>12e_sem</text></comment>
+        <comment><text>13e_sem</text></comment>
+        <comment><text>14e_sem</text></comment>
+        <comment><text>15e_sem</text></comment>
+        <comment><text>16e_sem</text></comment>
+       
+    
 </telecaster>
index 5358ac897346827c0c4532849ca45d52aa6096e2..e4f675dfb8f021b021324f4a84e348faceb5215e 100644 (file)
@@ -45,6 +45,9 @@ install_dir = '/var/www/telecaster'
 if not os.path.exists(install_dir):
     os.mkdir(install_dir)
 
+user = raw_input('Give a user to use the TeleCaster system : ')
+print 'Installing...'
+
 os.system('cp -ra ./* ' + install_dir + os.sep)
 os.system('rm -rf ' + install_dir + os.sep + 'tools/edcast-jack')
 os.system('rm -rf ' + install_dir + os.sep + 'tools/deefuzzer')
@@ -53,9 +56,9 @@ etc_dir = '/etc'
 conf_dir = etc_dir + os.sep + 'telecaster'
 if not os.path.exists(conf_dir):
     os.mkdir(conf_dir)
-    os.system('chown -R  root:root ./conf/etc/')
     os.system('cp -ra ./conf/etc/* ' + etc_dir + os.sep)
-
+    os.system('chown -R  root:root ' + etc_dir)
+    
 init_dir = '/etc/rc2.d'
 init_link = init_dir + os.sep + 'S97jackd'
 if not os.path.exists(init_link):
@@ -65,7 +68,6 @@ init_link = init_dir + os.sep + 'S99vncserver'
 if not os.path.exists(init_link):
     os.system('ln -s /etc/init.d/vncserver ' + init_link)
     
-user = raw_input('Give a user to use the TeleCaster system : ')
 os.system('chown -R ' + user + ':' + user + ' ' + install_dir) 
 home = os.sep + 'home' + os.sep + user + os.sep
 home_dirs = ['fluxbox', 'vnc']
@@ -74,8 +76,8 @@ for dir in home_dirs:
     home_dir = home + '.' + dir
     if not os.path.exists(home_dir):
         os.mkdir(home_dir)
-    os.system('cp ' + conf_dir + os.sep + 'home' + os.sep + dir + '/* ' + home_dir)
-    os.system('chown -R ' + user + ':' + user + ' ' + home_dir) 
+        os.system('cp ' + conf_dir + os.sep + 'home' + os.sep + dir + '/* ' + home_dir)
+        os.system('chown -R ' + user + ':' + user + ' ' + home_dir) 
 
 #var_dir = '/var/www/telecaster'
 #if not os.path.exists(var_dir):
index 6bf34262586764df7a0b0bd95103a5f687596120..7c77c3d396f2c188a0291e8240a88bb187d751ca 100644 (file)
@@ -85,15 +85,8 @@ class Station(Conference):
         self.conf = self.conf['telecaster']
         self.user = pwd.getpwuid(os.getuid())[0]
         self.user_dir = '/home' + os.sep + self.user + os.sep + '.telecaster'
-        self.url_ext = self.conf['infos']['url']
         self.rec_dir = self.conf['media']['rec_dir']
-        self.host = self.conf['server']['host']
-        self.port = self.conf['server']['port']
-        self.rss_dir = self.conf['server']['rss']['dir']
-        self.rss_file = 'telecaster.xml'
-        self.password = self.conf['server']['sourcepassword']
-        self.url_int = 'http://'+self.host+':'+self.port
-        self.deefuzzer_default_conf_file = self.conf['server']['deefuzzer_default_conf']
+        self.deefuzzer_default_conf_file = self.conf['deefuzzer']['conf']
         self.deefuzzer_user_file = self.user_dir + os.sep + 'deefuzzer.xml'
         self.bitrate = self.conf['media']['bitrate']
         self.dict['Bitrate'] = str(self.bitrate) + ' kbps'
@@ -107,9 +100,7 @@ class Station(Conference):
         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.mount_point = '-'.join([clean_string(self.title),  clean_string(self.department),  clean_string(self.conference)])
         self.filename = clean_string('-'.join(self.description[1:])) + '-' + self.time_txt + '.' + self.format
         self.output_dir = self.rec_dir + os.sep + self.date + os.sep + self.department
         self.file_dir = self.output_dir + os.sep + self.ServerName
@@ -133,50 +124,42 @@ class Station(Conference):
             else:
                 self.jack_inputs.append(jack_inputs['name'])
 
-        # DeeFuzzzer setup
         self.deefuzzer_dict = xml2dict(self.deefuzzer_default_conf_file)
-        self.station_local = self.deefuzzer_dict['deefuzzer']['station'][0]
-        self.station_distant = self.deefuzzer_dict['deefuzzer']['station'][1]
-
-        self.station_local['infos']['short_name'] = self.mount_point
-        self.station_local['infos']['name'] = self.ServerName
-        self.station_local['infos']['description'] = self.ServerDescription.replace(' ','_')
-        self.station_local['infos']['genre'] = self.genre
-        self.station_local['server']['host'] = '127.0.0.1'
-        self.station_local['server']['port'] = self.port
-        self.station_local['server']['sourcepassword'] = self.password
-        self.station_local['media']['bitrate'] = self.bitrate
-        self.station_local['media']['dir'] = self.play_dir
-        self.station_local['media']['voices'] = str(len(self.jack_inputs))
-        self.station_local['record']['mode'] = '1'
-        self.station_local['record']['dir'] = self.file_dir
-        self.station_local['relay']['mode'] = '1'
-        self.station_local['relay']['author'] = self.professor
-
-        self.station_distant['infos']['short_name'] = self.mount_point
-        self.station_distant['infos']['name'] = self.ServerName
-        self.station_distant['infos']['description'] = self.ServerDescription.replace(' ','_')
-        self.station_distant['infos']['genre'] = self.genre
-        self.station_distant['server']['host'] = self.host
-        self.station_distant['server']['port'] = self.port
-        self.station_distant['server']['sourcepassword'] = self.password
-        self.station_distant['media']['bitrate'] = self.bitrate
-        self.station_distant['media']['dir'] = self.play_dir
-        self.station_distant['media']['voices'] = str(len(self.jack_inputs))
-        self.station_distant['record']['mode'] = '0'
-        self.station_distant['record']['dir'] = self.file_dir
-        self.station_distant['relay']['mode'] = '1'
-        self.station_distant['relay']['author'] = self.professor
-
-        self.deefuzzer_local_port = self.station_local['control']['port']
+        self.deefuzzer_osc_ports =  []
+        self.server_ports = []
+        
+        for station in self.deefuzzer_dict['deefuzzer']['station']:
+            if station['control']['mode'] == 1:
+                self.deefuzzer_osc_ports.append(station['control']['port'])
+                self.server_ports.append(station['server']['port'])
+            if station['server']['host'] == 'localhost' or  station['server']['host'] == '127.0.0.1':
+                self.conf['play_port'] = station['server']['port']
+            else:
+                self.conf['play_port'] = '8000'
+
+    def deefuzzer_setup(self):
+        i = 0
+        for station in self.deefuzzer_dict['deefuzzer']['station']:
+            station['infos']['short_name'] = self.mount_point
+            station['infos']['name'] = self.ServerName
+            station['infos']['description'] = self.ServerDescription.replace(' ','_')
+            station['infos']['genre'] = self.genre
+            station['media']['bitrate'] = self.bitrate
+            station['media']['dir'] = self.play_dir
+            station['media']['voices'] = str(len(self.jack_inputs))
+            station['record']['dir'] = self.file_dir
+            station['relay']['mode'] = '1'
+            station['relay']['author'] = self.professor
+            self.deefuzzer_dict['deefuzzer']['station'][i] = station
+            i += 1        
         self.deefuzzer_xml = dicttoxml(self.deefuzzer_dict)
 
-    def write_deefuzzer_conf(self):
+    def deefuzzer_write_conf(self):
         conf_file = open(self.deefuzzer_user_file,'w')
         conf_file.write(self.deefuzzer_xml)
         conf_file.close()
 
-    def start_deefuzzer(self):
+    def deefuzzer_start(self):
         command = 'deefuzzer ' + self.deefuzzer_user_file + ' &'
         os.system(command)
         self.set_lock()
@@ -191,13 +174,14 @@ class Station(Conference):
     def del_lock(self):
         os.remove(self.lock_file)
 
-    def stop_deefuzzer(self):
-            os.system('kill -9 '+self.deefuzzer_pid[0])
+    def deefuzzer_stop(self):
+        os.system('kill -9 '+self.deefuzzer_pid[0])
 
-    def stop_rec(self):
+    def rec_stop(self):
         if len(self.deefuzzer_pid) != 0:
-            target = liblo.Address(self.deefuzzer_local_port)
-            liblo.send(target, "/record", 0)
+            for port in self.deefuzzer_osc_ports:
+                target = liblo.Address(port)
+                liblo.send(target, "/record", 0)
 
     def mp3_convert(self):
         os.system('oggdec -o - '+ self.file_dir+os.sep+self.filename+' | lame -S -m m -h -b '+ self.bitrate + \
@@ -239,53 +223,12 @@ class Station(Conference):
 
     def start(self):
         self.set_lock()
-        self.write_deefuzzer_conf()
-        self.start_deefuzzer()
-        #self.update_rss()
+        self.deefuzzer_setup()
+        self.deefuzzer_write_conf()
+        self.deefuzzer_start()
 
     def stop(self):
-        self.stop_rec()
-        time.sleep(2)
-        self.stop_deefuzzer()
-        #if self.format == 'ogg':
-        #    self.write_tags_ogg()
-        #elif self.format == 'mp3':
-        #    self.write_tags_mp3()
+        self.rec_stop()
+        time.sleep(1)
+        self.deefuzzer_stop()
         self.del_lock()
-        #self.mp3_convert()
-        #self.rsync_out()
-
-    def update_rss(self):
-        rss_item_list = []
-        if not os.path.exists(self.rss_dir):
-            os.makedirs(self.rss_dir)
-
-        time_now = datetime.datetime.now().strftime("%x-%X")
-
-        media_description = '<table>'
-        media_description_item = '<tr><td>%s:   </td><td><b>%s</b></td></tr>'
-        for key in self.dict.keys():
-            if self.dict[key] != '':
-                media_description += media_description_item % (key.capitalize(), self.dict[key])
-        media_description += '</table>'
-
-        media_link = self.url_ext + '/rss/' + self.rss_file
-        media_link = media_link.decode('utf-8')
-
-        rss_item_list.append(RSSItem(
-            title = self.ServerName,
-            link = media_link,
-            description = media_description,
-            guid = Guid(media_link),
-            pubDate = self.time_txt,)
-            )
-
-        rss = RSS2(title = self.title + ' - ' + self.department,
-                            link = self.url_ext,
-                            description = self.ServerDescription.decode('utf-8'),
-                            lastBuildDate = str(time_now),
-                            items = rss_item_list,)
-
-        #f = open(self.rss_dir + os.sep + self.rss_file, 'w')
-        #rss.write_xml(f, 'utf-8')
-        #f.close()
index 2485f2a9fec4711392a0aa42e47550962598f79a..20df966e2b5ad6c9566877aa690d4816c498cd11 100755 (executable)
@@ -35,7 +35,7 @@
 # Author: Guillaume Pellerin <yomguy@parisson.com>
 """
 
-version = '0.4.1'
+version = '0.4.2'
 
 
 import os
@@ -53,13 +53,14 @@ class TeleCaster:
     """Manage the calls of Station and Webview to get the network and
     disk streams"""
 
-    def __init__(self, conf_file, session_file):
+    def __init__(self, conf_file):
         """Main function"""
         self.conf_file = conf_file
-        self.session_file = session_file
         conf_dict = xml2dict(self.conf_file)
         self.conf = conf_dict['telecaster']
         self.title = self.conf['infos']['name']
+        self.log_file = self.conf['log']
+        self.logger = Logger(self.log_file)
         self.uid = os.getuid()
         self.url = self.conf['infos']['url']
         self.user = pwd.getpwuid(os.getuid())[0]
@@ -73,7 +74,7 @@ class TeleCaster:
         deefuzzer_pid = get_pid('/usr/bin/deefuzzer', self.uid)
         writing = edcast_pid != []
         casting = deefuzzer_pid != []
-        form = WebView(self.session_file, self.url, version)
+        form = WebView(self.conf, version)
 
         if deefuzzer_pid == [] and form.has_key("action") and \
             form.has_key("department") and form.has_key("conference") and \
@@ -89,29 +90,32 @@ class TeleCaster:
 
             s = Station(self.conf_file, self.conference_dict, self.lock_file)
             s.start()
-            time.sleep(1)
+            self.logger.write_info('starting')
+            time.sleep(2)
             self.main()
 
         elif deefuzzer_pid != [] and os.path.exists(self.lock_file) and not form.has_key("action"):
             self.conference_dict = get_conference_from_lock(self.lock_file)
             form.stop_form(self.conference_dict, writing, casting)
+            self.logger.write_info('page stop')
 
         elif deefuzzer_pid and form.has_key("action") and form["action"].value == "stop":
             if os.path.exists(self.lock_file):
                 self.conference_dict = get_conference_from_lock(self.lock_file)
             s = Station(self.conf_file, self.conference_dict, self.lock_file)
             s.stop()
+            self.logger.write_info('stopping')
             time.sleep(1)
             self.main()
 
         elif deefuzzer_pid == []:
             form.start_form(writing, casting)
+            self.logger.write_info('page start')
 
 
 conf_file = '/etc/telecaster/telecaster.xml'
-session_file = '/etc/telecaster/sessions.xml'
 
 if __name__ == '__main__':
-    t = TeleCaster(conf_file, session_file)
+    t = TeleCaster(conf_file)
     t.main()
 
index 8ce7f8b0e76c18332398262038bc2005fdf6ce8d..40a61991e6e19a102b4e5b1d44d58e08b09f8ca6 100644 (file)
@@ -3,5 +3,4 @@ from xmltodict import *
 from tools import *
 from acpi import *
 from PyRSS2Gen import *
-
-
+from logger import Logger
index 50349c1aef3af98663c970a1d688ce5d500efe1d..776bf977b4b3d194be493de305a880b02b54e6a6 100644 (file)
@@ -45,6 +45,27 @@ from xmltodict import *
 import socket
 import fcntl
 import struct
+import subprocess
+
+class SubProcessPipe:
+    def __init__(self, command, stdin=None):
+        """Read media and stream data through a generator.
+        Taken from Telemeta (see http://telemeta.org)"""
+
+        self.buffer_size = 0xFFFF
+
+        if not stdin:
+            stdin =  subprocess.PIPE
+
+        self.proc = subprocess.Popen(command.encode('utf-8'),
+                    shell = True,
+                    bufsize = self.buffer_size,
+                    stdin = stdin,
+                    stdout = subprocess.PIPE,
+                    close_fds = True)
+
+        self.input = self.proc.stdin
+        self.output = self.proc.stdout
 
 def get_ip_address(ifname):
     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@@ -77,16 +98,21 @@ def xml2dict(conf_file):
 
 def get_pid(proc,uid):
     """Get a process pid filtered by arguments and uid"""
-    (list1, list2) = os.popen4('pgrep -fl -U '+str(uid)+' '+'"'+proc+'"')
-    procs = list2.readlines()
+    command = 'pgrep -fl -U '+str(uid)+' '+'"'+proc+'"'
+    proc = SubProcessPipe(command)
+    list = proc.output
+    procs = list.readlines()
     pids = []
     if procs != '':
         for proc in procs:
             pid = proc.split(' ')[0]
             command = ' '.join(proc.split(' ')[1:])[:-1]
             pids.append(pid)
-    return pids
-
+    if len(pids) == 1:
+        return [] 
+    else:
+        return [pids[0]]
+        
 def get_params_from_lock(lock_file):
     lockfile = open(lock_file,'r')
     params = lockfile.readline()
index 04f1c08b872e0d7547659f048a6c8e76bba4e385..cce7e0dd9bb66633b2232686e329ac51ac5f76d0 100644 (file)
@@ -4,7 +4,7 @@
 """
    telecaster
 
-   Copyright (c) 2006-2008 Guillaume Pellerin <yomguy@parisson.org>
+   Copyright (c) 2006-2010 Guillaume Pellerin <yomguy@parisson.org>
 
 # This software is governed by the CeCILL  license under French law and
 # abiding by the rules of distribution of free software.  You can  use,
@@ -52,11 +52,10 @@ cgitb.enable()
 class WebView(FieldStorage):
     """Gives the web CGI frontend"""
 
-    def __init__(self, school_file, url, version):
+    def __init__(self, conf,  version):
         FieldStorage.__init__(self)
+        self.conf = conf
         self.version = version
-        self.conf = xml2dict(school_file)
-        self.conf = self.conf['telecaster']
         self.interfaces = ['eth0', 'eth1', 'eth2']
         ip = ''
         for interface in self.interfaces:
@@ -67,22 +66,20 @@ class WebView(FieldStorage):
                 break
             except:
                 self.ip = 'localhost'
-        if 'host' in self.conf:
-            self.host = self.conf['host']
+        if 'url' in self.conf['infos']:
+            self.url = 'http://' + self.conf['infos']['url']
         else:
-            self.host = self.ip
-        self.url = 'http://' + self.host
+            self.url = 'http://' + self.ip
         self.rss_url = self.url+'/rss/telecaster.xml'
-        self.port = self.conf['port']
+        self.port = '8000'
         self.acpi = acpi.Acpi()
-        self.format = self.conf['format']
-        self.title = self.conf['title']
+        self.format = self.conf['media']['format']
+        self.short_name = self.conf['infos']['short_name']
+        self.title = self.conf['infos']['name'] + ' - ' +  self.conf['infos']['description']
         self.departments = self.conf['department']
         self.professors = self.conf['professor']
         self.professors.sort()
         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
@@ -95,7 +92,7 @@ class WebView(FieldStorage):
 
     def header(self):
         # Required header that tells the browser how to render the HTML.
-        print "Content-Type: text/html\n\n"
+        print "Content-Type: text/html\n"
         print "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"
         print "<HTML>"
         print "<HEAD>"
@@ -173,16 +170,7 @@ class WebView(FieldStorage):
             power_info = "<span style=\"color: green\">secteur</span>"
         else:
             power_info = ""
-
-        #if self.power_state == 0:
-            #batt_info = "en d&eacute;charge"
-        #elif self.power_state == 1:
-            #batt_info = "charg&eacute;e"
-        #elif self.power_state == 2:
-            #batt_info = "en charge"
-        #else:
-            #batt_info = ""
-
+            
         if self.acpi.percent() == 127:
             batt_charge = '<span style=\"color: green\">100 &#37;</span>'
         else:
@@ -205,14 +193,14 @@ class WebView(FieldStorage):
         print "<div class=\"hardware\">"
         print "<div class=\"title\">Status</div>"
         print "<table class=\"hardware\">"
+        print "<tr><td>Name</td><TD> : </TD>"
+        print "<td>%s</td></tr>" % self.conf['infos']['url']
+        print "<tr><td>IP address</td><TD> : </TD>"
+        print "<td>%s</td></tr>" % ip_info
         print "<tr><td>Power</td><TD> : </TD>"
         print "<td>%s</td></tr>" % power_info
-        #print "<tr><td>Etat batterie :</td>"
-        #print "<td>%s</td></tr>" % batt_info
         print "<tr><td>Battery charge</td><TD> : </TD>"
         print "<td>%s</td></tr>" % batt_charge
-        #print "<tr><td>Estimation dur&eacute;e batterie :</td>"
-        #print "<td>%s</td></tr>" % self.acpi.estimated_lifetime()
         try:
             print "<tr><td>Temp core 1</td><TD> : </TD><td>%s</td></tr>" % self.acpi.temperature(0)
         except:
@@ -221,8 +209,6 @@ class WebView(FieldStorage):
             print "<tr><td>Temp core 2</td><TD> : </TD><td>%s</td></tr>" % self.acpi.temperature(1)
         except:
             pass
-        print "<tr><td>IP address</td><TD> : </TD>"
-        print "<td>%s</td></tr>" % ip_info
         print "<tr><td>JACK audio server</td><TD> : </TD>"
         print "<td>%s</td></tr>" % jackd_info
         print "<td><div class=\"buttons\">"
@@ -241,10 +227,11 @@ class WebView(FieldStorage):
 
 
     def start_form(self, writing, casting, message=''):
-        self.refresh = False
-        self.header()
         self.casting = writing
         self.writing = casting
+        self.refresh = False
+        
+        self.header()
         self.hardware_data()
         print "<form method=\"post\" action=\"telecaster.py\" name=\"formulaire\">"
         print "<div class=\"main\">"
@@ -270,49 +257,31 @@ class WebView(FieldStorage):
         print "<TD><INPUT type = text name = \"professor\"></TD></TR>"
         print "<TR><TH align=\"left\">Commentaire</TH><TD> : </TD>"
         print "<TD><INPUT type = text name = \"comment\"></TD></TR>"
-
-        #print "<TD><select name=\"comment\">"
-        #print "<option selected>...........Choisissez un commentaire...........</option>"
-        #for comment in self.comments:
-        #    print "<option value=\""+comment['text']+"\">"+comment['text']+"</option>"
-        #print "</select></TD></TR>"
-
         print "</table>"
         print "</div>"
-        #print "<h5><a href=\""+self.url+":"+self.port+"/augustins.pre-barreau.com_live."+self.format+".m3u\">Cliquez ici pour &eacute;couter le flux continu 24/24 en direct</a></h5>"
         print "<div class=\"tools\">"
         print "<div class=\"buttons\">"
-        #print "<INPUT TYPE = hidden NAME = \"action\" VALUE = \"start\">"
         print "<button type=\"submit\" class=\"positive\"><img src=\"img/arrow_refresh.png\" alt=\"\">Refresh</button>"
         print "<button type=\"submit\" name=\"action\" value=\"start\" class=\"negative\"><img src=\"img/stop.png\" alt=\"\">Record</button>"
-        print "<a href=\"http://"+self.ip+"/archives/\"><img src=\"img/folder_go.png\" alt=\"\">Archives</a>"
-        print "<a href=\"http://"+self.ip+"/trash/\"><img src=\"img/bin.png\" alt=\"\">Trash</a>"
-        #print "<INPUT TYPE = submit VALUE = \"Enregistrer\">"
+        print "<a href=\"http://"+self.url+"/archives/\"><img src=\"img/folder_go.png\" alt=\"\">Archives</a>"
+        print "<a href=\"http://"+self.url+"/trash/\"><img src=\"img/bin.png\" alt=\"\">Trash</a>"
         print "</div>"
         print "</div>"
         print "</form>"
         self.colophon()
         self.footer()
 
-    def encode_form(self, message=''):
-        self.header()
-        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>"
-        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.mount_point ='-'.join([clean_string(self.short_name),clean_string(department), clean_string(conference)])+'.'+self.format+'.m3u'
         self.writing = writing
         self.casting = casting
         self.refresh = True
+        
         self.header()
         self.hardware_data()
         print "<div class=\"main\">"
@@ -324,28 +293,15 @@ class WebView(FieldStorage):
         print "<TR><TH align=\"left\">Professeur</TH><TD> : </TD><TD>"+professor+"</TD></TR>"
         print "<TR><TH align=\"left\">Commentaire</TH><TD> : </TD><TD>"+comment+"</TD></TR>"
         print "</table>"
-        #print "<h5><a href=\""+self.url+":"+self.port+"/"+clean_string(self.title)+"_-_"+clean_string(department)+"_-_"+clean_string(conference)+"."+self.format+".m3u\">Cliquez ici pour &eacute;couter cette formation en direct</a></h5>"
         print "</div>"
-
-        #print """<div class="rss" id="chan">
-                #<b><div id="chan_description"></div></b><br>
-                #<div id="chan_title"></div>
-                #<div id="chan_link"></div>
-                #<div id="chan_description"></div>
-                #<a id="chan_image_link" href=""></a>
-                #<div id="chan_items"></div>
-                #<div id="chan_pubDate"></div>
-                #<div id="chan_copyright"></div>
-            #</div>"""
-
         print "<div class=\"tools\">"
         print "<form method=\"post\" action=\"telecaster.py\">"
         print "<div class=\"buttons\">"
         print "<button type=\"submit\"><img src=\"img/arrow_refresh.png\" alt=\"\">Refresh</button>"
-        print "<a href=\"http://"+self.ip+":"+self.port+"/"+clean_string(self.title)+"_-_"+clean_string(department)+"_-_"+clean_string(conference)+"."+self.format+".m3u\"><img src=\"img/control_play_blue.png\" alt=\"\">Play</a>"
+        print "<a href=\"http://"+self.url+":"+self.port+"/"+self.mount_point+"\"><img src=\"img/control_play_blue.png\" alt=\"\">Play</a>"
         print "<button type=\"submit\" name=\"action\" value=\"stop\" class=\"negative\"><img src=\"img/cancel.png\" alt=\"\">Stop</button>"
-        print "<a href=\"http://"+self.ip+"/archives/\"><img src=\"img/folder_go.png\" alt=\"\">Archives</a>"
-        print "<a href=\"http://"+self.ip+"/trash/\"><img src=\"img/bin.png\" alt=\"\">Trash</a>"
+        print "<a href=\"http://"+self.url+"/archives/\"><img src=\"img/folder_go.png\" alt=\"\">Archives</a>"
+        print "<a href=\"http://"+self.url+"/trash/\"><img src=\"img/bin.png\" alt=\"\">Trash</a>"
         print "</div>"
         print "</form>"
         print "</div>"