Now with votes!
parent
913179fd3c
commit
07e7827b8c
|
@ -1,2 +1,2 @@
|
||||||
from webapp import app
|
from webapp import app
|
||||||
app.run("127.0.0.1", 2007, debug=True)
|
app.run("0.0.0.0", 2007, debug=True)
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
/** include - including .js files from JS - bfults@gmail.com - 2005-02-09 **
|
|
||||||
** Code licensed under Creative Commons Attribution-ShareAlike License **
|
|
||||||
** http://creativecommons.org/licenses/by-sa/2.0/ **/
|
|
||||||
var hIncludes = null;
|
|
||||||
function include(sURI, cls, id, ignore_duplicates)
|
|
||||||
{
|
|
||||||
if (document.getElementsByTagName) {
|
|
||||||
if (!ignore_duplicates && !hIncludes) {
|
|
||||||
hIncludes = {};
|
|
||||||
var cScripts = document.getElementsByTagName("script");
|
|
||||||
for (var i=0,len=cScripts.length; i < len; i++)
|
|
||||||
if (cScripts[i].src) hIncludes[cScripts[i].src] = cScripts[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ignore_duplicates || !hIncludes[sURI]) {
|
|
||||||
var oNew = document.createElement("script");
|
|
||||||
oNew.type = "text/javascript";
|
|
||||||
oNew.src = sURI;
|
|
||||||
if (cls != undefined) oNew.className = cls;
|
|
||||||
if (id != undefined) oNew.id = id;
|
|
||||||
if (hIncludes != undefined) hIncludes[sURI]=true;
|
|
||||||
document.getElementsByTagName("head")[0].appendChild(oNew);
|
|
||||||
}
|
|
||||||
return (ignore_duplicates || hIncludes[sURI]);
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* code borrowed from rysiek at brama. */
|
|
||||||
|
|
||||||
include('/js/openlayers/OpenLayers.js', 'js-libs');
|
|
||||||
var osm, map, markers_layer, zoom, center, brama_pos, epsg4326;
|
|
||||||
function initOpenLayersMap(mapobj) {
|
|
||||||
zoom = 16
|
|
||||||
center = new OpenLayers.LonLat(21.002971, 52.246246);
|
|
||||||
hs_pos = new OpenLayers.LonLat(21.002971, 52.246246);
|
|
||||||
epsg4326 = new OpenLayers.Projection("EPSG:4326");
|
|
||||||
|
|
||||||
map = new OpenLayers.Map(mapobj, {maxResolution: 0.703125});
|
|
||||||
|
|
||||||
osm = new OpenLayers.Layer.OSM.Mapnik("OpenStreetMap (Mapnik)", {
|
|
||||||
displayOutsideMaxExtent: true,
|
|
||||||
wrapDateLine: true,
|
|
||||||
buffer: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
map.addLayer(osm);
|
|
||||||
map.setCenter(center.clone().transform(epsg4326, map.getProjectionObject()), zoom);
|
|
||||||
|
|
||||||
markers_layer = new OpenLayers.Layer.Markers("Markery");
|
|
||||||
var icon_size = new OpenLayers.Size(50, 30);
|
|
||||||
var icon_offset = new OpenLayers.Pixel(-(icon_size.w/2), -(icon_size.h/2));
|
|
||||||
|
|
||||||
var hs = new OpenLayers.Marker(
|
|
||||||
hs_pos.clone().transform(epsg4326, map.getProjectionObject()),
|
|
||||||
new OpenLayers.Icon('/img/hackerspace.svg', icon_size, icon_offset)
|
|
||||||
);
|
|
||||||
|
|
||||||
markers_layer.setVisibility(true);
|
|
||||||
markers_layer.addMarker(hs);
|
|
||||||
map.addLayer(markers_layer);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var map_attempt_timeout = 500;
|
|
||||||
var map_attempts_no = 30;
|
|
||||||
|
|
||||||
function mapInitAttempt() {
|
|
||||||
if ( (typeof OpenLayers != 'undefined') && (typeof OpenLayers.Layer.OSM.Mapnik != 'undefined') ) {
|
|
||||||
$(this).stopTime()
|
|
||||||
$('#map img').fadeOut('fast', function(){
|
|
||||||
$("#map").addClass('osm')
|
|
||||||
initOpenLayersMap("map")
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if ( ($("script[src='/js/openlayers/openstreetmap.js']").length == 0) && (typeof OpenLayers != 'undefined') && (typeof OpenLayers.Layer.OSM.Mapnik == 'undefined') ) {
|
|
||||||
include('/js/openlayers/openstreetmap.js', 'js-libs');
|
|
||||||
}
|
|
||||||
map_attempts_no--
|
|
||||||
if (map_attempts_no > 0) {
|
|
||||||
if (typeof console != 'undefined') console.debug('OSM/OL :: not yet... (' + map_attempts_no + ' attempts left)')
|
|
||||||
} else {
|
|
||||||
$(this).stopTime()
|
|
||||||
if (typeof console != 'undefined') console.debug('OSM/OL :: not yet... cancelling.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function(){
|
|
||||||
$(this).everyTime(map_attempt_timeout, mapInitAttempt);
|
|
||||||
});
|
|
File diff suppressed because one or more lines are too long
|
@ -1,141 +0,0 @@
|
||||||
/**
|
|
||||||
* Namespace: Util.OSM
|
|
||||||
*/
|
|
||||||
OpenLayers.Util.OSM = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constant: MISSING_TILE_URL
|
|
||||||
* {String} URL of image to display for missing tiles
|
|
||||||
*/
|
|
||||||
OpenLayers.Util.OSM.MISSING_TILE_URL = "http://openstreetmap.org/openlayers/img/404.png";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Property: originalOnImageLoadError
|
|
||||||
* {Function} Original onImageLoadError function.
|
|
||||||
*/
|
|
||||||
OpenLayers.Util.OSM.originalOnImageLoadError = OpenLayers.Util.onImageLoadError;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: onImageLoadError
|
|
||||||
*/
|
|
||||||
OpenLayers.Util.onImageLoadError = function() {
|
|
||||||
if (this.src.match(/^http:\/\/[abc]\.[a-z]+\.openstreetmap\.org\//)) {
|
|
||||||
this.src = OpenLayers.Util.OSM.MISSING_TILE_URL;
|
|
||||||
} else if (this.src.match(/^http:\/\/[def]\.tah\.openstreetmap\.org\//)) {
|
|
||||||
// do nothing - this layer is transparent
|
|
||||||
} else {
|
|
||||||
OpenLayers.Util.OSM.originalOnImageLoadError;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class: OpenLayers.Layer.OSM.Mapnik
|
|
||||||
*
|
|
||||||
* Inherits from:
|
|
||||||
* - <OpenLayers.Layer.OSM>
|
|
||||||
*/
|
|
||||||
OpenLayers.Layer.OSM.Mapnik = OpenLayers.Class(OpenLayers.Layer.OSM, {
|
|
||||||
/**
|
|
||||||
* Constructor: OpenLayers.Layer.OSM.Mapnik
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* name - {String}
|
|
||||||
* options - {Object} Hashtable of extra options to tag onto the layer
|
|
||||||
*/
|
|
||||||
initialize: function(name, options) {
|
|
||||||
var url = [
|
|
||||||
"http://a.tile.openstreetmap.org/${z}/${x}/${y}.png",
|
|
||||||
"http://b.tile.openstreetmap.org/${z}/${x}/${y}.png",
|
|
||||||
"http://c.tile.openstreetmap.org/${z}/${x}/${y}.png"
|
|
||||||
];
|
|
||||||
options = OpenLayers.Util.extend({ numZoomLevels: 19 }, options);
|
|
||||||
var newArguments = [name, url, options];
|
|
||||||
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
|
|
||||||
},
|
|
||||||
|
|
||||||
CLASS_NAME: "OpenLayers.Layer.OSM.Mapnik"
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class: OpenLayers.Layer.OSM.Osmarender
|
|
||||||
*
|
|
||||||
* Inherits from:
|
|
||||||
* - <OpenLayers.Layer.OSM>
|
|
||||||
*/
|
|
||||||
OpenLayers.Layer.OSM.Osmarender = OpenLayers.Class(OpenLayers.Layer.OSM, {
|
|
||||||
/**
|
|
||||||
* Constructor: OpenLayers.Layer.OSM.Osmarender
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* name - {String}
|
|
||||||
* options - {Object} Hashtable of extra options to tag onto the layer
|
|
||||||
*/
|
|
||||||
initialize: function(name, options) {
|
|
||||||
var url = [
|
|
||||||
"http://a.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
|
|
||||||
"http://b.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
|
|
||||||
"http://c.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png"
|
|
||||||
];
|
|
||||||
options = OpenLayers.Util.extend({ numZoomLevels: 18 }, options);
|
|
||||||
var newArguments = [name, url, options];
|
|
||||||
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
|
|
||||||
},
|
|
||||||
|
|
||||||
CLASS_NAME: "OpenLayers.Layer.OSM.Osmarender"
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class: OpenLayers.Layer.OSM.CycleMap
|
|
||||||
*
|
|
||||||
* Inherits from:
|
|
||||||
* - <OpenLayers.Layer.OSM>
|
|
||||||
*/
|
|
||||||
OpenLayers.Layer.OSM.CycleMap = OpenLayers.Class(OpenLayers.Layer.OSM, {
|
|
||||||
/**
|
|
||||||
* Constructor: OpenLayers.Layer.OSM.CycleMap
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* name - {String}
|
|
||||||
* options - {Object} Hashtable of extra options to tag onto the layer
|
|
||||||
*/
|
|
||||||
initialize: function(name, options) {
|
|
||||||
var url = [
|
|
||||||
"http://a.andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png",
|
|
||||||
"http://b.andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png",
|
|
||||||
"http://c.andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png"
|
|
||||||
];
|
|
||||||
options = OpenLayers.Util.extend({ numZoomLevels: 19 }, options);
|
|
||||||
var newArguments = [name, url, options];
|
|
||||||
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
|
|
||||||
},
|
|
||||||
|
|
||||||
CLASS_NAME: "OpenLayers.Layer.OSM.CycleMap"
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class: OpenLayers.Layer.OSM.Maplint
|
|
||||||
*
|
|
||||||
* Inherits from:
|
|
||||||
* - <OpenLayers.Layer.OSM>
|
|
||||||
*/
|
|
||||||
OpenLayers.Layer.OSM.Maplint = OpenLayers.Class(OpenLayers.Layer.OSM, {
|
|
||||||
/**
|
|
||||||
* Constructor: OpenLayers.Layer.OSM.Maplint
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* name - {String}
|
|
||||||
* options - {Object} Hashtable of extra options to tag onto the layer
|
|
||||||
*/
|
|
||||||
initialize: function(name, options) {
|
|
||||||
var url = [
|
|
||||||
"http://d.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png",
|
|
||||||
"http://e.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png",
|
|
||||||
"http://f.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png"
|
|
||||||
];
|
|
||||||
options = OpenLayers.Util.extend({ numZoomLevels: 18, isBaseLayer: false, visibility: false }, options);
|
|
||||||
var newArguments = [name, url, options];
|
|
||||||
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
|
|
||||||
},
|
|
||||||
|
|
||||||
CLASS_NAME: "OpenLayers.Layer.OSM.Maplint"
|
|
||||||
});
|
|
|
@ -4,57 +4,18 @@
|
||||||
* cc by-nc-sa */
|
* cc by-nc-sa */
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
var rotimageMoving = false;
|
function vote_click() {
|
||||||
|
var url = $(this).attr("href");
|
||||||
$("#rotimage").mouseover(function() {
|
var header = $(this).parent();
|
||||||
if (!rotimageMoving)
|
$.get(url, function(data) {
|
||||||
{
|
var html = $(".quoteheader", data).html();
|
||||||
rotimageMoving = true;
|
header.html(html);
|
||||||
$("#rotimage").animate({
|
$(".upvote", $(header)).click(vote_click);
|
||||||
height: "200px",
|
$(".downvote", $(header)).click(vote_click);
|
||||||
}, 300, "swing", function() {
|
});
|
||||||
rotimageMoving = false;
|
return false;
|
||||||
});
|
}
|
||||||
}
|
$(".upvote").click(vote_click);
|
||||||
});
|
$(".downvote").click(vote_click);
|
||||||
$("#rotimage").mouseout(function() {
|
|
||||||
if (!rotimageMoving)
|
|
||||||
{
|
|
||||||
rotimageMoving = true;
|
|
||||||
$("#rotimage").animate({
|
|
||||||
height: "100px",
|
|
||||||
}, 300, "swing", function() {
|
|
||||||
rotimageMoving = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$.get("/at", function(data) {
|
|
||||||
var jdata = JSON.parse(data);
|
|
||||||
var users = jdata.users.length;
|
|
||||||
|
|
||||||
if (users > 0)
|
|
||||||
{
|
|
||||||
var text = 'According to <a href="http://at.hackerspace.pl">our instruments</a> there ';
|
|
||||||
if (users == 1)
|
|
||||||
text += 'is one person';
|
|
||||||
else
|
|
||||||
text += 'are ' + users + ' people';
|
|
||||||
text += ' at the hackerspace right now.';
|
|
||||||
|
|
||||||
$("#status-tooltip p").html(text);
|
|
||||||
$("#status img").attr("src", "/img/status-open.png");
|
|
||||||
$("#status-tooltip").css("display", "block");
|
|
||||||
$("#status").css("display", "block");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$("#status img").attr("src", "/img/status-closed.png");
|
|
||||||
$("#status").css("display", "block");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -4,11 +4,19 @@
|
||||||
<h3 style="margin-bottom: 10px;">{{ title }}:</h3>
|
<h3 style="margin-bottom: 10px;">{{ title }}:</h3>
|
||||||
{% for quote in quotes %}
|
{% for quote in quotes %}
|
||||||
<div class="quote">
|
<div class="quote">
|
||||||
<div class ="quoteheader">
|
<div class ="quoteheader quoteheader-{{ quote.id }}">
|
||||||
<a href="/quotes/view/{{ quote.id }}">#{{ quote.id }}</a>
|
<a href="/quotes/view/{{ quote.id }}">#{{ quote.id }}</a>
|
||||||
<a href="/quotes/up/{{ quote.id }}">Up↑</a>
|
{% if quote.user_score < 1 %}
|
||||||
|
<a class="upvote" href="/quotes/up/{{ quote.id }}">Up↑</a>
|
||||||
|
{% else %}
|
||||||
|
<a class="upvote" href="#" style="text-decoration: line-through;">Up↑</a>
|
||||||
|
{% endif %}
|
||||||
{{ quote.score}} / {{ quote.votes }}
|
{{ quote.score}} / {{ quote.votes }}
|
||||||
<a href="/quotes/down/{{ quote.id }}">Down↓</a>
|
{% if quote.user_score > -1 %}
|
||||||
|
<a class="downvote" href="/quotes/down/{{ quote.id }}">Down↓</a>
|
||||||
|
{% else %}
|
||||||
|
<a class="downvote" href="#" style="text-decoration: line-through;">Down↓</a>
|
||||||
|
{% endif %}
|
||||||
{{ quote.date }}
|
{{ quote.date }}
|
||||||
</div>
|
</div>
|
||||||
<p class="quotetext">{{ quote.text }}</p>
|
<p class="quotetext">{{ quote.text }}</p>
|
||||||
|
|
|
@ -8,15 +8,47 @@ def get_quotes():
|
||||||
quote = {}
|
quote = {}
|
||||||
quote["id"] = str(_id)
|
quote["id"] = str(_id)
|
||||||
score = _up - _down
|
score = _up - _down
|
||||||
quote["score"] = "+" if score >= 0 else "-"
|
quote["score"] = "+" if score >= 0 else ""
|
||||||
quote["score"] += str(score)
|
quote["score"] += str(score)
|
||||||
quote["votes"] = str(_up + _down)
|
quote["votes"] = str(_up + _down)
|
||||||
quote["date"] = time.strftime("%y-%m-%d %H:%M %Z", time.localtime(_date))
|
quote["date"] = time.strftime("%y-%m-%d %H:%M %Z", time.localtime(_date))
|
||||||
quote["text"] = _text
|
quote["text"] = _text
|
||||||
|
quote["user_score"] = get_user_votes(_id)
|
||||||
quotes.append(quote)
|
quotes.append(quote)
|
||||||
return quotes
|
return quotes
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_votes(_id):
|
||||||
|
"""Get user votes (if any) for quote id."""
|
||||||
|
if ("vote_%i" % _id) in flask.session:
|
||||||
|
return int(flask.session["vote_%i" % _id])
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def set_user_votes(_id, votes):
|
||||||
|
flask.session["vote_%i" % _id] = str(votes)
|
||||||
|
|
||||||
|
def upvote(_id):
|
||||||
|
if get_user_votes(_id) < 1:
|
||||||
|
if get_user_votes(_id) < 0:
|
||||||
|
# correcting vote
|
||||||
|
database.execute("UPDATE quotes SET _down = _down - 1 WHERE _id = ?;", _id)
|
||||||
|
else:
|
||||||
|
# normal vote
|
||||||
|
database.execute("UPDATE quotes SET _up = _up + 1 WHERE _id = ?;", _id)
|
||||||
|
set_user_votes(_id, get_user_votes(_id) + 1)
|
||||||
|
|
||||||
|
|
||||||
|
def downvote(_id):
|
||||||
|
if get_user_votes(_id) > -1:
|
||||||
|
if get_user_votes(_id) > 0:
|
||||||
|
# correcting vote
|
||||||
|
database.execute("UPDATE quotes SET _up = _up - 1 WHERE _id = ?;", _id)
|
||||||
|
else:
|
||||||
|
# normal vote
|
||||||
|
database.execute("UPDATE quotes SET _down = _down + 1 WHERE _id = ?;", _id)
|
||||||
|
set_user_votes(_id, get_user_votes(_id) - 1)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/quotes/")
|
@app.route("/quotes/")
|
||||||
def recent_quotes():
|
def recent_quotes():
|
||||||
database.execute("SELECT _id, _up, _down, _text, _meta, _date FROM quotes WHERE _approved = 1;")
|
database.execute("SELECT _id, _up, _down, _text, _meta, _date FROM quotes WHERE _approved = 1;")
|
||||||
|
@ -29,6 +61,22 @@ def queue_quotes():
|
||||||
quotes = get_quotes()
|
quotes = get_quotes()
|
||||||
return flask.render_template("list.html", quotes=quotes, title="Moderation Queue")
|
return flask.render_template("list.html", quotes=quotes, title="Moderation Queue")
|
||||||
|
|
||||||
|
@app.route("/quotes/view/<int:_id>")
|
||||||
|
def quote_view(_id):
|
||||||
|
database.execute("SELECT _id, _up, _down, _text, _meta, _date FROM quotes WHERE _id = ?;", _id)
|
||||||
|
quotes = get_quotes()
|
||||||
|
return flask.render_template("list.html", quotes=quotes, title="Quote #%i" % _id)
|
||||||
|
|
||||||
|
@app.route("/quotes/up/<int:_id>")
|
||||||
|
def upvote_quote(_id):
|
||||||
|
upvote(_id)
|
||||||
|
return quote_view(_id)
|
||||||
|
|
||||||
|
@app.route("/quotes/down/<int:_id>")
|
||||||
|
def downvote_quote(_id):
|
||||||
|
downvote(_id)
|
||||||
|
return quote_view(_id)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/new", methods=["GET", "POST"])
|
@app.route("/new", methods=["GET", "POST"])
|
||||||
def new_quote():
|
def new_quote():
|
||||||
|
|
Reference in New Issue