Image Database Start

This commit is contained in:
GRMrGecko 2013-06-02 16:33:42 -05:00
commit e6c208abb1
40 changed files with 21643 additions and 0 deletions

6
.htaccess Normal file
View File

@ -0,0 +1,6 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>

7
License.txt Normal file
View File

@ -0,0 +1,7 @@
ISC License (ISCL)
Copyright (c) 2011 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

6
code/.htaccess Normal file
View File

@ -0,0 +1,6 @@
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule . ../index.php [L]
</IfModule>

23
code/404.php Normal file
View File

@ -0,0 +1,23 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
header("HTTP/1.0 404 Not Found");
require_once("header.php");
?>
<h1>File Not Found</h1>
<?
require_once("footer.php");
exit();
?>

137
code/api.php Normal file
View File

@ -0,0 +1,137 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
if (isset($_MGM['user']) && $_MGM['user']['level']==1 && $_MGM['path'][1]=="users") {
if ($_MGM['path'][2]=="list") {
$results = databaseQuery("SELECT * FROM users");
while ($result = databaseFetchAssoc($results)) {
$level = "Normal";
if ($result['level']==0)
$level = "Disabled";
if ($result['level']==1)
$level = "Administrator";
if ($result['level']==2)
$level = "Moderator";
if ($result['level']==3)
$level = "Tagger";
?><tr><td class="id"><?=$result['docid']?></td><td class="email"><?=$result['email']?></td><td class="level" value="<?=$result['level']?>"><?=$level?></td></tr><?
}
}
if ($_MGM['path'][2]=="update") {
$id = (isset($_REQUEST['id']) ? trim($_REQUEST['id']) : "");
$email = (isset($_REQUEST['email']) ? trim($_REQUEST['email']) : "");
$password = (isset($_REQUEST['password']) ? trim($_REQUEST['password']) : "");
$level = (isset($_REQUEST['level']) ? trim($_REQUEST['level']) : "");
$results = databaseQuery("SELECT * FROM users WHERE docid=%s", $id);
$result = databaseFetchAssoc($results);
if ($result!=NULL) {
if (empty($email))
$email = $result['email'];
$epassword = $result['password'];
if (!empty($password)) {
$salt = substr(sha1(rand()),0,12);
$epassword = $salt.hash("sha512", $salt.hash("sha512", $password));
}
if ($level=="")
$level = $result['level'];
databaseQuery("UPDATE users SET email=%s,password=%s,level=%s WHERE docid=%s", $email, $epassword, $level, $id);
}
}
if ($_MGM['path'][2]=="create") {
$email = (isset($_REQUEST['email']) ? trim($_REQUEST['email']) : "");
$password = (isset($_REQUEST['password']) ? trim($_REQUEST['password']) : "");
$level = (isset($_REQUEST['level']) ? trim($_REQUEST['level']) : "");
if (!empty($email) && !empty($level)) {
$salt = substr(sha1(rand()),0,12);
$epassword = $salt.hash("sha512", $salt.hash("sha512", $password));
databaseQuery("INSERT INTO users (email, password, time, level) VALUES (%s,%s,%d,%s)", $email, $epassword, $_MGM['time'], $level);
}
}
exit();
}
if (isset($_MGM['user']) && $_MGM['path'][1]=="save_tags") {
$hash = (isset($_REQUEST['hash']) ? trim($_REQUEST['hash']) : "");
$tags = (isset($_REQUEST['tags']) ? trim($_REQUEST['tags']) : "");
$results = databaseQuery("SELECT * FROM images WHERE hash=%s", $hash);
$result = databaseFetchAssoc($results);
if ($result!=NULL) {
if ($_MGM['user']['level']<=3 || $_MGM['user']['docid']==$result['user_id'])
databaseQuery("UPDATE images SET tags=%s WHERE hash=%s", $tags, $hash);
}
exit();
}
if (isset($_MGM['user']) && $_MGM['user']['level']<=2 && $_MGM['path'][1]=="delete") {
$hash = (isset($_REQUEST['hash']) ? trim($_REQUEST['hash']) : "");
$results = databaseQuery("SELECT * FROM images WHERE hash=%s", $hash);
$result = databaseFetchAssoc($results);
if ($result!=NULL) {
unlink("./data/".$result['hash'].".".$result['extension']);
unlink("./thumbs/".$result['hash'].".".$result['extension']);
databaseQuery("DELETE FROM images WHERE hash=%s", $hash);
}
exit();
}
if (isset($_MGM['user']) && $_MGM['path'][1]=="tagless") {
$results = NULL;
if ($_MGM['user']['level']<=3)
$results = databaseQuery("SELECT * FROM images WHERE tags='' ORDER BY time ASC LIMIT 1");
else
$results = databaseQuery("SELECT * FROM images WHERE tags='' AND user=%s ORDER BY time ASC LIMIT 1", $_MGM['user']['docid']);
$result = databaseFetchAssoc($results);
if ($result!=NULL) {
?>
<span id="image" hash="<?=$result['hash']?>" user="<?=$result['user_id']?>" extension="<?=$result['extension']?>" tags="<?=$result['tags']?>" image_width="<?=$result['width']?>" image_height="<?=$result['height']?>" file_size="<?=$result['file_size']?>" time="<?=$result['time']?>" original="<?=generateURL("data/".$result['hash'].".".$result['extension'])?>"></span>
<?
}
exit();
}
if ($_MGM['path'][1]=="hash") {
$results = databaseQuery("SELECT * FROM images WHERE hash like %s ORDER BY time ASC LIMIT 1", $_MGM['path'][2]);
$result = databaseFetchAssoc($results);
if ($result!=NULL) {
?>
<span id="image" hash="<?=$result['hash']?>" user="<?=$result['user_id']?>" extension="<?=$result['extension']?>" tags="<?=$result['tags']?>" image_width="<?=$result['width']?>" image_height="<?=$result['height']?>" file_size="<?=$result['file_size']?>" time="<?=$result['time']?>" original="<?=generateURL("data/".$result['hash'].".".$result['extension'])?>"></span>
<?
}
exit();
}
$limit = 96;
$page = (intval($_MGM['path'][1])==0 || empty($_MGM['path'][1]) ? 1 : intval($_MGM['path'][1]))-1;
$offset = $limit*$page;
$filter = (isset($_REQUEST['filter']) ? trim($_REQUEST['filter']) : "");
$results = NULL;
if (!empty($filter))
$results = databaseQuery("SELECT * FROM images WHERE images MATCH %s LIMIT %d,%d", $filter, $offset, $limit);
else
$results = databaseQuery("SELECT * FROM images ORDER BY time DESC LIMIT %d,%d", $offset, $limit);
?><div id="content"><?
$count = 0;
while ($result = databaseFetchAssoc($results)) {
?>
<span class="image" hash="<?=$result['hash']?>" user="<?=$result['user_id']?>" extension="<?=$result['extension']?>" tags="<?=$result['tags']?>" image_width="<?=$result['width']?>" image_height="<?=$result['height']?>" file_size="<?=$result['file_size']?>" time="<?=$result['time']?>" original="<?=generateURL("data/".$result['hash'].".".$result['extension'])?>"><img src="<?=generateURL("thumbs/".$result['hash'].".".$result['extension'])?>" width="<?=$result['thumb_width']?>" height="<?=$result['thumb_height']?>" /></span>
<?
$count++;
}
?>
</div>
<div id="count"><?=$count?></div>
<div id="limit"><?=$limit?></div>
<div id="page"><?=$page?></div>
<div id="offset"><?=$offset?></div>
<div id="next_page"><?=($count==$limit ? $page+2 : "")?></div>
<?
exit();
?>

209
code/hash.php Normal file
View File

