mirror of
https://git.ikl.sh/132ikl/liteshort.git
synced 2023-08-10 21:13:04 +03:00
Add latest shortlink functionality, disable browser cache for redirects, fix baseurl retrieval
This commit is contained in:
parent
62edb23d59
commit
9800858fb3
@ -54,6 +54,12 @@ site_domain:
|
|||||||
# Default: unset
|
# Default: unset
|
||||||
subdomain:
|
subdomain:
|
||||||
|
|
||||||
|
# String: URL which takes you to the most recent short URL's destination
|
||||||
|
# Short URLs cannot be created with this string if set
|
||||||
|
# Default: l
|
||||||
|
latest: 'l'
|
||||||
|
|
||||||
# Boolean: Show link to project repository on GitHub at bottom right corner of page
|
# Boolean: Show link to project repository on GitHub at bottom right corner of page
|
||||||
# Default: true
|
# Default: true
|
||||||
show_github_link: true
|
show_github_link: true
|
||||||
|
|
||||||
|
52
liteshort.py
52
liteshort.py
@ -3,7 +3,7 @@
|
|||||||
# This software is license under the MIT license. It should be included in your copy of this software.
|
# This software is license under the MIT license. It should be included in your copy of this software.
|
||||||
# A copy of the MIT license can be obtained at https://mit-license.org/
|
# A copy of the MIT license can be obtained at https://mit-license.org/
|
||||||
|
|
||||||
from flask import Flask, current_app, flash, g, jsonify, redirect, render_template, request, send_from_directory, url_for
|
from flask import Flask, current_app, flash, g, jsonify, make_response, redirect, render_template, request, send_from_directory, url_for
|
||||||
import bcrypt
|
import bcrypt
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
@ -22,13 +22,13 @@ def load_config():
|
|||||||
req_options = {'admin_username': 'admin', 'database_name': "urls", 'random_length': 4,
|
req_options = {'admin_username': 'admin', 'database_name': "urls", 'random_length': 4,
|
||||||
'allowed_chars': 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
|
'allowed_chars': 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
|
||||||
'random_gen_timeout': 5, 'site_name': 'liteshort', 'site_domain': None, 'show_github_link': True,
|
'random_gen_timeout': 5, 'site_name': 'liteshort', 'site_domain': None, 'show_github_link': True,
|
||||||
'secret_key': None, 'disable_api': False, 'subdomain': ''
|
'secret_key': None, 'disable_api': False, 'subdomain': '', 'latest': 'l'
|
||||||
}
|
}
|
||||||
|
|
||||||
config_types = {'admin_username': str, 'database_name': str, 'random_length': int,
|
config_types = {'admin_username': str, 'database_name': str, 'random_length': int,
|
||||||
'allowed_chars': str, 'random_gen_timeout': int, 'site_name': str,
|
'allowed_chars': str, 'random_gen_timeout': int, 'site_name': str,
|
||||||
'site_domain': (str, type(None)), 'show_github_link': bool, 'secret_key': str,
|
'site_domain': (str, type(None)), 'show_github_link': bool, 'secret_key': str,
|
||||||
'disable_api': bool, 'subdomain': (str, type(None))
|
'disable_api': bool, 'subdomain': (str, type(None)), 'latest': (str, type(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
for option in req_options.keys():
|
for option in req_options.keys():
|
||||||
@ -62,7 +62,7 @@ def authenticate(username, password):
|
|||||||
def check_long_exist(long):
|
def check_long_exist(long):
|
||||||
query = query_db('SELECT short FROM urls WHERE long = ?', (long,))
|
query = query_db('SELECT short FROM urls WHERE long = ?', (long,))
|
||||||
for i in query:
|
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
|
if i and (len(i['short']) <= current_app.config["random_length"]) and i['short'] != current_app.config['latest']: # Checks if query if pre-existing URL is same as random length URL
|
||||||
return i['short']
|
return i['short']
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ def generate_short(rq):
|
|||||||
return response(rq, None, 'Timeout while generating random short URL')
|
return response(rq, None, 'Timeout while generating random short URL')
|
||||||
short = ''.join(random.choice(current_app.config['allowed_chars'])
|
short = ''.join(random.choice(current_app.config['allowed_chars'])
|
||||||
for i in range(current_app.config['random_length']))
|
for i in range(current_app.config['random_length']))
|
||||||
if not check_short_exist(short):
|
if not check_short_exist(short) and short != app.config['latest']:
|
||||||
return short
|
return short
|
||||||
|
|
||||||
|
|
||||||
@ -114,6 +114,14 @@ def get_long(short):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_baseUrl():
|
||||||
|
if current_app.config['site_domain']:
|
||||||
|
# TODO: un-hack-ify adding the protocol here
|
||||||
|
return 'https://' + current_app.config['site_domain'] + '/'
|
||||||
|
else:
|
||||||
|
return request.base_url
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
@ -143,14 +151,25 @@ def response(rq, result, error_msg="Error: Unknown error"):
|
|||||||
else:
|
else:
|
||||||
if result and result is not True:
|
if result and result is not True:
|
||||||
flash(result, 'success')
|
flash(result, 'success')
|
||||||
return render_template("main.html")
|
|
||||||
elif not result:
|
elif not result:
|
||||||
flash(error_msg, 'error')
|
flash(error_msg, 'error')
|
||||||
return render_template("main.html")
|
return render_template("main.html")
|
||||||
return render_template("main.html")
|
|
||||||
|
|
||||||
|
def set_latest(long):
|
||||||
|
if app.config['latest']:
|
||||||
|
if query_db('SELECT short FROM urls WHERE short = ?', (current_app.config['latest'],)):
|
||||||
|
get_db().cursor().execute("UPDATE urls SET long = ? WHERE short = ?",
|
||||||
|
(long, current_app.config['latest']))
|
||||||
|
else:
|
||||||
|
get_db().cursor().execute("INSERT INTO urls (long,short) VALUES (?, ?)",
|
||||||
|
(long, current_app.config['latest']))
|
||||||
|
|
||||||
|
|
||||||
def validate_short(short):
|
def validate_short(short):
|
||||||
|
if short == app.config['latest']:
|
||||||
|
return response(request, None,
|
||||||
|
'Short URL cannot be the same as a special URL ({})'.format(short))
|
||||||
for char in short:
|
for char in short:
|
||||||
if char not in current_app.config['allowed_chars']:
|
if char not in current_app.config['allowed_chars']:
|
||||||
return response(request, None,
|
return response(request, None,
|
||||||
@ -209,10 +228,12 @@ def main():
|
|||||||
def main_redir(url):
|
def main_redir(url):
|
||||||
long = get_long(url)
|
long = get_long(url)
|
||||||
if long:
|
if long:
|
||||||
return redirect(long, 301)
|
resp = make_response(redirect(long, 301))
|
||||||
|
else:
|
||||||
flash('Short URL "' + url + '" doesn\'t exist', 'error')
|
flash('Short URL "' + url + '" doesn\'t exist', 'error')
|
||||||
redirect_site = url_for('main')
|
resp = make_response(redirect(url_for('main')))
|
||||||
return redirect(redirect_site)
|
resp.headers.set('Cache-Control', 'no-store, must-revalidate')
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
@app.route('/', methods=['POST'], subdomain=app.config['subdomain'])
|
@app.route('/', methods=['POST'], subdomain=app.config['subdomain'])
|
||||||
@ -228,7 +249,7 @@ def main_post():
|
|||||||
else:
|
else:
|
||||||
return result
|
return result
|
||||||
if get_long(short) == request.form['long']:
|
if get_long(short) == request.form['long']:
|
||||||
return response(request, (('https://' + app.config['site_domain'] + '/') or request.base_url) + short,
|
return response(request, get_baseUrl() + 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)
|
||||||
@ -237,12 +258,15 @@ def main_post():
|
|||||||
'Short URL already taken')
|
'Short URL already taken')
|
||||||
long_exists = check_long_exist(request.form['long'])
|
long_exists = check_long_exist(request.form['long'])
|
||||||
if long_exists and not request.form.get('short'):
|
if long_exists and not request.form.get('short'):
|
||||||
# TODO: un-hack-ify adding the protocol here
|
set_latest(request.form['long'])
|
||||||
return response(request, (('https://' + app.config['site_domain'] + '/') or request.base_url) + long_exists,
|
get_db().commit()
|
||||||
|
return response(request, get_baseUrl() + 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))
|
||||||
|
set_latest(request.form['long'])
|
||||||
get_db().commit()
|
get_db().commit()
|
||||||
return response(request, (('https://' + app.config['site_domain'] + '/') or request.base_url) + short,
|
|
||||||
|
return response(request, get_baseUrl() + short,
|
||||||
'Error: Failed to generate')
|
'Error: Failed to generate')
|
||||||
elif request.form.get('api'):
|
elif request.form.get('api'):
|
||||||
if current_app.config['disable_api']:
|
if current_app.config['disable_api']:
|
||||||
|
Loading…
Reference in New Issue
Block a user