initial commit, adding flask structure, README, routes

- routes defined in routes.py uses the <path:..> function to catch
  every non-empty url comming along
- request.full_path is used to get the entire url, as <path:> would
  remove eg GET '?' from the url, which we don't want
  for the link forwarding.
- request.full_path[1:] removes the '/' from the url
This commit is contained in:
Raphael Maenle 2021-08-12 11:45:31 +02:00
commit 85850a9d63
13 changed files with 159 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
__pycache__/

16
README.md Normal file
View File

@ -0,0 +1,16 @@
## Link shortener
this project is a tiny flask implementation that automatically generates
shortened links for any url.
If you're on a website, `add short.maenle.tech` to the beginning of the url,
and the flask app returns a shortened url that it saves in a json file on the
server and forwards to the original url when accessed.
## Further Todos
- add https encryption
- add uWSGI
- use sqlite3 instead of json

8
app/__init__.py Normal file
View File

@ -0,0 +1,8 @@
from flask import Flask
app = Flask(__name__,
static_folder='static',
template_folder='template')
from app import routes

42
app/routes.py Normal file
View File

@ -0,0 +1,42 @@
from flask import render_template,redirect,request, jsonify
from app import app
import os, json
import random, string
app.secret_key = os.environ.get("SECRET_KEY") or os.urandom(24)
app.view_functions['static']
SHORT_HOST = 'short.maenle.tech'
@app.route("/to/<path:short>", host=SHORT_HOST)
def short(short):
f = open('app/static/res/short.json', 'r')
data = json.load(f)
for s in data:
if s['short'] == short:
return redirect(s['path'], code=302)
return jsonify(success=False)
@app.route("/<path:path>", host=SHORT_HOST)
def long(path):
full_path = request.full_path[1:]
f = open('app/static/res/short.json', 'r')
data = json.load(f)
for s in data:
if s['path'] == full_path:
return jsonify(path="short.maenle.tech/to/"+s['short'])
letters = string.ascii_lowercase
short = ''.join(random.choice(letters) for i in range(12))
data.append({'path': full_path, 'short': short})
f = open('app/static/res/short.json', 'w')
json.dump(data, f)
f.close()
template = render_template("short.html", path="short.maenle.tech/to/"+short)
return template

10
app/static/css/style.css Normal file
View File

@ -0,0 +1,10 @@
html
{
font-family: Segoe UI, Frutiger, sans-serif;
width: 100%; height: 100%
}
body {
margin: 0px;
}

BIN
app/static/res/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1 @@
[]

18
app/template/short.html Normal file
View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8", content="width=device-width", name="viewport"/>
<title>Link Shortening</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
<link rel="shortcut icon" type="image/jpg" href="{{ url_for('static', filename='res/favicon.ico') }}">
</head>
<body>
<h2>
Your Link:
</h2>
{{ path }}
</body>
</html>

7
docker/README.md Normal file
View File

@ -0,0 +1,7 @@
## Goal
run short-server in a docker-compose environment
## Usage
1. `docker-compose up -d` starts the containers in background

28
docker/docker-compose.yml Normal file
View File

@ -0,0 +1,28 @@
version: '3'
services:
short-server:
build:
context: ./short-server
image: daria/short-server:latest
container_name: short-server
environment:
- FLASK_APP=/home/short-server/server.py
- FLASK_ENV=development
volumes:
- ../:/home/short-server
ports:
- "0.0.0.0:8086:8086"
networks:
net:
ipv4_address: '172.25.0.12'
volumes:
database:
driver: local
networks:
net:
ipam:
driver: default
config:
- subnet: 172.25.0.0/24

View File

@ -0,0 +1,8 @@
FROM python:3.8-slim-buster
RUN apt-get update && apt-get upgrade -y
RUN apt-get install gcc libmariadbclient-dev -y
RUN pip3 install google-oauth google-api-python-client
RUN pip3 install flask Flask-SQLAlchemy flask_migrate flask_wtf python-dotenv mysqlclient
COPY docker-entrypoint.sh /usr/local/bin/
EXPOSE 3001
ENTRYPOINT ["docker-entrypoint.sh"]

View File

@ -0,0 +1,12 @@
#!/bin/bash
set -e
sleep 5
if [[ "$1" = "shell" ]]; then
exec /bin/bash
fi
cd /home/short-server
python3 server.py

8
server.py Executable file
View File

@ -0,0 +1,8 @@
from app import app
@app.shell_context_processor
def make_shell_context():
return{'app': app, 'position': Position}
if __name__ == '__main__':
app.run('0.0.0.0', 8088, debug=True)