def __init__(self, *args, **kwds):
super(StationForm, self).__init__(*args, **kwds)
self.fields['organization'].queryset = Organization.objects.order_by('name')
- self.fields['department'].queryset = Department.objects.order_by('name')
self.fields['conference'].queryset = Conference.objects.order_by('title')
self.fields['session'].queryset = Session.objects.order_by('name')
self.fields['professor'].queryset = Professor.objects.order_by('name')
self.date = datetime.datetime.now().strftime("%Y")
self.time = datetime.datetime.now().strftime("%x-%X")
self.time_txt = self.time.replace('/','_').replace(':','_').replace(' ','_')
- self.conf = conf
-
- self.conf = self.conf['telecaster']
self.user = pwd.getpwuid(os.getuid())[0]
self.user_dir = '/home' + os.sep + self.user + os.sep + '.telecaster'
self.rec_dir = self.conf['media']['rec_dir']
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'
self.record = str_to_bool(self.conf['media']['record'])
self.rec_dir = self.conf['media']['rec_dir']
self.play_dir = self.conf['media']['play_dir']
self.ogg_quality = self.conf['media']['ogg_quality']
self.format = self.conf['media']['format']
self.channels = int(self.conf['media']['channels'])
- self.description = [self.title, self.department, self.conference, self.session, self.professor, self.comment]
- self.server_name = [self.title, self.department, self.conference]
+ self.description = [self.organization.name, self.conference.department.name, self.conference.title, self.session.name, self.professor.name, self.comment]
+ self.server_name = [self.organization.name, self.conference.department.name, self.conference.title]
self.ServerDescription = clean_string('-'.join(self.description))
self.ServerName = clean_string('_-_'.join(self.server_name))
- self.mount_point = self.ServerName
+ self.mount_point = self.ServerName + '.' + self.format
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.output_dir = self.rec_dir + os.sep + self.date + os.sep + self.conference.department.name
self.file_dir = self.output_dir + os.sep + self.ServerName
self.uid = os.getuid()
- self.odd_pid = get_pid('^edcast_jack', self.uid)
self.deefuzzer_pid = get_pid('/usr/bin/deefuzzer '+self.deefuzzer_user_file, 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.new_title = clean_string('-'.join(self.server_name)+'-'+self.session.name+'-'+self.professor.name+'-'+self.comment)
+ self.short_title = clean_string('-'.join(self.conference.title)+'-'+self.session.name+'-'+self.professor.name+'-'+self.comment)
self.genre = self.conf['infos']['genre']
self.encoder = 'TeleCaster by Parisson'
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+ \
+ ' --add-id3v2 --tt "'+ self.new_title + '" --ta "'+self.professor+'" --tl "'+self.organization+'" --ty "'+self.date+ \
'" --tg "'+self.genre+'" - ' + self.file_dir+os.sep+self.ServerDescription + '.mp3 &')
def write_tags_ogg(self):
audio = OggVorbis(file)
audio['TITLE'] = self.new_title.decode('utf8')
audio['ARTIST'] = self.professor.decode('utf8')
- audio['ALBUM'] = self.title.decode('utf8')
+ audio['ALBUM'] = self.organization.decode('utf8')
audio['DATE'] = self.date.decode('utf8')
audio['GENRE'] = self.genre.decode('utf8')
- audio['SOURCE'] = self.title.decode('utf8')
+ audio['SOURCE'] = self.organization.decode('utf8')
audio['ENCODER'] = self.encoder.decode('utf8')
audio['COMMENT'] = self.comment.decode('utf8')
audio.save()
#tag = tags.__dict__['ARTIST']
audio.add(TP1(encoding=3, text=self.professor.decode('utf8')))
#tag = tags.__dict__['ALBUM']
- audio.add(TAL(encoding=3, text=self.title.decode('utf8')))
+ audio.add(TAL(encoding=3, text=self.organization.decode('utf8')))
#tag = tags.__dict__['DATE']
audio.add(TDRC(encoding=3, text=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
#tag = tags.__dict__['GENRE']
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+{% load telecaster_utils %}
+{% load i18n %}
+
<HTML>
<HEAD>
<TITLE>TeleCaster - {{ self.title }}</TITLE>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
-<link href="/telecaster/css/telecaster.css" rel="stylesheet" type="text/css">
+<link href="{% url telecaster-css "telecaster.css" %}" rel="stylesheet" type="text/css">
{% block javascript %}
-<script language="Javascript" type="text/javascript" >
-function choix(formulaire)
-{var j; var i = formulaire.department.selectedIndex;
-if (i == 0)
-for(j = 1; j < {{ departments|len ; j++)
- formulaire.conference.options[j].text="";
-else{
-switch (i){
- case '+str(k+1)+' : var text = new Array({{ conferences }});
- break;
-}
-for(j = 0; j<'+str(self.conference_nb_max)+'; j++)
-formulaire.conference.options[j+1].text=text[j];
-}
-formulaire.conference.selectedIndex=0;}
-</script>
{% endblock javascript %}
</HEAD>
<BODY>
<div class="bg">
-<div class="header">"
-<img src="img/logo_telecaster_wh.png" alt="logo_telecaster">
+<div class="header">
+<img src="{% url telecaster-images "logo_telecaster_wh.png"%}" alt="logo_telecaster">
<div class="title_main"> TeleCaster - Audio Web Live Recording</div>
</div>
{% block hardware %}
-{% if acpi.power_state == 0 %}
-
-
<div class="hardware">
<div class="title">Status</div>
<table class="hardware">
<td><span style="{% if status.ip == 'localhost' %}color: red; font-weight: bold;{% else %}color: green;{% endif %}">{{ status.ip }}</span></td>
</tr>
<tr><td>Power</td><TD> : </TD>
-<td><span style="{% if status.power_state == 0 %}color: red; font-weight: bold;{% else %}color: green;{% endif %}">{{ status.power }}</span></td>
+<td><span style="{% if status.power_state == 0 %}color: red; font-weight: bold;{% else %}color: green;{% endif %}">{{ status.acpi_state }}</span></td>
</tr>
<tr><td>Battery charge</td><TD> : </TD>
-<td><span style="{% if status.batt_charge == 0 %}color: red; font-weight: bold;{% else %}color: green;{% endif %}">{{ status.batt_charge }}</span></td>
+<td><span style="{% if status.batt_charge == 0 %}color: red; font-weight: bold;{% else %}color: green;{% endif %}">{{ status.acpi_percent }}</span></td>
</tr>
<tr><td>Temp core 1</td><TD> : </TD><td>{{ status.temperature }} </td></tr>
<tr><td>JACK audio server</td><TD> : </TD>
</table>
</div>
</div>
+{% endblock hardware %}
{% block content %}
{% endblock content %}
{% block footer %}
-<div class=\"colophon\">TeleCaster "+self.version+" © <span>{% year %}</span> <a href=\"http://parisson.com\">Parisson SARL</a>. Tous droits réservés.
+<div class="tools">
+ <div class="buttons">
+ <button type="submit" class="positive"><img src="{% url telecaster-images "arrow_refresh.png" %}" alt="">Refresh</button>
+ <button type="submit" name="action" value="start" class="negative"><img src="{% url telecaster-images "stop.png" %}" alt="">Record</button>
+ <a href="http://{{ status.ip }}:{{ station.port }}/{{ station.mount_point }}"><img src="{% url telecaster-images "control_play_blue.png" %}" alt="">Play Live</a>
+ <a href="/archives/"><img src="{% url telecaster-images "folder_go.png" %}" alt="">Archives</a>
+ <a href="/trash/"><img src="{% url telecaster-images "bin.png" %}" alt="">Trash</a>
+ </div>
</div>
+<div class="colophon">TeleCaster 0.6 © <span>2011</span> <a href="http://parisson.com">Parisson SARL</a>. {% trans "All rights reserved" %}</div>
+{% endblock footer %}
+
</div>
</BODY>
</HTML>
+
-{% extends "/telecaster/base.html" %}
+{% extends "telecaster/base.html" %}
{% block content %}
<table class="form">
<tr><td colspan="2">{% for error in form.non_field_errors %}<li class="error">{{ error }}</li>{% endfor %}</td></tr>
- {% for field in form %}
+ {% for field in station %}
<tr>
<tr><td class="error">{{ field.errors }}</td></tr>
<td>{{ field.label_tag }}:</td>
{% endfor %}
</table>
-<div class="tools">
- <div class="buttons">
- <button type="submit" class="positive"><img src="img/arrow_refresh.png" alt="">Refresh</button>
- <button type="submit" name="action" value="start" class="negative"><img src="img/stop.png" alt="">Record</button>
- <a href="http://"+self.ip+":"+self.port+"/"+self.mount_point+""><img src="img/control_play_blue.png" alt="">Play Live</a>
- <a href="/archives/"><img src="img/folder_go.png" alt="">Archives</a>
- <a href="/trash/"><img src="img/bin.png" alt="">Trash</a>
- </div>
-</div>
</div>
</form>
-{% extends "/telecaster/base.html" %}
+{% extends "telecaster/base.html" %}
{% block content %}
<TR><TH align="left">Commentaire</TH><TD> : </TD><TD>{{ station.comment }}</TD></TR>
</table>
</div>
-<div class="tools">
-<div class="buttons">
-<button type="submit"><img src="img/arrow_refresh.png" alt="">Refresh</button>
-<a href="http://"+self.ip+":"+self.port+"/"+self.mount_point+""><img src="img/control_play_blue.png" alt="">Play</a>
-<button type="submit" name="action" value="stop" class="negative"><img src="img/cancel.png" alt="">Stop</button>
-<a href="/archives/"><img src="img/folder_go.png" alt="">Archives</a>
-<a href="/trash/"><img src="img/bin.png" alt="">Trash</a>
-</div>
-</div>
+
</form>
{% endblock content %}
--- /dev/null
+from django import template
+from django.utils.http import urlquote
+from telecaster import models
+from django.core.urlresolvers import reverse
+from django.utils import html
+from django import template
+from django.utils.text import capfirst
+from django.utils.translation import ungettext
+#from docutils.core import publish_parts
+from django.utils.encoding import smart_str, force_unicode
+from django.utils.safestring import mark_safe
+from django import db
+from django.conf import settings
+
+import re
+import datetime
+
+register = template.Library()
+
+@register.filter
+def len(list):
+ return len(list)
htdocs = os.path.dirname(__file__) + '/htdocs'
urlpatterns = patterns('',
- url(r'^', web_view.index, name="telecaster-index"),
+ url(r'^$', web_view.index, name="telecaster-index"),
# CSS+Images (FIXME: for developement only)
url(r'^css/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': htdocs+'/css'},
- name="telemeta-css"),
+ name="telecaster-css"),
url(r'images/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': htdocs+'/images'},
- name="telemeta-images"),
+ name="telecaster-images"),
url(r'^js/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': htdocs+'/js'},
- name="telemeta-js"),
+ name="telecaster-js"),
# JSON RPC
url(r'^json/$', jsonrpc_site.dispatch, name='jsonrpc_mountpoint'),
from models import *
from forms import*
+from jsonrpc import jsonrpc_method
+
+from django.utils.decorators import method_decorator
+from django.contrib.auth import authenticate, login
+from django.template import RequestContext, loader
+from django import template
+from django.http import HttpResponse, HttpResponseRedirect
+from django.http import Http404
+from django.shortcuts import render_to_response, redirect
+from django.views.generic import list_detail
+from django.conf import settings
+from django.contrib import auth
+from django.contrib import messages
+from django.contrib.auth.decorators import login_required, permission_required
+from django.core.context_processors import csrf
+from django.forms.models import modelformset_factory, inlineformset_factory
+from django.contrib.auth.models import User
+from django.utils.translation import ugettext
+from django.contrib.auth.forms import UserChangeForm
+from django.core.exceptions import ObjectDoesNotExist
+
def render(request, template, data = None, mimetype = None):
return render_to_response(template, data, context_instance=RequestContext(request),
def index(self, request):
self.get_ids()
stations = Station.objects.filter(started=True)
+ status = self.get_status()
- if stations and (self.writing or self.casting):
+ if stations or (self.writing or self.casting):
template = 'telecaster/stop.html'
# FIXME: manage multiple stations
station = stations[0]
+ station.set_conf(self.conf)
+ station.setup()
if request.method == 'POST':
- station.set_conf(self.conf)
- station.setup()
station.stop()
time.sleep(2)
self.logger.write_info('stop')
else:
station = StationForm()
- return render(request, template, {'station': station})
+ return render(request, template, {'station': station, 'status': status})
def get_hosts(self):
ip = ''
def get_ids(self):
edcast_pid = get_pid('edcast_jack', self.uid)
deefuzzer_pid = get_pid('/usr/bin/deefuzzer '+self.user_dir+os.sep+'deefuzzer.xml', self.uid)
+ jackd_pid = get_pid('jackd', self.uid)
+ if jackd_pid == []:
+ jackd_pid = get_pid('jackdbus', self.uid)
self.writing = edcast_pid != []
self.casting = deefuzzer_pid != []
+ self.jacking = jackd_pid != []
+ @jsonrpc_method('telecaster.get_status')
def get_status(self):
self.get_hosts()
self.get_ids()
self.acpi.update()
status = {}
- status['acpi_state'] = acpi_states[self.acpi.charging_state()]
- status['acpi_percent'] = self.acpi.percent()
- status['acpi_temperature'] = self.acpi.temperature(0)
- status['jack_state'] = jackd_pid != []
+ status['acpi_state'] = self.acpi_states[self.acpi.charging_state()]
+ status['acpi_percent'] = str(self.acpi.percent())
+ #status['acpi_temperature'] = self.acpi.temperature(0)
+ status['jack_state'] = self.jacking
status['url'] = self.url
status['ip'] = self.ip
status['url'] = self.url