@ -0,0 +1,209 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
require_once("header.php");
?>
<style type="text/css">
#imageViewer_sidebar {
opacity: 0.9;
position: fixed;
top: 41px;
bottom: 0;
left: 0;
width: 200px;
z-index: 1032;
overflow: scroll;
padding-top: 8px;
background-color: #ffffff;
-webkit-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
-moz-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
box-shadow: 0 1px 10px rgba(0,0,0,0.1);
}
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
#imageViewer_sidebar {
width: 100px;
}
}
#imageViewer_sidebar .basic_info {
padding-top: 5px;
padding-left: 5px;
padding-right: 5px;
}
#imageViewer_sidebar .tags {
padding-top: 5px;
padding-left: 5px;
padding-right: 5px;
}
#imageViewer_sidebar .tags_edit {
width: 180px;
height: 250px;
}
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
#imageViewer_sidebar .tags_edit {
width: 80px;
height: 150px;
}
}
#imageViewer_main {
position: fixed;
z-index: 1031;
border:4px solid #ffffff;
border-radius: 4px;
background-color: #ffffff;
-webkit-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
-moz-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
box-shadow: 0 1px 10px rgba(0,0,0,0.1);
}
</style>
<div id="image_loader" style="display: none;"></div>
<div id="imageViewer_sidebar">
<div class="basic_info"></div>
<div class="tags"></div>
<?if (isset($_MGM['user'])) {?>
<textarea class="tags_edit hide"></textarea>
<button type="button" class="btn" id="imageViewer_editTags">Edit Tags</button>
<div id="imageViewer_apiloader" style="display: none;"></div>
<?}?>
</div>
<div id="imageViewer_main"></div>
<script type="text/javascript">
function loadNext() {
$("#image_loader").load("<?=generateURL("api/hash/".$_MGM['path'][1])?>/", function(response, status, xhr) {
loadImage($("#image_loader #image"), 0);
});
}
var imageViewing = "";
function repositionImage() {
if (imageViewing=="") {
return;
}
var image = $("#image_loader [hash='"+imageViewing+"']");
var width = image.attr("image_width");
var height = image.attr("image_height");
var spaceWidth = ($(window).width()-$("#imageViewer_sidebar").width())-20;
var spaceHeight = ($(window).height()-$(".navbar").height())-20;
var newWidth = width;
var newHeight = height;
if (width>spaceWidth || height>spaceHeight) {
var widthFactor = spaceWidth/width;
var heightFactor = spaceHeight/height;
var scaleFactor = 1;
if (widthFactor<heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
newWidth = Math.round(width*scaleFactor);
newHeight = Math.round(height*scaleFactor);
}
$("imageViewer_main img").css({width: newWidth, height: newHeight});
$("#imageViewer_main").css({top: (((spaceHeight-newHeight)/2)+$(".navbar").height())+5, right: ((spaceWidth-newWidth)/2)+5, width: newWidth, height: newHeight});
}
function bytesToSize(bytes) {
var size = bytes;
var type = "Bytes";
if (size>=1024) {
size = size/1024;
type = "KB";
}
if (size>=1024) {
size = size/1024;
type = "MB";
}
if (size>=1024) {
size = size/1024;
type = "GB";
}
return (Math.round(size*100)/100)+" "+type;
}
function loadImage(image) {
imageViewing = image.attr("hash");
$("#imageViewer_main").html("<a href=\""+image.attr("original")+"\" target=\"blank\"><img src=\""+image.attr("original")+"\" /></a>");
repositionImage();
$("#imageViewer_sidebar .basic_info").html("");
$("#imageViewer_sidebar .basic_info").append("<a href=\"<?=generateURL("hash/")?>"+image.attr("hash")+"/\">Image Link</a><br />");
$("#imageViewer_sidebar .basic_info").append("Date: "+date("m/d/y h:i:s A", image.attr("time"))+"<br />");
$("#imageViewer_sidebar .basic_info").append("Size: "+image.attr("image_width")+"x"+image.attr("image_height")+"<br />");
$("#imageViewer_sidebar .basic_info").append("File Size: "+bytesToSize(image.attr("file_size"))+"<br />");
$("#imageViewer_sidebar .tags").html("");
<?if (isset($_MGM['user'])) {?>
$("#imageViewer_sidebar .tags_edit").val(image.attr("tags"));
<?}?>
var tags = image.attr("tags").split(" ");
for (var i=0; i<tags.length; i++) {
var tag = tags[i].replace(/_/g, " ");
$("#imageViewer_sidebar .tags").append(tag+"<br />");
}
<?if (isset($_MGM['user']) && $_MGM['user']['level']>=4) {?>
if (image.attr("user")=="<?=$_MGM['user']['docid']?>") {
$("#imageViewer_editTags").show();
} else {
$("#imageViewer_editTags").hide();
}
<?}?>
}
$(document).ready(function() {
$("#imageViewer_sidebar").css({top: $(".navbar").height()});
$(window).resize(function() {
repositionImage();
$("#imageViewer_sidebar").css({top: $(".navbar").height()});
});
<?if (isset($_MGM['user'])) {?>
$("#imageViewer_editTags").click(function() {
if (imageViewing=="") {
return;
}
if ($(this).text()=="Edit Tags") {
$(this).text("Save Tags");
$("#imageViewer_sidebar .tags").addClass("hide");
$("#imageViewer_sidebar .tags_edit").removeClass("hide");
} else {
$(this).text("Edit Tags");
$("#imageViewer_sidebar .tags").removeClass("hide");
$("#imageViewer_sidebar .tags_edit").addClass("hide");
$("#imageViewer_sidebar .tags").html("");
var tags = $("#imageViewer_sidebar .tags_edit").val().split(" ");
for (var i=0; i<tags.length; i++) {
var tag = tags[i].replace(/_/g, " ");
$("#imageViewer_sidebar .tags").append(tag+"<br />");
}
$("#imageViewer_apiloader").load("<?=generateURL("api/save_tags")?>/", {hash: imageViewing, tags: $("#imageViewer_sidebar .tags_edit").val()});
}
});
<?}?>
loadNext();
});
</script>
<?
require_once("footer.php");
exit();
?>

0
code/index.html Normal file
View File

369
code/index.php Normal file
View File

@ -0,0 +1,369 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
require_once("header.php");
?>
<style type="text/css">
.image {
width: 180px;
height: 180px;
display: inline-block;
text-align: center;
vertical-align: middle;
}
.image img {
border:3px solid #e8e8e8;
border-radius: 2px;
box-shadow: 0 1px 3px rgba(0,0,0,0.055);
}
#imageViewer_sidebar {
opacity: 0.9;
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 200px;
z-index: 1032;
overflow: scroll;
padding-top: 8px;
background-color: #ffffff;
-webkit-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
-moz-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
box-shadow: 0 1px 10px rgba(0,0,0,0.1);
}
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
#imageViewer_sidebar {
width: 100px;
}
}
#imageViewer_close {
padding-right: 18px;
padding-top: 2px;
}
#imageViewer_sidebar .basic_info {
padding-top: 5px;
padding-left: 5px;
padding-right: 5px;
}
#imageViewer_sidebar .tags {
padding-top: 5px;
padding-left: 5px;
padding-right: 5px;
}
#imageViewer_sidebar .tags_edit {
width: 180px;
height: 250px;
}
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
#imageViewer_sidebar .tags_edit {
width: 80px;
height: 150px;
}
}
#imageViewer_main {
position: fixed;
z-index: 1031;
border:4px solid #ffffff;
border-radius: 4px;
background-color: #ffffff;
-webkit-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
-moz-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
box-shadow: 0 1px 10px rgba(0,0,0,0.1);
}
#backdrop {
opacity: 0.8;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1030;
background-color: #000000;
}
</style>
<div id="images_loader" style="display: none;"></div>
<div id="images_main"></div>
<?if (isset($_MGM['user']) && $_MGM['user']['level']<=2) {?>
<div id="imageViewer_confirmDelete" class="modal hide fade" tabindex="-1" role="dialog">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>Delete Image</h3>
</div>
<div class="modal-body">
<p>You are about to delete an image from the database.</p>
<p>Are you sure you wish to do this?</p>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">No</button>
<button class="btn btn-danger" data-dismiss="modal" id="imageViewer_confirmDelete_yes">Yes</button>
</div>
</div>
<?}?>
<div id="imageViewer_sidebar" class="hide">
<button type="button" class="btn" id="imageViewer_previousButton"><div class="icon-arrow-left"></div></button>
<button type="button" class="btn" id="imageViewer_nextButton"><div class="icon-arrow-right"></div></button>
<button type="button" class="close" id="imageViewer_close">&times;</button>
<div class="basic_info"></div>
<div class="tags"></div>
<?if (isset($_MGM['user'])) {?>
<textarea class="tags_edit hide"></textarea>
<button type="button" class="btn" id="imageViewer_editTags">Edit Tags</button>
<?if ($_MGM['user']['level']<=2) {?>
<button type="button" class="btn btn-danger" id="imageViewer_delete">Delete</button>
<?}?>
<div id="imageViewer_apiloader" style="display: none;"></div>
<?}?>
</div>
<div id="imageViewer_main" class="hide"></div>
<div id="backdrop" class="hide"></div>
<script type="text/javascript">
var filter = "";
var readyToLoad = false;
var loadingPage = false;
var currentPage = 0;
function loadPage(page) {
if (loadingPage) {
return;
}
currentPage = page;
loadingPage = true;
//console.log("Loading "+page);
$("#images_loader").load("<?=generateURL("api")?>/"+page, {filter: filter}, function(response, status, xhr) {
$("#images_main").append($("#images_loader #content").html());
$("#images_loader #content").html("");
if ($("#images_loader #next_page").text()!="") {
readyToLoad = true;
}
loadingPage = false;
});
}
var imageViewing = "";
function repositionImage(animate) {
if (imageViewing=="") {
return;
}
var image = $("#images_main .image[hash='"+imageViewing+"']");
var width = image.attr("image_width");
var height = image.attr("image_height");
var spaceWidth = ($(window).width()-$("#imageViewer_sidebar").width())-20;
var spaceHeight = $(window).height()-20;
var newWidth = width;
var newHeight = height;
if (width>spaceWidth || height>spaceHeight) {
var widthFactor = spaceWidth/width;
var heightFactor = spaceHeight/height;
var scaleFactor = 1;
if (widthFactor<heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
newWidth = Math.round(width*scaleFactor);
newHeight = Math.round(height*scaleFactor);
}
$("imageViewer_main img").css({width: newWidth, height: newHeight});
if (animate==1) {
$("#imageViewer_main").css({top: (newWidth*-1)-20, right: ((spaceWidth-newWidth)/2)+5, width: newWidth, height: newHeight});
$("#imageViewer_main").animate({top: ((spaceHeight-newHeight)/2)+5});
} else if (animate==2) {
$("#imageViewer_main").css({top: ((spaceHeight-newHeight)/2)+5, right: ((spaceWidth-newWidth)/2)+5, width: newWidth, height: newHeight});
$("#imageViewer_main").animate({top: spaceHeight+20}, {duration: 400, complete: function() {
$("#imageViewer_main").addClass("hide");
}});
} else if (animate==3 || animate==4) {
$("#imageViewer_main").css({top: ((spaceHeight-newHeight)/2)+5, right: ((spaceWidth-newWidth)/2)+5, width: newWidth, height: newHeight});
$("#imageViewer_main").animate({right: (spaceWidth*-1)-20}, {duration: 400, complete: function() {
if (animate==3) {
loadImage(image.next(), 1);
} else {
loadImage(image.prev(), 1);
}
}});
} else {
$("#imageViewer_main").css({top: ((spaceHeight-newHeight)/2)+5, right: ((spaceWidth-newWidth)/2)+5, width: newWidth, height: newHeight});
}
}
function bytesToSize(bytes) {
var size = bytes;
var type = "Bytes";
if (size>=1024) {
size = size/1024;
type = "KB";
}
if (size>=1024) {
size = size/1024;
type = "MB";
}
if (size>=1024) {
size = size/1024;
type = "GB";
}
return (Math.round(size*100)/100)+" "+type;
}
function loadImage(image, animate) {
if (animate==0) {
$("#backdrop").css("opacity", 0);
$("#backdrop").removeClass("hide");
$("#backdrop").animate({opacity: 0.8});
$("#imageViewer_sidebar").css("left", "-210px");
$("#imageViewer_sidebar").removeClass("hide");
$("#imageViewer_sidebar").animate({left: 0});
}
imageViewing = image.attr("hash");
$("#imageViewer_main").removeClass("hide");
$("#imageViewer_main").html("<a href=\""+image.attr("original")+"\" target=\"blank\"><img src=\""+image.attr("original")+"\" /></a>");
repositionImage(1);
$("#imageViewer_sidebar .basic_info").html("");
$("#imageViewer_sidebar .basic_info").append("<a href=\"<?=generateURL("hash/")?>"+image.attr("hash")+"/\">Image Link</a><br />");
$("#imageViewer_sidebar .basic_info").append("Date: "+date("m/d/y h:i:s A", image.attr("time"))+"<br />");
$("#imageViewer_sidebar .basic_info").append("Size: "+image.attr("image_width")+"x"+image.attr("image_height")+"<br />");
$("#imageViewer_sidebar .basic_info").append("File Size: "+bytesToSize(image.attr("file_size"))+"<br />");
$("#imageViewer_sidebar .tags").html("");
<?if (isset($_MGM['user'])) {?>
$("#imageViewer_sidebar .tags_edit").val(image.attr("tags"));
<?}?>
var tags = image.attr("tags").split(" ");
for (var i=0; i<tags.length; i++) {
var tag = tags[i].replace(/_/g, " ");
$("#imageViewer_sidebar .tags").append(tag+"<br />");
}
<?if (isset($_MGM['user']) && $_MGM['user']['level']>=4) {?>
if (image.attr("user")=="<?=$_MGM['user']['docid']?>") {
$("#imageViewer_editTags").show();
} else {
$("#imageViewer_editTags").hide();
}
<?}?>
if (image.prev().length!=0) {
$("#imageViewer_previousButton").removeAttr("disabled");
} else {
$("#imageViewer_previousButton").attr("disabled","disabled");
}
if (image.next().length!=0) {
$("#imageViewer_nextButton").removeAttr("disabled");
} else {
$("#imageViewer_nextButton").attr("disabled","disabled");
}
}
$(document).ready(function() {
$("#images_main").on("click", ".image", function() {
loadImage($(this), 0);
});
$("#imageViewer_previousButton").click(function() {
repositionImage(4);
});
$("#imageViewer_nextButton").click(function() {
repositionImage(3);
});
function closeImageViewer() {
$("#backdrop").animate({opacity: 0}, {duration: 400, complete: function() {
$("#backdrop").addClass("hide");
}});
$("#imageViewer_sidebar").animate({left: "-210px"}, {duration: 400, complete: function() {
$("#imageViewer_sidebar").addClass("hide");
}});
<?if (isset($_MGM['user'])) {?>
$("#imageViewer_sidebar .tags").removeClass("hide");
$("#imageViewer_sidebar .tags_edit").addClass("hide");
$("#imageViewer_editTags").text("Edit Tags");
<?}?>
repositionImage(2);
}
$("#backdrop, #imageViewer_close").click(closeImageViewer);
$(window).resize(function() {
repositionImage(0);
});
<?if (isset($_MGM['user'])) {?>
$("#imageViewer_editTags").click(function() {
if (imageViewing=="") {
return;
}
if ($(this).text()=="Edit Tags") {
$(this).text("Save Tags");
$("#imageViewer_sidebar .tags").addClass("hide");
$("#imageViewer_sidebar .tags_edit").removeClass("hide");
} else {
$(this).text("Edit Tags");
$("#imageViewer_sidebar .tags").removeClass("hide");
$("#imageViewer_sidebar .tags_edit").addClass("hide");
$("#imageViewer_sidebar .tags").html("");
var tags = $("#imageViewer_sidebar .tags_edit").val().split(" ");
for (var i=0; i<tags.length; i++) {
var tag = tags[i].replace(/_/g, " ");
$("#imageViewer_sidebar .tags").append(tag+"<br />");
}
$("#imageViewer_apiloader").load("<?=generateURL("api/save_tags")?>/", {hash: imageViewing, tags: $("#imageViewer_sidebar .tags_edit").val()});
}
});
<?if ($_MGM['user']['level']<=2) {?>
$("#imageViewer_delete").click(function() {
if (imageViewing=="") {
return;
}
$("#imageViewer_confirmDelete").modal();
});
$("#imageViewer_confirmDelete_yes").click(function() {
$("#imageViewer_apiloader").load("<?=generateURL("api/delete")?>/", {hash: imageViewing});
closeImageViewer();
$("#images_main .image[hash='"+imageViewing+"']").remove();
});
<?}?>
<?}?>
filter = $("#filter_field").val();
loadPage(0);
$(window).scroll(function(){
if (readyToLoad && $(window).scrollTop()>=($(document).height()-$(window).height())-300) {
readyToLoad = false;
loadPage($("#images_loader #next_page").text());
}
});
$("#filter_form").submit(function() {
filter = $("#filter_field").val();
$("#images_main").html("");
loadPage(0);
return false;
});
});
</script>
<?
require_once("footer.php");
?>

53
code/login.php Normal file
View File

@ -0,0 +1,53 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
$error = "";
if (isset($_REQUEST['login'])) {
$email = (isset($_REQUEST['email']) ? trim($_REQUEST['email']) : "");
$password = (isset($_REQUEST['password']) ? trim($_REQUEST['password']) : "");
$result = databaseQuery("SELECT * FROM users WHERE email=%s AND level!=0", $email);
$user = databaseFetchAssoc($result);
if ($user==NULL) {
$error = "Invalid login credentials.";
} else {
$salt = substr($user['password'], 0, 12);
$epassword = $salt.hash("sha512", $salt.hash("sha512", $password));
if ($epassword!=$user['password']) {
$error = "Invalid login credentials.";
} else {
databaseQuery("UPDATE users SET time=%d WHERE email=%s", $_MGM['time'], $email);
setcookie("{$_MGM['CookiePrefix']}user_email", $email, $_MGM['time']+31536000, $_MGM['CookiePath'], $_MGM['CookieDomain']);
setcookie("{$_MGM['CookiePrefix']}user_password", hash("sha512", $epassword.$_MGM['time']), $_MGM['time']+31536000, $_MGM['CookiePath'], $_MGM['CookieDomain']);
header("location: ".generateURL());
exit();
}
}
}
require_once("header.php");
if (!empty($error)) {
?><div style="color: #ff0000; font-weight: bold;"><?=$error?></div><?
}
?>
<form action="<?=generateURL("login")?>" method="POST">
<input type="hidden" name="login" value="true" />
<input type="text" placeholder="Email" name="email" /><br />
<input type="password" placeholder="Password" name="password" /><br />
<input type="submit" value="Login" class="btn" />
</form>
<?
require_once("footer.php");
exit();
?>

20
code/logout.php Normal file
View File

@ -0,0 +1,20 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
setcookie("{$_MGM['CookiePrefix']}user_email", "", $_MGM['time'], $_MGM['CookiePath'], $_MGM['CookieDomain']);
setcookie("{$_MGM['CookiePrefix']}user_password", "", $_MGM['time'], $_MGM['CookiePath'], $_MGM['CookieDomain']);
header("location: ".generateURL());
exit();
?>

107
code/re-ocr.php Normal file
View File

@ -0,0 +1,107 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
if ($_MGM['path'][1]=="process") {
$file = (isset($_REQUEST['file']) ? $_REQUEST['file'] : "");
$hash = pathinfo($file, PATHINFO_FILENAME);
echo "Hash: ".$hash."<br />\n";
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$process = proc_open("./ocr \"".$file."\"", $descriptorspec, $pipes, getcwd());
fclose($pipes[0]);
$ocr = "";
while (is_resource($process)) {
$read = $pipes;
$write = null;
$except = null;
$result = stream_select($read, $write, $except, 30);
if ($result==0) {
fclose($pipes[1]);
fclose($pipes[2]);
proc_terminate($process,9);
break;
} else if ($result>0) {
$line = fread($pipes[1], 8192);
if (strlen($line)==0) {
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
break;
}
$ocr .= $line;
}
}
echo "OCR: ".$ocr."<br />\n";
databaseQuery("UPDATE images SET ocr=%s WHERE hash=%s", $ocr, $hash);
exit();
}
$files = glob("./data/*");
require_once("header.php");
?>
Processing...<br />
<div id="result"></div>
<script type="text/javascript">
var files = new Array(<?
$array = "";
for ($i=0; $i<count($files); $i++) {
//if (in_array(pathinfo($files[$i], PATHINFO_EXTENSION), $allowedExtensions)) {
if ($array!="")
$array .= ",";
$array .= "\"".str_replace("\"", "\\\"", $files[$i])."\"";
}
echo $array;
?>);
var i=0;
function processFiles() {
if (i<files.length) {
var status = document.createElement("p");
status.innerHTML = "Processing "+(i+1)+" of "+files.length+" files.";
document.getElementById("result").appendChild(status);
var request = new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState==4) {
var status = document.createElement("p");
status.innerHTML = request.responseText;
document.getElementById("result").appendChild(status);
processFiles();
}
}
request.open("post", "<?=generateURL("re-ocr/process")?>", true);
request.setRequestHeader("Cache-Control", "no-cache");
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send("file="+encodeURIComponent(files[i]));
i++;
} else {
var completed = document.createElement("p");
completed.innerHTML = "Processing Completed.";
document.getElementById("result").appendChild(completed);
}
}
processFiles();
</script>
<?
require_once("footer.php");
exit();
?>

