- FTP Sharing
- New Upload & New Search
- Performance and stuff under the hood
- Desktop Notifications
- Right-Click on photos and albums
- Retina Thumbs
- Improved Interface
pull/4/head 1.1
Tobias Reich 11 years ago
parent b565390419
commit dcc51497c3

@ -1,3 +1,10 @@
/**
* @name animations.css
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*/
/* bounceInDown ------------------------------------------------*/ /* bounceInDown ------------------------------------------------*/
@-webkit-keyframes bounceInDown { @-webkit-keyframes bounceInDown {
0% { 0% {
@ -350,21 +357,17 @@
@-ms-keyframes zoomOut { @-ms-keyframes zoomOut {
0% { 0% {
opacity: 1; opacity: 1;
-ms-transform: scale(1);
} }
100% { 100% {
opacity: 0; opacity: 0;
-ms-transform: scale(.5);
} }
} }
@-o-keyframes zoomOut { @-o-keyframes zoomOut {
0% { 0% {
opacity: 1; opacity: 1;
-o-transform: scale(1);
} }
100% { 100% {
opacity: 0; opacity: 0;
-o-transform: scale(.5);
} }
} }
@keyframes zoomOut { @keyframes zoomOut {
@ -400,21 +403,17 @@
@-ms-keyframes zoomIn { @-ms-keyframes zoomIn {
0% { 0% {
opacity: 0; opacity: 0;
-ms-transform: scale(.5);
} }
100% { 100% {
opacity: 1; opacity: 1;
-ms-transform: scale(1);
} }
} }
@-o-keyframes zoomIn { @-o-keyframes zoomIn {
0% { 0% {
opacity: 0; opacity: 0;
-o-transform: scale(.5);
} }
100% { 100% {
opacity: 1; opacity: 1;
-o-transform: scale(1);
} }
} }
@keyframes zoomIn { @keyframes zoomIn {

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 127 KiB

@ -1,3 +1,10 @@
/**
* @name style.css
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*/
/* Reset -------------------------------------------------*/ /* Reset -------------------------------------------------*/
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { margin:0; padding:0; border:0; font-size:100%; font:inherit; vertical-align:baseline; } html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { margin:0; padding:0; border:0; font-size:100%; font:inherit; vertical-align:baseline; }
article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section { display:block; } article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section { display:block; }
@ -7,43 +14,6 @@ blockquote,q { quotes:none; }
blockquote:before,blockquote:after,q:before,q:after { content:''; content:none; } blockquote:before,blockquote:after,q:before,q:after { content:''; content:none; }
table { border-collapse:collapse; border-spacing:0; } table { border-collapse:collapse; border-spacing:0; }
/* Screen behavior -------------------------------------------------*/
@media only screen and (max-width: 900px) {
#title span { display: none; }
}
@media only screen and (max-width: 640px) {
#title { display: none; }
#button_move { display: none; }
.center {
top: 0px !important;
left: 0px !important;
}
.message {
position: fixed !important;
width: 100% !important;
height: 100% !important;
margin: 1px 0px 0px 0px !important;
border-radius: 0px !important;
/* Animation */
-webkit-animation-name: moveUp !important;
-webkit-animation-duration: .3s !important;
-moz-animation-name: moveUp !important;
-moz-animation-duration: .3s !important;
-o-animation-name: moveUp !important;
-o-animation-duration: .3s !important;
animation-name: moveUp !important;
animation-duration: .3s !important;
}
}
/* Basics -------------------------------------------------*/ /* Basics -------------------------------------------------*/
html, body { html, body {
min-height: 100%; min-height: 100%;
@ -106,7 +76,7 @@ body { background-color: #222; background-image: url(../img/background.jpg); fon
.tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; }
.tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; }
/* Overlay ------------------------------------------------*/ /* Animations ------------------------------------------------*/
.fadeIn { .fadeIn {
-webkit-animation-name: fadeIn; -webkit-animation-name: fadeIn;
-webkit-animation-duration: .3s; -webkit-animation-duration: .3s;
@ -344,7 +314,7 @@ header {
background-image: -o-linear-gradient(top, #555 0%, #333 100%); background-image: -o-linear-gradient(top, #555 0%, #333 100%);
background: linear-gradient(top, #555 0%, #333 100%); background: linear-gradient(top, #555 0%, #333 100%);
border: 1px solid #252525; border: 1px solid #222;
border-radius: 3px; border-radius: 3px;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0px 1px 0px #444; box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0px 1px 0px #444;
cursor: pointer; cursor: pointer;
@ -462,6 +432,7 @@ header {
position: absolute; position: absolute;
padding: 41px 0px 33px 0px; padding: 41px 0px 33px 0px;
width: 100%; width: 100%;
-webkit-overflow-scrolling: touch;
} }
/* Photo ------------------------------------------------*/ /* Photo ------------------------------------------------*/
@ -525,7 +496,7 @@ header {
box-shadow: 0px 1px 5px #111; box-shadow: 0px 1px 5px #111;
border: 3px solid #ccc; border: 3px solid #ccc;
} }
.album:hover img { .album:hover img, .album.active img {
box-shadow: 0px 0px 10px #005ecc; box-shadow: 0px 0px 10px #005ecc;
} }
@ -909,6 +880,9 @@ header {
box-shadow: 0px 2px 4px #000; box-shadow: 0px 2px 4px #000;
-webkit-transition: background-color .3s; -webkit-transition: background-color .3s;
} }
#image_view.full {
background-color: #111;
}
#image_view #image { #image_view #image {
position: absolute; position: absolute;
@ -960,10 +934,16 @@ header {
left: 20px; left: 20px;
-webkit-transition: left .3s; -webkit-transition: left .3s;
} }
#image_view.full a#previous {
left: -50px;
}
#image_view a#next { #image_view a#next {
right: 20px; right: 20px;
-webkit-transition: right .3s -webkit-transition: right .3s
} }
#image_view.full a#next {
right: -50px;
}
/* InfoBox ------------------------------------------------*/ /* InfoBox ------------------------------------------------*/
#infobox_overlay { #infobox_overlay {
@ -1094,6 +1074,7 @@ header {
width: 100%; width: 100%;
height: 35px; height: 35px;
} }
#infobox #edit_title,
#infobox #edit_description { #infobox #edit_description {
display: inline; display: inline;
margin-left: 3px; margin-left: 3px;
@ -1289,17 +1270,75 @@ header {
width: 0%; width: 0%;
height: 100%; height: 100%;
box-shadow: 0 1px 0 #000, 1px 0px 2px #000; box-shadow: 0 1px 0 #000, 1px 0px 2px #000;
background: rgb(255,255,255); /* Old browsers */ background-color: #f5f2f7;
background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(241,241,241,1) 50%, rgba(225,225,225,1) 51%, rgba(246,246,246,1) 100%); /* FF3.6+ */ background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f2f7), to(#c7c6c8));
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,1)), color-stop(50%,rgba(241,241,241,1)), color-stop(51%,rgba(225,225,225,1)), color-stop(100%,rgba(246,246,246,1))); /* Chrome,Safari4+ */ background-image: -webkit-linear-gradient(top, #f5f2f7, #c7c6c8);
background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(241,241,241,1) 50%,rgba(225,225,225,1) 51%,rgba(246,246,246,1) 100%); /* Chrome10+,Safari5.1+ */ background-image: -moz-linear-gradient(top, #f5f2f7, #c7c6c8);
background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(241,241,241,1) 50%,rgba(225,225,225,1) 51%,rgba(246,246,246,1) 100%); /* Opera11.10+ */ background-image: -o-linear-gradient(top, #f5f2f7, #c7c6c8);
background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(241,241,241,1) 50%,rgba(225,225,225,1) 51%,rgba(246,246,246,1) 100%); /* IE10+ */ background-image: -ms-linear-gradient(top, #f5f2f7, #c7c6c8);
background: linear-gradient(top, rgba(255,255,255,1) 0%,rgba(241,241,241,1) 50%,rgba(225,225,225,1) 51%,rgba(246,246,246,1) 100%); /* W3C */ background-image: linear-gradient(top, #f5f2f7, #c7c6c8);
border-radius: 5px; border-radius: 5px;
-webkit-transition: width .2s, opacity .5;
-moz-transition: width .2s, opacity .5;
-o-transition: width .2s, opacity .5;
transition: width .2s, opacity .5;
}
/* Screen behavior -------------------------------------------------*/
@media only screen and (max-width: 900px) {
#title {
margin: 11px 30% 0px 20%;
width: 50%;
}
#title.view { margin: 11px 20% 0px 20%; width: 60%; }
#title span { display: none; }
}
@media only screen and (max-width: 640px) {
#title { display: none; }
#title.view { display: block; margin: 11px 20% 0px 15%; width: 65%; }
#button_move { display: none; }
#button_archive { display: none; }
.center {
top: 0px;
left: 0px;
}
.message {
position: fixed;
width: 100%;
height: 100%;
margin: 1px 0px 0px 0px !important;
border-radius: 0px;
/* Animation */
-webkit-animation-name: moveUp;
-webkit-animation-duration: .3s;
-moz-animation-name: moveUp;
-moz-animation-duration: .3s;
-o-animation-name: moveUp;
-o-animation-duration: .3s;
animation-name: moveUp;
animation-duration: .3s;
}
.album {
margin: 40px 0px 0px 50px;
}
.photo {
margin: 40px 0px 0px 50px;
}
.message.add {
margin-top: 0px;
}
.add_album {
margin: 30px 0px -10px 55px;
}
-webkit-transition: width .2s;
-moz-transition: width .2s;
-o-transition: width .2s;
transition: width .2s;
} }

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Before

Width:  |  Height:  |  Size: 184 B

After

Width:  |  Height:  |  Size: 184 B

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Before

Width:  |  Height:  |  Size: 113 B

After

Width:  |  Height:  |  Size: 113 B

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

@ -32,7 +32,6 @@
<div id="tools_albums"> <div id="tools_albums">
<a class="button" id="button_signout">Sign Out</a> <a class="button" id="button_signout">Sign Out</a>
<a class="button icon icon-plus-sign button_add"></a> <a class="button icon icon-plus-sign button_add"></a>
<!--<a class="button icon icon-refresh" id="button_sync"></a>-->
<a class="button_divider"></a> <a class="button_divider"></a>
<input id="search" type="text" name="search" placeholder="Search …"> <input id="search" type="text" name="search" placeholder="Search …">
</div> </div>
@ -48,7 +47,7 @@
<a class="button" id="button_back">Back</a> <a class="button" id="button_back">Back</a>
<div class="tools" id="button_trash" title="Delete"><a class="icon-trash"></a></div> <div class="tools" id="button_trash" title="Delete"><a class="icon-trash"></a></div>
<div class="tools" id="button_move" title="Move to Album"><a class="icon-folder-open"></a></div> <div class="tools" id="button_move" title="Move to Album"><a class="icon-folder-open"></a></div>
<div class="tools" id="button_download" title="Download Photo"><a class="icon-download"></a></div> <div class="tools" id="button_download" title="Full Photo"><a class="icon-resize-full"></a></div>
<a class="button_divider less"></a> <a class="button_divider less"></a>
<div class="tools" id="button_info" title="Show Info"><a class="icon-info-sign"></a></div> <div class="tools" id="button_info" title="Show Info"><a class="icon-info-sign"></a></div>
<div class="tools" id="button_edit" title="Edit Title"><a class="icon-edit"></a></div> <div class="tools" id="button_edit" title="Edit Title"><a class="icon-edit"></a></div>
@ -79,9 +78,20 @@
<!-- JS --> <!-- JS -->
<script type="text/javascript" src="js/frameworks.js"></script> <script type="text/javascript" src="js/frameworks.js"></script>
<script type="text/javascript" src="js/upload.js"></script>
<script type="text/javascript" src="js/build.js"></script> <!-- Development
<script type="text/javascript" src="js/functions.js"></script> <script type="text/javascript" src="js/modules/lychee.js"></script>
<script type="text/javascript" src="js/modules/build.js"></script>
<script type="text/javascript" src="js/modules/albums.js"></script>
<script type="text/javascript" src="js/modules/photos.js"></script>
<script type="text/javascript" src="js/modules/visible.js"></script>
<script type="text/javascript" src="js/modules/loadingBar.js"></script>
<script type="text/javascript" src="js/modules/contextMenu.js"></script>
<script type="text/javascript" src="js/modules/search.js"></script> -->
<!-- Production -->
<script type="text/javascript" src="js/functions.js"></script>
<script type="text/javascript" src="js/main.js"></script> <script type="text/javascript" src="js/main.js"></script>
</body> </body>

