Add link redirects
This commit is contained in:
		
							parent
							
								
									33628a56d0
								
							
						
					
					
						commit
						b75add1e15
					
				
					 3 changed files with 55 additions and 28 deletions
				
			
		| 
						 | 
					@ -10,9 +10,14 @@ admin_password: 'password'
 | 
				
			||||||
# Hashed password (bcrypt) to make admin API requests - Preferred over plaintext, use securepass.sh to generate
 | 
					# 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
 | 
					# Please note that authentication takes noticeably longer than using plaintext password
 | 
				
			||||||
# Don't include the <username>: segment, just the hash
 | 
					# Don't include the <username>: 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'
 | 
					#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
 | 
					# Filename of the URL database
 | 
				
			||||||
# Default: 'urls'
 | 
					# Default: 'urls'
 | 
				
			||||||
database_name: 'urls'
 | 
					database_name: 'urls'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										52
									
								
								liteshort.py
									
										
									
									
									
								
							
							
						
						
									
										52
									
								
								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 bcrypt
 | 
				
			||||||
import random
 | 
					import random
 | 
				
			||||||
import sqlite3
 | 
					import sqlite3
 | 
				
			||||||
| 
						 | 
					@ -58,12 +58,8 @@ def check_long_exist(long):
 | 
				
			||||||
    return False
 | 
					    return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def check_short_exist(short, long=None):  # Allow to also check against a long link
 | 
					def check_short_exist(short):  # Allow to also check against a long link
 | 
				
			||||||
    query = query_db('SELECT * FROM urls WHERE short = ?', (short,))
 | 
					    if get_long(short):
 | 
				
			||||||
    for i in query:
 | 
					 | 
				
			||||||
        if i and i['short'] == short and i['long'] == long:
 | 
					 | 
				
			||||||
            return short
 | 
					 | 
				
			||||||
    if query:
 | 
					 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
    return False
 | 
					    return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,6 +98,13 @@ def generate_short(rq):
 | 
				
			||||||
            return short
 | 
					            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():
 | 
					def list_shortlinks():
 | 
				
			||||||
    result = query_db('SELECT * FROM urls', (), False, None)
 | 
					    result = query_db('SELECT * FROM urls', (), False, None)
 | 
				
			||||||
    result = nested_list_to_dict(result)
 | 
					    result = nested_list_to_dict(result)
 | 
				
			||||||
| 
						 | 
					@ -129,10 +132,13 @@ def response(rq, result, error_msg="Error: Unknown error"):
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return jsonify(success=False, error=error_msg)
 | 
					            return jsonify(success=False, error=error_msg)
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        if result:
 | 
					        if result and result is not True:
 | 
				
			||||||
            return render_template("main.html", result=(True, result))
 | 
					            flash(result, 'success')
 | 
				
			||||||
        else:
 | 
					            return render_template("main.html")
 | 
				
			||||||
            return render_template("main.html", result=(False, error_msg))
 | 
					        elif not result:
 | 
				
			||||||
 | 
					            flash(error_msg, 'error')
 | 
				
			||||||
 | 
					            return render_template("main.html")
 | 
				
			||||||
 | 
					        return render_template("main.html")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def validate_short(short):
 | 
					def validate_short(short):
 | 
				
			||||||
| 
						 | 
					@ -175,36 +181,46 @@ def close_db(error):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.config.update(load_config())  # Add YAML config to Flask config
 | 
					app.config.update(load_config())  # Add YAML config to Flask config
 | 
				
			||||||
 | 
					app.secret_key = app.config['secret_key']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.route('/')
 | 
					@app.route('/')
 | 
				
			||||||
def main():
 | 
					def main():
 | 
				
			||||||
    return render_template("main.html")
 | 
					    return response(request, True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route('/<url>')
 | 
				
			||||||
 | 
					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'])
 | 
					@app.route('/', methods=['POST'])
 | 
				
			||||||
def main_post():
 | 
					def main_post():
 | 
				
			||||||
    # Check if long in form (ie. provided by curl) and not blank (browsers always send blank forms as empty quote)
 | 
					    # 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 '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']:
 | 
					        if 'short' in request.form and request.form['short']:
 | 
				
			||||||
            # Validate long as URL and short custom text against allowed characters
 | 
					            # 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'])
 | 
					            result = validate_short(request.form['short'])
 | 
				
			||||||
            if validate_short(request.form['short']) is True:
 | 
					            if validate_short(request.form['short']) is True:
 | 
				
			||||||
                short = request.form['short']
 | 
					                short = request.form['short']
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                return result
 | 
					                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,
 | 
					                return response(request, (current_app.config['site_url'] or request.base_url) + short,
 | 
				
			||||||
                                'Error: Failed to return pre-existing non-random shortlink')
 | 
					                                'Error: Failed to return pre-existing non-random shortlink')
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            short = generate_short(request)
 | 
					            short = generate_short(request)
 | 
				
			||||||
        if check_short_exist(short) is True:
 | 
					        if check_short_exist(short):
 | 
				
			||||||
            return response(request, None,
 | 
					            return response(request, None,
 | 
				
			||||||
                            'Short URL already exists')
 | 
					                            'Short URL already taken')
 | 
				
			||||||
        long_exists = check_long_exist(request.form['long'])
 | 
					        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,
 | 
					            return response(request, (current_app.config['site_url'] or request.base_url) + long_exists,
 | 
				
			||||||
                            'Error: Failed to return pre-existing random shortlink')
 | 
					                            'Error: Failed to return pre-existing random shortlink')
 | 
				
			||||||
        get_db().cursor().execute('INSERT INTO urls (long,short) VALUES (?,?)', (request.form['long'], short))
 | 
					        get_db().cursor().execute('INSERT INTO urls (long,short) VALUES (?,?)', (request.form['long'], short))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,14 +23,20 @@
 | 
				
			||||||
            </p>
 | 
					            </p>
 | 
				
			||||||
        </form>
 | 
					        </form>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    {% if result is defined and result[0] %}
 | 
					    {% with messages = get_flashed_messages(with_categories=true) %}
 | 
				
			||||||
    <div class="success">
 | 
					        {% if messages %}
 | 
				
			||||||
        ✓ Shortlink successfully generated! Available at  <a href="{{ result[1] }}">{{ result[1] }}</a>
 | 
					            {% for category, message in messages %}
 | 
				
			||||||
    </div>
 | 
					                {% if category == 'success' %}
 | 
				
			||||||
    {% elif result is defined and not result[0] %}
 | 
					                <div class="success">
 | 
				
			||||||
    <div class="error">
 | 
					                    ✓ Shortlink successfully generated! Available at  <a href="{{ message }}">{{ message }}</a>
 | 
				
			||||||
        ✖ Shortlink failed to generate! {{ result[1] }}
 | 
					                </div>
 | 
				
			||||||
    </div>
 | 
					                {% elif category == 'error' %}
 | 
				
			||||||
    {% endif %}
 | 
					                <div class="error">
 | 
				
			||||||
 | 
					                    ✖ {{ message }}
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                {% endif %}
 | 
				
			||||||
 | 
					            {% endfor %}
 | 
				
			||||||
 | 
					        {% endif %}
 | 
				
			||||||
 | 
					    {% endwith %}
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
		Reference in a new issue