Commit 40c289dc authored by JackV's avatar JackV
Browse files

First implementation

parent 518ce489
body {
background-color: #90f290;
}
table#link_table * {
border: 1px solid black;
}
table#link_table {
border-collapse: collapse;
}
table#link_table * > td {
padding: 10px;
margin: auto;
}
<html>
<head>
<title>UUS Admin Area</title>
<link rel="stylesheet" href="admin/admin.css">
</head>
<body>
<div>
<div>
<form id="new_link" action="" method="post">
<label>Short Url Name: </label>
<input type="text" id="short_url" />
<label>Long Url Address: </label>
<input type="text" id="long_url">
<input id="newlink_submit" type="button" value="Add"
</form>
</div>
<div class="links">
<table id="link_table">
<tr>
<th>Short Link Name</th>
<th>Redirect Url</th>
<th>View Count</th>
<th>Options</th>
</tr>
</table>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="admin/admin.js"></script>
</body>
</html>
var edit_field = '<input type="button" class="edit_btn" value="Edit"></input><input type="button" class="del_btn" value="Delete"></input>';
function refresh_list(){
$("table#link_table").find("tr:gt(0)").remove();
$.ajax({
type: "GET",
url: "/api/v1/listurls",
dataType: "json",
success: function(response){
$.each(response, function(index, value){
$("#link_table").append('<tr id="'+ index +'"><td>'+ index +
"</td><td>"+ value['url'] +
"</td><td>"+ value['count'] +
"</td><td>"+ edit_field +"</td>")
})
}
})
}
$(document).ready(function(){
refresh_list();
})
$(document).on("click", "#newlink_submit", function(){
var short_url = $(this).parent().children("#short_url")[0].value;
var long_url = $(this).parent().children("#long_url")[0].value;
$.ajax({
type: "POST",
url: "/api/v1/addurl",
contentType: "application/json",
data: JSON.stringify({"name": short_url, "url": long_url}),
success: function(){refresh_list()}
})
})
$(document).on("click", ".edit_btn", function(){
var table_row = $(this).closest('tr');
var short_url = table_row.attr('id');
var long_url = $(table_row).children("td")[1].innerHTML;
document.getElementById('short_url').value = short_url;
document.getElementById('long_url').value = long_url;
window.scrollTo(0,0);
})
$(document).on("click", ".del_btn", function(){
var button_elem = $(this);
var link_id = button_elem.closest('tr').attr('id');
$.ajax({
type: "POST",
url: "/api/v1/delurl",
contentType: "application/json",
data: JSON.stringify({"name": link_id}),
success: function(){refresh_list()}
})
})
#!/usr/bin/env python3
import flask
from flask_redis import FlaskRedis
from flask_httpauth import HTTPBasicAuth
import re
import os
app = flask.Flask(__name__)
auth = HTTPBasicAuth()
app.config['REDIS_URL'] = 'redis://127.0.0.1:6379/0'
redis_store = FlaskRedis()
redis_store.init_app(app)
pure_string = re.compile(r'^\w+$')
admin_dir = os.path.join(os.getcwd(), 'admin')
def handle_redirect(path):
final_url = redis_store.get('url.' + path)
if final_url:
redis_store.incr('count.' + path)
return flask.redirect(final_url)
else:
return flask.abort(404)
@auth.get_password
def handle_login(username):
password = redis_store.get("user." + username)
if password is not None:
return password.decode()
else:
return None
@app.route('/admin')
@auth.login_required
def adminui():
return flask.send_from_directory(admin_dir,
'admin.html',
as_attachment=False)
@app.route('/admin/<path:path>')
@auth.login_required
def admin_files(path):
return flask.send_from_directory(admin_dir,
path,
as_attachment=False)
@app.route('/api/v1/addurl', methods=['POST'])
@auth.login_required
def add_url():
payload = flask.request.get_json()
if payload:
try:
short_url = payload['name']
long_url = payload['url']
if not pure_string.match(short_url):
return flask.abort(400)
if not redis_store.exists('url.' + short_url):
redis_store.set('count.' + short_url, 0)
redis_store.set('url.' + short_url, long_url)
return ''
except KeyError:
return flask.abort(400)
else:
flask.abort(400)
@app.route('/api/v1/delurl', methods=['POST'])
@auth.login_required
def del_url():
payload = flask.request.get_json()
if payload:
try:
redis_store.delete('url.' + payload['name'])
redis_store.delete('count.' + payload['name'])
return ''
except KeyError:
return flask.abort(400)
else:
flask.abort(400)
@app.route('/api/v1/listurls')
@auth.login_required
def list_urls():
keys = map(lambda x: x.decode(), redis_store.keys('url.*'))
return_dict = {}
for key in keys:
real_key = key.replace('url.', '', 1)
return_dict[real_key] = {'url': redis_store.get(key).decode(),
'count': int(redis_store.get('count.' + real_key).decode())}
return flask.jsonify(return_dict)
@app.route('/<path:path>')
def redirect(path):
if pure_string.match(path):
return handle_redirect(path)
else:
return flask.abort(404)
if __name__ == "__main__":
app.run()
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