53
code/setup.php Normal file
View File

@ -0,0 +1,53 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
$result = databaseQuery("SELECT * FROM settings WHERE name='db_version'");
if ($result==NULL) {
databaseQuery("CREATE TABLE settings (name TEXT, value TEXT)");
databaseQuery("INSERT INTO settings (name, value) VALUES ('db_version',%d)", $_MGM['version']);
databaseQuery("CREATE VIRTUAL TABLE images USING fts3(user_id INTEGER, hash TEXT, extension TEXT, name TEXT, file_size INTEGER, width INTEGER, height INTEGER, thumb_file_size INTEGER, thumb_width INTEGER, thumb_height INTEGER, tags TEXT, external_data TEXT, ocr TEXT, time INTEGER)");
databaseQuery("CREATE TABLE users (docid INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT, password TEXT, time INTEGER, level INTEGER)");
require_once("header.php");
?>
<form action="<?=generateURL()?>" method="POST">
<input type="hidden" name="create_user" value="first" />
<input type="text" placeholder="Email" name="email" /><br />
<input type="password" placeholder="Password" name="password" /><br />
<input type="submit" value="Create Admin" class="btn" />
</form>
<?
require_once("footer.php");
exit();
}
if (isset($_REQUEST['create_user'])) {
$email = (isset($_REQUEST['email']) ? trim($_REQUEST['email']) : "");
$password = (isset($_REQUEST['password']) ? trim($_REQUEST['password']) : "");
if ($_REQUEST['create_user']=="first") {
$result = databaseQuery("SELECT COUNT(*) AS count FROM users");
$count = databaseFetchAssoc($result);
if ($count['count']==0 && !empty($email) && !empty($password)) {
$salt = substr(sha1(rand()),0,12);
$epassword = $salt.hash("sha512", $salt.hash("sha512", $password));
databaseQuery("INSERT INTO users (email, password, time, level) VALUES (%s,%s,%d,1)", $email, $epassword, $_MGM['time']);
setcookie("{$_MGM['CookiePrefix']}user_email", $email, $_MGM['time']+31536000, $_MGM['CookiePath'], $_MGM['CookieDomain']);
setcookie("{$_MGM['CookiePrefix']}user_password", hash("sha512", $epassword.$_MGM['time']), $_MGM['time']+31536000, $_MGM['CookiePath'], $_MGM['CookieDomain']);
header("location: ".generateURL());
exit();
}
}
}
?>

