# HG changeset patch # User ymh # Date 1413761493 -7200 # Node ID e27c3c1c57f1e23847b53820f7da2bc1fc064a97 # Parent 926f0426ce7856b5140bb1fa360b90f769930da5 end of admin. change the index page and add a redirect to it on the landing page diff -r 926f0426ce78 -r e27c3c1c57f1 annot-server/annotserver.py --- a/annot-server/annotserver.py Sun Oct 19 12:52:38 2014 +0200 +++ b/annot-server/annotserver.py Mon Oct 20 01:31:33 2014 +0200 @@ -7,8 +7,7 @@ from twisted.application import service, internet, strports from twisted.internet import reactor from twisted.python.threadpool import ThreadPool -from twisted.web import server -from twisted.web import resource +from twisted.web import server, resource from twisted.web.wsgi import WSGIResource from twisted.web.static import Data, File @@ -22,6 +21,12 @@ WS_PORT = 8090 OSC_PORT = 9090 +class BaseRedirect(resource.Resource): + isLeaf = True + def render_GET(self, request): + request.redirect(request.URLPath().child('p/')) + return "" + def make_service(conn, debug=False): s = service.MultiService() @@ -54,8 +59,8 @@ rootWs.putChild("broadcast", wsResource) rootWs.putChild("annot", wsAnnotResource) - webResource = resource.Resource() + webResource.putChild("",BaseRedirect()) webResource.putChild(getattr(config,'STATIC_URL').lstrip('/'), File(getattr(config,'STATIC_ROOT'))) # Create the WSGI resource wsgiAppAsResource = WSGIResource(reactor, wsgiThreadPool, app) diff -r 926f0426ce78 -r e27c3c1c57f1 annot-server/models.py --- a/annot-server/models.py Sun Oct 19 12:52:38 2014 +0200 +++ b/annot-server/models.py Mon Oct 20 01:31:33 2014 +0200 @@ -8,7 +8,8 @@ import json import uuid -from sqlalchemy import Column, Integer, String, DateTime, Text, Table, Index, text, ForeignKey +from sqlalchemy import (Column, Integer, String, DateTime, Text, Table, Index, + text, ForeignKey, Boolean) from sqlalchemy.orm import relationship, backref from sqlalchemy.sql import func from sqlalchemy.dialects.postgresql import UUID, JSON @@ -58,6 +59,8 @@ code = Column(String(255), unique=True, nullable=False) label = Column(String(2048), nullable=False) description = Column(Text(), nullable=True) + start_date = Column(DateTime(), nullable=True) + active = Column(Boolean(), nullable=False, default=True, server_default='1') sessions = relationship("EventSession", order_by="EventSession.order", backref="event") @@ -65,6 +68,8 @@ return self.code Index('idx_event_code', Event.code) +Index('idx_event_active', Event.active) +Index('idx_event_start_date', Event.start_date) class EventSession(Base): __tablename__ = 'event_session' @@ -73,7 +78,10 @@ event_id = Column(Integer, ForeignKey(Event.id), nullable=False) project_id = Column(String(2048), nullable=True) order = Column(Integer, nullable=False, default=0) + start_ts = Column(DateTime(timezone=True), nullable=True) + duration = Column(Integer, nullable=True) categories_json = Column(JSON, nullable=True) Index('idx_event_session_order', EventSession.order) +Index('idx_event_session_start_ts', EventSession.start_ts) diff -r 926f0426ce78 -r e27c3c1c57f1 annot-server/static/css/base.css --- a/annot-server/static/css/base.css Sun Oct 19 12:52:38 2014 +0200 +++ b/annot-server/static/css/base.css Mon Oct 20 01:31:33 2014 +0200 @@ -3,3 +3,11 @@ overflow-y: scroll; background-color: #faa; } + +div { + text-align:left; +} + +.event-label { + font-size: 2em; +} diff -r 926f0426ce78 -r e27c3c1c57f1 annot-server/webapp/admin.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/annot-server/webapp/admin.py Mon Oct 20 01:31:33 2014 +0200 @@ -0,0 +1,102 @@ +# +# See LICENCE for detail +# Copyright (c) 2014 IRI +# + +import json +import urllib + +from flask.ext.admin import Admin +from flask.ext.admin.contrib.sqla import ModelView +from flask.ext.admin.contrib.sqla.form import AdminModelConverter +from flask.ext.admin.contrib.sqla.filters import BooleanEqualFilter +from flask.ext.admin.model.form import InlineFormAdmin, converts + +from jinja2 import Markup + +from wtforms import fields + +import database +import models +import config +from webapp import app + +admin = Admin(app) + + +def build_ldt_url(view, context, model, name): + # `view` is current administrative view + # `context` is instance of jinja2.runtime.Context + # `model` is model instance + # `name` is property name + if not model.project_id \ + or not model.categories_json \ + or not isinstance(model.categories_json, dict) \ + or not getattr(config,'LDT_PLATFORM_BASE_URL',None): + return '' + + output = [] + + for c in model.categories_json.get("categories",[]): + if "subcategories" in c and len(c["subcategories"])>0: + for sc in c["subcategories"]: + output.append({"name": sc["code"],"keywords": [ sc["label"] ], "color" : sc["color"] }) + else: + output.append({"name": c["code"],"keywords": [ c["label"] ], "color" : c["color"] }) + + base_url = getattr(config,'LDT_PLATFORM_BASE_URL','') + "/ldt/embediframe/?" + url_query_params = {'project_id': model.project_id, 'polemic': 'all', 'polemics_list': json.dumps(output, separators=(',',':'))} + + url = base_url + urllib.urlencode(url_query_params) + + return Markup("%s" % (url,url[:80]+"...")) + + +class EventView(ModelView): + column_searchable_list = ('code', 'label') + column_list = ('code', 'label', 'start_date', 'active') + column_filters = ('code', 'label', 'start_date', 'active') + form_create_rules = ('code', 'label', 'description', 'start_date') + inline_models = (models.EventSession,) + #form_edit_rules = ('label', 'description', 'start_date', 'active', 'code') + + def __init__(self, session, **kwargs): + super(EventView, self).__init__(models.Event, session, **kwargs) + + +class DictToJSONField(fields.TextAreaField): + def process_data(self, value): + if value is None: + value = {} + + self.data = json.dumps(value, indent=2) + + def process_formdata(self, valuelist): + if valuelist: + self.data = json.loads(valuelist[0]) + else: + self.data = '{}' + +class JsonAdminConverter(AdminModelConverter): + @converts('JSON') + def conv_JSON(self, field_args, **extra): + return DictToJSONField(**field_args) + +class EventSessionView(ModelView): + + column_default_sort = ( models.Event.code, True) + column_sortable_list = (('event', models.Event.code),) + column_auto_select_related = True + column_list = ('event', 'project_id', 'order', 'categories_json', 'url') + column_filters = ('event',) + column_formatters = {'url': build_ldt_url, 'categories_json': lambda v, c, m, p: json.dumps(m.categories_json)[:80] if m.categories_json else ''} + + model_form_converter=JsonAdminConverter + + def __init__(self, session, **kwargs): + super(EventSessionView, self).__init__(models.EventSession, session, **kwargs) + + + +admin.add_view(EventView(database.db_session)) +admin.add_view(EventSessionView(database.db_session)) diff -r 926f0426ce78 -r e27c3c1c57f1 annot-server/webapp/templates/broadcast.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/annot-server/webapp/templates/broadcast.html Mon Oct 20 01:31:33 2014 +0200 @@ -0,0 +1,56 @@ + + + + + + + + +

