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] %} -
- ✓ Shortlink successfully generated! Available at {{ result[1] }} -
- {% 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 %} \ No newline at end of file