144
code/tagless.php Normal file
View File

@ -0,0 +1,144 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
require_once("header.php");
?>
<style type="text/css">
#imageViewer_sidebar {
opacity: 0.9;
position: fixed;
top: 41px;
bottom: 0;
left: 0;
width: 200px;
z-index: 1032;
overflow: scroll;
padding-top: 8px;
background-color: #ffffff;
-webkit-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
-moz-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
box-shadow: 0 1px 10px rgba(0,0,0,0.1);
}
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
#imageViewer_sidebar {
width: 100px;
}
}
#imageViewer_sidebar .tags_edit {
width: 180px;
height: 250px;
}
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
#imageViewer_sidebar .tags_edit {
width: 80px;
height: 150px;
}
}
#imageViewer_main {
position: fixed;
z-index: 1031;
border:4px solid #ffffff;
border-radius: 4px;
background-color: #ffffff;
-webkit-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
-moz-box-shadow: 0 1px 10px rgba(0,0,0,0.1);
box-shadow: 0 1px 10px rgba(0,0,0,0.1);
}
</style>
<div id="image_loader" style="display: none;"></div>
<div id="imageViewer_sidebar">
<?if (isset($_MGM['user'])) {?>
<textarea class="tags_edit"></textarea>
<button type="button" class="btn" id="imageViewer_save">Save/Next</button>
<div id="imageViewer_apiloader" style="display: none;"></div>
<?}?>
</div>
<div id="imageViewer_main"></div>
<script type="text/javascript">
function loadNext() {
$("#image_loader").load("<?=generateURL("api/tagless")?>/", function(response, status, xhr) {
loadImage($("#image_loader #image"), 0);
});
}
var imageViewing = "";
function repositionImage() {
if (imageViewing=="") {
return;
}
var image = $("#image_loader [hash='"+imageViewing+"']");
var width = image.attr("image_width");
var height = image.attr("image_height");
var spaceWidth = ($(window).width()-$("#imageViewer_sidebar").width())-20;
var spaceHeight = ($(window).height()-$(".navbar").height())-20;
var newWidth = width;
var newHeight = height;
if (width>spaceWidth || height>spaceHeight) {
var widthFactor = spaceWidth/width;
var heightFactor = spaceHeight/height;
var scaleFactor = 1;
if (widthFactor<heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
newWidth = Math.round(width*scaleFactor);
newHeight = Math.round(height*scaleFactor);
}
$("imageViewer_main img").css({width: newWidth, height: newHeight});
$("#imageViewer_main").css({top: (((spaceHeight-newHeight)/2)+$(".navbar").height())+5, right: ((spaceWidth-newWidth)/2)+5, width: newWidth, height: newHeight});
}
function loadImage(image) {
imageViewing = image.attr("hash");
$("#imageViewer_main").html("<a href=\""+image.attr("original")+"\" target=\"blank\"><img src=\""+image.attr("original")+"\" /></a>");
repositionImage();
<?if (isset($_MGM['user'])) {?>
$("#imageViewer_sidebar .tags_edit").val(image.attr("tags"));
$("#imageViewer_sidebar .tags_edit").focus();
<?}?>
}
$(document).ready(function() {
$("#imageViewer_sidebar").css({top: $(".navbar").height()});
$(window).resize(function() {
repositionImage();
$("#imageViewer_sidebar").css({top: $(".navbar").height()});
});
<?if (isset($_MGM['user'])) {?>
$("#imageViewer_save").click(function() {
if (imageViewing=="") {
return;
}
$("#imageViewer_apiloader").load("<?=generateURL("api/save_tags")?>/", {hash: imageViewing, tags: $("#imageViewer_sidebar .tags_edit").val()}, function() {
loadNext();
});
});
<?}?>
loadNext();
});
</script>
<?
require_once("footer.php");
exit();
?>

252
code/upload.php Normal file
View File

@ -0,0 +1,252 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
if ($_MGM['path'][1]=="complete") {
if ($_MGM['path'][2]=="process") {
$file = (isset($_REQUEST['file']) ? $_REQUEST['file'] : "");
$filename = pathinfo($file, PATHINFO_FILENAME);
$extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
echo "Processing ".basename($file)."<br />\n";
if (!file_exists($file)) {
echo "Error: <span style=\"color: #ff0000;\">File does not exist.</span>";
unlink($file);
exit();
}
$allowedExtensions = array("png", "jpg", "jpeg", "gif", "tif", "tiff", "bmp");
if (!in_array($extension, $allowedExtensions)) {
echo "Error: <span style=\"color: #ff0000;\">Extension is not allowed.</span>";
unlink($file);
exit();
}
$fileSize = filesize($file);
echo "Size: ".$fileSize."<br />\n";
list($width, $height, $type, $attr) = getimagesize($file);
if (!isset($width) || !isset($height)) {
echo "Error: <span style=\"color: #ff0000;\">Cannot read image.</span>";
unlink($file);
exit();
}
echo "Width: ".$width." Height: ".$height."<br />\n";
$hash = md5_file($file);
if ($hash==NULL) {
echo "Error: <span style=\"color: #ff0000;\">Unable to hash image.</span>";
unlink($file);
exit();
}
echo "Hash: ".$hash."<br />\n";
$newFile = "./data/".$hash.".".$extension;
if (file_exists($newFile)) {
echo "Error: <span style=\"color: #ff0000;\">File already uploaded.</span>";
unlink($file);
exit();
}
$ocr = "";
if (file_exists("./ocr")) {
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$process = proc_open("./ocr \"".$file."\"", $descriptorspec, $pipes, getcwd());
fclose($pipes[0]);
while (is_resource($process)) {
$read = $pipes;
$write = null;
$except = null;
$result = stream_select($read, $write, $except, 30);
if ($result==0) {
fclose($pipes[1]);
fclose($pipes[2]);
proc_terminate($process,9);
break;
} else if ($result>0) {
$line = fread($pipes[1], 8192);
if (strlen($line)==0) {
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
break;
}
$ocr .= $line;
}
}
echo "OCR: ".$ocr."<br />\n";
}
$tags = array();
$external_data = "";
$plugins = glob("./external_data_plugins/*.php");
for ($i=0; $i<count($plugins); $i++) {
require($plugins[$i]);
}
echo "External Data: ".$external_data."<br />\n";
$thumbFile = "./thumbs/".$hash.".".$extension;
$target = 150;
$newWidth = $width;
$newHeight = $height;
if ($width>$target || $height>$target) {
$widthFactor = $target/$width;
$heightFactor = $target/$height;
$scaleFactor = 1;
if ($widthFactor<$heightFactor)
$scaleFactor = $widthFactor;
else
$scaleFactor = $heightFactor;
$newWidth = round($width*$scaleFactor);
$newHeight = round($height*$scaleFactor);
}
if ($type==IMAGETYPE_GIF) {
$tmp = "./thumbs/coalesce".rand().".gif";
system($_MGM['imagemagick']."convert \"".$file."\" -coalesce \"".$tmp."\"");
system($_MGM['imagemagick']."convert -size ".$width."x".$height." \"".$tmp."\" -resize ".$newWidth."x".$newHeight." \"".$thumbFile."\"");
unlink($tmp);
} else {
system($_MGM['imagemagick']."convert -size ".$width."x".$height." \"".$file."\" -resize ".$newWidth."x".$newHeight." \"".$thumbFile."\"");
}
chmod($thumbFile, 0666);
echo "Saved thumbnail.<br />\n";
rename($file, $newFile);
echo "Moved Original.<br />\n";
databaseQuery("INSERT INTO images (user_id,hash,extension,name,file_size,width,height,thumb_file_size,thumb_width,thumb_height,tags,external_data,ocr,time) VALUES (%s,%s,%s,%s,%d,%d,%d,%d,%d,%d,%s,%s,%s,%d)", $_MGM['user']['docid'], $hash, $extension, $filename, $fileSize, $width, $height, filesize($thumbFile), $newWidth, $newHeight, implode(" ", $tags), $external_data, $ocr, $_MGM['time']);
echo "Complete.<br />\n";
exit();
}
$files = glob("./load/*");
require_once("header.php");
?>
Processing...<br />
<div id="result"></div>
<script type="text/javascript">
var files = new Array(<?
$array = "";
for ($i=0; $i<count($files); $i++) {
//if (in_array(pathinfo($files[$i], PATHINFO_EXTENSION), $allowedExtensions)) {
if ($array!="")
$array .= ",";
$array .= "\"".str_replace("\"", "\\\"", $files[$i])."\"";
}
echo $array;
?>);
var i=0;
function processFiles() {
if (i<files.length) {
var status = document.createElement("p");
status.innerHTML = "Processing "+(i+1)+" of "+files.length+" files.";
document.getElementById("result").appendChild(status);
var request = new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState==4) {
var status = document.createElement("p");
status.innerHTML = request.responseText;
document.getElementById("result").appendChild(status);
processFiles();
}
}
request.open("post", "<?=generateURL("upload/complete/process")?>", true);
request.setRequestHeader("Cache-Control", "no-cache");
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send("file="+encodeURIComponent(files[i]));
i++;
} else {
var completed = document.createElement("p");
completed.innerHTML = "Processing Completed.";
document.getElementById("result").appendChild(completed);
}
}
processFiles();
</script>
<?
require_once("footer.php");
exit();
}
$file = $_SERVER['HTTP_X_FILENAME'];
if (isset($file)) {
$input = fopen("php://input", "r");
if (file_exists("./load/".$file))
unlink("./load/".$file);
$output = fopen("./load/".$file, "w");
while ($data = fread($input, 1024))
fwrite($output, $data);
fclose($output);
fclose($input);
echo "uploaded";
exit();
}
require_once("header.php");
?>
<script type="text/javascript">
function upload() {
var files = document.getElementById("files").files;
document.getElementById("files").setAttribute("disabled", "true");
document.getElementById("uploadButton").setAttribute("disabled", "true");
var i=0;
function setupFile() {
if (i<files.length) {
document.getElementById("progress").innerHTML = "Uploading "+(i+1)+" of "+files.length+" files.";
var file = files[i];
if (file.name==undefined) {
document.getElementById("progress").innerHTML = "Error: Browser unsupported.";
return;
}
var request = new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState==4)
setupFile();
}
request.open("post", "<?=generateURL("upload")?>", true);
request.setRequestHeader("Cache-Control", "no-cache");
request.setRequestHeader("X-FILENAME", file.name);
request.setRequestHeader("Content-Type", "multipart/form-data");
request.send(file);
i++;
} else {
document.getElementById("progress").innerHTML = "Upload Complete.";
document.getElementById("files").removeAttribute("disabled");
document.getElementById("uploadButton").removeAttribute("disabled");
document.getElementById("files").form.reset();
window.location = "<?=generateURL("upload/complete")?>";
}
}
setupFile();
}
</script>
<form>
<input type="file" multiple="true" id="files" />
<input type="button" id="uploadButton" onclick="upload()" value="Upload" class="btn" />
</form>
<div id="progress"></div>
<?
require_once("footer.php");
exit();
?>

103
code/users.php Normal file
View File

@ -0,0 +1,103 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
require_once("header.php");
?>
<div id="user_edit" class="modal hide fade" tabindex="-1" role="dialog" style="width: 260px; margin-left: -130px;">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3 id="myModalLabel">Edit User</h3>
</div>
<div class="modal-body">
<div style="display: none;" id="user_edit_id"></div>
<input type="text" id="user_edit_email" placeholder="Email" /><br />
<input type="password" id="user_edit_password" placeholder="Password" /><br />
<select id="user_edit_level">
<option value="4">Normal</option>
<option value="3">Tagger</option>
<option value="2">Moderator</option>
<option value="1">Administrator</option>
<option value="0">Disabled</option>
</select>
<div style="display: none;" id="user_edit_load"></div>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal">Cancel</button>
<button class="btn btn-primary" data-dismiss="modal" id="user_edit_save">Save</button>
</div>
</div>
<div id="user_add" class="modal hide fade" tabindex="-1" role="dialog" style="width: 260px; margin-left: -130px;">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3 id="myModalLabel">Create User</h3>
</div>
<div class="modal-body">
<input type="text" id="user_add_email" placeholder="Email" /><br />
<input type="password" id="user_add_password" placeholder="Password" /><br />
<select id="user_add_level">
<option value="4">Normal</option>
<option value="3">Tagger</option>
<option value="2">Moderator</option>
<option value="1">Administrator</option>
<option value="0">Disabled</option>
</select>
<div style="display: none;" id="user_add_load"></div>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal">Cancel</button>
<button class="btn btn-primary" data-dismiss="modal" id="user_add_create">Create</button>
</div>
</div>
<button class="btn btn-primary" id="add_user">Create User</button><br /><br />
<table class="table table-striped table-bordered table-hover" id="users_list">
<thead>
<tr><th>#</th><th>Email</th><th>Level</th></tr>
</thead>
<tbody>
</tbody>
</table>
<script type="text/javascript">
function loadUsers() {
$("#users_list tbody").load("<?=generateURL("api/users/list")?>/")
}
$(document).ready(function() {
$("#users_list").on("click", "tbody tr", function() {
$("#user_edit_id").text($(this).find(".id").text());
$("#user_edit_email").val($(this).find(".email").text());
$("#user_edit_level").val($(this).find(".level").attr("value"));
$("#user_edit").modal();
});
$("#user_edit_save").click(function() {
$("#user_edit_load").load("<?=generateURL("api/users/update")?>/", {id: $("#user_edit_id").text(), email: $("#user_edit_email").val(), password: $("#user_edit_password").val(), level: $("#user_edit_level").val()}, function(response, status, xhr) {
loadUsers();
});
});
$("#add_user").click(function() {
$("#user_add").modal();
});
$("#user_add_create").click(function() {
$("#user_edit_load").load("<?=generateURL("api/users/create")?>/", {email: $("#user_add_email").val(), password: $("#user_add_password").val(), level: $("#user_add_level").val()}, function(response, status, xhr) {
loadUsers();
});
});
loadUsers();
});
</script>
<?
require_once("footer.php");
exit();
?>

