Commit 647974ec authored by Sacha's avatar Sacha Committed by SXibolet@2PITAU
Browse files

mainly tweaks with the web client

parent a37588f5
No preview for this file type
# -*- coding: utf-8 -*-
from flask import Blueprint, jsonify, request, session, render_template
from functools import wraps
from digest import digest
from pymongo import MongoClient
from config import MONGO_PORT
......@@ -8,10 +9,28 @@ import datetime
import forms
from error import UsageError
import nltk.data
from nltk.tokenize import RegexpTokenizer
mturk = Blueprint('/training', __name__)
sent_detector = nltk.data.load('tokenizers/punkt/english.pickle')
tokenizer = RegexpTokenizer(r'\w+')
def require_human(view):
@wraps(view)
def protected_view(*args, **kwargs):
if loggedin():
return view(*args, **kwargs)
else:
raise UsageError('not human!')
return protected_view
def success():
return jsonify({
'ok': 1
})
@mturk.errorhandler(UsageError)
......@@ -24,28 +43,47 @@ def handle_error(error):
@mturk.route('/', methods=['GET', 'POST'])
def index():
css = digest('mturk/highlight.css')
js = digest('mturk/highlight.js')
if session.get('human') != 'yes':
form = forms.BeginHIT()
if form.validate_on_submit():
session['human'] = 'yes'
else:
return render_template('mturk_welcome.html', **locals())
article = get_next_doc()
n_sentences = len(article['full'])
# minimum reading time in milliseconds (at 700 wpm, fast skimming pace)
minimum_time = int(100 * (float(6 * len(tokenizer.tokenize(article['full']))) / 7))
article['full'] = sent_detector.tokenize(article['full'].strip())
session['started_reading'] = datetime.datetime.utcnow()
session['n_sentences'] = len(article['full'])
session['reading_url'] = article['url']
return render_template('mturk_highlight.html',
css=css,
js=js,
minimum_time=minimum_time,
n_sentences=n_sentences,
article=article)
@mturk.route('/mark_available')
@require_human
def mark_available():
return success()
@mturk.route('/submit', methods=['GET', 'POST'])
@require_human
def update_doc(data, url):
if 'sis' not in request.args:
raise UsageError('missing argument!')
if 'checked' not in request.args:
raise UsageError('missing ``checked``!')
col = get_collection()
increment_reads(col, url)
toggle_being_read(col, url, False)
return success()
def get_collection():
......@@ -58,7 +96,9 @@ def increment_reads(col, url):
return col.update_one({
'url': url
}, {
'$inc': {
'$set': {
'ts': datetime.datetime.utcnow()
}, '$inc': {
'n_reads': 1
}
}).modified_count
......
......@@ -7,6 +7,7 @@ from error import UsageError
import sys
# http://arxiv.org/pdf/1409.8152v1.pdf <== source of terms
TT_DIR = 'training_terms'
......
......@@ -214,8 +214,8 @@ def controversy(articles, social_content):
'linguistic_score': sentence_linguistic_score,
'sentiment_score': sentence_sentiment_score
})
# 15% of the sentence count
n = int(math.ceil(len(sentences) * .15))
# 10% of the sentence count
n = int(math.ceil(len(sentences) * .10))
# n (15%) largest scores (recall greater entropy ==> more controversial)
nlargest = heapq.nlargest(n, map(lambda x: x['score'], sentences))
# only provide controversial sentences with "enough" related tweets
......
......@@ -19,8 +19,7 @@ a {
a:hover, a:active {
background-color: #eee;
color: #800; }
a:hover { border-bottom: 1px dashed #d9d9d9; }
a:active { border-bottom: 1px solid #d9d9d9; }
a:active { border-bottom: 1px solid #ccc; }
input.field {
font-size: 16px;
padding: 6px 12px;
......
......@@ -16,6 +16,7 @@ header {
position: fixed;
font-size: 14px;
>div {
>a.mini { display: none; }
a:active, a:hover { border-bottom: none; }
padding: 0 15px 0 5px;
display: inline;
......@@ -165,6 +166,9 @@ figcaption { margin:10px 0 10px 0; }
span.danger { display: block; }
input[type='text'].top_loading { height: 40px; }
}
@media (max-width: 385px) {
nav { display: block; }
@media (max-width: 415px) {
header>div {
>a.mini { display: inline; }
>a.lg { display: none; }
}
}
var CONFIRMED_HIGHLIGHTS = false;
var STARTED_READING;
var count = parseInt(minimum_time / 1000);
var counter = setInterval(function() {timer();}, 1000);
function timer() {
count -= 1
if (count <= 0) {
clearInterval(counter);
$("#time_left span").html("submit <b>whenever</b> you're ready");
$("#time_left")
.removeClass('alert-warning')
.addClass('alert-success');
setTimeout(function() {
markAvailable();
}, 30000);
return;
}
$("#time_left span").html('<b>' + count + '</b> ' + ((count === 1) ? 'second' : 'seconds') + ' until you can submit');
}
$(document).ready(function() {
STARTED_READING = new Date().getTime();
setTimeout(function() {
updateCanSubmit();
}, minimum_time);
});
$(window).bind('beforeunload', function() {
});
function markAvailable() {
performRequest('mark_available',
function(data) {
alert(data['ok']);
}, function(data) {
console.log(data);
});
}
function performRequest(uri, callback, failure_callback) {
$.getJSON(uri,
function(data) {
callback(data);
}).fail(function(jqxhr, textStatus, error) {
failure_callback($.parseJSON(jqxhr.responseText));
});
};
function toggleControversial(i, el) {
if ($.inArray(i, controversial) !== -1) {
// ``i`` is in ``controversial``
controversial = $.grep(controversial, function(x) {
return x != i;
});
......@@ -12,10 +60,102 @@ function toggleControversial(i, el) {
$(el).removeClass('controversial');
} else {
controversial.push(i);
$(el).addClass('controversial');
$(el)
.addClass('controversial')
.prop('title', 'currently controversial');
}
updateCanSubmit();
}
function pastMinTime() {
var now = new Date();
var elapsed_ms = now.getTime() - STARTED_READING;
return (elapsed_ms > minimum_time);
}
function updateCanSubmit() {
var n_highlights = controversial.length;
if (n_highlights == 0 || !pastMinTime()) {
disable('#submit');
} else {
enable('#submit');
}
}
function displayError(message) {
$("#error").text(message);
setTimeout(function() {
$("#error").text('');
}, 3000);
}
function disable(el) {
$(el)
.prop('disabled', true)
.addClass('disabled');
}
function enable(el) {
$(el)
.prop('disabled', false)
.removeClass('disabled');
}
function submitComplete() {
}
function submitSucess(data) {
$("#bot_bar img").hide();
console.log(data);
}
function submitFailure(data) {
$("#bot_bar img").hide();
showError(data['message']);
}
$("#submit").click(function() {
console.log('%c not ready ', 'background: #222; color: #bada55');
disable('#full_article');
var n_highlights = controversial.length;
if (n_highlights > n_sentences) {
displayError('invalid # of highlights!')
enable('#full_article')
return;
}
for (var i = n_highlights - 1; i >= 0; i -= 1) {
var ei = controversial[i];
if (ei < 0 || ei > n_sentences) {
displayError('invalid sentence indices!');
return;
}
}
if (n_highlights < (n_sentences * 0.2) && !CONFIRMED_FEW_HIGHLIGHTS) {
showError("are you sure you've highlighted all controversial sentences? Submit again to confirm.");
CONFIRMED_HIGHLIGHTS = true;
return;
}
if (n_highlights > (0.8 * n_sentences)) {
showError("too many sentences highlighted");
return;
}
if (n_highlights > (0.5 * n_sentences)) {
showError("are you sure you've highlighted only controversial sentences? Submit again to confirm.");
CONFIRMED_HIGHLIGHTS = true;
return
}
if (!pastMinTime()) {
showError("your words per minute is too high");
return;
}
var uri = 'submit?checked=' + controversial.join();
$("#bot_bar img").show();
performRequest(uri, submitSuccess, submitFailure);
})
@import 'bootstrap.min.css';
* { font-family: 'Source Sans Pro', 'Ubuntu', 'Open Sans', 'Roboto', 'Helvetica', sans-serif; }
span.label-default {
line-height: 2.0;
background-color: #fff;
color: #bbb;
border: 1px solid #ccc; }
h2 { font-weight: 600; }
* { font-family: 'Open Sans', 'Ubuntu', 'Source Sans Pro', 'Roboto', 'Helvetica', sans-serif; }
h1 { font-weight: 700; }
.col-md-3 { background-color: #eee; }
#full_article {
font-size: 16px;
span { cursor: pointer; }
span.controversial {
background-color: #222;
color: #bada55; }
color: #fff;
background-color: #337ab7; }
}
#copyright { margin-bottom: 14em; }
.top_bar {
height: 8px;
background-color: #d9d9d9;
margin-bottom: 12px; }
#full_article {
text-align: justify; }
#full_article { text-align: justify; }
#bot_bar {
.col-md-12 {
.pull-left { padding: 8px; }
......
+function(e){var d=function(b,a){this.inState=this.$element=this.hoverState=this.timeout=this.enabled=this.options=this.type=null;this.init("tooltip",b,a)};d.VERSION="3.3.5";d.TRANSITION_DURATION=150;d.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}};d.prototype.init=function(b,a,
c){this.enabled=!0;this.type=b;this.$element=e(a);this.options=this.getOptions(c);this.$viewport=this.options.viewport&&e(e.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport);this.inState={click:!1,hover:!1,focus:!1};if(this.$element[0]instanceof document.constructor&&!this.options.selector)throw Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");b=this.options.trigger.split(" ");
for(a=b.length;a--;)if(c=b[a],"click"==c)this.$element.on("click."+this.type,this.options.selector,e.proxy(this.toggle,this));else if("manual"!=c){var f="hover"==c?"mouseleave":"focusout";this.$element.on(("hover"==c?"mouseenter":"focusin")+"."+this.type,this.options.selector,e.proxy(this.enter,this));this.$element.on(f+"."+this.type,this.options.selector,e.proxy(this.leave,this))}this.options.selector?this._options=e.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()};d.prototype.getDefaults=
function(){return d.DEFAULTS};d.prototype.getOptions=function(b){b=e.extend({},this.getDefaults(),this.$element.data(),b);b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay});return b};d.prototype.getDelegateOptions=function(){var b={},a=this.getDefaults();this._options&&e.each(this._options,function(c,f){a[c]!=f&&(b[c]=f)});return b};d.prototype.enter=function(b){var a=b instanceof this.constructor?b:e(b.currentTarget).data("bs."+this.type);a||(a=new this.constructor(b.currentTarget,
this.getDelegateOptions()),e(b.currentTarget).data("bs."+this.type,a));b instanceof e.Event&&(a.inState["focusin"==b.type?"focus":"hover"]=!0);if(a.tip().hasClass("in")||"in"==a.hoverState)a.hoverState="in";else{clearTimeout(a.timeout);a.hoverState="in";if(!a.options.delay||!a.options.delay.show)return a.show();a.timeout=setTimeout(function(){"in"==a.hoverState&&a.show()},a.options.delay.show)}};d.prototype.isInStateTrue=function(){for(var b in this.inState)if(this.inState[b])return!0;return!1};d.prototype.leave=
function(b){var a=b instanceof this.constructor?b:e(b.currentTarget).data("bs."+this.type);a||(a=new this.constructor(b.currentTarget,this.getDelegateOptions()),e(b.currentTarget).data("bs."+this.type,a));b instanceof e.Event&&(a.inState["focusout"==b.type?"focus":"hover"]=!1);if(!a.isInStateTrue()){clearTimeout(a.timeout);a.hoverState="out";if(!a.options.delay||!a.options.delay.hide)return a.hide();a.timeout=setTimeout(function(){"out"==a.hoverState&&a.hide()},a.options.delay.hide)}};d.prototype.show=
function(){var b=e.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var a=e.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(!b.isDefaultPrevented()&&a){var c=this,b=this.tip(),a=this.getUID(this.type);this.setContent();b.attr("id",a);this.$element.attr("aria-describedby",a);this.options.animation&&b.addClass("fade");var a="function"==typeof this.options.placement?this.options.placement.call(this,b[0],this.$element[0]):this.options.placement,
f=/\s?auto?\s?/i,l=f.test(a);l&&(a=a.replace(f,"")||"top");b.detach().css({top:0,left:0,display:"block"}).addClass(a).data("bs."+this.type,this);this.options.container?b.appendTo(this.options.container):b.insertAfter(this.$element);this.$element.trigger("inserted.bs."+this.type);var f=this.getPosition(),h=b[0].offsetWidth,g=b[0].offsetHeight;if(l){var l=a,k=this.getPosition(this.$viewport),a="bottom"==a&&f.bottom+g>k.bottom?"top":"top"==a&&f.top-g<k.top?"bottom":"right"==a&&f.right+h>k.width?"left":
"left"==a&&f.left-h<k.left?"right":a;b.removeClass(l).addClass(a)}f=this.getCalculatedOffset(a,f,h,g);this.applyPlacement(f,a);a=function(){var a=c.hoverState;c.$element.trigger("shown.bs."+c.type);c.hoverState=null;"out"==a&&c.leave(c)};e.support.transition&&this.$tip.hasClass("fade")?b.one("bsTransitionEnd",a).emulateTransitionEnd(d.TRANSITION_DURATION):a()}}};d.prototype.applyPlacement=function(b,a){var c=this.tip(),f=c[0].offsetWidth,d=c[0].offsetHeight,h=parseInt(c.css("margin-top"),10),g=parseInt(c.css("margin-left"),
10);isNaN(h)&&(h=0);isNaN(g)&&(g=0);b.top+=h;b.left+=g;e.offset.setOffset(c[0],e.extend({using:function(a){c.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0);c.addClass("in");var g=c[0].offsetWidth,k=c[0].offsetHeight;"top"==a&&k!=d&&(b.top=b.top+d-k);var m=this.getViewportAdjustedDelta(a,b,g,k);m.left?b.left+=m.left:b.top+=m.top;f=(h=/top|bottom/.test(a))?2*m.left-f+g:2*m.top-d+k;d=h?"offsetWidth":"offsetHeight";c.offset(b);this.replaceArrow(f,c[0][d],h)};d.prototype.replaceArrow=function(b,
a,c){this.arrow().css(c?"left":"top",50*(1-b/a)+"%").css(c?"top":"left","")};d.prototype.setContent=function(){var b=this.tip(),a=this.getTitle();b.find(".tooltip-inner")[this.options.html?"html":"text"](a);b.removeClass("fade in top bottom left right")};d.prototype.hide=function(b){function a(){"in"!=c.hoverState&&f.detach();c.$element.removeAttr("aria-describedby").trigger("hidden.bs."+c.type);b&&b()}var c=this,f=e(this.$tip),l=e.Event("hide.bs."+this.type);this.$element.trigger(l);if(!l.isDefaultPrevented())return f.removeClass("in"),
e.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",a).emulateTransitionEnd(d.TRANSITION_DURATION):a(),this.hoverState=null,this};d.prototype.fixTitle=function(){var b=this.$element;(b.attr("title")||"string"!=typeof b.attr("data-original-title"))&&b.attr("data-original-title",b.attr("title")||"").attr("title","")};d.prototype.hasContent=function(){return this.getTitle()};d.prototype.getPosition=function(b){b=b||this.$element;var a=b[0],c="BODY"==a.tagName,a=a.getBoundingClientRect();
null==a.width&&(a=e.extend({},a,{width:a.right-a.left,height:a.bottom-a.top}));var d=c?{top:0,left:0}:b.offset();b={scroll:c?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()};c=c?{width:e(window).width(),height:e(window).height()}:null;return e.extend({},a,b,c,d)};d.prototype.getCalculatedOffset=function(b,a,c,d){return"bottom"==b?{top:a.top+a.height,left:a.left+a.width/2-c/2}:"top"==b?{top:a.top-d,left:a.left+a.width/2-c/2}:"left"==b?{top:a.top+a.height/2-d/2,left:a.left-
c}:{top:a.top+a.height/2-d/2,left:a.left+a.width}};d.prototype.getViewportAdjustedDelta=function(b,a,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var h=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);/right|left/.test(b)?(c=a.top-h-g.scroll,a=a.top+h-g.scroll+d,c<g.top?e.top=g.top-c:a>g.top+g.height&&(e.top=g.top+g.height-a)):(d=a.left-h,a=a.left+h+c,d<g.left?e.left=g.left-d:a>g.right&&(e.left=g.left+g.width-a));return e};d.prototype.getTitle=function(){var b=
this.$element,a=this.options;return b.attr("data-original-title")||("function"==typeof a.title?a.title.call(b[0]):a.title)};d.prototype.getUID=function(b){do b+=~~(1E6*Math.random());while(document.getElementById(b));return b};d.prototype.tip=function(){if(!this.$tip&&(this.$tip=e(this.options.template),1!=this.$tip.length))throw Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip};d.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")};
d.prototype.enable=function(){this.enabled=!0};d.prototype.disable=function(){this.enabled=!1};d.prototype.toggleEnabled=function(){this.enabled=!this.enabled};d.prototype.toggle=function(b){var a=this;b&&(a=e(b.currentTarget).data("bs."+this.type),a||(a=new this.constructor(b.currentTarget,this.getDelegateOptions()),e(b.currentTarget).data("bs."+this.type,a)));b?(a.inState.click=!a.inState.click,a.isInStateTrue()?a.enter(a):a.leave(a)):a.tip().hasClass("in")?a.leave(a):a.enter(a)};d.prototype.destroy=
function(){var b=this;clearTimeout(this.timeout);this.hide(function(){b.$element.off("."+b.type).removeData("bs."+b.type);b.$tip&&b.$tip.detach();b.$tip=null;b.$arrow=null;b.$viewport=null})};var n=e.fn.tooltip;e.fn.tooltip=function(b){return this.each(function(){var a=e(this),c=a.data("bs.tooltip"),f="object"==typeof b&&b;if(c||!/destroy|hide/.test(b))if(c||a.data("bs.tooltip",c=new d(this,f)),"string"==typeof b)c[b]()})};e.fn.tooltip.Constructor=d;e.fn.tooltip.noConflict=function(){e.fn.tooltip=
n;return this}}(jQuery);
\ No newline at end of file
......@@ -12,6 +12,7 @@ Controversy &middot; hotspots of news articles</title>
<meta name="description" content="Hotspots of news articles: joint mining of news text and social media to discover controversial points in news. " />
<meta name="viewport" id="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1" />
<link rel=icon href="{{ url_for('static', filename='img/fav.ico') }}" />
<link rel=stylesheet href="//fonts.googleapis.com/css?family=Open+Sans:400,700" />
<link rel=stylesheet href="{{ css }}" />
{% if webkit is not none %}
......
......@@ -5,12 +5,12 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="{{ url_for('static', filename='img/fav.ico') }}" />
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="{{ css }}" />
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600,700" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="{{ css }}" type="text/css" />
<title>Training &middot; Controversy</title>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js" type="text/javascript"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js" type="text/javascript"></script>
<![endif]-->
</head>
<body>
......@@ -22,13 +22,12 @@
{% endblock %}
</div>
<script src="{{ url_for('static', filename='mturk/ie10-bug.js') }}"></script>
<script>
<script src="{{ url_for('static', filename='mturk/ie10-bug.js') }}" type="text/javascript"></script>
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-70419111-1', 'auto');
ga('send', 'pageview');
</script>
......
......@@ -2,17 +2,13 @@
{% block content %}
<!-- ``being_read``: {{ article.being_read }} -->
<!-- ``n_reads``: {{ article.n_reads }} -->
<div class="page-header">
<h2>Controversial sentences</h2>
</div>
<div class="row">
<div class="col-md-9">
<p class="lead">Please click any sentences which you believe are controversial. We define controversial as expressing an opinon which could be debated by many people. When done, click <b>"Submit"</b>.</p>
</div>
<div class="col-md-3">
<span class="label label-default">{{ article.title }}</span>
<span class="label label-default">{{ article.byline }}</span>
<span class="label label-default">{{ article.published }}</span>
<b>metadata</b>
{{ article.title }} <b>&middot;</b> {{ article.byline }} <b>&middot;</b> {{ article.published }}
</div>
<div class="col-md-12">
<hr>
......@@ -20,25 +16,37 @@
<div class="col-md-12">
<p id="full_article">
{% for sentence in article.full %}
<span onclick="toggleControversial({{ loop.index-1 }}, this)">{{ sentence }}</span>
<span title="currently non-controversial" onclick="toggleControversial({{ loop.index-1 }}, this)">{{ sentence }}</span>
{% endfor %}
</p>
</div>
<div class="col-md-12" id="copyright">
<p class="text-muted">Articles &copy; 2015, The New York Times Company. All rights reserved.</p>
<div class="col-md-6">
<div class="alert alert-warning" id="time_left" role="alert">
<span><span>
</div>
</div>
<div class="col-md-6" id="copyright">
<p class="text-muted">Study from the University of Illinois at Urbana-Champaign <img src="{{ url_for('static', filename='img/affiliation.jpg') }}">: I Lourentzou, G Dyer, A Sharma, CX Zhai. Articles &copy; 2015, The New York Times Company <img src="{{ url_for('static', filename='img/nytimes.png') }}" />. All rights reserved.</p>
</div>
<div class="row" id="bot_bar">
<div class="col-md-12">
<div class="pull-left">
<span id="errors"></span>
<img src="{{ url_for('static', filename='img/small-loading.gif') }}" style="display: none" />
<b class="text-warning" id="error"></b>
</div>
<input type="button" class="btn btn-lg btn-primary" id="submit" value="Submit" />
<input type="button" class="btn btn-lg btn-primary disabled" id="submit" value="Submit" />
</div>
</div>
</div>
<script src="{{ url_for('static', filename='mturk/jquery.min.js') }}"></script>
<script>
<script type="text/javascript" src="{{ url_for('static', filename='mturk/jquery.min.js') }}"></script>
<script type="text/javascript">
<!-- Turkers: if you modify these variables via a console, your work will be wasted:
you won't be paid, and we'll reject your submission server-side. -->
console.log("%c if you modify variables via a console, your work will be wasted:
you won't be paid, and we'll reject your submission server-side. ", 'background: #222; color: #bada55');
var controversial = [];
var minimum_time = {{ minimum_time }};
var n_sentences = {{ n_sentences }};
</script>
<script src="{{ url_for('static', filename='mturk/highlight.js') }}"></script>
<script type="text/javascript" src="{{ js }}"></script>
{% endblock %}
{% extends "mturk_base.html" %}
{% block content %}
<div class="page-header">
<h2>Controversial sentences</h2>
<h1>Controversial sentences</h1>
</div>
<div class="row">
<div class="col-md-12">
......
{% raw %}
<header>
<div>
<a href="#results">&larr; all articles</a>
<a class=lg href="#results">&larr; all articles</a>
<a class=mini href="#results">&larr;</a>
&middot;
<span title="{{ article.title }}" ng-bind-html="article.title | limitTo: lim"></span>
{{ article.title.length > lim ? '&hellip;' : ''}}
......@@ -33,10 +34,7 @@
</ul>
<article ng-bind-html="highlight(article.full, article.sentences)"></article>
<p>
Copyright &copy; 2015 The New York Times Company. All Rights Reserved. <a target=_blank href="{{ article.url }}">Article on nytimes.com</a>
Copyright &copy; 2015 The New York Times Company {% endraw %} <img src="{{ url_for('static', filename='img/nytimes.png') }}" /> {% raw %}. All Rights Reserved. <a target=_blank href="{{ article.url }}">Article on nytimes.com</a>
</p>
<nav>
</nav>
</main>
{% endraw %}
......@@ -26,7 +26,7 @@
<ul class=tweets>
<li ng-repeat="tweet in sentence.tweets">
<div class=tweet ng-mouseenter="hoverIn()" ng-mouseleave="hoverOut()" ng-class="{ 'happy' : tweet.is_positive, 'mad' : tweet.is_negative, 'hovering' : hovering, 'no-hover' : (!hovering && globalHover)}">
{{ tweet.tweet }}
{{ tweet.dirty }}
</div>
</li>
</ul>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment