# HG changeset patch # User ymh # Date 1413715958 -7200 # Node ID 926f0426ce7856b5140bb1fa360b90f769930da5 # Parent 69a7e0b101de57ac304b738dbbc5e0b822bbe596 add event + event session + admin + category json management. Must rebuild database diff -r 69a7e0b101de -r 926f0426ce78 annot-server/models.py --- a/annot-server/models.py Fri Oct 17 17:54:06 2014 +0200 +++ b/annot-server/models.py Sun Oct 19 12:52:38 2014 +0200 @@ -8,38 +8,28 @@ import json import uuid -from sqlalchemy import Column, Integer, String, DateTime, Table, Index, text +from sqlalchemy import Column, Integer, String, DateTime, Text, Table, Index, text, ForeignKey +from sqlalchemy.orm import relationship, backref from sqlalchemy.sql import func from sqlalchemy.dialects.postgresql import UUID, JSON from database import Base, engine -#def get_table_create_stmt(): -# return ( -# "CREATE TABLE IF NOT EXISTS annotations ( " -# "id serial PRIMARY KEY, " -# "uuid uuid UNIQUE, " -# "created timestamp default (now() at time zone 'utc') NOT NULL, " -# "ts timestamptz NOT NULL, " -# "event varchar(255) NOT NULL, " -# "channel varchar(255) NOT NULL, " -# "content json);" -# ) class Annotation(Base): - __tablename__ = 'annotations' + __tablename__ = 'annotation' id = Column(Integer, primary_key=True, nullable=False) uuid = Column(UUID, unique=True, nullable=False) created = Column(DateTime, nullable=False, server_default=text("(now() at time zone 'utc')") ) ts = Column(DateTime(timezone=True), nullable=False) - event = Column(String(255), nullable=False) + event_code = Column(String(255), ForeignKey('event.code'), nullable=False) channel = Column(String(255), nullable=False) content = Column(JSON) -Index('idx_event', Annotation.event) -Index('idx_channel', Annotation.channel) -Index('idx_ts', Annotation.ts) +Index('idx_annotation_event', Annotation.event_code) +Index('idx_annotation_channel', Annotation.channel) +Index('idx_annotation_ts', Annotation.ts) def insert_annot_async(params, conn): @@ -59,3 +49,31 @@ defer.addCallback(lambda _: stmt.params) return defer + + +class Event(Base): + __tablename__ = 'event' + + id = Column(Integer, primary_key=True, nullable=False) + code = Column(String(255), unique=True, nullable=False) + label = Column(String(2048), nullable=False) + description = Column(Text(), nullable=True) + + sessions = relationship("EventSession", order_by="EventSession.order", backref="event") + + def __unicode__(self): + return self.code + +Index('idx_event_code', Event.code) + +class EventSession(Base): + __tablename__ = 'event_session' + + id = Column(Integer, primary_key=True, nullable=False) + event_id = Column(Integer, ForeignKey(Event.id), nullable=False) + project_id = Column(String(2048), nullable=True) + order = Column(Integer, nullable=False, default=0) + categories_json = Column(JSON, nullable=True) + + +Index('idx_event_session_order', EventSession.order) diff -r 69a7e0b101de -r 926f0426ce78 annot-server/oscserver.py --- a/annot-server/oscserver.py Fri Oct 17 17:54:06 2014 +0200 +++ b/annot-server/oscserver.py Sun Oct 19 12:52:38 2014 +0200 @@ -37,7 +37,7 @@ params = { 'ts' : ts, - 'event': getAddressParts(message.address)[1], + 'event_code': getAddressParts(message.address)[1], 'channel' : utils.PIANOROLL_CHANNEL, 'content' : values } diff -r 69a7e0b101de -r 926f0426ce78 annot-server/settings.py.tmpl --- a/annot-server/settings.py.tmpl Fri Oct 17 17:54:06 2014 +0200 +++ b/annot-server/settings.py.tmpl Sun Oct 19 12:52:38 2014 +0200 @@ -8,5 +8,4 @@ STATIC_URL = '/static' STATIC_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)),'static') - -from settings import * +LDT_PLATFORM_BASE_URL = 'http://ldt.iri.centrepompidou.fr/ldtplatform' diff -r 69a7e0b101de -r 926f0426ce78 annot-server/webapp/__init__.py --- a/annot-server/webapp/__init__.py Fri Oct 17 17:54:06 2014 +0200 +++ b/annot-server/webapp/__init__.py Sun Oct 19 12:52:38 2014 +0200 @@ -18,3 +18,4 @@ import webapp.views import webapp.api +import webapp.admin diff -r 69a7e0b101de -r 926f0426ce78 annot-server/webapp/templates/pianoroll.html --- a/annot-server/webapp/templates/pianoroll.html Fri Oct 17 17:54:06 2014 +0200 +++ b/annot-server/webapp/templates/pianoroll.html Sun Oct 19 12:52:38 2014 +0200 @@ -21,7 +21,7 @@

stop intervals - temps écoulé :


-    
-    
+    
+    
 
-
\ No newline at end of file
+
diff -r 69a7e0b101de -r 926f0426ce78 annot-server/webapp/views.py
--- a/annot-server/webapp/views.py	Fri Oct 17 17:54:06 2014 +0200
+++ b/annot-server/webapp/views.py	Sun Oct 19 12:52:38 2014 +0200
@@ -3,9 +3,15 @@
 # Copyright (c) 2014 IRI
 #
 