1109
css/bootstrap-responsive.css vendored Normal file

File diff suppressed because it is too large Load Diff

9
css/bootstrap-responsive.min.css vendored Normal file

File diff suppressed because one or more lines are too long

6167
css/bootstrap.css vendored Normal file

File diff suppressed because it is too large Load Diff

9
css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

7
data/.htaccess Normal file
View File

@ -0,0 +1,7 @@
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !(\.gif|\.png|\.jpg|\.jpeg|\.tif|\.tiff)$
RewriteRule . ../index.php [L]
</IfModule>

6
databases/.htaccess Normal file
View File

@ -0,0 +1,6 @@
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule . ../index.php [L]
</IfModule>

0
databases/index.html Normal file
View File

108
dbSQLITE.php Normal file
View File

@ -0,0 +1,108 @@
<?php
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
function connectToDatabase() {
global $_MGM;
if (isset($_MGM['DBConnection'])) closeDatabase();
$_MGM['DBConnection'] = NULL;
$_MGM['DBConnection'] = new PDO("sqlite:".$_MGM['DBName']);
$_MGM['DBConnection']->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($_MGM['DBPersistent'])
$_MGM['DBConnection']->setAttribute(PDO::ATTR_PERSISTENT, TRUE);
if ($_MGM['DBConnection']==NULL) error("Database Connection Failed");
}
function closeDatabase() {
global $_MGM;
if (isset($_MGM['DBConnection'])) {
$_MGM['DBConnection'] = NULL;
}
}
function escapeString($theString) {
global $_MGM;
return $_MGM['DBConnection']->quote($theString);
}
function quoteObject($theObject) {
global $_MGM;
if (is_null($theObject)) {
return "NULL";
} else if (is_string($theObject)) {
return escapeString($theObject);
} else if (is_float($theObject) || is_integer($theObject)) {
return $theObject;
} else if (is_bool($theObject)) {
return ($theObject ? 1 : 0);
}
return "NULL";
}
function databaseQuery($format) {
global $_MGM;
$result = NULL;
try {
if (isset($_MGM['DBConnection'])) {
$args = func_get_args();
array_shift($args);
$args = array_map("quoteObject", $args);
$query = vsprintf($format, $args);
$result = $_MGM['DBConnection']->query($query);
}
//if ($result==NULL) error("Failed to run query on database");
} catch (Exception $e) {
//echo $e->getMessage()."<br />\n";
//error("Failed to run query on database");
}
return $result;
}
function databaseRowCount($theResult) {
global $_MGM;
if ($theResult==NULL)
return 0;
return $theResult->rowCount();
}
function databaseFieldCount($theResult) {
global $_MGM;
if ($theResult==NULL)
return 0;
return $theResult->columnCount();
}
function databaseLastID() {
global $_MGM;
$result = 0;
if (isset($_MGM['DBConnection'])) {
$result = $_MGM['DBConnection']->lastInsertId();
}
return $result;
}
function databaseFetch($theResult) {
global $_MGM;
return $theResult->fetch();
}
function databaseFetchNum($theResult) {
global $_MGM;
return $theResult->fetch(PDO::FETCH_NUM);
}
function databaseFetchAssoc($theResult) {
global $_MGM;
return $theResult->fetch(PDO::FETCH_ASSOC);
}
function databaseResultSeek($theResult, $theLocation) {
global $_MGM;
return false;
}
function databaseFreeResult($theResult) {
global $_MGM;
$theResult = NULL;
}
?>

View File

@ -0,0 +1,6 @@
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule . ../index.php [L]
</IfModule>

View File

19
footer.php Normal file
View File

@ -0,0 +1,19 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
?>
</div>
</body>
</html>

73
header.php Normal file
View File

@ -0,0 +1,73 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Image Database</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link href="<?=$_MGM['installPath']?>css/bootstrap.min.css" rel="stylesheet">
<style>
body {
padding-top: 60px;
}
</style>
<link href="<?=$_MGM['installPath']?>css/bootstrap-responsive.min.css" rel="stylesheet">
<script type="text/javascript" src="<?=$_MGM['installPath']?>js/jquery.min.js"></script>
<script type="text/javascript" src="<?=$_MGM['installPath']?>js/bootstrap.min.js"></script>
<script type="text/javascript" src="<?=$_MGM['installPath']?>js/date.js"></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="brand" href="<?=$_MGM['installPath']?>">Image Database</a>
<div class="nav-collapse collapse">
<ul class="nav">
<?if (isset($_MGM['user'])) {?>
<li><a href="<?=$_MGM['installPath']?>upload">Upload</a></li>
<li><a href="<?=$_MGM['installPath']?>tagless/">Tagless Images</a></li>
<?if ($_MGM['user']['level']==1) {?>
<li><a href="<?=$_MGM['installPath']?>users/">User Management</a></li>
<?}?>
<?}?>
<?if (isset($_MGM['user'])) {?>
<li><a href="<?=$_MGM['installPath']?>logout">Logout</a></li>
<?} else {?>
<li><a href="<?=$_MGM['installPath']?>login">Login</a></li>
<?}?>
</ul>
<?if ($_MGM['path'][0]=="") {?>
<form class="navbar-form pull-right" id="filter_form">
<input class="search-query" type="text" placeholder="Filter" id="filter_field" name="filter" value="<?=$_REQUEST['filter']?>" />
</form>
<?}?>
</div>
</div>
</div>
</div>
<div class="container">

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

125
index.php Normal file
View File

