diff --git a/app/__init__.py b/app/__init__.py index 20164f2..d7562aa 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,3 +1,3 @@ -from sanic import Sanic +from flask import Flask -app = Sanic() +app = Flask(__name__) diff --git a/app/controllers/api.py b/app/controllers/api.py index 5e66390..1879b6b 100644 --- a/app/controllers/api.py +++ b/app/controllers/api.py @@ -1,10 +1,9 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -import time import logging import config -from sanic import response +from flask import request, jsonify, abort from app import app from app.models.site import Site from app.models.comment import Comment @@ -12,25 +11,10 @@ from app.helpers.hashing import md5 from app.services import processor logger = logging.getLogger(__name__) -cache = {} -cache_time = 0 - -def get_cached(key): - global cache - global cache_time - value = cache.get(key,None) - if (time.time() - cache_time) > 120: - cache = {} - cache_time = time.time() - return value - -def set_cached(key, value): - global cache - cache[key] = value @app.route("/comments", methods=['GET']) -def query_comments(request): +def query_comments(): comments = [] try: @@ -52,47 +36,37 @@ def query_comments(request): d['date'] = comment.published.strftime("%Y-%m-%d %H:%M:%S") logger.debug(d) comments.append(d) - r = response.json({'data': comments}) + r = jsonify({'data': comments}) + r.status_code = 200 except: logger.warn('bad request') - r = response.json({'data': []}, status=400) + r = jsonify({'data': []}) + r.status_code = 400 return r -async def get_cached_comments_count(request): +@app.route("/comments/count", methods=['GET']) +def get_comments_count(): try: token = request.args.get('token', '') url = request.args.get('url', '') - key = '%s:%s' % (token, url) - count = get_cached(key) - if count is None: - count = Comment.select(Comment).join(Site).where( - (Comment.url == url) & - (Comment.published.is_null(False)) & - (Site.token == token)).count() - set_cached(key, count) - r = {'count': count} + count = Comment.select(Comment).join(Site).where( + (Comment.url == url) & + (Comment.published.is_null(False)) & + (Site.token == token)).count() + r = jsonify({'count': count}) + r.status_code = 200 except: - logger.exception("cache exception") - r = {'count': 0} + r = jsonify({'count': 0}) + r.status_code = 200 return r -@app.route("/comments/count", methods=['GET']) -async def get_comments_count(request): - return response.json(await get_cached_comments_count(request)) - - -@app.route("/comments", methods=['OPTIONS']) -def option_comments(request): - return response.text('OK') - - @app.route("/comments", methods=['POST']) -def new_comment(request): +def new_comment(): try: - data = request.json + data = request.get_json() logger.info(data) # validate token: retrieve site entity @@ -100,25 +74,25 @@ def new_comment(request): site = Site.select().where(Site.token == token).get() if site is None: logger.warn('Unknown site %s' % token) - return response.text('BAD_REQUEST', status=400) + abort(400) # honeypot for spammers captcha = data.get('captcha', '') if captcha: logger.warn('discard spam: data %s' % data) - return response.text('BAD_REQUEST', status=400) + abort(400) processor.enqueue({'request': 'new_comment', 'data': data}) except: logger.exception("new comment failure") - return response.text('BAD_REQUEST', status=400) + abort(400) - return response.text('OK') + return "OK" @app.route("/report", methods=['GET']) -def report(request): +def report(): try: token = request.args.get('token', '') @@ -126,25 +100,25 @@ def report(request): if secret != config.SECRET: logger.warn('Unauthorized request') - return response.text('UNAUTHORIZED', status=401) + abort(401) site = Site.select().where(Site.token == token).get() if site is None: logger.warn('Unknown site %s' % token) - return response.text('', status=404) + abort(404) processor.enqueue({'request': 'report', 'data': token}) except: logger.exception("report failure") - return response.text('ERROR', status=500) + abort(500) - return response.text('OK') + return "OK" @app.route("/accept", methods=['GET']) -def accept_comment(request): +def accept_comment(): try: id = request.args.get('comment', '') @@ -152,19 +126,19 @@ def accept_comment(request): if secret != config.SECRET: logger.warn('Unauthorized request') - return response.text('UNAUTHORIZED', status=401) + abort(401) processor.enqueue({'request': 'late_accept', 'data': id}) except: logger.exception("accept failure") - return response.text('', status=500) + abort(500) - return response.text('PUBLISHED') + return "PUBLISHED" @app.route("/reject", methods=['GET']) -def reject_comment(request): +def reject_comment(): try: id = request.args.get('comment', '') @@ -172,12 +146,12 @@ def reject_comment(request): if secret != config.SECRET: logger.warn('Unauthorized request') - return response.text('UNAUTHORIZED', status=401) + abort(401) processor.enqueue({'request': 'late_reject', 'data': id}) except: logger.exception("reject failure") - return response.text('ERROR', status=500) + abort(500) - return response.text('REJECTED') + return "REJECTED" diff --git a/app/controllers/mail.py b/app/controllers/mail.py index 0c7ba87..7ade3fc 100644 --- a/app/controllers/mail.py +++ b/app/controllers/mail.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- import logging -from sanic import response +from flask import request, abort from app import app from app.services import processor @@ -10,16 +10,16 @@ logger = logging.getLogger(__name__) @app.route("/inbox", methods=['POST']) -def new_mail(request): +def new_mail(): try: - data = request.json + data = request.get_json() logger.debug(data) processor.enqueue({'request': 'new_mail', 'data': data}) except: logger.exception("new mail failure") - return response.text('BAD_REQUEST', status=400) + abort(400) - return response.text('OK') + return "OK" diff --git a/app/controllers/reader.py b/app/controllers/reader.py index 0631861..2673105 100644 --- a/app/controllers/reader.py +++ b/app/controllers/reader.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- import logging -from sanic import response +from flask import request, abort from app import app from app.services import processor @@ -10,7 +10,7 @@ logger = logging.getLogger(__name__) @app.route("/unsubscribe", methods=['GET']) -def unsubscribe(request): +def unsubscribe(): try: data = { @@ -24,6 +24,6 @@ def unsubscribe(request): except: logger.exception("unsubscribe failure") - return response.text('BAD_REQUEST', status=400) + abort(400) - return response.text('OK') + return "OK" diff --git a/app/run.py b/app/run.py index 5c821a0..fc8bd1a 100644 --- a/app/run.py +++ b/app/run.py @@ -4,6 +4,8 @@ import os import sys import logging +from werkzeug.contrib.fixers import ProxyFix +from flask.ext.cors import CORS # add current path and parent path to syspath current_path = os.path.dirname(__file__) @@ -15,8 +17,6 @@ for path in paths: # more imports import config -from sanic_cors import CORS, cross_origin - from app.services import database from app.services import processor from app.controllers import api @@ -59,16 +59,17 @@ processor.start(template_path) logger.info("Start Stacosys application") # enable CORS -cors = CORS(app, resources=r'/comments/*') +cors = CORS(app, resources={r"/comments/*": {"origins": "*"}}) # tune logging level if not config.DEBUG: logging.getLogger('app.cors').level = logging.WARNING logging.getLogger('werkzeug').level = logging.WARNING +app.wsgi_app = ProxyFix(app.wsgi_app) + if __name__ == '__main__': + app.run(host=config.HTTP_ADDRESS, port=config.HTTP_PORT, - debug=config.DEBUG, - log_config=None, - workers=config.HTTP_WORKERS) + debug=config.DEBUG, use_reloader=False) diff --git a/app/services/__init__.py b/app/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/services/processor.py b/app/services/processor.py index 7bba82d..2c18536 100644 --- a/app/services/processor.py +++ b/app/services/processor.py @@ -356,9 +356,9 @@ def rss(token, onstart=False): for row in Comment.select().join(Site).where( Site.token == token, Comment.published).order_by( -Comment.published).limit(10): - item_link = "http://%s%s" % (site.url, row.url) + item_link = "%s://%s%s" % (config.RSS_URL_PROTO, site.url, row.url) items.append(PyRSS2Gen.RSSItem( - title='%s - http://%s%s' % (row.author_name, site.url, row.url), + title='%s - %s://%s%s' % (config.RSS_URL_PROTO, row.author_name, site.url, row.url), link=item_link, description=md.convert(row.content), guid=PyRSS2Gen.Guid('%s/%d' % (item_link, row.id)), @@ -367,7 +367,7 @@ def rss(token, onstart=False): rss = PyRSS2Gen.RSS2( title=rss_title, - link="http://" + site.url, + link='%s://%s' % (config.RSS_URL_PROTO, site.url), description="Commentaires du site '%s'" % site.name, lastBuildDate=datetime.now(), items=items) diff --git a/config.py b/config.py index 4d969dc..16f780a 100644 --- a/config.py +++ b/config.py @@ -10,7 +10,7 @@ DB_URL = "sqlite:///db.sqlite" MAIL_URL = "http://localhost:8025/mbox" HTTP_ADDRESS = "0.0.0.0" -HTTP_PORT = 8000 +HTTP_PORT = 8100 HTTP_WORKERS = 1 CORS_ORIGIN = "*" @@ -20,4 +20,5 @@ SECRET = "Uqca5Kc8xuU6THz9" ROOT_URL = 'http://localhost:8000' +RSS_URL_PROTO = 'http' RSS_FILE = 'comments.xml' diff --git a/go-http/httpfastcache.go b/go-http/httpfastcache.go index 16a1cc4..dd09c42 100644 --- a/go-http/httpfastcache.go +++ b/go-http/httpfastcache.go @@ -47,7 +47,7 @@ func commentsCount(w http.ResponseWriter, r *http.Request) { } // relay request to stacosys - //fmt.Println("QUERY: " + config.Stacosys + r.URL.String()) + fmt.Println("QUERY: " + config.Stacosys + r.URL.String()) response, err := http.Get(config.Stacosys + r.URL.String()) if err != nil { http.NotFound(w, r) @@ -80,6 +80,7 @@ func main() { json.Unmarshal(file, &config) fmt.Printf("config: %s\n", string(file)) + http.HandleFunc("/comments/count/", commentsCount) http.HandleFunc("/comments/count", commentsCount) http.ListenAndServe(config.HostPort, nil) } diff --git a/requirements.txt b/requirements.txt index a06b7da..cc8994e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ -aiofiles==0.3.1 +click==6.7 clize==2.4 -hiredis==0.2.0 -httptools==0.0.9 +Flask==0.12.2 +Flask-Cors==3.0.3 +itsdangerous==0.24 Jinja2==2.7.3 Markdown==2.6.2 MarkupSafe==0.23 @@ -9,9 +10,5 @@ peewee==2.6.0 PyMySQL==0.6.6 PyRSS2Gen==1.1 requests==2.7.0 -sanic==0.5.4 -Sanic-Cors==0.5.4.2 six==1.9.0 -ujson==1.35 -uvloop==0.8.0 -websockets==3.3 +Werkzeug==0.12.2