refresh();
setInterval(refresh,d);
};
+
+function station_status(){
+ var j = json; //global variable
+ var data = j({},"telecaster.station_status",
+ function(data){
+ var res = data.result;
+ return res;
+ },
+ function(){
+ return false;
+ }
+ );
+};
+
+
+
+var playlistUtils = {
+ playlists : [],
+
+ /**
+ * Returns an uniqid by creating the current local time in millisecond + a random number. Used for markers and some json calls
+ * Copied from Timeside.utils.uniqid (Timeside might NOT ALWAYS be loaded, see home.html when user is authenitcated)
+ **/
+
+ uniqid : function() {
+ var d = new Date();
+ return new String(d.getTime() + '' + Math.floor(Math.random() * 1000000)).substr(0, 18);
+ },
+
+ start : function(dictionary){
+
+ if(dictionary.public_id===undefined){
+ dictionary.public_id = this.uniqid(); //defined in application.js
+ }
+ json([dictionary],'telemeta.start',function(){
+ station_status();
+ });
+ },
+
+ showForm: function(anchorElement, id){
+
+ var o = 'organization';
+ var d = 'department';
+ var d = 'department';
+
+ var dd = {};
+ var playlist = this;
+
+ var playlists = this.playlists;
+ for (var i=0; i< playlists.length; i++){
+ if (playlists[i].id == id){
+ dd[t] = playlists[i].title;
+ dd[d] = playlists[i].description;
+ }
+ }
+
+ new PopupDiv({
+ 'content':dd,
+ invoker:anchorElement,
+ showOk:true,
+ onOk:function(data){
+ if(!data[t] && !data[d]){
+ return;
+ }
+ //convert language
+ playlist.update({
+ 'public_id': id,
+ 'title': data[t],
+ 'description': data[d],
+ });
+ }
+ }).show();
+ },
+
+}
+
+
+
class Station(Model):
- organization = ForeignKey(Organization, related_name='stations', verbose_name='organization',
- null=True, on_delete=models.SET_NULL)
- department = ForeignKey(Department, related_name='stations', verbose_name='department',
- null=True, on_delete=models.SET_NULL)
- conference = ForeignKey(Conference, related_name='stations', verbose_name='conference',
- null=True, on_delete=models.SET_NULL)
- session = ForeignKey(Session, related_name='stations', verbose_name='session',
- null=True, blank=True, on_delete=models.SET_NULL)
- professor = ForeignKey(Professor, related_name='stations', verbose_name='professor',
- null=True, blank=True, on_delete=models.SET_NULL)
- professor_free = CharField(_('professor'), max_length=255, blank=True)
+ public_id = CharField(_('public_id'), max_length=255, required=True)
+ organization = CharField(_('organization'), max_length=255, blank=True)
+ department = CharField(_('department'), max_length=255, blank=True)
+ conference = CharField(_('conference'), max_length=255, blank=True)
+ session = CharField(_('session'), max_length=255, blank=True)
+ professor = CharField(_('professor'), max_length=255, blank=True)
comment = ShortTextField(_('comments'), blank=True)
started = BooleanField(_('started'))
datetime_start = DateTimeField(_('time_start'), blank=True, null=True)
datetime_stop = DateTimeField(_('time_stop'), blank=True, null=True)
+
class Meta:
db_table = app_label + '_' + 'station'
return ' - '.join(self.description) + ' - ' + str(self.datetime_start) + ' > ' + str(self.datetime_stop)
def to_dict(self):
- dict = [ {'id':'organization','value': self.organization.name, 'class':'', 'label':'Organization'},
- {'id': 'department', 'value': self.department.name , 'class':'', 'label':'Departement'},
- {'id' : 'conference', 'value': self.conference.title, 'class':'' , 'label': 'Conference'},
- {'id': 'professor', 'value': self.professor.name, 'class':'' , 'label': 'Professor'},
- {'id': 'session', 'value': self.session.name, 'class':'' , 'label': 'Session'},
+ dict = [{'id':'public_id','value': self.public_id, 'class':'', 'label':'public_id'},
+ {'id':'organization','value': self.organization, 'class':'', 'label':'Organization'},
+ {'id': 'department', 'value': self.department , 'class':'', 'label':'Departement'},
+ {'id' : 'conference', 'value': self.conference, 'class':'' , 'label': 'Conference'},
+ {'id': 'professor', 'value': self.professor, 'class':'' , 'label': 'Professor'},
+ {'id': 'session', 'value': self.session, 'class':'' , 'label': 'Session'},
{'id': 'comment', 'value': self.comment, 'class':'' , 'label': 'Comment'},
{'id': 'started', 'value': str(self.started), 'class':'' , 'label': 'Started'},
]
@property
def description(self):
- description = [self.organization.name, self.conference.department.name, self.conference.title]
+ description = [self.organization, self.conference.department, self.conference]
if self.session:
- description.append(self.session.name)
+ description.append(self.session)
if self.professor:
- description.append(self.professor.name)
+ description.append(self.professor)
description.append(self.comment)
return description
self.ogg_quality = self.conf['media']['ogg_quality']
self.format = self.conf['media']['format']
self.channels = int(self.conf['media']['channels'])
- self.server_name = [self.organization.name, self.conference.department.name, self.conference.title]
+ self.server_name = [self.organization, self.department, self.conference]
self.ServerDescription = clean_string('-'.join(self.description))
self.ServerName = clean_string('_-_'.join(self.server_name))
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.conference.department.name
+ self.output_dir = self.rec_dir + os.sep + self.date + os.sep + self.department
self.file_dir = self.output_dir + os.sep + self.ServerName
self.uid = os.getuid()
self.deefuzzer_pid = get_pid('/usr/bin/deefuzzer '+self.deefuzzer_user_file, self.uid)
# self.deefuzzer_setup()
# self.deefuzzer_write_conf()
# self.deefuzzer_start()
+ self.save()
def stop(self):
self.started = False
# self.rec_stop()
# time.sleep(2)
# self.deefuzzer_stop()
+ self.save()
+
+ def configure(self, dict):
+ self.organization = dict['organization']
+ self.department = dict['department']
+ self.session = dict['session']
+ self.professor = dict['professor']
+ self.comment = dict['comment']
+ self.save()
class Record(Model):
--- /dev/null
+<!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="{% url telecaster-css "telecaster.css" %}" rel="stylesheet" type="text/css">
+<link href="{% url telecaster-video-js "video-js.css" %}" rel="stylesheet" type="text/css">
+
+{% block javascript %}
+<script src="{% url telecaster-js "jquery-1.6.min.js" %}" type="text/javascript"></script>
+<script src="{% url telecaster-js "application.js" %}" type="text/javascript"></script>
+<script src="{% url telecaster-video-js "video.js" %}" type="text/javascript"></script>
+{% endblock javascript %}
+
+<script type="text/javascript">
+{% block extrajavascript %}
+
+
+_V_("video_1").ready(function(){
+ var myPlayer = this;
+ myPlayer.volume(0);
+ // myPlayer.currentTime(120);
+ });
+
+
+jQuery(window).ready(function(){
+ var a = jQuery('#_record');
+ var f = jQuery('#_StationForm');
+ a.unbind('click').click(function(){f.submit();return false;});
+ });
+
+jQuery(window).ready(function(){
+ var a = jQuery('#_stop');
+ var f = jQuery('#_StationForm');
+ a.unbind('click').click(function(){f.submit();return false;});
+ });
+
+server_status_callback();
+
+{% endblock extrajavascript %}
+</script>
+
+</head>
+<body>
+<div class="bg">
+
+<div class="header">
+<img src="{% url telecaster-images "logo_telecaster_wh.png"%}" alt="logo_telecaster">
+<div class="title_main"> TeleCaster</div>
+</div>
+
+{% block hardware %}
+<div class="hardware">
+<div class="title">Status</div>
+
+{% block video %}
+<div class="video">
+<video id="video_1" class="video-js vjs-default-skin" controls autoplay preload="auto" width="360" height="240" data-setup="{}">
+<source src="http://{{ host }}:8080/consume/safe" type="video/webm">
+</video>
+</div>
+{% endblock video %}
+
+<div id="server_status_table_wrapper" class="status">
+</div>
+
+</div>
+</div>
+{% endblock hardware %}
+
+{% block message %}
+{% if messages %}
+<ul class="messages">
+ {% for message in messages %}
+ <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
+ {% endfor %}
+</ul>
+{% endif %}
+{% endblock message %}
+
+{% block content %}
+<div id="main" class="main">
+
+<form enctype="multipart/form-data" id="_StationForm" method="post" action="" name="formulaire">{% csrf_token %}
+<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 station %}
+ <tr>
+ {% if field.errors %}<tr><td class="warning">{{ field.errors }}</td></tr>{% endif %}
+ {% if not field.html_name in hidden_fields %}
+ <td>{% trans field.label_tag %}:</td><td>{{ field }}</td>
+ {% else %}
+ <td>{{ field.label_tag.as_hidden }}</td><td>{{ field.as_hidden }}</td>
+ {% endif %}
+ </tr>
+ {% endfor %}
+</table>
+</form>
+
+</div>
+{% endblock content %}
+
+{% block buttons %}
+<div id="tools" class="tools">
+ <a class="component_icon button icon_record" href="#" id="_record">Record</a>
+ <a class="component_icon button icon_play" href="http://{{ status.ip }}:{{ station.port }}/{{ station.mount_point }}">Play Live</a>
+ <a class="component_icon button icon_archives" href="/archives/">Archives</a>
+ <a class="component_icon button icon_trash" href="/trash/">Trash</a>
+</div>
+{% endblock buttons %}
+
+<div class="colophon">TeleCaster 0.6 © <span>2011</span> <a href="http://parisson.com">Parisson SARL</a>. {% trans "All rights reserved" %}</div>
+
+</div>
+
+</body>
+</html>
+
# initialization
-web_view = WebView(settings.TELECASTER_CONF)
+web_view = WebView()
htdocs = os.path.dirname(__file__) + '/htdocs'
urlpatterns = patterns('',
url(r'^$', web_view.index, name="telecaster-index"),
- url(r'^record/$', web_view.record, name="telecaster-record"),
url(r'^items/(?P<id>.*)$', web_view.index, name="telecaster-item"),
# CSS+Images (FIXME: for developement only)
class WebView(object):
- hidden_fields = ['started', 'datetime_start', 'datetime_stop']
+ hidden_fields = ['started', 'datetime_start', 'datetime_stop', 'public_id']
def __init__(self, conf_file):
self.uid = os.getuid()
self.user_dir = '/home' + os.sep + self.user + os.sep + '.telecaster'
if not os.path.exists(self.user_dir):
os.makedirs(self.user_dir)
- self.conf_file = conf_file
+ self.conf_file = settings.TELECASTER_CONF
conf_dict = xml2dict(self.conf_file)
self.conf = conf_dict['telecaster']
self.title = self.conf['infos']['name']
self.url = self.conf['infos']['url']
self.status = Status()
- def index(self, request, id=None):
+ def index(self, request):
+ template = 'telecaster/index.html'
stations = Station.objects.filter(started=True)
if stations:
- # FIXME: manage multiple stations
- template = 'telecaster/stop.html'
- if id:
- station = Station.objects.get(id=id)
- else:
- station = stations[0]
- if request.method == 'POST':
- station.stop()
-# time.sleep(2)
- station.save()
- self.logger.write_info('stop')
- return HttpResponseRedirect('/telecaster/record')
- else:
- return render(request, template, {'station': station, 'hidden_fields': self.hidden_fields, 'host': self.get_host(request) })
- else:
- return HttpResponseRedirect('/telecaster/record')
-
-
- def record(self, request):
- template = 'telecaster/start.html'
- if request.method == 'POST':
- station = Station()
- form = StationForm(data=request.POST, instance=station)
- if form.is_valid():
- station.set_conf(self.conf)
- station.setup()
- station.start()
- station.save()
- self.logger.write_info('start')
-# time.sleep(2)
- return HttpResponseRedirect('/telecaster/')
- else:
- form = StationForm()
+ messages.warning(request, 'A station is already started !')
+ form = StationForm()
+ return render(request, template, {'station': form, 'hidden_fields': self.hidden_fields,
+ 'host': self.get_host(request) })
- return render(request, template, {'station': form, 'hidden_fields': self.hidden_fields, 'host': self.get_host(request) })
def get_host(self, request):
host = request.META['HTTP_HOST']
status.update()
return status.to_dict()
- def get_server_status(self):
- self.status.update()
- return self.status
-
@jsonrpc_method('telecaster.get_station_status')
def get_station_status(request):
stations = Station.objects.filter(started=True)
else:
station = {}
return station
+
+ @jsonrpc_method('telecaster.start')
+ def start(request, station_dict):
+ if isinstance(station_dict, dict):
+ station = Station(public_id=dict['public_id'])
+ station.configure(station_dict)
+ conf = xml2dict(settings.TELECASTER_CONF)
+ conf = conf['telecaster']
+ station.set_conf(conf)
+ station.setup()
+ station.start()
+ else:
+ messages.error(request, 'Bad station dictionary')
+
+ @jsonrpc_method('telecaster.stop')
+ def stop(request):
+ stations = Station.objects.filter(started=True)
+ for station in stations:
+ station.stop()
+