@ -0,0 +1,125 @@
<?
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT);
$_MGM = array();
$_MGM['version'] = "1";
$_MGM['DBType'] = "SQLITE"; // MYSQL, POSTGRESQL, SQLITE.
$_MGM['DBPersistent'] = NO;
$_MGM['DBHost'] = "localhost";
$_MGM['DBUser'] = "";
$_MGM['DBPassword'] = "";
$_MGM['DBName'] = "databases/main.db"; // File location for SQLite.
$_MGM['DBPort'] = 0; // 3306 = MySQL Default, 5432 = PostgreSQL Default.
$_MGM['DBPrefix'] = "";
$_MGM['adminEmail'] = "default@domain.com";
require_once("db{$_MGM['DBType']}.php");
$_MGM['imagemagick'] = ""; // Path to ImageMagick bin folder.
putenv("TZ=US/Central");
$_MGM['time'] = time();
$_MGM['domain'] = $_SERVER['HTTP_HOST'];
$_MGM['domainname'] = str_replace("www.", "", $_MGM['domain']);
$_MGM['port'] = $_SERVER['SERVER_PORT'];
$_MGM['ssl'] = ($_MGM['port']==443);
if ($_SERVER['REMOTE_ADDR'])
$_MGM['ip'] = $_SERVER['REMOTE_ADDR'];
if ($_SERVER['HTTP_PC_REMOTE_ADDR'])
$_MGM['ip'] = $_SERVER['HTTP_PC_REMOTE_ADDR'];
if ($_SERVER['HTTP_CLIENT_IP'])
$_MGM['ip'] = $_SERVER['HTTP_CLIENT_IP'];
if ($_SERVER['HTTP_X_FORWARDED_FOR'])
$_MGM['ip'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
$_MGM['installPath'] = substr($_SERVER['SCRIPT_NAME'], 0, strlen($_SERVER['SCRIPT_NAME'])-strlen(end(explode("/", $_SERVER['SCRIPT_NAME']))));
if (!isset($_GET['d'])) {
$tmp = explode("?", substr($_SERVER['REQUEST_URI'], strlen($_MGM['installPath'])));
$tmp = urldecode($tmp[0]);
if (substr($tmp, 0, 9)=="index.php")
$tmp = substr($tmp, 10, strlen($tmp)-10);
$_MGM['fullPath'] = $tmp;
} else {
$tmp = $_GET['d'];
if (substr($tmp, 0, 1)=="/")
$tmp = substr($tmp, 1, strlen($tmp)-1);
$_MGM['fullPath'] = $tmp;
}
if (strlen($_MGM['fullPath'])>255) error("The URI you entered is to large");
$_MGM['path'] = explode("/", strtolower($_MGM['fullPath']));
$_MGM['CookiePrefix'] = "";
$_MGM['CookiePath'] = $_MGM['installPath'];
$_MGM['CookieDomain'] = ".".$_MGM['domainname'];
function generateURL($path) {
global $_MGM;
return "http".($_MGM['ssl'] ? "s" : "")."://".$_MGM['domain'].(((!$_MGM['ssl'] && $_MGM['port']==80) || ($_MGM['ssl'] && $_MGM['port']==443)) ? "" : ":{$_MGM['port']}").$_MGM['installPath'].$path;
}
connectToDatabase();
if (file_exists("code/setup.php")) {
require("code/setup.php");
}
if (isset($_COOKIE["{$_MGM['CookiePrefix']}user_email"])) {
$result = databaseQuery("SELECT * FROM users WHERE email=%s AND level!=0", $_COOKIE["{$_MGM['CookiePrefix']}user_email"]);
$user = databaseFetchAssoc($result);
if ($user!=NULL && hash("sha512", $user['password'].$user['time'])==$_COOKIE["{$_MGM['CookiePrefix']}user_password"]) {
$_MGM['user'] = $user;
}
}
if (!isset($_MGM['user']) && $_MGM['path'][0]=="login") {
require("code/login.php");
}
if (isset($_MGM['user']) && $_MGM['path'][0]=="logout") {
require("code/logout.php");
}
if ($_MGM['path'][0]=="re-ocr") {
require("code/re-ocr.php");
}
if (isset($_MGM['user']) && $_MGM['path'][0]=="upload") {
require("code/upload.php");
}
if ($_MGM['path'][0]=="api") {
require("code/api.php");
}
if (isset($_MGM['user']) && $_MGM['user']['level']==1 && $_MGM['path'][0]=="users") {
require("code/users.php");
}
if (isset($_MGM['user']) && $_MGM['path'][0]=="tagless") {
require("code/tagless.php");
}
if ($_MGM['path'][0]=="hash") {
require("code/hash.php");
}
if ($_MGM['path'][0]!="") {
require("code/404.php");
}
require("code/index.php");
?>

2280
js/bootstrap.js vendored Normal file

File diff suppressed because it is too large Load Diff

6
js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

267
js/date.js Normal file
View File

@ -0,0 +1,267 @@
function date (format, timestamp) {
// http://kevin.vanzonneveld.net
// + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
// + parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: MeEtc (http://yass.meetcweb.com)
// + improved by: Brad Touesnard
// + improved by: Tim Wiel
// + improved by: Bryan Elliott
//
// + improved by: Brett Zamir (http://brett-zamir.me)
// + improved by: David Randall
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Brett Zamir (http://brett-zamir.me)
// + improved by: Brett Zamir (http://brett-zamir.me)
// + improved by: Theriault
// + derived from: gettimeofday
// + input by: majak
// + bugfixed by: majak
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Alex
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// + improved by: Theriault
// + improved by: Brett Zamir (http://brett-zamir.me)
// + improved by: Theriault
// + improved by: Thomas Beaucourt (http://www.webapp.fr)
// + improved by: JT
// + improved by: Theriault
// + improved by: Rafał Kukawski (http://blog.kukawski.pl)
// + bugfixed by: omid (http://phpjs.org/functions/380:380#comment_137122)
// + input by: Martin
// + input by: Alex Wilson
// + bugfixed by: Chris (http://www.devotis.nl/)
// % note 1: Uses global: php_js to store the default timezone
// % note 2: Although the function potentially allows timezone info (see notes), it currently does not set
// % note 2: per a timezone specified by date_default_timezone_set(). Implementers might use
// % note 2: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function
// % note 2: in order to adjust the dates in this function (or our other date functions!) accordingly
// * example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
// * returns 1: '09:09:40 m is month'
// * example 2: date('F j, Y, g:i a', 1062462400);
// * returns 2: 'September 2, 2003, 2:26 am'
// * example 3: date('Y W o', 1062462400);
// * returns 3: '2003 36 2003'
// * example 4: x = date('Y m d', (new Date()).getTime()/1000);
// * example 4: (x+'').length == 10 // 2009 01 09
// * returns 4: true
// * example 5: date('W', 1104534000);
// * returns 5: '53'
// * example 6: date('B t', 1104534000);
// * returns 6: '999 31'
// * example 7: date('W U', 1293750000.82); // 2010-12-31
// * returns 7: '52 1293750000'
// * example 8: date('W', 1293836400); // 2011-01-01
// * returns 8: '52'
// * example 9: date('W Y-m-d', 1293974054); // 2011-01-02
// * returns 9: '52 2011-01-02'
var that = this,
jsdate,
f,
formatChr = /\\?([a-z])/gi,
formatChrCb,
// Keep this here (works, but for code commented-out
// below for file size reasons)
//, tal= [],
_pad = function (n, c) {
n = n.toString();
return n.length < c ? _pad('0' + n, c, '0') : n;
},
txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
formatChrCb = function (t, s) {
return f[t] ? f[t]() : s;
};
f = {
// Day
d: function () { // Day of month w/leading 0; 01..31
return _pad(f.j(), 2);
},
D: function () { // Shorthand day name; Mon...Sun
return f.l().slice(0, 3);
},
j: function () { // Day of month; 1..31
return jsdate.getDate();
},
l: function () { // Full day name; Monday...Sunday
return txt_words[f.w()] + 'day';
},
N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun]
return f.w() || 7;
},
S: function(){ // Ordinal suffix for day of month; st, nd, rd, th
var j = f.j()
i = j%10;
if (i <= 3 && parseInt((j%100)/10) == 1) i = 0;
return ['st', 'nd', 'rd'][i - 1] || 'th';
},
w: function () { // Day of week; 0[Sun]..6[Sat]
return jsdate.getDay();
},
z: function () { // Day of year; 0..365
var a = new Date(f.Y(), f.n() - 1, f.j()),
b = new Date(f.Y(), 0, 1);
return Math.round((a - b) / 864e5);
},
// Week
W: function () { // ISO-8601 week number
var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3),
b = new Date(a.getFullYear(), 0, 4);
return _pad(1 + Math.round((a - b) / 864e5 / 7), 2);
},
// Month
F: function () { // Full month name; January...December
return txt_words[6 + f.n()];
},
m: function () { // Month w/leading 0; 01...12
return _pad(f.n(), 2);
},
M: function () { // Shorthand month name; Jan...Dec
return f.F().slice(0, 3);
},
n: function () { // Month; 1...12
return jsdate.getMonth() + 1;
},
t: function () { // Days in month; 28...31
return (new Date(f.Y(), f.n(), 0)).getDate();
},
// Year
L: function () { // Is leap year?; 0 or 1
var j = f.Y();
return j % 4 === 0 & j % 100 !== 0 | j % 400 === 0;
},
o: function () { // ISO-8601 year
var n = f.n(),
W = f.W(),
Y = f.Y();
return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0);
},
Y: function () { // Full year; e.g. 1980...2010
return jsdate.getFullYear();
},
y: function () { // Last two digits of year; 00...99
return f.Y().toString().slice(-2);
},
// Time
a: function () { // am or pm
return jsdate.getHours() > 11 ? "pm" : "am";
},
A: function () { // AM or PM
return f.a().toUpperCase();
},
B: function () { // Swatch Internet time; 000..999
var H = jsdate.getUTCHours() * 36e2,
// Hours
i = jsdate.getUTCMinutes() * 60,
// Minutes
s = jsdate.getUTCSeconds(); // Seconds
return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
},
g: function () { // 12-Hours; 1..12
return f.G() % 12 || 12;
},
G: function () { // 24-Hours; 0..23
return jsdate.getHours();
},
h: function () { // 12-Hours w/leading 0; 01..12
return _pad(f.g(), 2);
},
H: function () { // 24-Hours w/leading 0; 00..23
return _pad(f.G(), 2);
},
i: function () { // Minutes w/leading 0; 00..59
return _pad(jsdate.getMinutes(), 2);
},
s: function () { // Seconds w/leading 0; 00..59
return _pad(jsdate.getSeconds(), 2);
},
u: function () { // Microseconds; 000000-999000
return _pad(jsdate.getMilliseconds() * 1000, 6);
},
// Timezone
e: function () { // Timezone identifier; e.g. Atlantic/Azores, ...
// The following works, but requires inclusion of the very large
// timezone_abbreviations_list() function.
/* return that.date_default_timezone_get();
*/
throw 'Not supported (see source code of date() for timezone on how to add support)';
},
I: function () { // DST observed?; 0 or 1
// Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
// If they are not equal, then DST is observed.
var a = new Date(f.Y(), 0),
// Jan 1
c = Date.UTC(f.Y(), 0),
// Jan 1 UTC
b = new Date(f.Y(), 6),
// Jul 1
d = Date.UTC(f.Y(), 6); // Jul 1 UTC
return ((a - c) !== (b - d)) ? 1 : 0;
},
O: function () { // Difference to GMT in hour format; e.g. +0200
var tzo = jsdate.getTimezoneOffset(),
a = Math.abs(tzo);
return (tzo > 0 ? "-" : "+") + _pad(Math.floor(a / 60) * 100 + a % 60, 4);
},
P: function () { // Difference to GMT w/colon; e.g. +02:00
var O = f.O();
return (O.substr(0, 3) + ":" + O.substr(3, 2));
},
T: function () { // Timezone abbreviation; e.g. EST, MDT, ...
// The following works, but requires inclusion of the very
// large timezone_abbreviations_list() function.
/* var abbr = '', i = 0, os = 0, default = 0;
if (!tal.length) {
tal = that.timezone_abbreviations_list();
}
if (that.php_js && that.php_js.default_timezone) {
default = that.php_js.default_timezone;
for (abbr in tal) {
for (i=0; i < tal[abbr].length; i++) {
if (tal[abbr][i].timezone_id === default) {
return abbr.toUpperCase();
}
}
}
}
for (abbr in tal) {
for (i = 0; i < tal[abbr].length; i++) {
os = -jsdate.getTimezoneOffset() * 60;
if (tal[abbr][i].offset === os) {
return abbr.toUpperCase();
}
}
}
*/
return 'UTC';
},
Z: function () { // Timezone offset in seconds (-43200...50400)
return -jsdate.getTimezoneOffset() * 60;
},
// Full Date/Time
c: function () { // ISO-8601 date.
return 'Y-m-d\\TH:i:sP'.replace(formatChr, formatChrCb);
},
r: function () { // RFC 2822
return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
},
U: function () { // Seconds since UNIX epoch
return jsdate / 1000 | 0;
}
};
this.date = function (format, timestamp) {
that = this;
jsdate = (timestamp === undefined ? new Date() : // Not provided
(timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
);
return format.replace(formatChr, formatChrCb);
};
return this.date(format, timestamp);
}

