#!/usr/bin/python3
# vim: set fileencoding=utf-8 ts=4 sts=4 sw=4 tw=80 expandtab :
# Copyright (C) 2012 Florian Bruhin <me@the-compiler.org>
# NAME is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# NAME is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with NAME. If not, see <http://www.gnu.org/licenses/>.
import sys
import bottle
import sqlalchemy
import sqlalchemy.ext.declarative
from bottle import route, put, post, request
from bottle.ext.sqlalchemy import SQLAlchemyPlugin
from sqlalchemy import Integer, Column, Sequence, String, ForeignKey, Text, UniqueConstraint
from sqlalchemy.orm import sessionmaker
from sqlalchemy.exc import SQLAlchemyError
Base = sqlalchemy.ext.declarative.declarative_base()
engine = sqlalchemy.create_engine(
'mysql+oursql://npc:CENSORED@localhost/npc',
echo=True, pool_recycle=3600
)
create_session = sessionmaker(bind=engine)
class Votes(Base):
__tablename__ = 'votes'
vote_id = Column(Integer, Sequence('vote_id_seq'), primary_key=True)
ip = Column(String(39))
task_id = Column(Integer)
lang_id = Column(Integer)
__table_args__ = (UniqueConstraint('ip', 'task_id', name='unique_vote'),)
class Tasks(Base):
__tablename__ = 'tasks'
task_id = Column(Integer, Sequence('task_id_seq'), primary_key=True)
name = Column(String(255))
desc = Column(Text())
class Langs(Base):
__tablename__ = 'langs'
lang_id = Column(Integer, Sequence('lang_id_seq'), primary_key=True)
name = Column(String(255))
@route('/getlangs')
def getlangs(db):
langs = db.query(Langs)
result = "".join(["<li>{}</li>".format(lang.name) for lang in langs])
return "<ul>{}</ul>".format(result)
@route('/gettasks')
def gettasks(db):
tasks = db.query(Tasks)
langs = db.query(Langs)
result=''
for task in tasks:
result+="<li>Name: {} / Desc: {}</li><br />".format(task.name, task.desc)
for lang in langs:
result+='<a href="/vote?lang={}&task={}">{}</a> '.format(lang.lang_id,
task.task_id, lang.name)
Return "<ul>{}</ul>".format(result)
@route('/vote')
def vote():
ip = request.environ.get('REMOTE_ADDR')
langid = request.query.lang
taskid = request.query.task
newvote = Votes(ip=ip, lang_id=langid, task_id=taskid)
session = create_session()
try:
session.add(newvote)
session.commit()
except sqlalchemy.exc.IntegrityError:
session.rollback()
return 'already voted'
except SQLAlchemyError:
session.rollback()
return 'sql-fail'
else:
return 'ok'
finally:
session.close()
# e.g. example.com/addlang?lang=python
@route('/addlang')
def addlang(db):
newlang = Langs(name=request.query.lang)
db.add(newlang)
@route('/addtask')
def addtask_get():
return ('<form method="post" action=""><input name="name" />'
'<textarea name="desc"></textarea><input type="submit /></form>')
@post('/addtask')
def addtask_post(db):
newtask = Tasks(name=request.forms.name, desc=request.forms.desc)
db.add(newtask)
return 'ok'
@route('/getvotes')
def getvotes(db):
tasks = db.query(Tasks)
langs = db.query(Langs)
result=''
for task in tasks:
result+='<h1>Task {}: {}</h1>'.format(task.task_id, task.name)
result+='<ul>'
for lang in langs:
count = db.query(Votes).filter_by(
task_id=task.task_id, lang_id=lang.lang_id).count()
result+='<li>{} - {}</li>'.format(lang.name, count)
result+='</ul>'
return result
bottle.install(SQLAlchemyPlugin(engine, Base.metadata, create=True))
if __name__ == '__main__':
bottle.debug(True)
bottle.run(reloader=True)