initial commit
This commit is contained in:
parent
a001193aab
commit
e7fbb4a76e
11
settings.py
Normal file
11
settings.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
DEBUG = True
|
||||||
|
DATABASE = "urlshort.db"
|
||||||
|
FOOBAR = "PONG"
|
||||||
|
DEFAULT_SCHEMA = '''
|
||||||
|
CREATE TABLE IF NOT EXISTS pastes (id INT PRIMARY KEY, paste_url TEXT NOT NULL, target TEXT NOT NULL, method_id INT NOT NULL, ip TEXT NOT NULL, timestamp TEXT NOT NULL);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS methods (id INT PRIMARY KEY, name TEXT NOT NULL);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS access (id INT PRIMARY KEY NOT NULL, paste_id TEXT NOT NULL, ip TEXT NOT NULL, user_agent TEXT NOT NULL);
|
||||||
|
'''
|
2
templates/new_paste.html
Normal file
2
templates/new_paste.html
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<!doctype html>
|
||||||
|
<a href="http://localhost:5000/{{paste_id}}">http://localhost:5000/{{paste_id}}</a>
|
BIN
urlshort.db
Normal file
BIN
urlshort.db
Normal file
Binary file not shown.
90
urlshort.py
Normal file
90
urlshort.py
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#!/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("/<pasteID>")
|
||||||
|
@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"])
|
Loading…
Reference in a new issue