~jshsj/python_link_shortener

python_link_shortener/server.py -rw-r--r-- 3.3 KiB
f467640a — JSH initial commit 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from flask import Flask, render_template, request, redirect, send_from_directory
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import exc
from flask_wtf import FlaskForm
from flask_wtf.csrf import CSRFProtect
from wtforms import StringField, BooleanField
from wtforms.validators import DataRequired, Length
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address


import base64, sys, os

app = Flask(__name__)
host = 'http://localhost:5000'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///urls.db'
app.secret_key = "sadasdas"

with open('vars.txt', 'r') as infile:
    content = infile.read()
    content = content.split('::')
    host = content[0]
    app.secret_key = content[1]

csrf = CSRFProtect(app)
db = SQLAlchemy(app)
limiter = Limiter(
    app,
    key_func=get_remote_address,
    default_limits = ["60 per minute", "1 per second"]
    )





class ShortUrl(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    original_url = db.Column(db.String(1000), unique=False, nullable=False)

    def __repr__(self):
        return f'Url: {self.original_url}'

class CustomUrl(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    original_url = db.Column(db.String(1000), unique=False, nullable=False)
    custom_url = db.Column(db.String(1000), unique=True, nullable=False)

class UrlInputForm(FlaskForm):
    url = StringField('URL', validators=[DataRequired(), Length(max=1000)])
    use_custom = BooleanField('Eigene URL benutzen?')
    custom_url = StringField('Eigene URL', validators=[Length(max=900)])


@app.route('/', methods=['GET', 'POST'])
def home():
    if request.method == 'POST':
        form = UrlInputForm()
        if not form.validate_on_submit():
            return render_template('home.html', form=form)
        url = ''
        original_url = form.url.data
        if (form.use_custom.data == True):
            try:
                custom_url = form.custom_url.data
                if custom_url == "":
                    return render_template('home.html', form=form)
                url = CustomUrl(original_url=original_url, custom_url=custom_url)        
                db.session.add(url)
                db.session.commit()
                return render_template('home.html', custom_url=host + '/c/' + custom_url)
            except exc.IntegrityError as e:
                print(e)
                db.session.rollback()
                return render_template('home.html', error="Deine URL ist leider schon benutzt. Probier eine andere.")

        url = ShortUrl(original_url = original_url)
        db.session.add(url)
        db.session.commit()
        short_url = base64.urlsafe_b64encode(bytes([url.id])).decode('utf-8')
        return render_template('home.html', custom_url=host + "/s/" + short_url)

    form = UrlInputForm()
    return render_template('home.html', form=form)

@app.route('/c/<custom_url>')
def redirect_custom_url(custom_url):
    original_url = CustomUrl.query.filter_by(custom_url=custom_url).first().original_url
    return redirect(original_url)

@app.route('/s/<string:short_url>')
def redirect_short_url(short_url):
    decoded_bytes = base64.urlsafe_b64decode(short_url)
    decoded_id = int.from_bytes(decoded_bytes, byteorder=sys.byteorder)
    original_url = ShortUrl.query.get(decoded_id).original_url
    return redirect(original_url)