9807
js/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

6
js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

6
load/.htaccess Normal file
View File

@ -0,0 +1,6 @@
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule . ../index.php [L]
</IfModule>

53
ocr.cpp Normal file
View File

@ -0,0 +1,53 @@
//
// Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted, provided that the above copyright notice
// and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
// ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <tesseract/baseapi.h>
#include <iostream>
int main(int argc, char **argv) {
if (argc!=2) {
std::cerr << "Please specify an image" << std::endl;
return -1;
}
cv::Mat image = cv::imread(argv[1]);
if (image.empty()) {
std::cerr << "Cannot open source image" << std::endl;
return -1;
}
cv::Mat gray;
cv::cvtColor(image, gray, CV_BGR2GRAY);
cv::Mat final;
cv::threshold(gray, final, 225, 255, cv::THRESH_BINARY);
/*cv::namedWindow("Display window", CV_WINDOW_AUTOSIZE);
cv::imshow("Display window", final);
cv::waitKey(0);*/
tesseract::TessBaseAPI tess;
tess.Init(NULL, "eng", tesseract::OEM_DEFAULT);
tess.SetPageSegMode(tesseract::PSM_SINGLE_BLOCK);
tess.SetImage((uchar*)final.data, final.cols, final.rows, 1, final.cols);
char *out = tess.GetUTF8Text();
std::cout << out;
return 0;
}

3
ocr.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
g++ -I/usr/local/include `pkg-config --cflags --libs opencv tesseract` ocr.cpp -o ocr

81
readme.md Normal file
View File

@ -0,0 +1,81 @@
#Requirements
1: [pdo sqlite](http://php.net/manual/en/ref.pdo-sqlite.php)
2: [gd](http://php.net/manual/en/book.image.php)
3: Due to my coding style, you must allow [short tags](http://php.net/manual/en/ini.core.php) \("<?"\) in php.
4: Installation of [ImageMagick](http://www.imagemagick.org/script/index.php). You can test this by typing "convert" in terminal. If needed, you can change configuration in index.php for the bin path.
#Installation
1: Copy all files to your server.
2: Change permissions to folders databases, load, data, and thumbs so that php can write to them. If you do not know the correct permissions, 777 will work but is inscure on shared servers.
3: Visit the database on your server and the setup process will commence.
4: Once you have finished the setup process. You may delete the setup file in the code folder if you do not want to allow anyone to setup a new database if for some reason the file gets currupted.
#Setting up your server
##Nginx
Here is the configuration you need to add to your nginx server.
```text
location ~* /(databases|load|code|external_data_plugins) {
rewrite ^ /index.php?$args;
}
location ~* /(data|thumbs)/.*(?<\!\.gif|\.png|\.jpg|\.jpeg|\.tif|\.tiff)$ {
rewrite ^ /index.php?$args;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
```
It is best to placet the ones with "rewrite" above your php include.
You can test by visiting /code/index.php to see if it loads the index file or if it shows a 404 error.
##Apache
For Apache, i've already included the .htaccess files needed. Just make sure your server is configured to allow htaccess and mod_rewrite. Best test by visiting /code/index.php.
#Getting OCR to work.
I've included code to OCR images for text. It's not perfect, but it provides great power.
In-order to use it, you must first install [OpenCV](http://opencv.org/) and [Tesseract-OCR]([https://code.google.com/p/tesseract-ocr/). Then you should just be able to run ```./ocr.sh``` in terminal with the image database directory as your current working directory. Only tested on OS X.
#Writing an External Data Plugin
External Data plugins allows you to write plugins which grabs data from another site about an image and put it into the metadata to make search better. For an example, if there is an image tag site which contains your image and good tags, you could write your plugin to grab the tags and store them so when you search for say green, your image will popup as the tag green was on that image via the site.
Writing a plugin is simple. Make a new file in the folder external_data_plugins and then put your code inside of it to grab the data and fill the database.
```php
<?
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => "http://mrgeckosmedia.com/some-api",
CURLOPT_POSTFIELDS => array(
"md5" => $hash
),
CURLOPT_RETURNTRANSFER => true
));
$received = json_decode(curl_exec($ch), true);
curl_close($ch);
if (isset($received['result']['tags'])) {
if (!empty($external_data))
$external_data .= " ";
//Append to the "$external_data" variable with the description to provide rich content.
$external_data .= $received['result']['description'];
//Prefill Tags in database.
$dtags = explode(" ", $received['result']['tags']);
for ($i=0; $i<count($dtags); $i++) {
if (!in_array($dtags[$i], $tags))
array_push($tags, $dtags[$i]);
}
}
?>
```
You have access to many variables about the file being processed including it's name and extension. Just look at code/upload.php to see what is available.
#Known Problems
There is going to be issues with people who add tags or other user fields that contains a quotation mark or anything else which could interrupt the HTML code (not an sql injection). I was too lazy and didn't want to look up my code for preventing these sorts of issues. So for now, just use it as a personal database. There isn't a public registration module anyway. Maybe when I get time, I'll fix these possible issues.
There isn't any error reporting in the API and there isn't anyway for the user to know that such an error such as network issues or database issues occured.

7
thumbs/.htaccess Normal file
View File

@ -0,0 +1,7 @@
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !(\.gif|\.png|\.jpg|\.jpeg|\.tif|\.tiff)$
RewriteRule . ../index.php [L]
</IfModule>