From 4b95b70a04342084242323d4a0521fff31d5c107 Mon Sep 17 00:00:00 2001 From: socks Date: Thu, 20 Apr 2017 18:42:36 +0100 Subject: [PATCH] Converted files to unix format --- smash/__init__.py | 98 +++---- smash/config.py | 62 ++--- smash/static/css/custom.css | 318 +++++++++++----------- smash/templates/add.html | 84 +++--- smash/templates/index.html | 40 +-- smash/views.py | 528 ++++++++++++++++-------------------- 6 files changed, 541 insertions(+), 589 deletions(-) diff --git a/smash/__init__.py b/smash/__init__.py index 85d19dd..054eed3 100644 --- a/smash/__init__.py +++ b/smash/__init__.py @@ -1,49 +1,49 @@ -import os -from flask import Flask, g -from flask_sqlalchemy import SQLAlchemy -from . import config, log - - -log.configure_logging() -app = Flask(__name__) -conf = config.Config('config.json') - -# Load database URL for SQLAlchemy from environment -app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL'] - -# This flag tells the program it's deployed on heroku -if 'HEROKU' in os.environ: - conf.add(('HEROKU', 1)) - -# Load app name from environment if it's not in the config -if ('APPNAME' in conf.config and - conf.config['APPNAME']=="" and - 'APPNAME' in os.environ): - conf.add(('APPNAME', os.environ['APPNAME'])) - -# Load app brand name from environment if it's not in the config -if ('APPBRAND' in conf.config and - conf.config['APPBRAND']=="" and - 'APPBRAND' in os.environ): - conf.add(('APPBRAND', os.environ['APPBRAND'])) - -# Load admin key and secret key from environment -if 'ADMINSECRET' in os.environ: - conf.add(('ADMINSECRET', os.environ['ADMINSECRET'])) - -if 'SECRETKEY' in os.environ: - conf.add(('SECRETKEY', os.environ['SECRETKEY'])) - -# Set the secret key -if 'SECRETKEY' in conf.config: - app.secret_key = conf.config['SECRETKEY'] -else: - exit("Secret key not set.") - -db = SQLAlchemy(app) - -from smash.models_sqlalchemy import * - -db.create_all() - -from . import views +import os +from flask import Flask, g +from flask_sqlalchemy import SQLAlchemy +from . import config, log + + +log.configure_logging() +app = Flask(__name__) +conf = config.Config('config.json') + +# Load database URL for SQLAlchemy from environment +app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL'] + +# This flag tells the program it's deployed on heroku +if 'HEROKU' in os.environ: + conf.add(('HEROKU', 1)) + +# Load app name from environment if it's not in the config +if ('APPNAME' in conf.config and + conf.config['APPNAME']=="" and + 'APPNAME' in os.environ): + conf.add(('APPNAME', os.environ['APPNAME'])) + +# Load app brand name from environment if it's not in the config +if ('APPBRAND' in conf.config and + conf.config['APPBRAND']=="" and + 'APPBRAND' in os.environ): + conf.add(('APPBRAND', os.environ['APPBRAND'])) + +# Load admin key and secret key from environment +if 'ADMINSECRET' in os.environ: + conf.add(('ADMINSECRET', os.environ['ADMINSECRET'])) + +if 'SECRETKEY' in os.environ: + conf.add(('SECRETKEY', os.environ['SECRETKEY'])) + +# Set the secret key +if 'SECRETKEY' in conf.config: + app.secret_key = conf.config['SECRETKEY'] +else: + exit("Secret key not set.") + +db = SQLAlchemy(app) + +from smash.models_sqlalchemy import * + +db.create_all() + +from . import views diff --git a/smash/config.py b/smash/config.py index 96c894c..dd03e73 100644 --- a/smash/config.py +++ b/smash/config.py @@ -1,31 +1,31 @@ -import json - -class Config(object): - def __init__(self, filename): - self.filename = filename - self.config = json.loads(open(self.filename, 'r').read()) - - - def save(self): - with open(self.filename, 'w') as outf: - outf.write( - json.dumps( - self.config, - indent=4, - sort_keys=True) - ) - - - def reload(self): - self.config = json.loads(open(self.filename, 'r').read()) - - - def add(self, param): - self.config[param[0]] = param[1] - self.save() - - - def remove(self, paramname): - if self.config.get(paramname) is not None: - del self.config[paramname] - self.save() +import json + +class Config(object): + def __init__(self, filename): + self.filename = filename + self.config = json.loads(open(self.filename, 'r').read()) + + + def save(self): + with open(self.filename, 'w') as outf: + outf.write( + json.dumps( + self.config, + indent=4, + sort_keys=True) + ) + + + def reload(self): + self.config = json.loads(open(self.filename, 'r').read()) + + + def add(self, param): + self.config[param[0]] = param[1] + self.save() + + + def remove(self, paramname): + if self.config.get(paramname) is not None: + del self.config[paramname] + self.save() diff --git a/smash/static/css/custom.css b/smash/static/css/custom.css index 9150a01..956881e 100644 --- a/smash/static/css/custom.css +++ b/smash/static/css/custom.css @@ -1,161 +1,161 @@ -html, body { - font-family: 'Montserrat'; - margin: 0; - padding: 0; - height: 100%; - background-image: url("../images/bg.png"); -} - -.content { - min-height: 100%; - position: relative; -} - -.navbar-upper{ - margin-bottom: 0px; - min-height: 25px; - border-radius: 0px; - background-color: #03A9F4; - border: 0px; -} - -.navbar-default .navbar-brand-upper{ - font-family: 'Rubik Mono One'; - color: #FAFAFA; - height: 25px; - padding: 0px; - padding-left: 5px; - line-height: 25px; - text-shadow: -2px 2px 2px rgba(33, 33, 33, 0.85); -} - -.navbar-default .navbar-brand:hover{ - color: #FAFAFA; -} - -.navbar-lower{ - min-height: 30px; - background-color: #212121; - border: 0px; - box-shadow: 0px 2px 10px 0px rgba(33, 33, 33, 0.85); -} - -.navbar-nav > li > a{ - padding: 10px 15px 10px 15px; - color: #FAFAFA; -} - -.nav > li > a:hover{ - background-color: #424242; -} - -.navbar-right{ - margin: 0; -} - -.navbar-form { - margin: 0; - padding: 0; - height: 40px; -} - -.navbar-form > .form-group{ - height: 100%; -} - -.navbar-form > .form-group > .form-control { - border-radius: 0px; - border: 0; - border-bottom: 2px solid #FAFAFA; - background-color: inherit; - height: 100%; - color: #FAFAFA -} - -.navbar-form > .form-group > .form-control:focus { - box-shadow: none; - border-bottom: 2px solid #03A9F4; -} - -.footer { - background-color: #212121; - box-shadow: 0 -2px 10px 0px rgba(33, 33, 33, 0.85); - position: absolute; - padding: 0; - margin-top: 50px; - right: 0; - left: 0; - bottom: -50px; -} - -.footer-copyright { - text-align: center; - color: #FAFAFA; - font-variant: small-caps; - bottom: 0; -} - -.quote-link { - color: #424242; - font-weight: bold; - padding-left: 8px; -} - -.quote { - font-family: 'Inconsolata', monospace; -} - -.quote-header { - background-color: #b3e5fc; - border-bottom: 1px solid; - border-color: #4fc3f7; - margin-bottom: 2px; -} - -.quote-date { - padding-right: 8px; -} - -.rate-positive { - color: #4caf50; -} - -.rate-negative { - color: #f44336; -} - -.table-separator{ - background-color: #03A9F4; - padding: 0!important; - width: 3px; - height: 100%; -} - -.table{ - height: 100%; -} - -.table > tbody > tr > td{ - border-top: 0; -} - -.tags { - margin-bottom: 4px; -} - -.badge { - background-color: #03A9F4; -} +html, body { + font-family: 'Montserrat'; + margin: 0; + padding: 0; + height: 100%; + background-image: url("../images/bg.png"); +} + +.content { + min-height: 100%; + position: relative; +} + +.navbar-upper{ + margin-bottom: 0px; + min-height: 25px; + border-radius: 0px; + background-color: #03A9F4; + border: 0px; +} + +.navbar-default .navbar-brand-upper{ + font-family: 'Rubik Mono One'; + color: #FAFAFA; + height: 25px; + padding: 0px; + padding-left: 5px; + line-height: 25px; + text-shadow: -2px 2px 2px rgba(33, 33, 33, 0.85); +} + +.navbar-default .navbar-brand:hover{ + color: #FAFAFA; +} + +.navbar-lower{ + min-height: 30px; + background-color: #212121; + border: 0px; + box-shadow: 0px 2px 10px 0px rgba(33, 33, 33, 0.85); +} + +.navbar-nav > li > a{ + padding: 10px 15px 10px 15px; + color: #FAFAFA; +} + +.nav > li > a:hover{ + background-color: #424242; +} + +.navbar-right{ + margin: 0; +} + +.navbar-form { + margin: 0; + padding: 0; + height: 40px; +} + +.navbar-form > .form-group{ + height: 100%; +} + +.navbar-form > .form-group > .form-control { + border-radius: 0px; + border: 0; + border-bottom: 2px solid #FAFAFA; + background-color: inherit; + height: 100%; + color: #FAFAFA +} + +.navbar-form > .form-group > .form-control:focus { + box-shadow: none; + border-bottom: 2px solid #03A9F4; +} + +.footer { + background-color: #212121; + box-shadow: 0 -2px 10px 0px rgba(33, 33, 33, 0.85); + position: absolute; + padding: 0; + margin-top: 50px; + right: 0; + left: 0; + bottom: -50px; +} + +.footer-copyright { + text-align: center; + color: #FAFAFA; + font-variant: small-caps; + bottom: 0; +} + +.quote-link { + color: #424242; + font-weight: bold; + padding-left: 8px; +} + +.quote { + font-family: 'Inconsolata', monospace; +} + +.quote-header { + background-color: #b3e5fc; + border-bottom: 1px solid; + border-color: #4fc3f7; + margin-bottom: 2px; +} + +.quote-date { + padding-right: 8px; +} + +.rate-positive { + color: #4caf50; +} + +.rate-negative { + color: #f44336; +} + +.table-separator{ + background-color: #03A9F4; + padding: 0!important; + width: 3px; + height: 100%; +} + +.table{ + height: 100%; +} + +.table > tbody > tr > td{ + border-top: 0; +} + +.tags { + margin-bottom: 4px; +} + +.badge { + background-color: #03A9F4; +} .mod-form { padding-left: 8px; display: inline; } - -.btn-mod { - padding: 0px 4px; - border-radius: 0px; - display: inline; + +.btn-mod { + padding: 0px 4px; + border-radius: 0px; + display: inline; } .pagination { @@ -165,9 +165,9 @@ html, body { .pagination>li>a { color: #03A9F4; -} - -.pagination>.active>a { - background-color: #03A9F4; - border-color: #03A9F4; -} +} + +.pagination>.active>a { + background-color: #03A9F4; + border-color: #03A9F4; +} diff --git a/smash/templates/add.html b/smash/templates/add.html index 47c882d..60b9204 100644 --- a/smash/templates/add.html +++ b/smash/templates/add.html @@ -1,42 +1,42 @@ -{% extends "base.html" %} -{% block content %} - -
-
- - - - - - - - - - - - - - - - - - -
-
- -
-
- - -
-
- - -
-
- IP and connection time are logged. -
-
-
- -{% endblock %} +{% extends "base.html" %} +{% block content %} + +
+
+ + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+
+ + +
+
+ IP and connection time are logged. +
+
+
+ +{% endblock %} diff --git a/smash/templates/index.html b/smash/templates/index.html index bd5c8a9..0efc7ad 100644 --- a/smash/templates/index.html +++ b/smash/templates/index.html @@ -1,20 +1,20 @@ -{% extends "base.html" %} -{% block content %} - - - - - - - - - -
- {{ welcometext|safe }} - - - {{ newstext|safe }} -
- -{{ msg|safe }} -{% endblock %} +{% extends "base.html" %} +{% block content %} + + + + + + + + + +
+ {{ welcometext|safe }} + + + {{ newstext|safe }} +
+ +{{ msg|safe }} +{% endblock %} diff --git a/smash/views.py b/smash/views.py index 84a1d77..791b19b 100644 --- a/smash/views.py +++ b/smash/views.py @@ -1,17 +1,17 @@ -import datetime +import datetime import random -import logging -import psycopg2 -from flask import render_template, Markup, request, abort, session, g - -from smash.models_sqlalchemy import * -from smash import app, conf, db - -logger = logging.getLogger(__name__) - - -def timestamp(): - return datetime.datetime.now().strftime("%H:%M:%S %d/%m/%y") +import logging +import psycopg2 +from flask import render_template, Markup, request, abort, session, g + +from smash.models_sqlalchemy import * +from smash import app, conf, db + +logger = logging.getLogger(__name__) + + +def timestamp(): + return datetime.datetime.now().strftime("%H:%M:%S %d/%m/%y") def message(level, msg): @@ -27,16 +27,16 @@ def message(level, msg): def before_request(): g.appname = conf.config['APPNAME'] g.appbrand = conf.config['APPBRAND'] - - -@app.route('/') -def index(): - welcome = conf.config['MOTD'] - news = ("

{}

{} running on smash quote database" - " engine launched today

").format( - datetime.datetime.now().strftime("%d/%m/%y"), - conf.config['APPNAME'] - ) + + +@app.route('/') +def index(): + welcome = conf.config['MOTD'] + news = ("

{}

{} running on smash quote database" + " engine launched today

").format( + datetime.datetime.now().strftime("%d/%m/%y"), + conf.config['APPNAME'] + ) #Show random quote on the homepage if any exist quotes = Quote.query.filter_by(approved=True).order_by(Quote.id.desc()).all() @@ -45,56 +45,56 @@ def index(): quote = random.choice(quotes) news = str(Markup.escape(quote.content)).replace('\n', '
') - return render_template( - "index.html", - title="Quotes", - welcometext=welcome, - newstext=news - ) - - -@app.route('/login', methods=['GET', 'POST']) -def login_page(): - if request.method == 'POST': - if request.form["secret"] == conf.config['ADMINSECRET']: - session['authorized'] = True - - return render_template( + return render_template( + "index.html", + title="Quotes", + welcometext=welcome, + newstext=news + ) + + +@app.route('/login', methods=['GET', 'POST']) +def login_page(): + if request.method == 'POST': + if request.form["secret"] == conf.config['ADMINSECRET']: + session['authorized'] = True + + return render_template( "login.html", ) -@app.route('/latest') -def latest(): - quotes = Quote.query.filter_by(approved=True).order_by(Quote.id.desc()).all() - allquotes = len(quotes) - quotes = quotes[:10] - - if len(quotes)>0: - # Replace line breaks with html breaks and escape special characters - for quote in quotes: - quote.content = str(Markup.escape(quote.content)).replace('\n', '
') - - return render_template( - "latest.html", - title="Latest", - quotes=quotes, - numpages=1 + allquotes//10 if allquotes%10 != 0 else allquotes//10, - curpage=0, - page_type="latest" - ) - else: - return message("alert-warning", "No quotes in the database.") - - -@app.route('/latest/') -def latest_page(page): - allquotes = len(Quote.query.filter_by(approved=True).order_by(Quote.id.desc()).all()) - quotes = Quote.query.filter_by(approved=True).order_by(Quote.id.desc()).all()[(page-1)*10:page*10] - - for quote in quotes: - quote.content = str(Markup.escape(quote.content)).replace('\n', '
') - +@app.route('/latest') +def latest(): + quotes = Quote.query.filter_by(approved=True).order_by(Quote.id.desc()).all() + allquotes = len(quotes) + quotes = quotes[:10] + + if len(quotes)>0: + # Replace line breaks with html breaks and escape special characters + for quote in quotes: + quote.content = str(Markup.escape(quote.content)).replace('\n', '
') + + return render_template( + "latest.html", + title="Latest", + quotes=quotes, + numpages=1 + allquotes//10 if allquotes%10 != 0 else allquotes//10, + curpage=0, + page_type="latest" + ) + else: + return message("alert-warning", "No quotes in the database.") + + +@app.route('/latest/') +def latest_page(page): + allquotes = len(Quote.query.filter_by(approved=True).order_by(Quote.id.desc()).all()) + quotes = Quote.query.filter_by(approved=True).order_by(Quote.id.desc()).all()[(page-1)*10:page*10] + + for quote in quotes: + quote.content = str(Markup.escape(quote.content)).replace('\n', '
') + return render_template( "latest.html", title="Latest - page {}".format(page), @@ -104,222 +104,174 @@ def latest_page(page): page_type="latest" ) -@app.route('/queue') -def queue(): - if not session.get('authorized'): - return message("alert-danger", "You are not authorized to view this page.") - - quotes = Quote.query.filter_by(approved=False).order_by(Quote.id).all() - - if len(quotes)>0: - # Replace line breaks with html breaks and escape special characters - for quote in quotes: - quote.content = str(Markup.escape(quote.content)).replace('\n', '
') - - return render_template( - "queue.html", - title="Queue", - quotes=quotes - ) - else: - return message("alert-warning", "No quotes in the database.") - - -@app.route('/moderate', methods=['POST']) -def moderate(): - if not session.get('authorized'): - return message("alert-danger", "You are not authorized to perform this action.") - - if request.form['submit'] == "Approve": - quote = Quote.query.filter_by(id=request.form['quoteid']).first() - quote.approved = True - db.session.commit() - - return message("alert-success", "Quote approved.") - - elif request.form['submit'] == "Delete": - quote = Quote.query.filter_by(id=request.form['quoteid']).first() - db.session.delete(quote) - db.session.commit() - - return message("alert-success", "Quote deleted.") - - abort(501) - - -@app.route('/quote/') -def quote(id): - quote = Quote.query.filter_by(id=id, approved=True).first() - - if quote is None: - return render_template( - "message.html", - alertclass="alert-warning", - message="No such quote." - ) - else: - quote.content = str(Markup.escape(quote.content)).replace('\n', '
') - return render_template( - "latest.html", - title="Quote #{}".format(quote.id), - quotes=[quote,], - numpages=1, - curpage=0, - page_type="quote" - ) - - -@app.route('/tag/') -def tag(tagname): - tag = Tag.query.filter_by(name=tagname).first() - - if len(list(tag.quotes))>0: - allquotes = len(list(tag.quotes)) - tag.quotes = tag.quotes[:10] - - # Replace line breaks with html breaks and escape special characters - for quote in tag.quotes: - quote.content = str(Markup.escape(quote.content)).replace('\n', '
') - - return render_template( - "latest.html", - title="Tag - {}".format(tagname), - quotes=tag.quotes, - numpages=1 + allquotes//10, - curpage=0, - page_type="tag/{}".format(tagname) - ) - else: - return message("alert-warning", "No quotes with this tag.") - - -@app.route('/tag//') -def tag_page(tagname, page): - tag = Tag.query.filter_by(name=tagname).first() - - if len(list(tag.quotes))>0: - allquotes = len(list(tag.quotes)) - tag.quotes = tag.quotes[(page-1)*10:page*10] - - for quote in tag.quotes: - quote.content = str(Markup.escape(quote.content)).replace('\n', '
') - - return render_template( - "latest.html", - title="Tag - {} - page {}".format(tagname, page), - quotes=tag.quotes, - numpages=1 + allquotes//10, - curpage=0, - page_type="tag/{}".format(tagname) - ) - - -@app.route('/tags') -def tags(): - tags = Tag.query.order_by(Tag.name).distinct().all() - tags = list(set([x.name for x in tags])) - - return render_template( - "tags.html", - title="Tags", - tags=tags - ) - - -@app.route('/search/') -def search(query): - quotes = Quote.query.filter_by(approved=True).filter(Quote.content.ilike('%{}%'.format(query))).order_by(Quote.id.desc()).all() - - allquotes = len(quotes) - quotes = quotes[:10] - - if len(quotes)>0: - # Replace line breaks with html breaks and escape special characters - for quote in quotes: - quote.content = str(Markup.escape(quote.content)).replace('\n', '
') - - return render_template( - "search.html", - title="Search for: {}".format(query), - quotes=quotes, - numpages=1 + allquotes//10, - curpage=0, - page_type="search", - search_query=query - ) - else: - return message("alert-warning", "No quotes in the database.") - - -@app.route('/search//') -def search_page(query, page): - allquotes = len(Quote.query.filter_by(approved=True).\ - filter(Quote.content.ilike('%{}%'.format(query))).\ - order_by(Quote.id.desc()).all()) - quotes = Quote.query.filter_by(approved=True).\ - filter(Quote.content.ilike('%{}%'.format(query))).\ - order_by(Quote.id.desc()).all()[(page-1)*10:page*10] - - for quote in quotes: - quote.content = str(Markup.escape(quote.content)).replace('\n', '
') - - return render_template( - "search.html", - title="Search for: {} - page {}".format(query, page), - quotes=quotes, - numpages=1 + allquotes//10, - curpage=page-1, - page_type="search", - search_query=query - ) - - -@app.route('/add', methods=['GET', 'POST']) -def add_new(): - if request.method == 'POST': - if request.form['submit'] == "Submit": - quote_body = request.form["newquote"] - quote_tags = request.form["tags"].split(',') - - quote = Quote(quote_body, request.remote_addr, timestamp()) - quote_tags = [Tag(tag) for tag in quote_tags] - - for tag in quote_tags: - dbtag = Tag.query.filter_by(name=tag.name).first() - if dbtag is not None: - quote.tags.append(dbtag) - else: - quote.tags.append(tag) - #quote.tags.extend(quote_tags) - - db.session.add(quote) - db.session.commit() - - return render_template( - "message.html", - alertclass="alert-success", - message="Quote added succesfully. It will need to be reviewed by the administrators before it shows up." - ) - - elif request.form['submit'] == "Preview": - preview = Quote(request.form['newquote'], request.remote_addr, timestamp()) - preview_tags = request.form["tags"].split(',') - preview.approved = True - preview.tags = [Tag(tag) for tag in preview_tags] - - return render_template( - "latest.html", - title="Quote preview", - quotes=[preview,], - numpages=1, - curpage=0, - page_type="quote" - ) - else: - abort(501) - - elif request.method == 'GET': - return render_template( - "add.html", - title="Add new" - ) +@app.route('/queue') +def queue(): + if not session.get('authorized'): + return message("alert-danger", "You are not authorized to view this page.") + + quotes = Quote.query.filter_by(approved=False).order_by(Quote.id).all() + + if len(quotes)>0: + # Replace line breaks with html breaks and escape special characters + for quote in quotes: + quote.content = str(Markup.escape(quote.content)).replace('\n', '
') + + return render_template( + "queue.html", + title="Queue", + quotes=quotes + ) + else: + return message("alert-warning", "No quotes in the database.") + + +@app.route('/moderate', methods=['POST']) +def moderate(): + if not session.get('authorized'): + return message("alert-danger", "You are not authorized to perform this action.") + + if request.form['submit'] == "Approve": + quote = Quote.query.filter_by(id=request.form['quoteid']).first() + quote.approved = True + db.session.commit() + + return message("alert-success", "Quote approved.") + + elif request.form['submit'] == "Delete": + quote = Quote.query.filter_by(id=request.form['quoteid']).first() + db.session.delete(quote) + db.session.commit() + + return message("alert-success", "Quote deleted.") + + abort(501) + + +@app.route('/quote/') +def quote(id): + quote = Quote.query.filter_by(id=id, approved=True).first() + + if quote is None: + return render_template( + "message.html", + alertclass="alert-warning", + message="No such quote." + ) + else: + quote.content = str(Markup.escape(quote.content)).replace('\n', '
') + return render_template( + "latest.html", + title="Quote #{}".format(quote.id), + quotes=[quote,], + numpages=1, + curpage=0, + page_type="quote" + ) + + +@app.route('/tag/') +def tag(tagname): + tag = Tag.query.filter_by(name=tagname).first() + + if len(list(tag.quotes))>0: + allquotes = len(list(tag.quotes)) + tag.quotes = tag.quotes[:10] + + # Replace line breaks with html breaks and escape special characters + for quote in tag.quotes: + quote.content = str(Markup.escape(quote.content)).replace('\n', '
') + + return render_template( + "latest.html", + title="Tag - {}".format(tagname), + quotes=tag.quotes, + numpages=1 + allquotes//10, + curpage=0, + page_type="tag/{}".format(tagname) + ) + else: + return message("alert-warning", "No quotes with this tag.") + + +@app.route('/tag//') +def tag_page(tagname, page): + tag = Tag.query.filter_by(name=tagname).first() + + if len(list(tag.quotes))>0: + allquotes = len(list(tag.quotes)) + tag.quotes = tag.quotes[(page-1)*10:page*10] + + for quote in tag.quotes: + quote.content = str(Markup.escape(quote.content)).replace('\n', '
') + + return render_template( + "latest.html", + title="Tag - {} - page {}".format(tagname, page), + quotes=tag.quotes, + numpages=1 + allquotes//10, + curpage=0, + page_type="tag/{}".format(tagname) + ) + + +@app.route('/tags') +def tags(): + tags = Tag.query.order_by(Tag.name).distinct().all() + tags = list(set([x.name for x in tags])) + + return render_template( + "tags.html", + title="Tags", + tags=tags + ) + + +@app.route('/search', methods=['POST']) +def search(): + if request.method == 'POST': + return render_template( + "message.html", + alertclass="alert-warning", + message="Not implemented yet. " + ) + else: + return 'Invalid request.' + + +@app.route('/add', methods=['GET', 'POST']) +def add_new(): + if request.method == 'POST': + if request.form['submit'] == "Submit": + quote_body = request.form["newquote"] + quote_tags = request.form["tags"].split(',') + + quote = Quote(quote_body, request.remote_addr, timestamp()) + quote_tags = [Tag(tag) for tag in quote_tags] + + for tag in quote_tags: + dbtag = Tag.query.filter_by(name=tag.name).first() + if dbtag is not None: + quote.tags.append(dbtag) + else: + quote.tags.append(tag) + #quote.tags.extend(quote_tags) + + db.session.add(quote) + db.session.commit() + + return render_template( + "message.html", + alertclass="alert-success", + message="Quote added succesfully. It will need to be reviewed by the administrators before it shows up." + ) + + elif request.form['submit'] == "Preview": + return str(request.form) + else: + abort(501) + + elif request.method == 'GET': + return render_template( + "add.html", + title="Add new" + )