#!/usr/bin/python3 # -*- coding: utf-8 -*- from flask import Flask, g, request, render_template, redirect import sqlite3 import random import string import math import time from flask_limiter import Limiter from contextlib import closing from urllib.parse import urlparse app = Flask(__name__) app.config.from_object("settings") limiter = Limiter(app, global_limits=["2 per minute", "100 per day"]) @app.before_request def before_request(): g.db = connect_db() @app.teardown_request def teardown_request(exception): db = getattr(g, "db", None) if db is not None: db.close() @app.route("/") @limiter.exempt def root(): return "Welcome to root!" @app.route("/") @limiter.exempt def paste(pasteID): target = query_db("SELECT target FROM pastes WHERE paste_url = ?", [pasteID], one=True) if target is None: return "Shorturl not found!" else: url = urlparse(target["target"]) if url.scheme is "": target = "http://" + url.path else: target = url.scheme + "://" + url.netloc + url.path return redirect(target, 301) @app.route("/new") @limiter.exempt def new_paste(): target_url = request.args.get("target", "") paste_id = add_redirect(target_url, 1) return render_template("new_paste.html", paste_id=paste_id) def add_redirect(target_url, method_id): paste_id = gen_new_id(5) ip = request.remote_addr timestamp = int(time.time()) db = getattr(g, "db", None) if db is not None: query = "INSERT INTO pastes (paste_url, target, method_id, ip, timestamp) VALUES (:paste_url, :target, :method_id, :ip, :timestamp);" args = {"paste_url" : paste_id, "target" : target_url, "method_id" : "1", "ip" : ip, "timestamp" : timestamp} db.cursor().execute(query, args) db.commit() db.close() return paste_id def gen_new_id(length): while True: new_id = "".join([random.choice(string.ascii_letters + string.digits) for n in range(length)]) if query_db("SELECT * FROM pastes WHERE paste_url = ?", [new_id], one=True) is None: break return new_id def query_db(query, args=(), one=False): with closing(connect_db()) as db: db.row_factory = sqlite3.Row cur = db.cursor().execute(query, args) rv = cur.fetchall() cur.close() return (rv[0] if rv else None) if one else rv def init_db(): with closing(connect_db()) as db: db.cursor().executescript(app.config["DEFAULT_SCHEMA"]) db.commit() def connect_db(): return sqlite3.connect(app.config["DATABASE"]) if __name__ == "__main__": app.run(debug=app.config["DEBUG"])