Commit b58f1dd2 authored by 132ikl's avatar 132ikl

Add web interface styling and configuration, fix existing long URL retrieval...

Add web interface styling and configuration, fix existing long URL retrieval and duplicate short URL checks
parent 513050e1
......@@ -26,4 +26,8 @@ allowed_chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
# Amount of time in seconds to spend generating random short URLs until timeout
# Default: 5
random_gen_timeout: 5
\ No newline at end of file
random_gen_timeout: 5
# Name shown on tab while on site and on page header
# Default: 'liteshort'
site_name: 'liteshort'
\ No newline at end of file
from flask import Flask, Response, request, current_app, g, send_from_directory
from flask import Flask, request, current_app, g, render_template
import bcrypt
import random
import sqlite3
......@@ -12,11 +12,11 @@ def load_config():
req_options = {'admin_username': 'admin', 'database_name': "urls", 'random_length': 4,
'allowed_chars': 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
'random_gen_timeout': 5
'random_gen_timeout': 5, 'site_name': 'liteshort'
}
config_types = {'admin_username': str, 'database_name': str, 'random_length': int,
'allowed_chars': str, 'random_gen_timeout': int}
'allowed_chars': str, 'random_gen_timeout': int, 'site_name': str}
for option in req_options.keys():
if option not in new_config.keys(): # Make sure everything in req_options is set in config
......@@ -45,19 +45,18 @@ def check_password(password, pass_config):
raise RuntimeError('This should never occur! Bailing...')
def check_short_exist(database, short):
database.cursor().execute("SELECT long FROM urls WHERE short = ?", (short,))
result = database.cursor().fetchone()
if database.cursor().fetchone():
return result
def check_short_exist(short):
query = query_db('SELECT long FROM urls WHERE short = ?', (short,))
if query:
return True
return False
def check_long_exist(database, long):
database.cursor().execute("SELECT short FROM urls WHERE long = ?", (long,))
result = database.cursor().fetchone()
if database.cursor().fetchone():
return result
def check_long_exist(long):
query = query_db('SELECT short FROM urls WHERE long = ?', (long,))
for i in query:
if i and (len(i['short']) <= current_app.config["random_length"]): # Checks if query if pre-existing URL is same as random length URL
return i['short']
return False
......@@ -77,6 +76,23 @@ def get_db():
return g.db
def query_db(query, args=(), one=False):
cur = get_db().execute(query, args)
rv = cur.fetchall()
cur.close()
return (rv[0] if rv else None) if one else rv
def response(rq, short, error_msg=None):
if 'json' in rq.form and rq.form['json']:
pass
else:
if short:
return render_template("main.html", result=(True, rq.base_url + short))
else:
return render_template("main.html", result=(False, error_msg))
config = load_config()
app = Flask(__name__)
......@@ -85,36 +101,36 @@ app.config.update(config) # Add loaded YAML config to Flask config
@app.route('/')
def main():
return send_from_directory('static', 'main.html')
return render_template("main.html")
@app.route('/', methods=['POST'])
def main_post():
if 'long' in request.form and request.form['long']:
database = get_db()
if 'short' in request.form and request.form['short']:
for char in request.form['short']:
if char not in current_app.config['allowed_chars']:
return Response('Character ' + char + ' not allowed in short URL.', status=200)
return response(request, None, 'Character ' + char + ' not allowed in short URL.')
short = request.form['short']
else:
timeout = time.time() + current_app.config['random_gen_timeout']
while True:
if time.time() >= timeout:
return Response('Timeout while generating random short URL.', status=200)
return response(request, None, 'Timeout while generating random short URL.')
short = generate_short()
if not check_short_exist(database, short):
if not check_short_exist(short):
break
short_exists = check_short_exist(database, short)
long_exists = check_long_exist(database, request.form['long'])
if long_exists and 'short' not in request.form:
return request.base_url + long_exists
short_exists = check_short_exist(short)
long_exists = check_long_exist(request.form['long'])
if long_exists and not ('short' in request.form and request.form['short']):
return response(request, long_exists)
if short_exists:
return Response('Short URL already exists.', status=200)
return response(request, None, "Short URL already exists.")
database = get_db()
database.cursor().execute("INSERT INTO urls (long,short) VALUES (?,?)", (request.form['long'], short))
database.commit()
database.close()
return "Your shortened URL is available at " + request.base_url + short
return response(request, short)
else:
return "Long URL required!"
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>liteshort</title>
</head>
<body>
<form>
Long URL:
<br>
<input name="long" type="url">
<br>
Short URL:
<br>
<input name="short" type="text">
<br> <!-- TODO: Use CSS to do linebreaks -->
<input type="submit" value="Shorten" formmethod="post">
</form>
</body>
</html>
\ No newline at end of file
div.form {
margin-top: 5%;
text-align: center;
}
input {
margin: auto;
}
div.success {
display: inline-block;
font-family: Open Sans;
border-radius: 2vh;
padding: 2vh;
color: #62ad2c;
background-color: #E9FFD9;
border: 1px solid #62ad2c;
}
div.error {
display: inline-block;
font-family: Open Sans;
border-radius: 2vh;
padding: 2vh;
color: #a86464;
background-color: #FCE9E9;
border: 1px solid #a86464;
}
body {
text-align: center
}
div.success > a:link {
color: #62ad2c;
}
div.success > a:visited {
color: #507c52;
}
h2 {
font-weight: normal;
font-family: Open Sans;
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ config.site_name }}</title>
<link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="form">
<h2>{{ config.site_name }}</h2>
<form class="pure-form">
<input name="long" type="url" placeholder="Long URL">
<p>
<input name="short" type="text" placeholder="Custom link (optional)">
<p>
<button type="submit" class="pure-button pure-button-primary" formmethod="post">Shorten</button>
</form>
</div>
{% if result is defined and result[0] %}
<div class="success">
✓ Shortlink successfully generated! Available at <a href="{{ result[1] }}">{{ result[1] }}</a>
</div>
{% elif result is defined and not result[0] %}
<div class="error">
✖ Shortlink failed to generate! {{ result[1] }}
</div>
{% endif %}
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment