From b75add1e15074d369a2f331402b98105ebe54f00 Mon Sep 17 00:00:00 2001
From: 132ikl <132@ikl.sh>
Date: Sun, 24 Feb 2019 01:36:10 -0500
Subject: [PATCH] Add link redirects
---
config.yml | 7 +++++-
liteshort.py | 52 +++++++++++++++++++++++++++++----------------
templates/main.html | 24 +++++++++++++--------
3 files changed, 55 insertions(+), 28 deletions(-)
diff --git a/config.yml b/config.yml
index 52201c3..193dd63 100644
--- a/config.yml
+++ b/config.yml
@@ -10,9 +10,14 @@ admin_password: 'password'
# Hashed password (bcrypt) to make admin API requests - Preferred over plaintext, use securepass.sh to generate
# Please note that authentication takes noticeably longer than using plaintext password
# Don't include the : segment, just the hash
-# Default: '$2y$15$Dhll3IY42R.JNOYazarlG.8IndwMjxmHLpFsebJzcGTJd.gbsAwna' (hash for 'password')
+# Default: unset (required to start application)
#admin_hashed_password: '$2y$15$Dhll3IY42R.JNOYazarlG.8IndwMjxmHLpFsebJzcGTJd.gbsAwna'
+# Secret key used for cookies (used for storage of messages)
+# This should be a 12-16 character randomized string with letters, numbers, and symbols
+# Default: unset (required to start application)
+secret_key: 'S$JI8L*&xua%gBoL'
+
# Filename of the URL database
# Default: 'urls'
database_name: 'urls'
diff --git a/liteshort.py b/liteshort.py
index 8abc726..2454432 100644
--- a/liteshort.py
+++ b/liteshort.py
@@ -1,4 +1,4 @@
-from flask import Flask, request, current_app, g, render_template, jsonify
+from flask import Flask, current_app, flash, g, jsonify, redirect, render_template, request, url_for
import bcrypt
import random
import sqlite3
@@ -58,12 +58,8 @@ def check_long_exist(long):
return False
-def check_short_exist(short, long=None): # Allow to also check against a long link
- query = query_db('SELECT * FROM urls WHERE short = ?', (short,))
- for i in query:
- if i and i['short'] == short and i['long'] == long:
- return short
- if query:
+def check_short_exist(short): # Allow to also check against a long link
+ if get_long(short):
return True
return False
@@ -102,6 +98,13 @@ def generate_short(rq):
return short
+def get_long(short):
+ row = query_db('SELECT long FROM urls WHERE short = ?', (short,), True)
+ if row and row['long']:
+ return row['long']
+ return None
+
+
def list_shortlinks():
result = query_db('SELECT * FROM urls', (), False, None)
result = nested_list_to_dict(result)
@@ -129,10 +132,13 @@ def response(rq, result, error_msg="Error: Unknown error"):
else:
return jsonify(success=False, error=error_msg)
else:
- if result:
- return render_template("main.html", result=(True, result))
- else:
- return render_template("main.html", result=(False, error_msg))
+ if result and result is not True:
+ flash(result, 'success')
+ return render_template("main.html")
+ elif not result:
+ flash(error_msg, 'error')
+ return render_template("main.html")
+ return render_template("main.html")
def validate_short(short):
@@ -175,36 +181,46 @@ def close_db(error):
app.config.update(load_config()) # Add YAML config to Flask config
+app.secret_key = app.config['secret_key']
@app.route('/')
def main():
- return render_template("main.html")
+ return response(request, True)
+
+
+@app.route('/')
+def main_redir(url):
+ long = get_long(url)
+ if long:
+ return redirect(long, 301)
+ flash('Short URL "' + url + '" doesn\'t exist', 'error')
+ return redirect(url_for('main'))
@app.route('/', methods=['POST'])
def main_post():
# Check if long in form (ie. provided by curl) and not blank (browsers always send blank forms as empty quote)
if 'long' in request.form and request.form['long']:
+ if not validate_long(request.form['long']):
+ return response(request, None, "Long URL is not valid")
if 'short' in request.form and request.form['short']:
# Validate long as URL and short custom text against allowed characters
- if not validate_long(request.form['long']):
- return response(request, None, "Long URL is not valid")
result = validate_short(request.form['short'])
if validate_short(request.form['short']) is True:
short = request.form['short']
else:
return result
- if check_short_exist(short, request.form['long']) is short:
+ if get_long(short) == request.form['long']:
return response(request, (current_app.config['site_url'] or request.base_url) + short,
'Error: Failed to return pre-existing non-random shortlink')
else:
short = generate_short(request)
- if check_short_exist(short) is True:
+ if check_short_exist(short):
return response(request, None,
- 'Short URL already exists')
+ 'Short URL already taken')
long_exists = check_long_exist(request.form['long'])
- if long_exists:
+ if long_exists and not request.form['short']:
return response(request, (current_app.config['site_url'] or request.base_url) + long_exists,
'Error: Failed to return pre-existing random shortlink')
get_db().cursor().execute('INSERT INTO urls (long,short) VALUES (?,?)', (request.form['long'], short))
diff --git a/templates/main.html b/templates/main.html
index 4b35405..94dd809 100644
--- a/templates/main.html
+++ b/templates/main.html
@@ -23,14 +23,20 @@
- {% if result is defined and result[0] %}
-
- {% elif result is defined and not result[0] %}
-
- ✖ Shortlink failed to generate! {{ result[1] }}
-
- {% endif %}
+ {% with messages = get_flashed_messages(with_categories=true) %}
+ {% if messages %}
+ {% for category, message in messages %}
+ {% if category == 'success' %}
+
+ ✓ Shortlink successfully generated! Available at
{{ message }}
+
+ {% elif category == 'error' %}
+
+ ✖ {{ message }}
+
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+ {% endwith %}