OSC websocket Test

+ +

+   
+
diff -r 926f0426ce78 -r e27c3c1c57f1 annot-server/webapp/templates/index.html
--- a/annot-server/webapp/templates/index.html	Sun Oct 19 12:52:38 2014 +0200
+++ b/annot-server/webapp/templates/index.html	Mon Oct 20 01:31:33 2014 +0200
@@ -1,56 +1,23 @@
-
+
 
-   
-      
-      
-      
-   
-   
-      

OSC websocket Test

- -

-   
-
+
+  
+  
+  Mons by IRI
+  
+  
+
+
+  
+

Évènements actifs :

+ {% for event in events %} +
+ +
+
Code : {{ event.code }}
+
Description : {{ event.description }}
+
+
+ {% endfor %} +
+ diff -r 926f0426ce78 -r e27c3c1c57f1 annot-server/webapp/views.py --- a/annot-server/webapp/views.py Sun Oct 19 12:52:38 2014 +0200 +++ b/annot-server/webapp/views.py Mon Oct 20 01:31:33 2014 +0200 @@ -15,8 +15,8 @@ @app.route('/') def page_home(): - return render_template('index.html') - #return render_template('annotationclient.html', logging=True) + events = db_session.query(models.Event).filter(models.Event.active == True).order_by(models.Event.start_date, models.Event.code).all() + return render_template('index.html', events=events) @app.route('/annot') @@ -31,8 +31,9 @@ @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_query = db_session.query(models.Event).filter(models.Event.code == event_code, models.Event.active == True) event = event_query.one() + if not event: abort(404) diff -r 926f0426ce78 -r e27c3c1c57f1 utils/export_annotations.py --- a/utils/export_annotations.py Sun Oct 19 12:52:38 2014 +0200 +++ b/utils/export_annotations.py Mon Oct 20 01:31:33 2014 +0200 @@ -52,31 +52,6 @@ res.append({'name': 'user', 'op': "in", 'val':user_whitelist }) return res -# def parse_polemics(tw, extended_mode): -# """ -# parse polemics in text and return a list of polemic code. None if not polemic found -# """ -# polemics = {} -# for m in re.finditer("(\+\+|\-\-|\?\?|\=\=)",tw.text): -# pol_link = { -# '++' : u'OK', -# '--' : u'KO', -# '??' : u'Q', -# '==' : u'REF'}[m.group(1)] -# polemics[pol_link] = pol_link -# -# if extended_mode: -# if "?" in tw.text: -# polemics["Q"] = "Q" -# -# for entity in tw.entity_list: -# if entity.type == "entity_url": -# polemics["REF"] = "REF" -# -# if len(polemics) > 0: -# return polemics.keys() -# else: -# return None def set_logging(options, plogger=None, queue=None):