mirror of
https://github.com/gamaio/lobli.git
synced 2024-12-22 19:52:40 +00:00
Redis-only version of lob.li - Almost complete.
This version removes all the mysql stuff and uses a redis db for everything.
This commit is contained in:
parent
e52c236e47
commit
adfcc57e00
@ -13,41 +13,56 @@
|
||||
5 - Successful lob.li link resolve
|
||||
6 - Successful lookup of non-lob.li link
|
||||
7 - Unsuccessful lookup of non-lob.li link
|
||||
8 - Lookup of link Stats (returns 8 $sep JSONarray)
|
||||
*/
|
||||
|
||||
function shorten($sdb, $link, $seperator){
|
||||
$sql = "SELECT * FROM `links` WHERE `link` = '$link' LIMIT 1;";
|
||||
if($result = $sdb->query($sql)){
|
||||
if($row = $result->fetch_assoc()){
|
||||
$short = $row['shortlink'];
|
||||
return "1$seperator$short";
|
||||
}
|
||||
}
|
||||
if(checkRemoteFile($link) !== true) return "2$seperator$link";
|
||||
$title = getRemoteTitle($link);
|
||||
|
||||
$short = substr(number_format(time() * mt_rand(),0,'',''),0,5);
|
||||
$short = base_convert($short, 10, 36);
|
||||
|
||||
$dpass = substr(number_format(time() * mt_rand(),0,'',''),0,10);
|
||||
$dpass = base_convert($short.$dpass, 10, 36);
|
||||
function shorten($redis, $link, $linkage, $seperator){
|
||||
$short = $redis->get("links:id:$link");
|
||||
if($short){
|
||||
$title = $redis->get("links:title:$link");
|
||||
return "1$seperator$link$seperator$title";
|
||||
}else{
|
||||
do {
|
||||
if(checkRemoteFile($link) !== true) return "2$seperator$link";
|
||||
$title = getRemoteTitle($url);
|
||||
|
||||
$sql = "INSERT INTO `links` (link, shortlink, title, dpass, ddate) VALUES ('$link', '$short', '$title', '$dpass', NOW())";
|
||||
$short = substr(number_format(time() * mt_rand(),0,'',''),0,5);
|
||||
$short = base_convert($short, 10, 36);
|
||||
|
||||
if($result = $sdb->query($sql)): return "0$seperator$short$seperator$title";
|
||||
else: return '3'.$seperator.$sdb->error;
|
||||
endif;
|
||||
if(!$redis->exists("links:id:$short")) {
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
$xTime = 3136320000; // About 100 years, give or take
|
||||
|
||||
// Delete the links in 24 hours, 1 week, 1 month respectevly
|
||||
if($linkage == '0') $xTime = 86400;
|
||||
if($linkage == '1') $xTime = 604800;
|
||||
if($linkage == '2') $xTime = 2628000;
|
||||
|
||||
$redis->setex("links:id:$short", $xTime, $link);
|
||||
$redis->setex("links:title:$short", $xTime, $title);
|
||||
$redis->setex("links:date:$short", $xTime, date("d/m/Y", strtotime($str)));
|
||||
$redis->setex("tracking:clicks:$link", $xTime, 1);
|
||||
|
||||
return "0$seperator$short$seperator$title";
|
||||
}
|
||||
}
|
||||
|
||||
function stats($sdb, $seperator){
|
||||
|
||||
function stats($redis, $seperator){
|
||||
$tracking = $redis->keys("tracking:clicks:*");
|
||||
$tracking = rsort($tracking);
|
||||
$tracking = array_slice($tracking, 0, 5, true);
|
||||
return "8$seperator".json_encode($tracking);
|
||||
}
|
||||
|
||||
function getRemoteTitle($url){
|
||||
$url = parse_url($url);
|
||||
$tags = get_meta_tags($url['scheme'].'://'.$url['host']);
|
||||
$ret = sanitize($tags['description']);
|
||||
return $ret;
|
||||
if($tags = get_meta_tags($url['scheme'].'://'.$url['host'])){
|
||||
$ret = $tags['description'];
|
||||
return $ret;
|
||||
}else{ return false; }
|
||||
}
|
||||
|
||||
function checkRemoteFile($ip=null){
|
||||
@ -77,10 +92,11 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
function sanitize($input){
|
||||
if ($input == null) die("4");
|
||||
function sanitize($input, $seperator){
|
||||
if ($input == null) die("4$seperator");
|
||||
$output = strip_tags($input);
|
||||
$output = stripslashes($output);
|
||||
//filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING)
|
||||
$output = mysql_real_escape_string($output);
|
||||
return $output;
|
||||
}
|
||||
|
@ -1,6 +1,22 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
/*
|
||||
Redis scheme:
|
||||
links:
|
||||
id:
|
||||
link id - set to website
|
||||
title:
|
||||
link id - set to page description
|
||||
date:
|
||||
link id - set to today's date
|
||||
tracking:
|
||||
clicks:
|
||||
link id - int, increments with each unique IP
|
||||
ip:
|
||||
link id - list holding all visiting IPs for that link
|
||||
*/
|
||||
|
||||
// Generate a token on the fly. This should prevent POST spam attacks directly into process.php
|
||||
$token = substr(number_format(time() * mt_rand(),0,'',''),0,10);
|
||||
$token = base_convert($token, 10, 36);
|
||||
@ -13,47 +29,31 @@
|
||||
|
||||
require('Include/PHP/db.php');
|
||||
|
||||
function followLink($shortdb, $redis, $link){
|
||||
$link = $shortdb->real_escape_string(strtolower(stripslashes(strip_tags($link))));
|
||||
$link = str_replace('/', '', $link);
|
||||
|
||||
$sql = "SELECT * FROM `tracking` WHERE `id` = '$link' LIMIT 1;"; // Testing to see if the link has been visited before
|
||||
if($result = $shortdb->query($sql)){
|
||||
if($row = $result->fetch_assoc()){
|
||||
$sql = "UPDATE `tracking` SET `clicks` = `clicks` + 1 WHERE `id` = '$link'"; // Yes it has, increment clicks by 1
|
||||
if($result = $shortdb->query($sql)){
|
||||
if($result->num_rows == 0){
|
||||
die ($shortdb->error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$sql = "INSERT INTO `tracking` (id, clicks) VALUES ('$link', 1)"; // No it hasn't, add 1 click to the table
|
||||
if($result = $shortdb->query($sql)){
|
||||
if($result->num_rows == 0){
|
||||
die ($shortdb->error);
|
||||
function followLink($redis, $link){
|
||||
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) { // Get true IP of visiter if going through cloudflare
|
||||
$_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
|
||||
}
|
||||
|
||||
$ipTrack = $redis->lRange("tracking:ip:$link", 0, -1);
|
||||
if(!in_array($_SERVER['REMOTE_ADDR'], $ipTrack)){ // Check to see if visiter hit this link before (This would make it a lot easier to skew statistics if anyone would register multiples times)
|
||||
$redis->rPush("tracking:ip:$link", $_SERVER['REMOTE_ADDR']);
|
||||
|
||||
// Tracking code
|
||||
$tracking = $redis->get("tracking:clicks:$link");
|
||||
$trTtl = $redis->ttl("links:id:$link");
|
||||
|
||||
if(!$tracking || $trTtl != -2){
|
||||
$tracking = $redis->set("tracking:clicks:$link", 1);
|
||||
}else{
|
||||
if($trTtl == -2){ // The link has been deleted, no need to track it anymore
|
||||
break;
|
||||
}
|
||||
$tracking = $redis->incr("tracking:clicks:$link");
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find it in the redis db first, if not there, add it
|
||||
|
||||
$short = $redis->get($link);
|
||||
if (!$short || $short == null) {
|
||||
$sql = "SELECT * FROM `links` WHERE `shortlink` = '$link' LIMIT 1;";
|
||||
if($result = $shortdb->query($sql)){
|
||||
if($row = $result->fetch_assoc()){
|
||||
$llink = $row['link'];
|
||||
|
||||
$redis->set($link, $llink);
|
||||
|
||||
echo $llink;
|
||||
|
||||
//header("location:$link");
|
||||
exit(5); // Stop script execution to save on resources
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$short = $redis->get("links:id:$link");
|
||||
if($short){
|
||||
echo $short;
|
||||
exit(5);
|
||||
}
|
||||
@ -72,7 +72,7 @@
|
||||
|
||||
// This has been depreciated. Still here for backwards compatibility with existing links
|
||||
if(!empty($_GET['l'])){
|
||||
followLink($shortdb, $redis, $_GET['l']);
|
||||
followLink($redis, $_GET['l']);
|
||||
}
|
||||
|
||||
// New way to check for valid short links, two characters shorter than the if statement above
|
||||
@ -83,7 +83,7 @@
|
||||
if($key == "resolv"){ header("location:http://r.lob.li"); exit(12); }
|
||||
if($key == "about"){ header("location:http://a.lob.li"); exit(13); }
|
||||
|
||||
followLink($shortdb, $redis, $key);
|
||||
followLink($redis, $key);
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
@ -124,10 +124,10 @@
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon lexp">
|
||||
<select name="linkage" id="linkage">
|
||||
<option selected="selected">24hrs</option>
|
||||
<option>1 Week</option>
|
||||
<option>1 Month</option>
|
||||
<option>Forever</option>
|
||||
<option value="0" selected="selected">24hrs</option>
|
||||
<option value="1">1 Week</option>
|
||||
<option value="2">1 Month</option>
|
||||
<option value="3">Forever</option>
|
||||
</select>
|
||||
</span>
|
||||
<input type="text" class="form-control input-lg" id="link" name="link" placeholder="http://" required autofocus>
|
||||
@ -172,10 +172,6 @@
|
||||
$('#homelink').addClass('active');
|
||||
});
|
||||
|
||||
$(function () {
|
||||
$("[rel='tooltip']").tooltip();
|
||||
});
|
||||
|
||||
function copyToClipboard(text){
|
||||
window.prompt ("Copy to clipboard: Ctrl+C, Enter (when closed I will open your link in a new tab)", text);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
5 - Successful lob.li link resolve
|
||||
6 - Successful lookup of non-lob.li link
|
||||
7 - Unsuccessful lookup of non-lob.li link
|
||||
8 - Lookup of link Stats (returns 8 $sep JSONarray)
|
||||
*/
|
||||
|
||||
$short = "";
|
||||
@ -26,40 +27,6 @@
|
||||
$title = "";
|
||||
|
||||
$messages = array(
|
||||
"
|
||||
<div class=\"alert alert-success\" id=\"success\">
|
||||
Your link: <a href=\"http://lob.li/$short\" title=\"$title\" target=\"lobli.$short\">lob.li/$short</a>
|
||||
<a href=\"#\" id=\"copylink\" title=\"Copy Link\" onclick=\"copyToClipboard('http://lob.li/$short');\">
|
||||
<!--<a href=\"#\" id=\"newlink\" title=\"New Link\"> This would require changing how I generate links, and I don't feel like doing it right now - 6/22/12 1:21am EST
|
||||
<span class=\"glyphicon glyphicon-refresh\" style=\"float:right;\"></span>
|
||||
</a>-->
|
||||
<span class=\"glyphicon glyphicon-link\" style=\"float:right;padding-right:1%;\"></span>
|
||||
</a>
|
||||
</div>
|
||||
",
|
||||
"
|
||||
<div class=\"alert alert-warning\" id=\"warning\">
|
||||
Existing link: <a href=\"http://lob.li/$short\" title=\"$title\" target=\"lobli.$short\">lob.li/$short</a>
|
||||
<a href=\"#\" id=\"copylink\" title=\"Copy Link\" onclick=\"copyToClipboard('http://lob.li/$short');\">
|
||||
<span class=\"glyphicon glyphicon-link\" style=\"float:right;padding-right:1%;\"></span>
|
||||
</a>
|
||||
</div>
|
||||
",
|
||||
"
|
||||
<div class=\"alert alert-danger\" id=\"danger\">
|
||||
ERROR! - Your link: <a href=\"$link\" target=\"$link\">$link</a> didn't resolve to a website. <br />Please check your link and try again.
|
||||
</div>
|
||||
",
|
||||
"
|
||||
<div class=\"alert alert-danger\" id=\"danger\">
|
||||
ERROR! - Well this is embarrassing... This never happens, but I appear to have suffered a database error. <br />Here's what I know: $error
|
||||
</div>
|
||||
",
|
||||
"
|
||||
<div class=\"alert alert-danger\" id=\"danger\">
|
||||
ERROR! - The sanitize function seems to have failed. This shouldn't happen, maybe <a href=\"mailto:c0de@unps.us\">c0de</a> forgot a semi-colon somewhere or something.
|
||||
</div>
|
||||
",
|
||||
"
|
||||
<div class=\"alert alert-success\" id=\"success\">
|
||||
Your Resolved link: <a href=\"$link\" title=\"$title\">
|
||||
@ -87,18 +54,125 @@
|
||||
"
|
||||
);
|
||||
|
||||
if(empty($_GET['token']) || $_GET['token'] != $_SESSION['token'] || empty($_POST[$catchid]) || $_POST[$catchid] != $catchVal){
|
||||
die("<div id=\"danger\" class=\"alert alert-danger\">Oh Noes! Something happened and I can't continue.<br />Please try again by using the form located at <a href=\"http://lob.li\">lob.li</a>.</div>");
|
||||
}
|
||||
|
||||
require('Include/PHP/functions.php');
|
||||
|
||||
if(!empty($_POST['link'])){
|
||||
$short = sanitize($_POST['link']);
|
||||
if(!isset($_GET['getstats'])){
|
||||
$stats = stats($redis, $seperator);
|
||||
$stats = explode($seperator, $stats);
|
||||
|
||||
if(!empty($_GET['type'])){
|
||||
if($_GET['type'] == "htmltable"){
|
||||
foreach($stats as $stat){ // There should only be 5, but the page doesn't limit how many
|
||||
$id = explode(":", $stat);
|
||||
$id = $id[2]; // Grab just the short link ID
|
||||
|
||||
$linkData = $redis->lRange("links:$id", 0, -1);
|
||||
|
||||
$link = $linkData[0];
|
||||
$title = $linkData[1];
|
||||
$date = $linkData[2];
|
||||
$trackClicks = $redis->get("tracking:clicks:$id");
|
||||
|
||||
echo "
|
||||
<tr class=\"success\">
|
||||
<td></td>
|
||||
<td class=\"centertab\"><a href=\"#\">$id</a></td>
|
||||
<td><a href=\"$link\" title=\"$title\" class="res">$link</a></td>
|
||||
<td class=\"centertab\">$trackClicks</td>
|
||||
<td>$date</td>
|
||||
</tr>
|
||||
";
|
||||
}
|
||||
}elseif($_GET['type'] == "json"){
|
||||
echo $stats[1];
|
||||
exit;
|
||||
}else{
|
||||
die("ERROR: Wrong type. I accept htmltable or json as my type<br>htmltable will send the partial table that loads on <a href=\"http://s.lob.li\">lob.li/stats</a>, json outputs raw json array");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($_POST['link']) && !empty($_POST['linkage'])){
|
||||
if(empty($_GET['token']) || $_GET['token'] != $_SESSION['token'] || empty($_POST[$catchid]) || $_POST[$catchid] != $catchVal){
|
||||
die("<div id=\"danger\" class=\"alert alert-danger\">Oh Noes! Something happened and I can't continue.<br />Please try again by using the form located at <a href=\"http://lob.li\">lob.li</a>.</div>");
|
||||
}
|
||||
|
||||
//$short = sanitize($_POST['link'], $seperator);
|
||||
$short = $_POST['link'];
|
||||
$linkage = $_POST['linkage'];
|
||||
//echo $short;
|
||||
if(strpos($short, "http://") === false && strpos($short, "https://") === false){
|
||||
$short = "http://$short";
|
||||
}
|
||||
echo shorten($shortdb, $short, $seperator);
|
||||
|
||||
echo shorten($redis, $short, $linkage, $seperator);
|
||||
|
||||
$reShort = shorten($redis, $short, $linkage, $seperator);
|
||||
$reShort = explode($seperator, $reShort);
|
||||
$retCode = $reShort[0];
|
||||
|
||||
switch($retCode){
|
||||
case "0": // Successful link Shorten
|
||||
$short = $reShort[1];
|
||||
$title = $reShort[2];
|
||||
echo "
|
||||
<div class=\"alert alert-success\" id=\"success\">
|
||||
Your link: <a href=\"http://lob.li/$short\" title=\"$title\" target=\"lobli.$short\">lob.li/$short</a>
|
||||
<a href=\"#\" id=\"copylink\" title=\"Copy Link\" onclick=\"copyToClipboard('http://lob.li/$short');\">
|
||||
<!--<a href=\"#\" id=\"newlink\" title=\"New Link\"> This would require changing how I generate links, and I don't feel like doing it right now - 6/22/12 1:21am EST
|
||||
<span class=\"glyphicon glyphicon-refresh\" style=\"float:right;\"></span>
|
||||
</a>-->
|
||||
<span class=\"glyphicon glyphicon-link\" style=\"float:right;padding-right:1%;\"></span>
|
||||
</a>
|
||||
</div>
|
||||
";
|
||||
break;
|
||||
|
||||
case "1": // Existing Short Link Found
|
||||
$short = $reShort[1];
|
||||
$title = $reShort[2];
|
||||
echo "
|
||||
<div class=\"alert alert-warning\" id=\"warning\">
|
||||
Existing link: <a href=\"http://lob.li/$short\" title=\"$title\" target=\"lobli.$short\">lob.li/$short</a>
|
||||
<a href=\"#\" id=\"copylink\" title=\"Copy Link\" onclick=\"copyToClipboard('http://lob.li/$short');\">
|
||||
<span class=\"glyphicon glyphicon-link\" style=\"float:right;padding-right:1%;\"></span>
|
||||
</a>
|
||||
</div>
|
||||
";
|
||||
break;
|
||||
|
||||
case "2": // Dead Link
|
||||
$link = $reShort[1];
|
||||
echo "
|
||||
<div class=\"alert alert-danger\" id=\"danger\">
|
||||
ERROR! - Your link: <a href=\"$link\" target=\"$link\">$link</a> didn't resolve to a website. <br />Please check your link and try again.
|
||||
</div>
|
||||
";
|
||||
break;
|
||||
|
||||
case "3": // DB Error
|
||||
$error = $reShort[1];
|
||||
echo "
|
||||
<div class=\"alert alert-danger\" id=\"danger\">
|
||||
ERROR! - Well this is embarrassing... This never happens, but I appear to have suffered a database error. <br />Here's what I know: $error
|
||||
</div>
|
||||
";
|
||||
break;
|
||||
|
||||
case "4": // Sanitize Failure Error
|
||||
echo "
|
||||
<div class=\"alert alert-danger\" id=\"danger\">
|
||||
ERROR! - The sanitize function seems to have failed. This shouldn't happen, maybe <a href=\"mailto:c0de@unps.us\">c0de</a> forgot a semi-colon somewhere or something.
|
||||
</div>
|
||||
";
|
||||
break;
|
||||
|
||||
default:
|
||||
echo "<div id=\"danger\" class=\"alert alert-danger\">Oh Noes! Something happened and I can't continue.<br />Please try again by using the form located at <a href=\"http://lob.li\">lob.li</a>.</div>";
|
||||
break;
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
//foreach($messages as $message){
|
||||
// echo $message;
|
||||
|
Loading…
Reference in New Issue
Block a user