@ -1,247 +0,0 @@
/**
* @name build.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2012 by Philipp Maurer, Tobias Reich
*/
/*
Build Functions
This functions are used to generate HTML-Code.
*/
function buildDivider(title) {
return "<div class='divider fadeIn'><h1>" + title + "</h1></div>";
}
function buildAlbum(albumJSON) {
if(!albumJSON) return "";
if(!albumJSON.thumb0) albumJSON.thumb0 = "img/no_images.png";
if(!albumJSON.thumb1) albumJSON.thumb1 = "img/no_images.png";
if(!albumJSON.thumb2) albumJSON.thumb2 = "img/no_images.png";
if(!albumJSON.title) albumJSON.title = "Untitled";
if(albumJSON.title.length>18) albumJSON.title = albumJSON.title.substr(0, 18) + "...";
var album = "";
album += "<div class='album' data-id='" + albumJSON.id + "'>";
album += "<img src='" + albumJSON.thumb2 + "' width='200' height='200' alt='thumb'>";
album += "<img src='" + albumJSON.thumb1 + "' width='200' height='200' alt='thumb'>";
album += "<img src='" + albumJSON.thumb0 + "' width='200' height='200' alt='thumb'>";
album += "<div class='overlay'>";
album += "<h1>" + albumJSON.title + "</h1>";
album += "<a>" + albumJSON.sysdate + "</a>";
album += "</div>";
if(albumJSON.star=="1") album += "<a class='badge red icon-star'></a>";
if(albumJSON.public=="1") album += "<a class='badge red icon-rss'></a>";
if(albumJSON.unsorted=="1") album += "<a class='badge red icon-reorder'></a>";
album += "</div>";
return album;
}
function buildPhoto(photoJSON) {
if(photoJSON=="") return "";
if(!photoJSON.title) photoJSON.title = "";
if(!photoJSON.thumbUrl) photoJSON.thumbUrl = "img/no_image.png";
if(photoJSON.title.length>18) photoJSON.title = photoJSON.title.substr(0, 18) + "...";
var photo = "";
photo += "<div class='photo' data-id='" + photoJSON.id + "'>";
photo += "<img src='" + photoJSON.thumbUrl + "' width='200' height='200' alt='thumb'>";
photo += "<div class='overlay'>";
photo += "<h1>" + photoJSON.title + "</h1>";
photo += "<a>" + photoJSON.sysdate + "</a>";
photo += "</div>";
if(photoJSON.star=="1") photo += "<a class='badge red icon-star'></a>";
if(photoJSON.public=="1") photo += "<a class='badge red icon-rss'></a>";
photo += "</div>";
return photo;
}
function buildModal(title, text, button, func) {
var modal = "";
modal += "<div class='message_overlay fadeIn'>";
modal += "<div class='message center'>";
modal += "<h1>" + title + "</h1>";
modal += "<a class='close icon-remove-sign'></a>";
modal += "<p>" + text + "</p>";
$.each(button, function(index) {
if (index==0) modal += "<a onclick='message_click(" + index + ")' class='button active'>" + this + "</a>";
else modal += "<a onclick='message_click(" + index + ")' class='button'>" + this + "</a>";
});
modal += "</div>";
modal += "<script>";
modal += "function message_click(action) {";
modal += "switch (action) {";
$.each(func, function(index) {
modal += "case " + index + ":";
modal += this.toString();
modal += "break;";
});
modal += "} closeModal(); }";
modal += "</script>";
modal += "</div>";
return modal;
}
function buildAddModal() {
var modal = "";
modal += "<div class='message_overlay fadeIn'>";
modal += "<div class='message center add'>";
modal += "<h1>Add Album or Photo</h1>";
modal += "<a class='close icon-remove-sign'></a>";
modal += "<div id='add_album' class='add_album'>";
modal += "<div class='icon icon-folder-close'></div>";
modal += "<a>Add new Album</a>";
modal += "</div>";
modal += "<div id='add_photo' class='add_album'>";
modal += "<div class='icon icon-picture'></div>";
modal += "<a>Upload new Photo</a>";
modal += "</div>";
modal += "</div>";
modal += "</div>";
return modal;
}
function buildSignInModal() {
var modal = "";
modal += "<div class='message_overlay'>";
modal += "<div class='message center'>";
modal += "<h1><a class='icon-lock'></a> Sign in</h1>";
modal += "<div class='sign_in'>";
modal += "<input id='username' type='text' name='' value='' placeholder='username'>";
modal += "<input id='password' type='password' name='' value='' placeholder='password'>";
modal += "</div>";
modal += "<div id='version'>Version " + version + "</div>";
modal += "<a onclick='login()' class='button active'>Sign in</a>";
modal += "</div>";
modal += "</div>";
return modal;
}
function buildUploadModal() {
var modal = "";
modal += "<div class='upload_overlay fadeIn'>";
modal += "<div class='upload_message center'>";
modal += "<a class='icon-upload'></a>";
modal += "<div class='progressbar'><div></div></div>";
modal += "</div>";
modal += "</div>";
return modal;
}
function buildContextMenu(items) {
var menu = "";
menu += "<div class='contextmenu_bg'></div>";
menu += "<div class='contextmenu'>";
menu += "<table>";
menu += "<tbody>";
$.each(items, function(index) {
if (items[index][1].length!=0) {
menu += "<tr><td onclick='" + items[index][1] + "; closeContextMenu();'>" + items[index][0] + "</td></tr>";
}
});
menu += "</tbody>";
menu += "</table>";
menu += "</div>";
return menu;
}
function buildInfobox(photo) {
var infobox = "";
infobox += "<div class='header'><h1>About</h1><a class='icon-remove-sign'></a></div>";
infobox += "<div class='wrapper'>";
if (photo.public==1) photo.public = "Public"; else photo.public = "Private";
infos = [
["", "Basics"],
["Name", photo.title],
["Uploaded", photo.sysdate],
["Description", photo.description + " <div id='edit_description'><a class='icon-pencil'></a></div>"],
["", "Image"],
["Size", photo.size],
["Format", photo.type],
["Resolution", photo.width + " x " + photo.height],
["", "Camera"],
["Captured", photo.takedate],
["Make", photo.make],
["Type/Model", photo.model],
["Shutter Speed", photo.shutter],
["Aperture", photo.aperture],
["Focal Length", photo.focal],
["ISO", photo.iso],
["", "Share"],
["Privacy", photo.public],
["Short Link", photo.shortlink]
];
$.each(infos, function(index) {
if (infos[index][1]==""||infos[index][1]==undefined||infos[index][1]==null) infos[index][1] = "-";
if (infos[index][0]=="") {
infobox += "</table>";
infobox += "<div class='separater'><h1>" + infos[index][1] + "</h1></div>";
infobox += "<table id='infos'>";
} else {
infobox += "<tr>";
infobox += "<td>" + infos[index][0] + "</td>";
infobox += "<td>" + infos[index][1] + "</td>";
infobox += "</tr>";
}
});
infobox += "</table>";
infobox += "<div class='bumper'></div>";
infobox += "</div>";
return infobox;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -2,17 +2,11 @@
* @name main.js * @name main.js
* @author Philipp Maurer * @author Philipp Maurer
* @author Tobias Reich * @author Tobias Reich
* @copyright 2012 by Philipp Maurer, Tobias Reich * @copyright 2013 by Philipp Maurer, Tobias Reich
*/ */
var header = $("header"), /* Modules */
headerTitle = $("#title"), lychee.init("php/api.php", "");
content = $("#content"),
image_view = $("#image_view"),
loading = $("#loading"),
infobox = $("#infobox"),
api_path = "php/api.php",
version = "1.0.2";
$(document).ready(function(){ $(document).ready(function(){
@ -20,100 +14,120 @@ $(document).ready(function(){
if (mobileBrowser()) event_name = "touchend"; if (mobileBrowser()) event_name = "touchend";
else event_name = "click"; else event_name = "click";
/* Login */ /* Toolbar */
$("#password").live("keyup", function() { $("#button_signout").on(event_name, function() {
if ($(this).val().length>0) $(this).removeClass("error"); modal = build.modal("Sign Out", "Are you sure you want to leave and log out?", ["Sign out", "Stay here"], ["lychee.logout();", ""]);
});
/* Add Dialog */
$(".button_add").live(event_name, function() { $("body").append(buildAddModal) });
$("#add_album").live(event_name, addAlbum);
$("#add_photo").live(event_name, function() { $("#auswahl").html(""); $("#upload_files").click() });
/* Toolbar Buttons */
$("#button_signout").live(event_name, function() {
modal = buildModal("Sign Out", "Are you sure you want to leave and log out?", ["Sign out", "Stay here"], ["logout();", ""]);
$("body").append(modal); $("body").append(modal);
}); });
$("#button_download").live(event_name, function() { $("#button_download").on(event_name, function() {
link = $("#image_view #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, ""); link = $("#image_view #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
window.open(link,"_newtab"); window.open(link,"_newtab");
}); });
$("#button_move").live(event_name, function(e) { $("#button_share").on(event_name, function(e) {
showContextMenuMove(image_view.attr("data-id"), e.pageX, e.pageY); if ($("#button_share a.active").length) contextMenu.share(lychee.image_view.attr("data-id"), e.pageX, e.pageY);
else photos.setPublic(e);
}); });
$("#button_trash_album").live(event_name, function() { $("#button_trash_album").on(event_name, function() { albums.deleteDialog(lychee.content.attr("data-id")) });
if (content.attr("data-id")=="0") deleteUnsorted(); $("#button_move").on(event_name, function(e) { contextMenu.move(lychee.image_view.attr("data-id"), e.pageX, e.pageY) });
else deleteAlbum(); $("#button_trash").on(event_name, function() { photos.deleteDialog() });
}); $("#button_edit_album").on(event_name, function() { albums.rename() });
$("#button_trash").live(event_name, function() { deletePhoto() }); $("#button_edit").on(event_name, function() { photos.rename() });
$("#button_edit_album").live(event_name, function() { renameAlbum() }); $("#button_info").on(event_name, function() { photos.showInfobox() });
$("#button_edit").live(event_name, function() { renamePhoto() }); $("#button_archive").on(event_name, function() { albums.getArchive() });
$("#button_info").live(event_name, function() { showInfobox() }); $("#button_star").on(event_name, function() { photos.setStar() });
$("#button_archive").live(event_name, function() { getAlbumArchive() }); $(".copylink").on(event_name, function() { $(this).select() });
$("#button_sync").live(event_name, function() { syncFolder() });
/* Search */
/* Rename Album/Photo via Titlebar */ $("#search").on("keyup click", function() { search.find($(this).val()) });
$("#title.editable").live(event_name, function() {
if (visibleImageview()) renamePhoto(); else renameAlbum(); /* Back Buttons */
$("#button_back_home").on(event_name, function() { lychee.goto("") });
$("#button_back").on(event_name, function() { lychee.goto("a" + lychee.content.attr("data-id")) });
/* Image View */
$("#image_view")
.on(event_name, "a#previous", photos.previous)
.on(event_name, "a#next", photos.next);
/* Infobox */
$("#infobox")
.on(event_name, ".header a", function() { photos.hideInfobox() })
.on(event_name, "#edit_title", function() { photos.rename() })
.on(event_name, "#edit_description", function() { photos.setDescription() });
/* Keyboard */
Mousetrap
.bind('n', function(e) { $("body").append(build.addModal) })
.bind('u', function(e) { $("#auswahl").html(""); $("#upload_files").click() })
.bind('s', function(e) { if (visible.imageview()) $("#button_star").click() })
.bind('f', function(e) { if (visible.imageview()) $("#button_download").click() })
.bind('i', function(e) { if (visible.imageview()) photos.showInfobox() })
.bind('backspace', function(e) { if (visible.imageview()) photos.deleteDialog() })
.bind('left', function(e) { if (visible.imageview()) photos.previous() })
.bind('right', function(e) { if (visible.imageview()) photos.next() });
Mousetrap.bindGlobal('enter', function(e) {
if ($(".message .button.active").length) $(".message .button.active").addClass("pressed").click()
}); });
/* Context Menu */ Mousetrap.bindGlobal('esc', function(e) {
$(".photo").live("contextmenu", function(e) {
e.preventDefault(); e.preventDefault();
showContextMenuPhoto($(this).attr("data-id"), e.pageX, e.pageY); if ($(".message").length&&$(".sign_in").length==0) lychee.closeModal();
else if (visible.infobox()) photos.hideInfobox();
else if (visible.imageview()) lychee.goto("a" + lychee.content.attr("data-id"));
else if (visible.albums()&&$("#search").val().length!=0) search.reset();
}); });
$(".contextmenu_bg").live(event_name, closeContextMenu);
/* Star/Share Photo */ /* Document */
$("#button_star").live(event_name, setPhotoStar); $(document)
$("#button_share").live(event_name, function(e) {
if ($("#button_share a.active").length) showContextMenuShare(image_view.attr("data-id"), e.pageX, e.pageY);
else setPhotoPublic(e);
});
$(".copylink").live(event_name, function() { $(this).select() });
/* Upload */ /* Login */
$("#upload_files").live("change", function() { .on("keyup", "#password", function() { if ($(this).val().length>0) $(this).removeClass("error") })
closeModal();
handleFiles(this.files);
$("#upload_button").click();
});
/* Search */ /* Toolbar */
$("#search").live("keyup", function() { search($(this).val()) }); .on(event_name, "#title.editable", function() { if (visible.imageview()) photos.rename(); else albums.rename(); })
/* Nav Forward */ /* Navigation */
$(".album").live("click", function() { setURL("a" + $(this).attr("data-id")) }); .on("click", ".album", function() { lychee.goto("a" + $(this).attr("data-id")) })
$(".photo").live("click", function() { setURL("a" + content.attr("data-id") + "p" + $(this).attr("data-id")) }); .on("click", ".photo", function() {
if (lychee.content.attr("data-id")!="") lychee.goto("a" + lychee.content.attr("data-id") + "p" + $(this).attr("data-id"));
else lychee.goto("a" + $(this).attr("data-album-id") + "p" + $(this).attr("data-id"));
})
/* Nav Back */ /* Modal */
$("#button_back_home").live(event_name, function() { setURL("") }); .on(event_name, ".message .close", lychee.closeModal)
$("#button_back").live(event_name, function() { setURL("a" + content.attr("data-id")) });
/* Close Modal */ /* Add Dialog */
$(".message a.close").live(event_name, closeModal); .on(event_name, ".button_add", function() { $("body").append(build.addModal) })
.on(event_name, "#add_album", albums.add)
.on(event_name, "#add_photo", function() { $("#auswahl").html(""); $("#upload_files").click() })
/* Image View */ /* Upload */
$("#image_view a#previous").live(event_name, loadPreviousPhoto); .on("change", "#upload_files", function() { lychee.closeModal(); lychee.upload(this.files); })
$("#image_view a#next").live(event_name, loadNextPhoto);
/* Infobox */ /* Context Menu */
$("#infobox_overlay, #infobox .header a").live(event_name, function() { hideInfobox() }); .on("contextmenu", ".photo", contextMenu.photo)
$("#edit_description").live(event_name, function() { setPhotoDescription() }); .on("contextmenu", ".album", contextMenu.album)
.on(event_name, ".contextmenu_bg", contextMenu.close)
/* Window */ /* Infobox */
$(window).keydown(key); .on(event_name, "#infobox_overlay", function() { photos.hideInfobox() })
$(window).bind("popstate", getURL);
$(window).bind("mouseleave", hideControls);
$(window).bind("mouseenter", showControls);
/* Init */ /* Controls */
if ((BrowserDetect.browser=="Explorer")||(BrowserDetect.browser=="Safari"&&BrowserDetect.version<5)||(BrowserDetect.browser=="Chrome"&&BrowserDetect.version<18)||(BrowserDetect.browser=="Firefox"&&BrowserDetect.version<15)) { .bind("mouseenter", lychee.showControls)
.bind("mouseleave", lychee.hideControls);
modal = buildModal("Browser not supported", "You are currently using an outdated or unsupported Browser. This site might not work properly. Please consider to update your Browser!", ["Leave"], ["location.href = 'http://browsehappy.com';"]); /* Upload */
$("body").append(modal); document.documentElement.ondrop = function (e) {
e.stopPropagation();
e.preventDefault();
lychee.upload(event.dataTransfer.files);
return true;
}
} else init(); /* Init */
lychee.ready();
}); });

@ -0,0 +1,254 @@
/**
* @name albums.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* Albums Module
* Takes care of every action albums can handle and execute.
*/
albums = {
load: function() {
loadingBar.show();
lychee.animate(".album, .photo", "contentZoomOut");
/* Search */
lychee.content.attr("data-search", "");
lychee.animate(".divider", "fadeOut");
startTime = new Date().getTime();
lychee.api("getAlbums", "json", function(data) {
durationTime = (new Date().getTime() - startTime);
if (durationTime>300) waitTime = 0; else waitTime = 300 - durationTime;
$.timer(waitTime,function(){
$("#tools_album, #tools_photo").hide();
$("#tools_albums").show();
/* Smart Albums */
unsortedAlbum = new Object();
unsortedAlbum.id = 0;
unsortedAlbum.title = "Unsorted";
unsortedAlbum.sysdate = data.unsortNum + " photos";
unsortedAlbum.unsorted = 1;
if (data.unsortThumb0) unsortedAlbum.thumb0 = lychee.upload_path + data.unsortThumb0; else unsortedAlbum.thumb0 = "";
if (data.unsortThumb1) unsortedAlbum.thumb1 = lychee.upload_path + data.unsortThumb1; else unsortedAlbum.thumb1 = "";
if (data.unsortThumb2) unsortedAlbum.thumb2 = lychee.upload_path + data.unsortThumb2; else unsortedAlbum.thumb2 = "";
starredAlbum = new Object();
starredAlbum.id = "f";
starredAlbum.title = "Starred";
starredAlbum.sysdate = data.starredNum + " photos";
starredAlbum.star = 1;
if (data.starredThumb0) starredAlbum.thumb0 = lychee.upload_path + data.starredThumb0; else starredAlbum.thumb0 = "";
if (data.starredThumb1) starredAlbum.thumb1 = lychee.upload_path + data.starredThumb1; else starredAlbum.thumb1 = "";
if (data.starredThumb2) starredAlbum.thumb2 = lychee.upload_path + data.starredThumb2; else starredAlbum.thumb2 = "";
publicAlbum = new Object();
publicAlbum.id = "s";
publicAlbum.title = "Public";
publicAlbum.sysdate = data.publicNum + " photos";
publicAlbum.public = 1;
if (data.publicThumb0) publicAlbum.thumb0 = lychee.upload_path + data.publicThumb0; else publicAlbum.thumb0 = "";
if (data.publicThumb1) publicAlbum.thumb1 = lychee.upload_path + data.publicThumb1; else publicAlbum.thumb1 = "";
if (data.publicThumb2) publicAlbum.thumb2 = lychee.upload_path + data.publicThumb2; else publicAlbum.thumb2 = "";
smartData = build.divider("Smart Albums") + build.album(unsortedAlbum) + build.album(starredAlbum) + build.album(publicAlbum);
/* Albums */
if (data.albums) {
albumsData = build.divider("Albums");
$.each(data.album, function() { albumsData += build.album(this); });
} else albumsData = "";
lychee.content.html(smartData + albumsData);
lychee.animate(".album, .photo", "contentZoomIn");
document.title = "Lychee";
lychee.headerTitle.html("Albums").removeClass("editable");
$("img").retina();
loadingBar.hide();
});
})
},
loadInfo: function(albumID) {
if (albumID=="f"||albumID=="s"||albumID==0) {
lychee.headerTitle.removeClass("editable");
lychee.api("getSmartInfo", "json", function(data) {
switch (albumID) {
case "f":
document.title = "Lychee - Starred";
lychee.headerTitle.html("Starred<span> - " + data.starredNum + " photos</span>");
$("#button_edit_album, #button_trash_album, .button_divider").hide();
break;
case "s":
document.title = "Lychee - Public";
lychee.headerTitle.html("Public<span> - " + data.publicNum + " photos</span>");
$("#button_edit_album, #button_trash_album, .button_divider").hide();
break;
case "0":
document.title = "Lychee - Unsorted";
lychee.headerTitle.html("Unsorted<span> - " + data.unsortNum + " photos</span>");
$("#button_edit_album").hide();
$("#button_trash_album, .button_divider").show();
break;
}
loadingBar.hide();
});
} else {
params = "getAlbumInfo&albumID=" + albumID;
lychee.api(params, "json", function(data) {
$("#button_edit_album, #button_trash_album, .button_divider").show();
if (!data.title) data.title = "Untitled";
document.title = "Lychee - " + data.title;
lychee.headerTitle.html(data.title + "<span> - " + data.num + " photos</span>").addClass("editable");
loadingBar.hide();
});
}
},
add: function() {
title = prompt("Please enter a title for this album:", "Untitled");
lychee.closeModal();
if (title.length>2&&title.length<31) {
loadingBar.show();
params = "addAlbum&title=" + escape(title);
lychee.api(params, "text", function(data) {
if (data) lychee.goto("a" + data);
else loadingBar.show("error");
});
} else if (title.length>0) loadingBar.show("error", "Error", "Title to short or too long. Please try another one!");
},
hide: function(albumID) {
$(".album[data-id='" + albumID + "']").css("opacity", 0).animate({
width: 0,
marginLeft: 0
}, 300, function() {
$(this).remove();
});
},
delete: function(albumID, delAll) {
loadingBar.show();
params = "deleteAlbum&albumID=" + albumID + "&delAll=" + delAll;
lychee.api(params, "text", function(data) {
if (data) {
if (visible.albums()) {
albums.hide(albumID);
loadingBar.hide();
} else lychee.goto("");
} else loadingBar.show("error");
});
},
deleteDialog: function(albumID) {
if (albumID==0) {
f1 = "albums.delete(0, true);";
f2 = "";
modal = build.modal("Clear Unsorted", "Are you sure you want to delete all photos from 'Unsorted'?<br>This action can't be undone!", ["Clear Unsorted", "Keep Photos"], [f1, f2]);
$("body").append(modal);
} else {
if (visible.albums()) albumTitle = $(".album[data-id='" + albumID + "'] .overlay h1").html();
else albumTitle = lychee.title();
f1 = "albums.delete(" + albumID + ", true);";
f2 = "albums.delete(" + albumID + ", false);";
modal = build.modal("Delete Album", "Are you sure you want to delete the album '" + albumTitle + "' and all of the photos it contains? This action can't be undone!", ["Delete Album and Photos", "Keep Photos"], [f1, f2]);
$("body").append(modal);
}
},
rename: function(albumID) {
if (!albumID) oldTitle = lychee.title(); else oldTitle = "";
if (!albumID) albumID = lychee.content.attr("data-id");
newTitle = prompt("Please enter a new title for this album:", oldTitle);
if (albumID!=""&&albumID!=null&&albumID&&newTitle.length>2&&newTitle.length<31) {
loadingBar.show();
params = "setAlbumTitle&albumID=" + albumID + "&title=" + encodeURI(newTitle);
lychee.api(params, "text", function(data) {
if (data) {
if (visible.albums()) $(".album[data-id='" + albumID + "'] .overlay h1").html(newTitle);
else {
lychee.headerTitle.html(newTitle + "<span>" + $("#title span").html() + "</span>");
document.title = "Lychee - " + newTitle;
}
loadingBar.hide();
} else loadingBar.show("error");
});
} else if (newTitle.length>0) loadingBar.show("error", "Error", "New title to short or too long. Please try another one!");
},
getArchive: function() {
albumID = lychee.content.attr("data-id");
if (location.href.indexOf("index.html")>0) link = location.href.replace(location.hash, "").replace("index.html", "php/api.php?function=getAlbumArchive&albumID=" + albumID);
else link = location.href.replace(location.hash, "") + "php/api.php?function=getAlbumArchive&albumID=" + albumID;
location.href = link;
}
}

@ -0,0 +1,251 @@
/**
* @name build.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* Build Module
* This module is used to generate HTML-Code.
*/
build = {
divider: function(title) {
return "<div class='divider fadeIn'><h1>" + title + "</h1></div>";
},
album: function(albumJSON) {
if(!albumJSON) return "";
if(!albumJSON.thumb0) albumJSON.thumb0 = "img/no_images.png";
if(!albumJSON.thumb1) albumJSON.thumb1 = "img/no_images.png";
if(!albumJSON.thumb2) albumJSON.thumb2 = "img/no_images.png";
if(!albumJSON.title) albumJSON.title = "Untitled";
if(albumJSON.title.length>18) albumJSON.title = albumJSON.title.substr(0, 18) + "...";
var album = "";
album += "<div class='album' data-id='" + albumJSON.id + "'>";
album += "<img src='" + lychee.upload_path + albumJSON.thumb2 + "' width='200' height='200' alt='thumb'>";
album += "<img src='" + lychee.upload_path + albumJSON.thumb1 + "' width='200' height='200' alt='thumb'>";
album += "<img src='" + lychee.upload_path + albumJSON.thumb0 + "' width='200' height='200' alt='thumb'>";
album += "<div class='overlay'>";
album += "<h1>" + albumJSON.title + "</h1>";
album += "<a>" + albumJSON.sysdate + "</a>";
album += "</div>";
if(albumJSON.star=="1") album += "<a class='badge red icon-star'></a>";
if(albumJSON.public=="1") album += "<a class='badge red icon-rss'></a>";
if(albumJSON.unsorted=="1") album += "<a class='badge red icon-reorder'></a>";
album += "</div>";
return album;
},
photo: function(photoJSON) {
if(photoJSON=="") return "";
if(!photoJSON.title) photoJSON.title = "";
if(!photoJSON.thumbUrl) photoJSON.thumbUrl = "img/no_image.png";
if(photoJSON.title.length>18) photoJSON.title = photoJSON.title.substr(0, 18) + "...";
var photo = "";
photo += "<div class='photo' data-album-id='" + photoJSON.album + "' data-id='" + photoJSON.id + "'>";
photo += "<img src='" + lychee.upload_path + photoJSON.thumbUrl + "' width='200' height='200' alt='thumb'>";
photo += "<div class='overlay'>";
photo += "<h1>" + photoJSON.title + "</h1>";
photo += "<a>" + photoJSON.sysdate + "</a>";
photo += "</div>";
if(photoJSON.star=="1") photo += "<a class='badge red icon-star'></a>";
if(photoJSON.public=="1") photo += "<a class='badge red icon-rss'></a>";
photo += "</div>";
return photo;
},
modal: function(title, text, button, func) {
var modal = "";
modal += "<div class='message_overlay fadeIn'>";
modal += "<div class='message center'>";
modal += "<h1>" + title + "</h1>";
modal += "<a class='close icon-remove-sign'></a>";
modal += "<p>" + text + "</p>";
$.each(button, function(index) {
if (index==0) modal += "<a onclick='message_click(" + index + ")' class='button active'>" + this + "</a>";
else modal += "<a onclick='message_click(" + index + ")' class='button'>" + this + "</a>";
});
modal += "</div>";
modal += "<script>";
modal += "function message_click(action) {";
modal += "switch (action) {";
$.each(func, function(index) {
modal += "case " + index + ":";
modal += this.toString();
modal += "break;";
});
modal += "} lychee.closeModal(); }";
modal += "</script>";
modal += "</div>";
return modal;
},
addModal: function() {
var modal = "";
modal += "<div class='message_overlay fadeIn'>";
modal += "<div class='message center add'>";
modal += "<h1>Add Album or Photo</h1>";
modal += "<a class='close icon-remove-sign'></a>";
modal += "<div id='add_album' class='add_album'>";
modal += "<div class='icon icon-folder-close'></div>";
modal += "<a>Add new Album</a>";
modal += "</div>";
modal += "<div id='add_photo' class='add_album'>";
modal += "<div class='icon icon-picture'></div>";
modal += "<a>Upload new Photo</a>";
modal += "</div>";
modal += "</div>";
modal += "</div>";
return modal;
},
signInModal: function() {
var modal = "";
modal += "<div class='message_overlay'>";
modal += "<div class='message center'>";
modal += "<h1><a class='icon-lock'></a> Sign in</h1>";
modal += "<div class='sign_in'>";
modal += "<input id='username' type='text' name='' value='' placeholder='username'>";
modal += "<input id='password' type='password' name='' value='' placeholder='password'>";
modal += "</div>";
modal += "<div id='version'>Version " + lychee.version + "</div>";
modal += "<a onclick='lychee.login()' class='button active'>Sign in</a>";
modal += "</div>";
modal += "</div>";
return modal;
},
uploadModal: function() {
var modal = "";
modal += "<div class='upload_overlay fadeIn'>";
modal += "<div class='upload_message center'>";
modal += "<a class='icon-upload'></a>";
modal += "<div class='progressbar'><div></div></div>";
modal += "</div>";
modal += "</div>";
return modal;
},
contextMenu: function(items) {
var menu = "";
menu += "<div class='contextmenu_bg'></div>";
menu += "<div class='contextmenu'>";
menu += "<table>";
menu += "<tbody>";
$.each(items, function(index) {
if (items[index][1].length!=0) {
menu += "<tr><td onclick='" + items[index][1] + "; contextMenu.close();'>" + items[index][0] + "</td></tr>";
}
});
menu += "</tbody>";
menu += "</table>";
menu += "</div>";
return menu;
},
infobox: function(photo, forView) {
var infobox = "";
infobox += "<div class='header'><h1>About</h1><a class='icon-remove-sign'></a></div>";
infobox += "<div class='wrapper'>";
if (photo.public==1) photo.public = "Public"; else photo.public = "Private";
if (forView==true) editTitleHTML = ""; else editTitleHTML = " <div id='edit_title'><a class='icon-pencil'></a></div>";
if (forView==true) editDescriptionHTML = ""; else editDescriptionHTML = " <div id='edit_description'><a class='icon-pencil'></a></div>";
infos = [
["", "Basics"],
["Name", photo.title + editTitleHTML],
["Uploaded", photo.sysdate],
["Description", photo.description + editDescriptionHTML],
["", "Image"],
["Size", photo.size],
["Format", photo.type],
["Resolution", photo.width + " x " + photo.height],
["", "Camera"],
["Captured", photo.takedate],
["Make", photo.make],
["Type/Model", photo.model],
["Shutter Speed", photo.shutter],
["Aperture", photo.aperture],
["Focal Length", photo.focal],
["ISO", photo.iso],
["", "Share"],
["Privacy", photo.public],
["Short Link", photo.shortlink]
];
$.each(infos, function(index) {
if (infos[index][1]==""||infos[index][1]==undefined||infos[index][1]==null) infos[index][1] = "-";
if (infos[index][0]=="") {
infobox += "</table>";
infobox += "<div class='separater'><h1>" + infos[index][1] + "</h1></div>";
infobox += "<table id='infos'>";
} else {
infobox += "<tr>";
infobox += "<td>" + infos[index][0] + "</td>";
infobox += "<td class='attr_" + infos[index][0].toLowerCase() + "'>" + infos[index][1] + "</td>";
infobox += "</tr>";
}
});
infobox += "</table>";
infobox += "<div class='bumper'></div>";
infobox += "</div>";
return infobox;
}
}

@ -0,0 +1,140 @@
/**
* @name contextMenu.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* ContextMenu Module
* This module is used for the context menu.
*/
contextMenu = {
album: function(e) {
e.preventDefault();
mouse_x = e.pageX;
mouse_y = e.pageY;
albumID = $(this).attr("data-id");
if (albumID=="0"||albumID=="f"||albumID=="s") return false;
mouse_y -= $(document).scrollTop();
items = [
["Rename", "albums.rename(" + albumID + ")"],
["Delete", "albums.deleteDialog(" + albumID + ")"]
];
contextMenu.close();
$("body").css("overflow", "hidden");
$(".album[data-id='" + albumID + "']").addClass("active");
$("body").append(build.contextMenu(items));
$(".contextmenu").css({
"top": mouse_y,
"left": mouse_x
});
},
photo: function(e) {
e.preventDefault();
mouse_x = e.pageX;
mouse_y = e.pageY;
photoID = $(this).attr("data-id");
mouse_y -= $(document).scrollTop();
items = [
["Rename", "photos.rename(" + photoID + ")"],
["Move to Album", "contextMenu.move(" + photoID + ", " + (mouse_x+150) + ", " + (mouse_y+$(document).scrollTop()) + ")"],
["Delete", "photos.deleteDialog(" + photoID + ")"]
];
contextMenu.close();
$("body").css("overflow", "hidden");
$(".photo[data-id='" + photoID + "']").addClass("active");
$("body").append(build.contextMenu(items));
$(".contextmenu").css({
"top": mouse_y,
"left": mouse_x
});
},
move: function(photoID, mouse_x, mouse_y) {
mouse_y -= $(document).scrollTop();
lychee.api("getAlbums", "json", function(data) {
if (lychee.content.attr("data-id")==0) {
items = [];
} else {
items = [
["Unsorted", "photos.move(" + photoID + ", 0)"]
];
}
if (!data.albums) {
items = [
["Create new Album", "albums.add()"]
];
} else {
$.each(data.album, function(index) {
if (this.id!=lychee.content.attr("data-id")) {
if(!this.title) this.title = "Untitled";
items[items.length] = new Array(this.title, "photos.move(" + photoID + ", " + this.id + ")");
} else {
items[items.length] = new Array("", "");
}
});
}
contextMenu.close();
$("body").css("overflow", "hidden");
$(".photo[data-id='" + photoID + "']").addClass("active");
$("body").append(build.contextMenu(items));
$(".contextmenu").css({
"top": mouse_y,
"left": mouse_x-150
});
});
},
share: function(photoID, mouse_x, mouse_y) {
mouse_y -= $(document).scrollTop();
items = [
["<a class='icon-eye-close'></a> Make Private", "photos.setPublic()"],
["<a class='icon-twitter'></a> Twitter", "photos.share(0, " + photoID + ")"],
["<a class='icon-facebook'></a> Facebook", "photos.share(1, " + photoID + ")"],
["<a class='icon-envelope'></a> Mail", "photos.share(2, " + photoID + ")"],
["<a class='icon-link'></a> Copy Link", "photos.share(3, " + photoID + ")"],
["<a class='icon-link'></a> Copy Shortlink", "photos.share(4, " + photoID + ")"]
];
contextMenu.close();
$("body").css("overflow", "hidden");
$(".photo[data-id='" + photoID + "']").addClass("active");
$("body").append(build.contextMenu(items));
$(".contextmenu").css({
"top": mouse_y,
"left": mouse_x
});
},
close: function() {
$(".contextmenu_bg, .contextmenu").remove();
$(".photo.active, .album.active").removeClass("active");
$("body").css("overflow", "scroll");
}
}

@ -0,0 +1,58 @@
/**
* @name loadingBar.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* LoadingBar Module
* This module is used to show and hide the loading bar.
*/
loadingBar = {
show: function(status, errorTitle, errorText) {
if (!status) status = "loading";
switch (status) {
case "error":
if (!errorTitle||!errorText) {
errorTitle = "Error";
errorText = "Whoops, it looks like something went wrong. Please reload the site and try again!"
}
lychee.loadingBar
.removeClass("loading uploading error")
.addClass(status)
.html("<h1>" + errorTitle + ": <span>" + errorText + "</span></h1>")
.show()
.css("height", "40px");
lychee.header.css("margin-Top", "40px");
$.timer(3000,function(){ loadingBar.hide() });
break;
case "loading":
clearTimeout(lychee.loadingBar.data("timeout"));
lychee.loadingBar.data("timeout", setTimeout(function () {
lychee.loadingBar
.show()
.removeClass("loading uploading error")
.addClass(status);
if (visible.controls()) lychee.header.css("margin-Top", "3px");
}, 1000));
break;
}
},
hide: function() {
clearTimeout(lychee.loadingBar.data("timeout"));
lychee.loadingBar.html("").css("height", "3px");
if (visible.controls()) lychee.header.css("marginTop", "0px");
$.timer(300,function(){ lychee.loadingBar.hide(); });
}
}

@ -0,0 +1,296 @@
/**
* @name lychee.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* Lychee Module
* This module provides the basic functions of Lychee.
*/
lychee = {
init: function(api_path, upload_path) {
this.version = "1.1";
this.api_path = api_path;
this.upload_path = upload_path;
this.loadingBar = $("#loading");
this.header = $("header");
this.headerTitle = $("#title");
this.content = $("#content");
this.image_view = $("#image_view");
this.infobox = $("#infobox");
},
ready: function() {
$("#tools_albums").show();
if (!mobileBrowser()) $(".tools").tipsy({gravity: 'n'});
if (window.webkitNotifications) { window.webkitNotifications.requestPermission() };
lychee.api("loggedIn", "text", function(data) {
if (data!=1) {
$("body").append(build.signInModal());
$("#username").focus();
if (localStorage) {
local_username = localStorage.getItem("username");
if (local_username==null) return false;
if (local_username.length>1) $("#username").val(local_username);
$("#password").focus();
}
} else if (data) {
$(window).bind("popstate", lychee.load);
lychee.load();
}
});
},
api: function(params, type, callback) {
$.ajax({
type: "POST",
url: lychee.api_path,
data: "function=" + params,
dataType: type,
success: callback,
error: lychee.error
});
},
login: function() {
user = $("input#username").val();
password = hex_md5($("input#password").val());
params = "login&user=" + user + "&password=" + password;
lychee.api(params, "text", function(data) {
if (data) {
if (localStorage) { localStorage.setItem("username", user); }
$(window).bind("popstate", lychee.load);
lychee.load();
lychee.closeModal();
} else {
$("#password").val("").addClass("error");
$(".message .button.active").removeClass("pressed");
}
});
},
logout: function() {
lychee.api("logout", "text", function(data) {
window.location.reload();
});
},
upload: function(files) {
pre_progress = 0;
$(".upload_overlay").remove();
$("body").append(build.uploadModal());
var formData = new FormData();
for (var i = 0; i < files.length; i++) formData.append(i, files[i]);
formData.append("function", "upload");
if (lychee.content.attr("data-id")=="") formData.append("albumID", 0);
else formData.append("albumID", lychee.content.attr("data-id"));
var xhr = new XMLHttpRequest();
xhr.open('POST', lychee.api_path);
xhr.onload = function () {
if (xhr.status===200) {
$(".progressbar div").css("width", "100%");
$(".upload_overlay").removeClass("fadeIn").css("opacity", 0);
$.timer(300,function(){ $(".upload_overlay").remove() });
if (window.webkitNotifications&&BrowserDetect.browser=="Safari") {
var popup = window.webkitNotifications.createNotification("", "Upload complete", "You can now manage your new photos.");
popup.show();
}
if (lychee.content.attr("data-id")=="") lychee.goto("a0");
else photos.load(lychee.content.attr("data-id"));
}
};
xhr.upload.onprogress = function (event) {
if (event.lengthComputable) {
var progress = (event.loaded / event.total * 100 | 0);
if (progress>pre_progress) {
$(".progressbar div").css("width", progress + "%");
pre_progress = progress;
}
if (progress>=100) $(".progressbar div").css("opacity", 0.2);
}
};
$("#upload_files").val("");
xhr.send(formData);
},
load: function() {
contextMenu.close();
hash = document.location.hash.replace("#", "");
albumID = "";
photoID = "";
if (hash.indexOf("a")!=-1) albumID = hash.split("p")[0].replace("a", ""); else albumID = "";
if (hash.indexOf("p")!=-1) photoID = hash.split("p")[1]; else photoID = "";
lychee.content.attr("data-id", albumID);
lychee.image_view.attr("data-id", photoID);
if (albumID&&photoID) {
// Show ImageView
if (lychee.content.html()==""||$("#search").val().length!=0) {
lychee.content.hide();
photos.load(albumID, true);
}
photos.loadInfo(photoID);
} else if (albumID) {
// Show Album
if (visible.infobox) photos.hideInfobox();
if (!visible.controls()) lychee.showControls();
if (visible.imageview()) photos.hideView();
else photos.load(albumID, false);
} else {
// Show Albums
if (visible.infobox) photos.hideInfobox();
if (!visible.controls()) lychee.showControls();
if (visible.imageview()) photos.hideView();
albums.load();
}
},
goto: function(url) {
document.location.hash = url;
},
title: function() {
return lychee.headerTitle.html().replace($("#title span").html(), "").replace("<span></span>", "");
},
showControls: function() {
clearTimeout($(window).data("timeout"));
if (visible.imageview()) {
lychee.image_view.removeClass("full");
lychee.loadingBar.css("opacity", 1);
lychee.header.css("margin-Top", "0px");
if ($("#image_view #image.small").length>0) {
$("#image_view #image").css({
marginTop: -1*($("#image_view #image").height()/2)+20
});
} else {
$("#image_view #image").css({
top: 70,
right: 30,
bottom: 30,
left: 30
});
}
}
},
hideControls: function() {
if (visible.imageview()) {
clearTimeout($(window).data("timeout"));
$(window).data("timeout", setTimeout(function() {
lychee.image_view.addClass("full");
lychee.loadingBar.css("opacity", 0);
lychee.header.css("margin-Top", "-45px");
if ($("#image_view #image.small").length>0) {
$("#image_view #image").css({
marginTop: -1*($("#image_view #image").height()/2)
});
} else {
$("#image_view #image").css({
top: 0,
right: 0,
bottom: 0,
left: 0
});
}
}, 500));
}
},
closeModal: function() {
$(".message_overlay").removeClass("fadeIn").css("opacity", 0);
$.timer(300,function(){ $(".message_overlay").remove() });
},
animate: function(obj, animation) {
animations = [
["fadeIn", "fadeOut"],
["contentZoomIn", "contentZoomOut"]
];
if (!obj.jQuery) obj = $(obj);
for (i = 0; i < animations.length; i++) {
for (var x = 0; x < animations[i].length; x++) {
if (animations[i][x]==animation) {
obj.removeClass(animations[i][0] + " " + animations[i][1]).addClass(animation);
return true;
}
}
}
return false;
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
loadingBar.show("error", textStatus, errorThrown);
}
}

@ -0,0 +1,425 @@
/**
* @name photos.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* Photos Module
* Takes care of every action photos can handle and execute.
*/
photos = {
load: function(albumID, refresh) {
// If refresh is true the function will only refresh the content and not change the toolbar buttons either the title
if (!refresh) {
loadingBar.show();
if (visible.imageview()) photos.hideView();
lychee.animate(".album, .photo", "contentZoomOut");
lychee.animate(".divider", "fadeOut");
}
startTime = new Date().getTime();
params = "getPhotos&albumID=" + albumID;
lychee.api(params, "json", function(data) {
durationTime = (new Date().getTime() - startTime);
if (durationTime>300) waitTime = 0; else if (refresh) waitTime = 0; else waitTime = 300 - durationTime;
$.timer(waitTime,function(){
photosData = "";
$.each(data, function() { photosData += build.photo(this); });
lychee.content.html(photosData);
if (!refresh) {
lychee.animate(".album, .photo", "contentZoomIn");
$("#tools_albums, #tools_photo").hide();
$("#tools_album").show();
$("img").retina();
albums.loadInfo(albumID);
}
});
});
},
loadInfo: function(photoID) {
photos.showView();
loadingBar.show();
params = "getPhotoInfo&photoID=" + photoID;
lychee.api(params, "json", function(data) {
if (!data.title) data.title = "Untitled";
document.title = "Lychee - " + data.title;
lychee.headerTitle.html(data.title).addClass("editable");
$("#button_star a").removeClass("icon-star-empty icon-star");
if (data.star=="1") {
$("#button_star a").addClass("icon-star");
$("#button_star").attr("title", "Unstar Photo");
} else {
$("#button_star a").addClass("icon-star-empty");
$("#button_star").attr("title", "Star Photo");
}
if (data.public=="1") {
$("#button_share a").addClass("active");
$("#button_share").attr("title", "Make Photo Private");
} else {
$("#button_share a").removeClass("active");
$("#button_share").attr("title", "Share Photo");
}
data.url = lychee.upload_path + data.url;
if (visible.controls()&&photos.isSmall(data)) lychee.image_view.html("<a id='previous' class='icon-caret-left'></a><a id='next' class='icon-caret-right'></a><div id='image' class='small' style='background-image: url(" + data.url + "); width: " + data.width + "px; height: " + data.height + "px; margin-top: -" + parseInt(data.height/2-20) + "px; margin-left: -" + data.width/2 + "px;'></div>");
else if (visible.controls()) lychee.image_view.html("<a id='previous' class='icon-caret-left'></a><a id='next' class='icon-caret-right'></a><div id='image' style='background-image: url(" + data.url + ")'></div>");
else if (photos.isSmall(data)) lychee.image_view.html("<a id='previous' style='left: -50px' class='icon-caret-left'></a><a id='next' style='right: -50px' class='icon-caret-right'></a><div id='image' class='small' style='background-image: url(" + data.url + "); width: " + data.width + "px; height: " + data.height + "px; margin-top: -" + parseInt(data.height/2) + "px; margin-left: -" + data.width/2 + "px;'></div>");
else lychee.image_view.html("<a id='previous' style='left: -50px' class='icon-caret-left'></a><a id='next' style='right: -50px' class='icon-caret-right'></a><div id='image' style='background-image: url(" + data.url + "); top: 0px; right: 0px; bottom: 0px; left: 0px;'></div>");
lychee.animate(image_view, "fadeIn");
lychee.image_view.show();
if (!visible.controls()) lychee.hideControls();
lychee.infobox.html(build.infobox(data)).show();
$.timer(300,function(){ lychee.content.show(); });
loadingBar.hide();
});
},
isSmall: function(photo) {
size = [
["width", false],
["height", false]
];
if (photo.width<$(window).width()-60) size["width"] = true;
if (photo.height<$(window).height()-100) size["height"] = true;
if (size["width"]&&size["height"]) return true;
else return false;
},
showView: function() {
// Change toolbar-buttons
$("#tools_albums, #tools_album").hide();
$("#tools_photo").show();
// Make body not scrollable
$("body").css("overflow", "hidden");
},
hideView: function() {
// Change toolbar-buttons
$("#tools_photo, #tools_albums").hide();
$("#tools_album").show();
// Make body scrollable
$("body").css("overflow", "scroll");
// Change website title and url by using albums.loadInfo
albums.loadInfo(lychee.content.attr("data-id"));
// Hide ImageViewer
lychee.animate(image_view, "fadeOut");
$.timer(300,function(){ lychee.image_view.hide() });
},
showInfobox: function() {
if (!visible.infobox()) $("body").append("<div id='infobox_overlay'></div>");
lychee.infobox.css("right", "0px");
},
hideInfobox: function() {
$("#infobox_overlay").remove();
lychee.infobox.css("right", "-320px");
},
hide: function(photoID) {
$(".photo[data-id='" + photoID + "']").css("opacity", 0).animate({
width: 0,
marginLeft: 0
}, 300, function() {
$(this).remove();
if (!visible.imageview()) {
imgNum = parseInt($("#title span").html().replace("- ", "").replace(" photos", ""))-1;
$("#title span").html(" - " + imgNum + " photos");
}
});
},
delete: function(photoID) {
loadingBar.show();
params = "deletePhoto&photoID=" + photoID;
lychee.api(params, "text", function(data) {
if (data) {
photos.hide(photoID);
lychee.goto("a" + lychee.content.attr("data-id"));
loadingBar.hide();
} else loadingBar.show("error");
});
},
deleteDialog: function(photoID) {
if (!photoID) photoID = lychee.image_view.attr("data-id");
if (visible.imageview()) photoTitle = lychee.title();
else photoTitle = $(".photo[data-id='" + photoID + "'] .overlay h1").html();
if (photoTitle=="") photoTitle = "Untitled";
f1 = "photos.delete(" + photoID + ");";
f2 = "";
modal = build.modal("Delete Photo", "Are you sure you want to delete the photo '" + photoTitle + "'?<br>This action can't be undone!", ["Delete Photo", "Keep Photo"], [f1, f2]);
$("body").append(modal);
},
rename: function(photoID) {
if (!photoID) oldTitle = lychee.title(); else oldTitle = "";
if (!photoID) photoID = lychee.image_view.attr("data-id");
newTitle = prompt("Please enter a new title for this photo:", oldTitle);
if (photoID!=null&&photoID&&newTitle.length<31) {
loadingBar.show();
if (newTitle=="") newTitle = "Untitled";
params = "setPhotoTitle&photoID=" + photoID + "&title=" + encodeURI(newTitle);
lychee.api(params, "text", function(data) {
if (data) {
if (visible.imageview()) {
$("#infobox .attr_name").html($("#infobox .attr_name").html().replace(lychee.title(), newTitle));
lychee.headerTitle.html(newTitle);
document.title = "Lychee - " + newTitle;
}
$(".photo[data-id='" + photoID + "'] .overlay h1").html(newTitle);
loadingBar.hide();
} else loadingBar.show("error");
});
} else if (newTitle.length>0) loadingBar.show("error", "Error", "New title to short or too long. Please try another one!");
},
move: function(photoID, albumID) {
if (albumID>=0) {
loadingBar.show();
params = "movePhoto&photoID=" + photoID + "&albumID=" + albumID;
lychee.api(params, "text", function(data) {
if (data) {
photos.hide(photoID);
lychee.goto("a" + lychee.content.attr("data-id"));
loadingBar.hide();
} else loadingBar.show("error");
});
}
},
setStar: function() {
loadingBar.show();
photoID = lychee.image_view.attr("data-id");
params = "setPhotoStar&photoID=" + photoID;
lychee.api(params, "text", function(data) {
if (data) {
if ($("#button_star a.icon-star-empty").length) {
$("#button_star a").removeClass("icon-star-empty icon-star").addClass("icon-star");
$("#button_star").attr("title", "Unstar Photo");
} else {
$("#button_star a").removeClass("icon-star-empty icon-star").addClass("icon-star-empty");
$("#button_star").attr("title", "Star Photo");
}
photos.load(lychee.content.attr("data-id"), true);
loadingBar.hide();
} else loadingBar.show("error");
});
},
setPublic: function(e) {
loadingBar.show();
photoID = lychee.image_view.attr("data-id");
params = "setPhotoPublic&photoID=" + photoID + "&url=" + photos.getViewLink(photoID);
lychee.api(params, "text", function(data) {
if (data) {
if ($("#button_share a.active").length) {
$("#button_share a").removeClass("active");
$("#button_share").attr("title", "Make Private");
} else {
$("#button_share a").addClass("active");
$("#button_share").attr("title", "Share Photo");
contextMenu.share(photoID, e.pageX, e.pageY);
}
photos.load(lychee.content.attr("data-id"), true);
loadingBar.hide();
} else loadingBar.show("error");
});
},
setDescription: function() {
description = prompt("Please enter a description for this photo:", "");
photoID = lychee.image_view.attr("data-id");
if (description.length>0&&description.length<160) {
loadingBar.show();
params = "setPhotoDescription&photoID=" + photoID + "&description=" + escape(description);
lychee.api(params, "text", function(data) {
if (data) photos.loadInfo(photoID);
else loadingBar.show("error");
});
} else if (description.length>0) loadingBar.show("error", "Error", "Description to short or too long. Please try another one!");
},
share: function(service, photoID) {
loadingBar.show();
params = "sharePhoto&photoID=" + photoID + "&url=" + photos.getViewLink(photoID);
lychee.api(params, "json", function(data) {
switch (service) {
case 0:
link = data.twitter;
break;
case 1:
link = data.facebook;
break;
case 2:
link = data.mail;
break;
case 3:
link = "copy";
modal = build.modal("Copy Link", "You can use this link to share your image with other people: <input class='copylink' value='" + photos.getViewLink(photoID) + "'>", ["Close"], [""]);
$("body").append(modal);
$(".copylink").focus();
break;
case 4:
link = "copy";
modal = build.modal("Copy Shortlink", "You can use this link to share your image with other people: <input class='copylink' value='" + data.shortlink + "'>", ["Close"], [""]);
$("body").append(modal);
$(".copylink").focus();
break;
default:
link = "";
break;
}
if (link=="copy") loadingBar.hide();
else if (link.length>5) {
location.href = link;
loadingBar.hide();
} else loadingBar.show("error");
});
},
getViewLink: function(photoID) {
if (location.href.indexOf("index.html")>0) return location.href.replace("index.html" + location.hash, "view.php?p=" + photoID);
else return location.href.replace(location.hash, "view.php?p=" + photoID);
},
previous: function() {
albumID = lychee.content.attr("data-id");
photoID = lychee.image_view.attr("data-id");
params = "previousPhoto&photoID=" + photoID + "&albumID=" + albumID;
lychee.api(params, "json", function(data) {
if (data!=false) lychee.goto("a" + albumID + "p" + data.id);
});
},
next: function() {
albumID = lychee.content.attr("data-id");
photoID = lychee.image_view.attr("data-id");
params = "nextPhoto&photoID=" + photoID + "&albumID=" + albumID;
lychee.api(params, "json", function(data) {
if (data) lychee.goto("a" + albumID + "p" + data.id);
});
}
}

@ -0,0 +1,71 @@
/**
* @name photos.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* Search Module
* Searches through your photos and albums.
*/
search = {
find: function(term) {
clearTimeout($(window).data("timeout"));
$(window).data("timeout", setTimeout(function() {
if ($("#search").val().length!=0) {
params = "search&term=" + term;
lychee.api(params, "json", function(data) {
albumsData = "";
if (data&&data.albums) $.each(data.albums, function() { albumsData += build.album(this); });
photosData = "";
if (data&&data.photos) $.each(data.photos, function() { photosData += build.photo(this); });
if (albumsData==""&&photosData=="") code = "";
else if (albumsData=="") code = build.divider("Photos")+photosData;
else if (photosData=="") code = build.divider("Albums")+albumsData;
else code = build.divider("Photos")+photosData+build.divider("Albums")+albumsData;
if (lychee.content.attr("data-search")!=code) {
lychee.animate(".album, .photo", "contentZoomOut");
lychee.animate(".divider", "fadeOut");
$.timer(300,function(){
lychee.content.attr("data-search", code);
lychee.content.html(code);
lychee.animate(".album, .photo", "contentZoomIn");
});
}
});
} else search.reset();
}, 250));
},
reset: function() {
$("#search").val("");
if (lychee.content.attr("data-search")!="") {
lychee.content.attr("data-search", "");
lychee.animate(".divider", "fadeOut");
albums.load();
}
}
}

@ -0,0 +1,33 @@
/**
* @name visible.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* Visible Module
* This module is used to check if elements are visible or not.
*/
visible = {
albums: function() {
if ($("#tools_albums").css("display")=="block") return true;
else return false;
},
imageview: function() {
if ($("#image_view.fadeIn").length>0) return true;
else return false;
},
infobox: function() {
if (parseInt(lychee.infobox.css("right").replace("px", ""))==-320) return false;
else return true;
},
controls: function() {
if (lychee.loadingBar.css("opacity")>0) return true;
else return false;
}
}

@ -1,102 +0,0 @@
/**
* @name upload.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2012 by Philipp Maurer, Tobias Reich
*/
var global_progress = new Array(),
last_final_progress = 0;
function handleFiles(files) {
var i = 0;
var auswahl_div = document.getElementById('auswahl');
var imageType = /image.*/;
var fileList = files;
for(i = 0; i < fileList.length; i++) {
var img = document.createElement("img");
img.height = 0;
img.file = fileList[i];
img.name = 'pic_'+ i;
img.classList.add("obj");
auswahl_div.appendChild(img);
}
}
function sendFiles(){
imgs = document.querySelectorAll(".obj");
$(".upload_overlay").remove();
$("body").append(buildUploadModal());
global_progress = new Array();
last_final_progress = 0;
for(i = 0; i < imgs.length; i++) {
global_progress[i] = 0;
new FileUpload(i, imgs[i], imgs[i].file);
}
}
function changeProgress(i, progress) {
global_progress[i] = progress;
final_progress = 0;
for(i = 0; i < global_progress.length; i++) {
final_progress += global_progress[i];
}
if (Math.round(final_progress/document.querySelectorAll(".obj").length)%2==0&&Math.round(last_final_progress/document.querySelectorAll(".obj").length)<Math.round(final_progress/document.querySelectorAll(".obj").length)) {
$(".progressbar div").css("width", Math.round(final_progress/document.querySelectorAll(".obj").length) + "%");
}
last_final_progress = final_progress;
if ((final_progress/document.querySelectorAll(".obj").length)>=100) {
$(".progressbar div").css("width", "100%");
$.timer(1000,function(){
$(".upload_overlay").removeClass("fadeIn").css("opacity", 0);
$.timer(300,function(){ $(".upload_overlay").remove() });
if (content.attr("data-id")=="") setURL("a0");
else loadPhotos(content.attr("data-id"));
});
}
}
function FileUpload(i, img, file) {
var old_percent = 0,
xhr = new XMLHttpRequest(),
fd = new FormData,
percent = 0;
this.xhr = xhr;
this.xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) percent = Math.round((e.loaded * 100) / e.total);
changeProgress(i, percent);
}, false);
fd.append("File", file);
fd.append("function", "upload");
if (content.attr("data-id")=="") fd.append("albumID", 0);
else fd.append("albumID", content.attr("data-id"));
xhr.open("POST", "php/api.php", true);
xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
xhr.send(fd);
}

@ -2,7 +2,7 @@
* @name view.js * @name view.js
* @author Philipp Maurer * @author Philipp Maurer
* @author Tobias Reich * @author Tobias Reich
* @copyright 2012 by Philipp Maurer, Tobias Reich * @copyright 2013 by Philipp Maurer, Tobias Reich
*/ */
var header = $("header"), var header = $("header"),
@ -13,15 +13,20 @@ var header = $("header"),
$(document).ready(function(){ $(document).ready(function(){
/* Event Name */
if (mobileBrowser()) event_name = "touchend";
else event_name = "click";
/* Window */ /* Window */
$(window).keydown(key); $(window).keydown(key);
/* Infobox */ /* Infobox */
$("#infobox_overlay, #infobox .header a").live("click", function() { hideInfobox() }); $(document).on(event_name, "#infobox .header a", function() { hideInfobox() });
$("#button_info").live("click", function() { showInfobox() }); $(document).on(event_name, "#infobox_overlay", function() { hideInfobox() });
$("#button_info").on(event_name, function() { showInfobox() });
/* Download */ /* Download */
$("#button_download").live("click", function() { $("#button_download").on(event_name, function() {
link = $("#image_view #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, ""); link = $("#image_view #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
window.open(link,"_newtab"); window.open(link,"_newtab");
}); });
@ -83,11 +88,11 @@ function loadPhotoInfo(photoID) {
headerTitle.html(data.title); headerTitle.html(data.title);
image_view.attr("data-id", photoID); image_view.attr("data-id", photoID);
if (isPhotoSmall(data)) image_view.html("").append("<div id='image' class='small' style='background-image: url(" + data.url + "); width: " + data.width + "px; height: " + data.height + "px; margin-top: -" + parseInt((data.height/2)-20) + "px; margin-left: -" + data.width/2 + "px;'></div>"); if (isPhotoSmall(data)) image_view.html("<div id='image' class='small' style='background-image: url(" + data.url + "); width: " + data.width + "px; height: " + data.height + "px; margin-top: -" + parseInt((data.height/2)-20) + "px; margin-left: -" + data.width/2 + "px;'></div>");
else image_view.html("").append("<div id='image' style='background-image: url(" + data.url + "); top: 70px; right: 30px; bottom: 30px; left: 30px;'></div>"); else image_view.html("<div id='image' style='background-image: url(" + data.url + "); top: 70px; right: 30px; bottom: 30px; left: 30px;'></div>");
image_view.removeClass("fadeOut").addClass("fadeIn").show(); image_view.removeClass("fadeOut").addClass("fadeIn").show();
infobox.html(buildInfobox(data)).show(); infobox.html(build.infobox(data, true)).show();
}, error: ajaxError }); }, error: ajaxError });

@ -6,15 +6,14 @@ SET time_zone = "+00:00";
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */; /*!40101 SET NAMES utf8 */;
CREATE TABLE IF NOT EXISTS `lychee_albums` (
CREATE TABLE IF NOT EXISTS `albums` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL, `title` varchar(50) NOT NULL,
`sysdate` varchar(10) NOT NULL, `sysdate` varchar(10) NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `photos` ( CREATE TABLE IF NOT EXISTS `lychee_photos` (
`id` bigint(14) NOT NULL, `id` bigint(14) NOT NULL,
`title` varchar(50) NOT NULL, `title` varchar(50) NOT NULL,
`description` varchar(160) NOT NULL, `description` varchar(160) NOT NULL,
@ -36,8 +35,9 @@ CREATE TABLE IF NOT EXISTS `photos` (
`takedate` varchar(10) NOT NULL, `takedate` varchar(10) NOT NULL,
`taketime` varchar(8) NOT NULL, `taketime` varchar(8) NOT NULL,
`star` tinyint(1) NOT NULL, `star` tinyint(1) NOT NULL,
`album` varchar(30) NOT NULL DEFAULT '0',
`thumbUrl` varchar(50) NOT NULL, `thumbUrl` varchar(50) NOT NULL,
`album` varchar(30) NOT NULL DEFAULT '0',
`import_name` varchar(100) DEFAULT '',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

@ -4,13 +4,18 @@
* @name api.php * @name api.php
* @author Philipp Maurer * @author Philipp Maurer
* @author Tobias Reich * @author Tobias Reich
* @copyright 2012 by Philipp Maurer, Tobias Reich * @copyright 2013 by Philipp Maurer, Tobias Reich
*/ */
if(floatval(phpversion())<5.2) die("Please upgrade to PHP 5.2 or higher!");
if((isset($_POST["function"])&&$_POST["function"]!="")||(isset($_GET["function"])&&$_GET["function"]!="")) { if((isset($_POST["function"])&&$_POST["function"]!="")||(isset($_GET["function"])&&$_GET["function"]!="")) {
session_start(); session_start();
define("LYCHEE", true);
include("array2json.php"); include("array2json.php");
include("config.php");
include("functions.php"); include("functions.php");
// Security // Security
@ -20,7 +25,7 @@ if((isset($_POST["function"])&&$_POST["function"]!="")||(isset($_GET["function"]
if($_SESSION["login"]==true) { if($_SESSION["login"]==true) {
//Connect to DB //Connect to DB
dbConnect(); $database = dbConnect();
// Album Functions // Album Functions
if($_POST["function"]=="getAlbums") echo array2json(getAlbums()); if($_POST["function"]=="getAlbums") echo array2json(getAlbums());
@ -54,12 +59,13 @@ if((isset($_POST["function"])&&$_POST["function"]!="")||(isset($_GET["function"]
if($_POST["function"]=="syncFolder") echo syncFolder(); if($_POST["function"]=="syncFolder") echo syncFolder();
// Session Functions // Session Functions
if($_POST["function"]=="login") echo login($_POST['user'], $_POST['password']);
if($_POST["function"]=="logout") logout(); if($_POST["function"]=="logout") logout();
if($_POST["function"]=="loggedIn") echo true; if($_POST["function"]=="loggedIn") echo true;
} else { } else {
dbConnect(); $database = dbConnect();
// Photo Functions // Photo Functions
if($_POST["function"]=="getPhotoInfo"&&isset($_POST["photoID"])&&isPhotoPublic($_POST["photoID"])) echo array2json(getPhotoInfo($_POST["photoID"])); if($_POST["function"]=="getPhotoInfo"&&isset($_POST["photoID"])&&isPhotoPublic($_POST["photoID"])) echo array2json(getPhotoInfo($_POST["photoID"]));
@ -70,6 +76,11 @@ if((isset($_POST["function"])&&$_POST["function"]!="")||(isset($_GET["function"]
} }
} else echo "Error: No permission!"; } else {
header('HTTP/1.1 401 Unauthorized');
die("Error: No permission!");
}
?> ?>

@ -1,43 +1,43 @@
<?php <?php
function array2json($arr) { function array2json($arr) {
if(function_exists('json_encode')) return json_encode($arr); //Lastest versions of PHP already has this functionality. if(function_exists('json_encode')) return json_encode($arr); //Lastest versions of PHP already has this functionality.
$parts = array(); $parts = array();
$is_list = false; $is_list = false;
//Find out if the given array is a numerical array //Find out if the given array is a numerical array
$keys = array_keys($arr); $keys = array_keys($arr);
$max_length = count($arr)-1; $max_length = count($arr)-1;
if(($keys[0] == 0) and ($keys[$max_length] == $max_length)) {//See if the first key is 0 and last key is length - 1 if(($keys[0] == 0) and ($keys[$max_length] == $max_length)) {//See if the first key is 0 and last key is length - 1
$is_list = true; $is_list = true;
for($i=0; $i<count($keys); $i++) { //See if each key correspondes to its position for($i=0; $i<count($keys); $i++) { //See if each key correspondes to its position
if($i != $keys[$i]) { //A key fails at position check. if($i != $keys[$i]) { //A key fails at position check.
$is_list = false; //It is an associative array. $is_list = false; //It is an associative array.
break; break;
} }
} }
} }
foreach($arr as $key=>$value) { foreach($arr as $key=>$value) {
if(is_array($value)) { //Custom handling for arrays if(is_array($value)) { //Custom handling for arrays
if($is_list) $parts[] = array2json($value); /* :RECURSION: */ if($is_list) $parts[] = array2json($value); /* :RECURSION: */
else $parts[] = '"' . $key . '":' . array2json($value); /* :RECURSION: */ else $parts[] = '"' . $key . '":' . array2json($value); /* :RECURSION: */
} else { } else {
$str = ''; $str = '';
if(!$is_list) $str = '"' . $key . '":'; if(!$is_list) $str = '"' . $key . '":';
//Custom handling for multiple data types //Custom handling for multiple data types
if(is_numeric($value)) $str .= $value; //Numbers if(is_numeric($value)) $str .= $value; //Numbers
elseif($value === false) $str .= 'false'; //The booleans elseif($value === false) $str .= 'false'; //The booleans
elseif($value === true) $str .= 'true'; elseif($value === true) $str .= 'true';
else $str .= '"' . addslashes($value) . '"'; //All other things else $str .= '"' . addslashes($value) . '"'; //All other things
// :TODO: Is there any more datatype we should be in the lookout for? (Object?) // :TODO: Is there any more datatype we should be in the lookout for? (Object?)
$parts[] = $str; $parts[] = $str;
} }
} }
$json = implode(',',$parts); $json = implode(',',$parts);
if($is_list) return '[' . $json . ']';//Return numerical JSON if($is_list) return '[' . $json . ']';//Return numerical JSON
return '{' . $json . '}';//Return associative JSON return '{' . $json . '}';//Return associative JSON
} }
?> ?>

@ -0,0 +1,39 @@
<?php
define("LYCHEE", true);
// Declare
$error = "";
// Include
include("config.php");
// PHP Version
if (floatval(phpversion())<5.2) $error .= ("Error 100: Please upgrade to PHP 5.2 or higher!<br>\n");
// Extensions
if (!extension_loaded("exif")) $error .= ("Error 200: PHP exif extension not activated.<br>\n");
if (!extension_loaded("mbstring")) $error .= ("Error 201: PHP mbstring extension not activated.<br>\n");
if (!extension_loaded("gd")) $error .= ("Error 202: PHP gd extension not activated.<br>\n");
if (!extension_loaded("mysqli")) $error .= ("Error 203: PHP mysqli extension not activated.<br>\n");
// Config
if (!$db||$db=="") $error .= ("Error 300: No property for \$db in config.php.<br>\n");
if (!$dbUser||$dbUser=="") $error .= ("Error 301: No property for \$dbUser in config.php.<br>\n");
if (!$dbPassword||$dbPassword=="") $error .= ("Error 302: No property for \$dbPassword in config.php.<br>\n");
if (!$dbHost||$dbHost=="") $error .= ("Error 303: No property for \$dbHost in config.php.<br>\n");
if (!$user||$user=="") $error .= ("Error 304: No property for \$user in config.php.<br>\n");
if (!$password||$password=="") $error .= ("Error 305: No property for \$password in config.php.<br>\n");
// Database
$database = new mysqli($dbHost, $dbUser, $dbPassword, $db);
if (mysqli_connect_errno()!=0) $error .= ("Error 400: " . mysqli_connect_errno() . ": " . mysqli_connect_error() . "<br>\n");
// Permissions
if (substr(sprintf('%o', fileperms("../uploads/big/")), -4) != "0777") $error .= ("Error 500: Wrong permissions for \"/uploads/big\" (777 required).<br>\n");
if (substr(sprintf('%o', fileperms("../uploads/thumb/")), -4) != "0777") $error .= ("Error 501: Wrong permissions for \"/uploads/thumb\" (777 required).<br>\n");
if (substr(sprintf('%o', fileperms("../uploads/import/")), -4) != "0777") $error .= ("Error 502: Wrong permissions for \"/uploads/import\" (777 required).<br>\n");
if ($error == "") echo("Lychee is ready!"); else echo $error;
?>

@ -4,21 +4,23 @@
* @name config.php * @name config.php
* @author Philipp Maurer * @author Philipp Maurer
* @author Tobias Reich * @author Tobias Reich
* @copyright 2012 by Philipp Maurer, Tobias Reich * @copyright 2013 by Philipp Maurer, Tobias Reich
*/ */
if(!defined('LYCHEE')) die("Direct access is not allowed!");
//Database configurations //Database configurations
$db = "lychee"; //Database name $db = "lychee"; //Database name
$dbUser = "lychee"; //Username of the database $dbUser = "lychee"; //Username of the database
$dbPassword = "lychee_passwd"; //Password of the Database $dbPassword = "lychee_passwd"; //Password of the Database
$dbHost = "localhost"; //Host of the Database $dbHost = "localhost"; //Host of the Database
//lychee user configuration //Lychee user configuration
$user = "lychee"; //lychee username $user = "lychee"; //lychee username
$password = "1234"; //lychee password $password = "1234"; //lychee password
//Additional settings
$thumbQuality = 95; //Quality of the Thumbs (0-100). Default: 95 $thumbQuality = 95; //Quality of the Thumbs (0-100). Default: 95
$bitlyUsername = ""; //Your Bit.ly Username $bitlyUsername = ""; //Your Bit.ly Username
$bitlyApi = ""; //Your Bit.ly API Key $bitlyApi = ""; //Your Bit.ly API Key

@ -4,53 +4,53 @@
* @name functions.php * @name functions.php
* @author Philipp Maurer * @author Philipp Maurer
* @author Tobias Reich * @author Tobias Reich
* @copyright 2012 by Philipp Maurer, Tobias Reich * @copyright 2013 by Philipp Maurer, Tobias Reich
*/ */
include("config.php"); if(!defined('LYCHEE')) die("Direct access is not allowed!");
// Database Functions // Database Functions
function dbConnect() { function dbConnect() {
global $db, $dbUser, $dbPassword, $dbHost; global $db, $dbUser, $dbPassword, $dbHost;
$connect = mysql_connect($dbHost, $dbUser, $dbPassword); $database = new mysqli($dbHost, $dbUser, $dbPassword);
if(!$connect) { if (mysqli_connect_errno() != 0) {
echo "No connection: ".mysql_error(); echo mysqli_connect_errno().': '.mysqli_connect_error();
return false; return false;
} }
$dbSelect = mysql_select_db($db); if (!$database->select_db($db)) {
if(!$dbSelect) { createDatabase($db, $database);
if(createDatabase($db)){$dbSelect = mysql_select_db($db);} }
else {echo "Can not create Database!"; return false;} $query = "SELECT * FROM lychee_photos, lychee_albums;";
} if(!$database->query($query)) createTables($database);
$query = "SELECT * FROM photos, albums;"; return $database;
if(!mysql_query($query)) createTables();
return true;
} }
function dbClose() { function dbClose() {
$close = mysql_close(); global $database;
$close = $database->close();
if(!$close) { if(!$close) {
echo "Closing the connection failed!"; echo "Closing the connection failed!";
return false; return false;
} }
return true; return true;
} }
function createDatabase($db) { function createDatabase($db, $database) {
$query = "CREATE DATABASE $db;"; $query = "CREATE DATABASE IF NOT EXISTS $db;";
$result = mysql_query($query); $result = $database->query($query);
$database->select_db($db);
if(!$result) return false; if(!$result) return false;
return true; return true;
} }
function createTables() { function createTables($database) {
$query = "CREATE TABLE IF NOT EXISTS `albums` ( $query = "CREATE TABLE IF NOT EXISTS `lychee_albums` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL, `title` varchar(50) NOT NULL,
`sysdate` varchar(10) NOT NULL, `sysdate` varchar(10) NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;"; ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;";
$result = mysql_query($query); $result = $database->query($query);
if(!$result) return false; if(!$result) return false;
$query = "CREATE TABLE IF NOT EXISTS `photos` ( $query = "CREATE TABLE `lychee_photos` (
`id` bigint(14) NOT NULL, `id` bigint(14) NOT NULL,
`title` varchar(50) NOT NULL, `title` varchar(50) NOT NULL,
`description` varchar(160) NOT NULL, `description` varchar(160) NOT NULL,
@ -72,65 +72,81 @@ function createTables() {
`takedate` varchar(10) NOT NULL, `takedate` varchar(10) NOT NULL,
`taketime` varchar(8) NOT NULL, `taketime` varchar(8) NOT NULL,
`star` tinyint(1) NOT NULL, `star` tinyint(1) NOT NULL,
`album` varchar(30) NOT NULL DEFAULT '0',
`thumbUrl` varchar(50) NOT NULL, `thumbUrl` varchar(50) NOT NULL,
`album` varchar(30) NOT NULL DEFAULT '0',
`import_name` varchar(100) DEFAULT '',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;"; ) ENGINE=MyISAM DEFAULT CHARSET=latin1;";
$result = mysql_query($query); $result = $database->query($query);
if(!$result) return false; if(!$result) return false;
return true; return true;
} }
// Upload Functions // Upload Functions
function upload($file, $albumID) { function upload($files, $albumID) {
switch($albumID) { global $database;
case 's': foreach ($files as $file) {
$public = 1; switch($albumID) {
$star = 0; // s for public (share)
$albumID = 0; case 's':
break; $public = 1;
case 'f': $star = 0;
$star = 1; $albumID = 0;
$public = 0; break;
$albumID = 0; // f for starred (fav)
break; case 'f':
default: $star = 1;
$star = 0; $public = 0;
$public = 0; $albumID = 0;
break;
default:
$star = 0;
$public = 0;
}
$id = str_replace('.', '', microtime(true));
while(strlen($id)<14) $id .= 0;
$tmp_name = $file["tmp_name"];
$type = getimagesize($tmp_name);
if(($type[2]!=1)&&($type[2]!=2)&&($type[2]!=3)) return false;
$data = $file["name"];
$data = explode('.',$data);
$data = array_reverse ($data);
$data = $data[0];
if(!is_uploaded_file($file)) {
if (copy($tmp_name, "../uploads/big/$id.$data")) {
unlink($tmp_name);
$import_name = $tmp_name;
}
} else {
move_uploaded_file($tmp_name, "../uploads/big/$id.$data");
$import_name = "";
}
createThumb($id.".".$data);
// Read infos
$info = getCamera($id.".".$data);
$title="";
if(isset($info['type'])){$type=$info['type'];}else{$type="";}
if(isset($info['width'])){$width=$info['width'];}else{$width="";}
if(isset($info['height'])){$height=$info['height'] OR "";}else{$height="";}
if(isset($info['size'])){$size=$info['size'] OR "";}else{$size="";}
if(isset($info['date'])){$sysdate=$info['date'];}else{$sysdate="";}
if(isset($info['time'])){$systime=$info['time'];}else{$systime="";}
if(isset($info['iso'])){$iso=$info['iso'];}else{$iso="";}
if(isset($info['aperture'])){$aperture=$info['aperture'];}else{$aperture="";}
if(isset($info['make'])){$make=$info['make'];}else{$make="";}
if(isset($info['model'])){$model=$info['model'] OR "";}else{$model="";}
if(isset($info['shutter'])){$shutter=$info['shutter'];}else{$shutter="";}
if(isset($info['focal'])){$focal=$info['focal'];}else{$focal="";}
if(isset($info['takeDate'])){$takeDate=$info['takeDate'];}else{$takeDate="";}
if(isset($info['takeTime'])){$takeTime=$info['takeTime'];}else{$takeTime="";}
$query = "INSERT INTO lychee_photos (id, title, url, type, width, height, size, sysdate, systime, iso, aperture, make, model, shutter, focal, takedate, taketime, thumbUrl, album, public, star, import_name)
VALUES ('$id', '$title', 'uploads/big/$id.$data', '$type', '$width', '$height', '$size', '$sysdate', '$systime', '$iso', '$aperture', '$make', '$model', '$shutter', '$focal', '$takeDate', '$takeTime', 'uploads/thumb/$id.$data', '$albumID', '$public', '$star', '$import_name');";
$result = $database->query($query);
} }
$id = str_replace('.', '', microtime(true)); return true;
while(strlen($id)<14) $id .= 0;
$tmp_name = $file['File']["tmp_name"];
$type = getimagesize($tmp_name);
if(($type[2]!=1)&&($type[2]!=2)&&($type[2]!=3)) return false;
$data = $file['File']["name"];
$data = explode('.',$data);
$data = array_reverse ($data);
$data = $data[0];
move_uploaded_file($tmp_name, "../uploads/big/$id.$data");
createThumb($id.".".$data);
// Read infos
$info = getCamera($id.".".$data);
$title="";
if(isset($info['type'])){$type=$info['type'];}else{$type="";}
if(isset($info['width'])){$width=$info['width'];}else{$width="";}
if(isset($info['height'])){$height=$info['height'] OR "";}else{$height="";}
if(isset($info['size'])){$size=$info['size'] OR "";}else{$size="";}
if(isset($info['date'])){$sysdate=$info['date'];}else{$sysdate="";}
if(isset($info['time'])){$systime=$info['time'];}else{$systime="";}
if(isset($info['iso'])){$iso=$info['iso'];}else{$iso="";}
if(isset($info['aperture'])){$aperture=$info['aperture'];}else{$aperture="";}
if(isset($info['make'])){$make=$info['make'];}else{$make="";}
if(isset($info['model'])){$model=$info['model'] OR "";}else{$model="";}
if(isset($info['shutter'])){$shutter=$info['shutter'];}else{$shutter="";}
if(isset($info['focal'])){$focal=$info['focal'];}else{$focal="";}
if(isset($info['takeDate'])){$takeDate=$info['takeDate'];}else{$takeDate="";}
if(isset($info['takeTime'])){$takeTime=$info['takeTime'];}else{$takeTime="";}
$query = "INSERT INTO photos (id, title, url, type, width, height, size, sysdate, systime, iso, aperture, make, model, shutter, focal, takedate, taketime, thumbUrl, album, public, star)
VALUES ('$id', '$title', 'uploads/big/$id.$data', '$type', '$width', '$height', '$size', '$sysdate', '$systime', '$iso', '$aperture', '$make', '$model', '$shutter', '$focal', '$takeDate', '$takeTime', 'uploads/thumb/$id.$data', '$albumID', '$public', '$star');";
$result = mysql_query($query);
} }
function getCamera($photoID) { function getCamera($photoID) {
global $database;
$return = array(); $return = array();
$url = "../uploads/big/$photoID"; $url = "../uploads/big/$photoID";
$type = getimagesize($url); $type = getimagesize($url);
@ -152,7 +168,7 @@ function getCamera($photoID) {
$return['date'] = date("d.m.Y",filectime($url)); $return['date'] = date("d.m.Y",filectime($url));
$return['time'] = date("H:i:s",filectime($url)); $return['time'] = date("H:i:s",filectime($url));
echo $exif['FileDateTime']."<br/>".$exif['DateTimeOriginal']; //echo $exif['FileDateTime']."<br/>".$exif['DateTimeOriginal'];
// Camera Information // Camera Information
if(isset($exif['ISOSpeedRatings'])){$return['iso']="ISO-".$exif['ISOSpeedRatings'];} if(isset($exif['ISOSpeedRatings'])){$return['iso']="ISO-".$exif['ISOSpeedRatings'];}
@ -183,10 +199,12 @@ function getCamera($photoID) {
} }
return $return; return $return;
} }
function createThumb($photoName, $width = 200, $height = 200) { function createThumb($photoName, $width = 200, $width2x = 400, $height = 200, $height2x = 400) {
global $thumbQuality; global $database, $thumbQuality;
$photoUrl = "../uploads/big/$photoName"; $photoUrl = "../uploads/big/$photoName";
$newUrl = "../uploads/thumb/$photoName"; $newUrl = "../uploads/thumb/$photoName";
$thumbPhotoName = explode(".", $photoName);
$newUrl2x = "../uploads/thumb/".$thumbPhotoName[0]."@2x.".$thumbPhotoName[1];
$oldImg = getimagesize($photoUrl); $oldImg = getimagesize($photoUrl);
$type = $oldImg['mime']; $type = $oldImg['mime'];
switch($type) { switch($type) {
@ -196,6 +214,7 @@ function createThumb($photoName, $width = 200, $height = 200) {
default: return false; default: return false;
} }
$thumb = imagecreatetruecolor($width, $height); $thumb = imagecreatetruecolor($width, $height);
$thumb2x = imagecreatetruecolor($width2x, $height2x);
if($oldImg[0]<$oldImg[1]) { if($oldImg[0]<$oldImg[1]) {
$newSize = $oldImg[0]; $newSize = $oldImg[0];
$startWidth = 0; $startWidth = 0;
@ -206,10 +225,11 @@ function createThumb($photoName, $width = 200, $height = 200) {
$startHeight = 0; $startHeight = 0;
} }
imagecopyresampled($thumb,$sourceImg,0,0,$startWidth,$startHeight,$width,$height,$newSize,$newSize); imagecopyresampled($thumb,$sourceImg,0,0,$startWidth,$startHeight,$width,$height,$newSize,$newSize);
imagecopyresampled($thumb2x,$sourceImg,0,0,$startWidth,$startHeight,$width2x,$height2x,$newSize,$newSize);
switch($type) { switch($type) {
case "image/jpeg": imagejpeg($thumb,$newUrl,$thumbQuality); break; case "image/jpeg": imagejpeg($thumb,$newUrl,$thumbQuality); imagejpeg($thumb2x,$newUrl2x,$thumbQuality); break;
case "image/png": imagepng($thumb,$newUrl); break; case "image/png": imagepng($thumb,$newUrl); imagepng($thumb2x,$newUrl2x); break;
case "image/gif": imagegif($thumb,$newUrl); break; case "image/gif": imagegif($thumb,$newUrl); imagegif($thumb2x,$newUrl2x); break;
default: return false; default: return false;
} }
return true; return true;
@ -217,9 +237,13 @@ function createThumb($photoName, $width = 200, $height = 200) {
// Session Functions // Session Functions
function login($loginUser, $loginPassword) { function login($loginUser, $loginPassword) {
global $user, $password; global $database, $user, $password;
if(($loginUser == $user) && ($loginPassword == $password)){ if(($loginUser == $user) && ($loginPassword == md5($password))){
$_SESSION['login'] = true; $_SESSION['login'] = true;
ini_set("session.cookie_lifetime","86400");
ini_set("session.gc_maxlifetime", 86400);
ini_set("session.gc_probability",1);
ini_set("session.gc_divisor",1);
return true; return true;
} else { } else {
return false; return false;
@ -232,137 +256,149 @@ function logout() {
// Album Functions // Album Functions
function addAlbum($title) { function addAlbum($title) {
$title = mysql_escape_string($title); global $database;
$title = mysqli_real_escape_string($database, $title);
$sysdate = date("d.m.Y"); $sysdate = date("d.m.Y");
$query = "INSERT INTO albums (title, sysdate) VALUES ('$title', '$sysdate');"; $query = "INSERT INTO lychee_albums (title, sysdate) VALUES ('$title', '$sysdate');";
$result = mysql_query($query); $result = $database->query($query);
if(!$result) return false; if(!$result) return false;
return mysql_insert_id(); return $database->insert_id;
} }
function getAlbums() { function getAlbums() {
$return = array(array()); global $database;
$query = "SELECT id, title, sysdate FROM albums ORDER BY id DESC;"; $return = array(array(array()));
$result = mysql_query($query) OR die("Error: $result <br>".mysql_error());
// Smart Albums
$return = getSmartInfo();
// Albums
$query = "SELECT id, title, sysdate FROM lychee_albums ORDER BY id DESC;";
$result = $database->query($query) OR die("Error: $result <br>".$database->error);
$i=0; $i=0;
while($row = mysql_fetch_object($result)) { while($row = $result->fetch_object()) {
$return[$i]['id'] = $row->id; $return["album"][$i]['id'] = $row->id;
$return[$i]['title'] = $row->title; $return["album"][$i]['title'] = $row->title;
$return[$i]['sysdate'] = $row->sysdate; $return["album"][$i]['sysdate'] = $row->sysdate;
$albumID = $row->id; $albumID = $row->id;
$query = "SELECT thumbUrl FROM photos WHERE album = '$albumID' ORDER BY id DESC LIMIT 0, 3;"; $query = "SELECT thumbUrl FROM lychee_photos WHERE album = '$albumID' ORDER BY id DESC LIMIT 0, 3;";
$result2 = mysql_query($query); $result2 = $database->query($query);
$k = 0; $k = 0;
while($row2 = mysql_fetch_object($result2)){ while($row2 = $result2->fetch_object()){
$return[$i]["thumb$k"] = $row2->thumbUrl; $return["album"][$i]["thumb$k"] = $row2->thumbUrl;
$k++; $k++;
} }
if(!isset($return[$i]["thumb0"]))$return[$i]["thumb0"]=""; if(!isset($return["album"][$i]["thumb0"]))$return[$i]["thumb0"]="";
if(!isset($return[$i]["thumb1"]))$return[$i]["thumb1"]=""; if(!isset($return["album"][$i]["thumb1"]))$return[$i]["thumb1"]="";
if(!isset($return[$i]["thumb2"]))$return[$i]["thumb2"]=""; if(!isset($return["album"][$i]["thumb2"]))$return[$i]["thumb2"]="";
$i++; $i++;
} }
if($i==0) return false; if($i==0) $return["albums"] = false;
else $return["albums"] = true;
return $return; return $return;
} }
function getSmartInfo() { function getSmartInfo() {
$return = array(); global $database;
$query = "SELECT * FROM photos WHERE album = 0 ORDER BY id DESC;"; $return = array(array());
$result = mysql_query($query); $query = "SELECT * FROM lychee_photos WHERE album = 0 ORDER BY id DESC;";
$result = $database->query($query);
$i = 0; $i = 0;
while($row = mysql_fetch_object($result)) { while($row = $result->fetch_object()) {
if($i<3) $return["unsortThumb$i"] = $row->thumbUrl; if($i<3) $return["unsortThumb$i"] = $row->thumbUrl;
$i++; $i++;
} }
$return['unsortNum'] = $i; $return['unsortNum'] = $i;
$query2 = "SELECT * FROM photos WHERE public = 1 ORDER BY id DESC;"; $query2 = "SELECT * FROM lychee_photos WHERE public = 1 ORDER BY id DESC;";
$result2 = mysql_query($query2); $result2 = $database->query($query2);
$i = 0; $i = 0;
while($row2 = mysql_fetch_object($result2)) { while($row2 = $result2->fetch_object()) {
if($i<3) $return["publicThumb$i"] = $row2->thumbUrl; if($i<3) $return["publicThumb$i"] = $row2->thumbUrl;
$i++; $i++;
} }
$return['publicNum'] = $i; $return['publicNum'] = $i;
$query3 = "SELECT * FROM photos WHERE star = 1 ORDER BY id DESC;"; $query3 = "SELECT * FROM lychee_photos WHERE star = 1 ORDER BY id DESC;";
$result3 = mysql_query($query3); $result3 = $database->query($query3);
$i = 0; $i = 0;
while($row3 = mysql_fetch_object($result3)) { while($row3 = $result3->fetch_object()) {
if($i<3) $return["starredThumb$i"] = $row3->thumbUrl; if($i<3) $return["starredThumb$i"] = $row3->thumbUrl;
$i++; $i++;
} }
$return['starredNum'] = $i; $return['starredNum'] = $i;
return $return; return $return;
} }
function getAlbumInfo($albumID) { function getAlbumInfo($albumID) {
global $database;
$return = array(); $return = array();
$query = "SELECT * FROM albums WHERE id = '$albumID';"; $query = "SELECT * FROM lychee_albums WHERE id = '$albumID';";
$result = mysql_query($query); $result = $database->query($query);
$row = mysql_fetch_object($result); $row = $result->fetch_object();
$return['title'] = $row->title; $return['title'] = $row->title;
$return['date'] = $row->sysdate; $return['date'] = $row->sysdate;
$return['star'] = $row->star; $return['star'] = $row->star;
$return['public'] = $row->public; $return['public'] = $row->public;
$query = "SELECT COUNT(*) AS num FROM photos WHERE album = '$albumID';"; $query = "SELECT COUNT(*) AS num FROM lychee_photos WHERE album = '$albumID';";
$result = mysql_query($query); $result = $database->query($query);
$row = mysql_fetch_object($result); $row = $result->fetch_object();
$return['num'] = $row->num; $return['num'] = $row->num;
return $return; return $return;
} }
function setAlbumTitle($albumID, $title) { function setAlbumTitle($albumID, $title) {
$title = mysql_real_escape_string(urldecode($title)); global $database;
$title = mysqli_real_escape_string($database, urldecode($title));
if(strlen($title)<3||strlen($title)>30) return false; if(strlen($title)<3||strlen($title)>30) return false;
$query = "UPDATE albums SET title = '$title' WHERE id = '$albumID';"; $query = "UPDATE lychee_albums SET title = '$title' WHERE id = '$albumID';";
$result = mysql_query($query); $result = $database->query($query);
if(!$result) return false; if(!$result) return false;
return true; return true;
} }
function deleteAlbum($albumID, $delAll) { function deleteAlbum($albumID, $delAll) {
global $database;
if($delAll=="true") { if($delAll=="true") {
$query = "SELECT id FROM photos WHERE album = '$albumID';"; $query = "SELECT id FROM lychee_photos WHERE album = '$albumID';";
$result = mysql_query($query); $result = $database->query($query);
$error = false; $error = false;
while($row = mysql_fetch_object($result)) { while($row = $result->fetch_object()) {
if(!deletePhoto($row->id)) $error = true; if(!deletePhoto($row->id)) $error = true;
} }
} else { } else {
$query = "UPDATE photos SET album = '0' WHERE album = '$albumID';"; $query = "UPDATE lychee_photos SET album = '0' WHERE album = '$albumID';";
$result = mysql_query($query); $result = $database->query($query);
if(!$result) return false; if(!$result) return false;
} }
if($albumID!=0) { if($albumID!=0) {
$query = "DELETE FROM albums WHERE id = '$albumID';"; $query = "DELETE FROM lychee_albums WHERE id = '$albumID';";
$result = mysql_query($query); $result = $database->query($query);
if(!$result) return false; if(!$result) return false;
} }
if($error) return false; if($error) return false;
return true; return true;
} }
function getAlbumArchive($albumID) { function getAlbumArchive($albumID) {
global $database;
switch($albumID) { switch($albumID) {
case 's': case 's':
$query = "SELECT * FROM photos WHERE public = '1';"; $query = "SELECT * FROM lychee_photos WHERE public = '1';";
$zipTitle = "Public"; $zipTitle = "Public";
break; break;
case 'f': case 'f':
$query = "SELECT * FROM photos WHERE star = '1';"; $query = "SELECT * FROM lychee_photos WHERE star = '1';";
$zipTitle = "Starred"; $zipTitle = "Starred";
break; break;
default: default:
$query = "SELECT * FROM photos WHERE album = '$albumID';"; $query = "SELECT * FROM lychee_photos WHERE album = '$albumID';";
$zipTitle = "Unsorted"; $zipTitle = "Unsorted";
} }
$result = mysql_query($query); $result = $database->query($query);
$files = array(); $files = array();
$i=0; $i=0;
while($row = mysql_fetch_object($result)) { while($row = $result->fetch_object()) {
$files[$i] = "../".$row->url; $files[$i] = "../".$row->url;
$i++; $i++;
} }
$query = "SELECT * FROM albums WHERE id = '$albumID';"; $query = "SELECT * FROM lychee_albums WHERE id = '$albumID';";
$result = mysql_query($query); $result = $database->query($query);
$row = mysql_fetch_object($result); $row = $result->fetch_object();
if($albumID!=0&&is_numeric($albumID))$zipTitle = $row->title; if($albumID!=0&&is_numeric($albumID))$zipTitle = $row->title;
$filename = "./".$zipTitle.".zip"; $filename = "./".$zipTitle.".zip";
@ -390,17 +426,18 @@ function getAlbumArchive($albumID) {
// Photo Functions // Photo Functions
function getPhotos($albumID) { function getPhotos($albumID) {
global $database;
switch($albumID) { switch($albumID) {
case "f": $query = "SELECT * FROM photos WHERE star = 1 ORDER BY id DESC;"; case "f": $query = "SELECT * FROM lychee_photos WHERE star = 1 ORDER BY id DESC;";
break; break;
case "s": $query = "SELECT * FROM photos WHERE public = 1 ORDER BY id DESC;"; case "s": $query = "SELECT * FROM lychee_photos WHERE public = 1 ORDER BY id DESC;";
break; break;
default: $query = "SELECT * FROM photos WHERE album = '$albumID' ORDER BY id DESC;"; default: $query = "SELECT * FROM lychee_photos WHERE album = '$albumID' ORDER BY id DESC;";
} }
$result = mysql_query($query); $result = $database->query($query);
$return = array(array()); $return = array(array());
$i = 0; $i = 0;
while($row = mysql_fetch_array($result)) { while($row = $result->fetch_array()) {
$return[$i] = $row; $return[$i] = $row;
$i++; $i++;
} }
@ -408,15 +445,30 @@ function getPhotos($albumID) {
return $return; return $return;
} }
function getPhotoInfo($photoID) { function getPhotoInfo($photoID) {
$query = "SELECT * FROM photos WHERE id = '$photoID';"; global $database;
$result = mysql_query($query); if(!is_numeric($photoID)) {
$return = mysql_fetch_array($result); $query = "SELECT COUNT(*) AS quantity FROM lychee_photos WHERE import_name = '../uploads/import/$photoID';";
$result = $database->query($query);
$row = $result->fetch_object();
if($row->quantity == 0) {
importPhoto($photoID);
}
if(is_file("../uploads/import/$photoID")) {
importPhoto($photoID);
}
$query = "SELECT * FROM lychee_photos WHERE import_name = '../uploads/import/$photoID' ORDER BY ID DESC;";
} else {
$query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
}
$result = $database->query($query);
$return = $result->fetch_array();
return $return; return $return;
} }
function downloadPhoto($photoID) { function downloadPhoto($photoID) {
$query = "SELECT * FROM photos WHERE id = '$photoID';"; global $database;
$result = mysql_query($query); $query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
$row = mysql_fetch_object($result); $result = $database->query($query);
$row = $result->fetch_object();
$photo = "../".$row->url; $photo = "../".$row->url;
$title = $row->title; $title = $row->title;
@ -437,20 +489,23 @@ function downloadPhoto($photoID) {
return true; return true;
} }
function countPhotos() { function countPhotos() {
$query = "SELECT COUNT(*) AS num FROM photos;"; global $database;
$result = mysql_query($query); $query = "SELECT COUNT(*) AS num FROM lychee_photos;";
$row = mysql_fetch_object($result); $result = $database->query($query);
$row = $result->fetch_object();
return $row->num; return $row->num;
} }
function setPhotoPublic($photoID, $url) { function setPhotoPublic($photoID, $url) {
$query = "SELECT public, shortlink FROM photos WHERE id = '$photoID';"; global $database;
$row = mysql_fetch_object(mysql_query($query)); $query = "SELECT public, shortlink FROM lychee_photos WHERE id = '$photoID';";
$result = $database->query($query);
$row = $result->fetch_object();
if($row->public == 0){ if($row->public == 0){
$public = 1; $public = 1;
}else{ }else{
$public = 0; $public = 0;
} }
if(preg_match('/localhost/', $_SERVER['HTTP_REFERER'])) { if($public==0 || preg_match('/localhost/', $_SERVER['HTTP_REFERER']) || preg_match('\file:\/\/\/', $_SERVER['HTTP_REFERER'])) {
$shortlink = ""; $shortlink = "";
}else{ }else{
if($row->shortlink==""){ if($row->shortlink==""){
@ -459,108 +514,132 @@ function setPhotoPublic($photoID, $url) {
$shortlink = $row->shortlink; $shortlink = $row->shortlink;
} }
} }
$query = "UPDATE photos SET public = '$public', shortlink = '$shortlink' WHERE id = '$photoID';"; $query = "UPDATE lychee_photos SET public = '$public', shortlink = '$shortlink' WHERE id = '$photoID';";
$result = mysql_query($query); $result = $database->query($query);
if(!$result) return false; if(!$result) return false;
return true; return true;
} }
function setPhotoStar($photoID) { function setPhotoStar($photoID) {
$query = "SELECT star FROM photos WHERE id = '$photoID';"; global $database;
$row = mysql_fetch_object(mysql_query($query)); $query = "SELECT star FROM lychee_photos WHERE id = '$photoID';";
$result = $database->query($query);
$row = $result->fetch_object();
if($row->star == 0) { if($row->star == 0) {
$star = 1; $star = 1;
} else { } else {
$star = 0; $star = 0;
} }
$query = "UPDATE photos SET star = '$star' WHERE id = '$photoID';"; $query = "UPDATE lychee_photos SET star = '$star' WHERE id = '$photoID';";
$result = mysql_query($query); $result = $database->query($query);
return true; return true;
} }
function nextPhoto($photoID, $albumID) { function nextPhoto($photoID, $albumID) {
global $database;
switch($albumID) { switch($albumID) {
case 'f': $query = "SELECT * FROM photos WHERE id < '$photoID' AND star = '1' ORDER BY id DESC LIMIT 0, 1;"; case 'f': $query = "SELECT * FROM lychee_photos WHERE id < '$photoID' AND star = '1' ORDER BY id DESC LIMIT 0, 1;";
break; break;
case 's': $query = "SELECT * FROM photos WHERE id < '$photoID' AND public = '1' ORDER BY id DESC LIMIT 0, 1;"; case 's': $query = "SELECT * FROM lychee_photos WHERE id < '$photoID' AND public = '1' ORDER BY id DESC LIMIT 0, 1;";
break; break;
default: $query = "SELECT * FROM photos WHERE id < '$photoID' AND album = '$albumID' ORDER BY id DESC LIMIT 0, 1;"; default: $query = "SELECT * FROM lychee_photos WHERE id < '$photoID' AND album = '$albumID' ORDER BY id DESC LIMIT 0, 1;";
} }
$result = mysql_query($query); $result = $database->query($query);
$return = mysql_fetch_array($result); $return = $result->fetch_array();
if(!$return || ($return==0)) { if(!$return || ($return==0)) {
switch($albumID) { switch($albumID) {
case 'f': $query = "SELECT * FROM photos WHERE star = '1' ORDER BY id DESC LIMIT 0, 1;"; case 'f': $query = "SELECT * FROM lychee_photos WHERE star = '1' ORDER BY id DESC LIMIT 0, 1;";
break; break;
case 's': $query = "SELECT * FROM photos WHERE public = '1' ORDER BY id DESC LIMIT 0, 1;"; case 's': $query = "SELECT * FROM lychee_photos WHERE public = '1' ORDER BY id DESC LIMIT 0, 1;";
break; break;
default: $query = "SELECT * FROM photos WHERE album = '$albumID' ORDER BY id DESC LIMIT 0, 1;"; default: $query = "SELECT * FROM lychee_photos WHERE album = '$albumID' ORDER BY id DESC LIMIT 0, 1;";
} }
$result = mysql_query($query); $result = $database->query($query);
$return = mysql_fetch_array($result); $return = $result->fetch_array();
} }
return $return; return $return;
} }
function previousPhoto($photoID, $albumID) { function previousPhoto($photoID, $albumID) {
global $database;
switch($albumID) { switch($albumID) {
case 'f': $query = "SELECT * FROM photos WHERE id > '$photoID' AND star = '1' LIMIT 0, 1;"; case 'f': $query = "SELECT * FROM lychee_photos WHERE id > '$photoID' AND star = '1' LIMIT 0, 1;";
break; break;
case 's': $query = "SELECT * FROM photos WHERE id > '$photoID' AND public = '1' LIMIT 0, 1;"; case 's': $query = "SELECT * FROM lychee_photos WHERE id > '$photoID' AND public = '1' LIMIT 0, 1;";
break; break;
default: $query = "SELECT * FROM photos WHERE id > '$photoID' AND album = '$albumID' LIMIT 0, 1;"; default: $query = "SELECT * FROM lychee_photos WHERE id > '$photoID' AND album = '$albumID' LIMIT 0, 1;";
} }
$result = mysql_query($query); $result = $database->query($query);
$return = mysql_fetch_array($result); $return = $result->fetch_array();
if(!$return || ($return==0)) { if(!$return || ($return==0)) {
switch($albumID) { switch($albumID) {
case 'f': $query = "SELECT * FROM photos WHERE star = '1' ORDER BY id LIMIT 0, 1;"; case 'f': $query = "SELECT * FROM lychee_photos WHERE star = '1' ORDER BY id LIMIT 0, 1;";
break; break;
case 's': $query = "SELECT * FROM photos WHERE public = '1' ORDER BY id LIMIT 0, 1;"; case 's': $query = "SELECT * FROM lychee_photos WHERE public = '1' ORDER BY id LIMIT 0, 1;";
break; break;
default: $query = "SELECT * FROM photos WHERE album = '$albumID' ORDER BY id LIMIT 0, 1;"; default: $query = "SELECT * FROM lychee_photos WHERE album = '$albumID' ORDER BY id LIMIT 0, 1;";
} }
$result = mysql_query($query); $result = $database->query($query);
$return = mysql_fetch_array($result); $return = $result->fetch_array();
} }
return $return; return $return;
} }
function movePhoto($photoID, $newAlbum) { function movePhoto($photoID, $newAlbum) {
$query = "UPDATE photos SET album = '$newAlbum' WHERE id = '$photoID';"; global $database;
$result = mysql_query($query); $query = "UPDATE lychee_photos SET album = '$newAlbum' WHERE id = '$photoID';";
$result = $database->query($query);
if(!$result) return false; if(!$result) return false;
else return true; else return true;
} }
function setPhotoTitle($photoID, $title) { function setPhotoTitle($photoID, $title) {
$title = mysql_real_escape_string(urldecode($title)); global $database;
$title = mysqli_real_escape_string($database, urldecode($title));
if(strlen($title)>30) return false; if(strlen($title)>30) return false;
$query = "UPDATE photos SET title = '$title' WHERE id = '$photoID';"; $query = "UPDATE lychee_photos SET title = '$title' WHERE id = '$photoID';";
$result = mysql_query($query); $result = $database->query($query);
if(!$result) return false; if(!$result) return false;
else return true; else return true;
} }
function setPhotoDescription($photoID, $description) { function setPhotoDescription($photoID, $description) {
$description = mysql_real_escape_string(htmlentities($description)); global $database;
$description = mysqli_real_escape_string($database, htmlentities($description));
if(strlen($description)>160) return false; if(strlen($description)>160) return false;
$query = "UPDATE photos SET description = '$description' WHERE id = '$photoID';"; $query = "UPDATE lychee_photos SET description = '$description' WHERE id = '$photoID';";
$result = mysql_query($query); $result = $database->query($query);
if(!$result) return false; if(!$result) return false;
return true; return true;
} }
function deletePhoto($photoID) { function deletePhoto($photoID) {
$query = "SELECT * FROM photos WHERE id = '$photoID';"; global $database;
$result = mysql_query($query); $query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
$result = $database->query($query);
if(!$result) return false; if(!$result) return false;
$row = mysql_fetch_object($result); $row = $result->fetch_object();
$retinaUrl = explode(".", $row->thumbUrl);
$unlink1 = unlink("../".$row->url); $unlink1 = unlink("../".$row->url);
$unlink2 = unlink("../".$row->thumbUrl); $unlink2 = unlink("../".$row->thumbUrl);
if(!$unlink1 || !$unlink2) return false; $unlink3 = unlink("../".$retinaUrl[0].'@2x.'.$retinaUrl[1]);
$query = "DELETE FROM photos WHERE id = '$photoID';"; $query = "DELETE FROM lychee_photos WHERE id = '$photoID';";
$result = mysql_query($query); $result = $database->query($query);
if(!$unlink1 || !$unlink2 || !$unlink3) return false;
if(!$result) return false; if(!$result) return false;
return true; return true;
} }
function importPhoto($name) {
global $database;
$tmp_name = "../uploads/import/$name";
$details = getimagesize($tmp_name);
$size = filesize($tmp_name);
$nameFile = array(array());
$nameFile[0]['name'] = $name;
$nameFile[0]['type'] = $details['mime'];
$nameFile[0]['tmp_name'] = $tmp_name;
$nameFile[0]['error'] = 0;
$nameFile[0]['size'] = $size;
if(!upload($nameFile, 's')) return false;
else return true;
}
// Share Functions // Share Functions
function urlShortner($url) { function urlShortner($url) {
global $bitlyUsername, $bitlyApi; global $database, $bitlyUsername, $bitlyApi;
if($bitlyUsername==""||$bitlyApi=="") return false; if($bitlyUsername==""||$bitlyApi=="") return false;
$url = urlencode($url); $url = urlencode($url);
$bitlyAPI = "http://api.bit.ly/shorten?version=2.0.1&format=xml&longUrl=$url&login=$bitlyUsername&apiKey=$bitlyApi"; $bitlyAPI = "http://api.bit.ly/shorten?version=2.0.1&format=xml&longUrl=$url&login=$bitlyUsername&apiKey=$bitlyApi";
@ -572,9 +651,10 @@ function urlShortner($url) {
return $shortlink; return $shortlink;
} }
function sharePhoto($photoID, $url) { function sharePhoto($photoID, $url) {
$query = "SELECT * FROM photos WHERE id = '$photoID'"; global $database;
$result = mysql_query($query); $query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
$row = mysql_fetch_object($result); $result = $database->query($query);
$row = $result->fetch_object();
$thumb = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."/../../".$row->thumbUrl; $thumb = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."/../../".$row->thumbUrl;
$title = $row->title; $title = $row->title;
@ -583,8 +663,6 @@ function sharePhoto($photoID, $url) {
$twitterUrl = "https://twitter.com/share?url=".urlencode("$url"); $twitterUrl = "https://twitter.com/share?url=".urlencode("$url");
$facebookUrl = "http://www.facebook.com/sharer.php?u=".urlencode("$url")."&t=".urlencode($title); $facebookUrl = "http://www.facebook.com/sharer.php?u=".urlencode("$url")."&t=".urlencode($title);
$tumblrUrl = "http://www.tumblr.com/share/link?url=".urlencode("$url")."&name=". urlencode($title)."&description=".urlencode($description);
$pinterestUrl = "http://pinterest.com/pin/create/button/?url=".urlencode("$url")."&media=".urlencode($thumb);
$mailUrl = "mailto:?subject=".rawurlencode($title)."&body=".rawurlencode("Hey guy! Check this out: $url"); $mailUrl = "mailto:?subject=".rawurlencode($title)."&body=".rawurlencode("Hey guy! Check this out: $url");
$share = array(); $share = array();
@ -598,11 +676,11 @@ function sharePhoto($photoID, $url) {
return $share; return $share;
} }
function facebookHeader($photoID) { function facebookHeader($photoID) {
$database = dbConnect();
if(!is_numeric($photoID)) return false; if(!is_numeric($photoID)) return false;
dbConnect(); $query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
$query = "SELECT * FROM photos WHERE id = '$photoID';"; $result = $database->query($query);
$result = mysql_query($query); $row = $result->fetch_object();
$row = mysql_fetch_object($result);
$parseUrl = parse_url("http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); $parseUrl = parse_url("http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
$thumb = $parseUrl['scheme']."://".$parseUrl['host'].$parseUrl['path']."/../".$row->thumbUrl; $thumb = $parseUrl['scheme']."://".$parseUrl['host'].$parseUrl['path']."/../".$row->thumbUrl;
@ -614,37 +692,47 @@ function facebookHeader($photoID) {
return $return; return $return;
} }
function isPhotoPublic($photoID) { function isPhotoPublic($photoID) {
$query = "SELECT * FROM photos WHERE id = '$photoID';"; global $database;
$result = mysql_query($query); $photoID = mysqli_real_escape_string($database, $photoID);
$row = mysql_fetch_object($result); if(is_numeric($photoID)) {
if($row->public == 1) return true; $query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
return false; } else {
$query = "SELECT * FROM lychee_photos WHERE import_name = '../uploads/import/$photoID';";
}
$result = $database->query($query);
$row = $result->fetch_object();
if (!is_numeric($photoID)&&!$row) return true;
if($row->public == 1) {
return true;
} else {
return false;
}
} }
// Search Function // Search Function
function search($term) { function search($term) {
$term = mysql_real_escape_string($term); global $database;
$term = mysqli_real_escape_string($database, $term);
$query = "SELECT * FROM photos WHERE title like '%$term%' OR description like '%$term%';"; $query = "SELECT * FROM lychee_photos WHERE title like '%$term%' OR description like '%$term%';";
$result = mysql_query($query); $result = $database->query($query);
while($row = mysql_fetch_array($result)) { while($row = $result->fetch_array()) {
$return['photos'][] = $row; $return['photos'][] = $row;
} }
$query = "SELECT * FROM albums WHERE title like '%$term%';"; $query = "SELECT * FROM lychee_albums WHERE title like '%$term%';";
$result = mysql_query($query); $result = $database->query($query);
$i=0; $i=0;
while($row = mysql_fetch_array($result)) { while($row = $result->fetch_array()) {
$return['albums'][$i] = $row; $return['albums'][$i] = $row;
$query2 = "SELECT thumbUrl FROM lychee_photos WHERE album = '".$row['id']."' ORDER BY id DESC LIMIT 0, 3;";
$query = "SELECT thumbUrl FROM photos WHERE album = '".$row['id']."' ORDER BY id DESC LIMIT 0, 3;"; $result2 = $database->query($query2);
$result2 = mysql_query($query);
$k = 0; $k = 0;
while($row2 = mysql_fetch_object($result2)){ while($row2 = $result2->fetch_object()){
$return['albums'][$i]["thumb$k"] = $row2->thumbUrl; $return['albums'][$i]["thumb$k"] = $row2->thumbUrl;
$k++; $k++;
} }
$i++;
} }
return $return; return $return;
} }

@ -27,7 +27,7 @@ To use Lychee without restrictions, we recommend to increase the values of the f
Change the permissions of `/lychee/uploads` to 777, including all subfolders: Change the permissions of `/lychee/uploads` to 777, including all subfolders:
chmod -R 777 /lychee/uploads chmod -R 777 lychee/uploads/
#### Lychee configuration `lychee/php/config.php` #### Lychee configuration `lychee/php/config.php`
@ -40,8 +40,8 @@ Your photos are protected by a username and password you need to set:
$user = Your username for Lychee $user = Your username for Lychee
$password = Your password for Lychee $password = Your password for Lychee
Optional configuration: This settings are optional and doesn't need to be changed:
$thumbQuality = Photo thumbs quality $thumbQuality = Photo thumbs quality
-> Less means a inferiority quality of your thumbs, but faster loading -> Less means a inferiority quality of your thumbs, but faster loading
@ -52,14 +52,41 @@ Optional configuration:
## How to use ## How to use
After the configuration navigate your browser to the place where Lychee is located. Everything should work now. If not, check the logs and try to fix the error. After the configuration, navigate your browser to the place where Lychee is located. Everything should work now. If not, try the installation again.
### FTP Upload
You can upload and share photos directly from every FTP client with Lychee. To do so, upload images to `uploads/import/` and navigate your browser to the place where Lychee is located (e.g. `http://example.com/view.php?p=filename.png`). `filename.png` must be replaced by the filename of your uploaded file. [Sample configuration](http://lychee.electerious.com/view.php?p=13657692738813).
### Keyboard Shortcuts
######Everywhere
`n` New album/photo
`u` Upload photo
`esc` Close/Back
######Photoview
`s` Star photo
`i` Show information
`f` Show photo in new tab
`backspace` Delete photo
`left` Previous photo
`right` Next photo
## Browser Support
Lychee supports the latest versions of Google Chrome, Apple Safari and Mozilla Firefox. Photos you share with others can be viewed from every browser.
## About
Lychee is made by [Tobias Reich](http://electerious.com) (HTML, CSS, JS, Design, Website Design and Development) with the help of [Philipp Maurer](http://phinal.net) (PHP, MySQL).
##License ##License
(MIT License) (MIT License)
Copyright (C) 2012 [Tobias Reich](http://electerious.com) Copyright (C) 2013 [Tobias Reich](http://electerious.com)
Copyright (C) 2012 [Philipp Maurer](http://phinal.net) Copyright (C) 2013 [Philipp Maurer](http://phinal.net)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

@ -1,4 +1,3 @@
<?php require_once("php/functions.php"); ?>
<!DOCTYPE HTML> <!DOCTYPE HTML>
<html> <html>
<head> <head>
@ -19,22 +18,32 @@
<meta name="viewport" content="user-scalable=no, initial-scale=1"> <meta name="viewport" content="user-scalable=no, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<?php if(isset($_GET['p'])) echo facebookHeader($_GET['p']); ?> <?php
if(isset($_GET['p'])) {
define("LYCHEE", true);
include("php/config.php");
include("php/functions.php");
echo facebookHeader($_GET['p']);
}
?>
</head> </head>
<body> <body>
<!-- Loading -->
<div id="loading"></div>
<!-- Header --> <!-- Header -->
<header> <header>
<!-- Buttons --> <!-- Buttons -->
<div class="tools" id="button_download" title="Download Photo"><a class="icon-download"></a></div> <div class="tools" id="button_download" title="Full Photo"><a class="icon-resize-full"></a></div>
<div class="tools" id="button_info" title="Show Info"><a class="icon-info-sign"></a></div> <div class="tools" id="button_info" title="Show Info"><a class="icon-info-sign"></a></div>
<a id="title"></a> <a id="title" class="view"></a>
</header> </header>
@ -46,7 +55,7 @@
<!-- JS --> <!-- JS -->
<script type="text/javascript" src="js/frameworks.js"></script> <script type="text/javascript" src="js/frameworks.js"></script>
<script type="text/javascript" src="js/build.js"></script> <script type="text/javascript" src="js/modules/build.js"></script>
<script type="text/javascript" src="js/view.js"></script> <script type="text/javascript" src="js/view.js"></script>

Loading…
Cancel
Save