-from flask import render_template, jsonify, request
+import json
+
+from flask import render_template, jsonify, request, abort
+from jinja2 import Markup
+from sqlalchemy.orm import joinedload
 
 from webapp import app
+from database import db_session
+import models
 
 @app.route('/')
 def page_home():
@@ -22,6 +28,32 @@
 def page_annotationclient():
     return render_template('annotationclient.html', logging=True)
 
+@app.route('/annotationclient/')
+def page_annotationclient_event_code(event_code):
+    #TODO: check event code + get event session
+    event_query = db_session.query(models.Event).filter(models.Event.code==event_code)
+    event = event_query.one()
+    if not event:
+        abort(404)
+
+    #TODO: See why the relationship management does not work
+    event_session_q = db_session.query(models.EventSession).filter(models.EventSession.event_id==event.id).order_by(models.EventSession.order.desc())
+    event_session = event_session_q.first()
+
+    categories_json = None
+
+    if event_session:
+        categories_json = event_session.categories_json
+
+    if not categories_json:
+        categories_json = None
+
+    return render_template('annotationclient.html',
+        logging = True,
+        event_code = event_code,
+        categories_json = Markup(json.dumps(categories_json).replace('\'','\\\'')) if categories_json else None
+    )
+
 
 @app.route('/pianoroll')
 def page_pianoroll():
diff -r 69a7e0b101de -r 926f0426ce78 annot-server/websockets.py
--- a/annot-server/websockets.py	Fri Oct 17 17:54:06 2014 +0200
+++ b/annot-server/websockets.py	Sun Oct 19 12:52:38 2014 +0200
@@ -87,7 +87,7 @@
         params_annot = json.loads(msg)
 
         params = {
-            'event': self.event,
+            'event_code': self.event,
             'channel' : utils.ANNOTATION_CHANNEL,
             'content' : params_annot
         }
diff -r 69a7e0b101de -r 926f0426ce78 client/app/annotationclient.html
--- a/client/app/annotationclient.html	Fri Oct 17 17:54:06 2014 +0200
+++ b/client/app/annotationclient.html	Sun Oct 19 12:52:38 2014 +0200
@@ -95,7 +95,9 @@
             {% if logging %}logging: true,{% endif %}
             urls: {
                 dataUrl: "{{ config['STATIC_URL'] }}/data/categories.json"
-            }
+            },
+            categories_json: '{% if categories_json %}{{categories_json}}{% endif %}',
+            {% if event_code %}event_code: "{{event_code}}",{% endif %}
         });
   
 
diff -r 69a7e0b101de -r 926f0426ce78 client/app/app.js
--- a/client/app/app.js	Fri Oct 17 17:54:06 2014 +0200
+++ b/client/app/app.js	Sun Oct 19 12:52:38 2014 +0200
@@ -18,23 +18,26 @@
             //console.log('dataApi',$resource, context);
             this.dataResource = $resource(context.urls.dataUrl);
         })
-        .service('dataModel', function(dataApi) {
+        .service('dataModel', function(dataApi, context, $q) {
             //console.log('dataModel',this,dataApi);
-            this.data = dataApi.dataResource.get();
+            if(typeof context.categories_json !== 'undefined' && context.categories_json) {
+                this.data = JSON.parse(context.categories_json);
+            }
+            else {
+                this.data = dataApi.dataResource.get();
+            }
         })
         .controller('homeCtrl', function($scope, $location, dataModel, context, $interval){
-            
+
             function getURLParameter(name) {
                 return decodeURI(
                     (new RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]
                 );
             }
-            
-            //console.log('homeCtrl 1', $scope, $location, context);
-            //console.log('homeCtrl 2', context);
+
             $scope.data = dataModel.data;
 
-            dataModel.data.$promise.then(function(data) {
+            var process_categories = function(data) {
                 if(typeof data.categories!=='undefined' && data.categories.length>0){
                     var cats = [];
                     var nbCat = data.categories.length;
@@ -49,7 +52,14 @@
                     }
                     $scope.allCatLabels = cats;
                 }
-            });
+            };
+
+            if (typeof dataModel.data.$promise !== 'undefined') {
+                dataModel.data.$promise.then(process_categories);
+            }
+            else {
+                process_categories(dataModel.data);
+            }
 
             $scope.selectedlevel = false;
 
diff -r 69a7e0b101de -r 926f0426ce78 requirements.txt
--- a/requirements.txt	Fri Oct 17 17:54:06 2014 +0200
+++ b/requirements.txt	Sun Oct 19 12:52:38 2014 +0200
@@ -1,10 +1,13 @@
 Flask==0.10.1
+Flask-Admin==1.0.8
 Flask-Restless==0.14.2
 Jinja2==2.7.3
 MarkupSafe==0.23
 SQLAlchemy==0.9.8
 Twisted==14.0.2
 Werkzeug==0.9.6
+WTForms==1.0.5
+aniso8601==0.83
 autobahn==0.9.1
 itsdangerous==0.24
 lxml==3.4.0
@@ -14,9 +17,9 @@
 python-dateutil==2.2
 python-mimeparse==0.1.4
 pytz==2014.7
-requests>=2.4.3
+'requests>=2.4.3'
 six==1.8.0
--e hg+https://bitbucket.org/IRI/txosc/get/tip.tar.gz#egg=txosc
+txosc==0.2.0
 txpostgres==1.2.0
 wsgiref==0.1.2
 zope.interface==4.1.1