- All new redefined interface - Faster animations and transitions - Import from Dropbox - Import from Server - Download public albums - Several sorting options - Installation assistent - Infobox and description for albums - Faster loading and improved performance - Better file handling and upload - Album covers are chosen intelligent - Prettier URLs - Massive changes under the hood - IPTC support (Headline and Caption) - EXIF Orientation support How to update: 1. Replace all files, excluding `uploads/` 2. Open Lychee and enter your database detailspull/56/head v2.0
@ -1,8 +1,8 @@
|
||||
; Uncomment these lines to change PHP parameters if you are using PHP with CGI or FastCGI. Only works with PHP starting from 5.3.0.
|
||||
; Note that with FastCGI, you might also want to set FcgidBusyTimeout, FcgidIOTimeout and FcgidMaxRequestLen in your Apache config
|
||||
|
||||
;max_execution_time = 60
|
||||
;post_max_size = 100M
|
||||
;upload_max_size = 100M
|
||||
;upload_max_filesize = 5M
|
||||
;max_file_uploads = 100
|
||||
;max_execution_time = 200
|
||||
;post_max_size = 200M
|
||||
;upload_max_size = 200M
|
||||
;upload_max_filesize = 20M
|
||||
;max_file_uploads = 200
|
||||
|
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @name reset.css
|
||||
*/
|
||||
|
||||
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; }
|
||||
body { line-height:1; }
|
||||
ol,ul { list-style:none; }
|
||||
blockquote,q { quotes:none; }
|
||||
blockquote:before,blockquote:after,q:before,q:after { content:''; content:none; }
|
||||
table { border-collapse:collapse; border-spacing:0; }
|
@ -0,0 +1,311 @@
|
||||
/**
|
||||
* @name animations.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
/* Animation Setter ------------------------------------------------*/
|
||||
.fadeIn {
|
||||
-webkit-animation-name: fadeIn;
|
||||
-webkit-animation-duration: .3s;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
-moz-animation-name: fadeIn;
|
||||
-moz-animation-duration: .3s;
|
||||
-moz-animation-fill-mode: forwards;
|
||||
animation-name: fadeIn;
|
||||
animation-duration: .3s;
|
||||
animation-fill-mode: forwards; }
|
||||
|
||||
.fadeOut {
|
||||
-webkit-animation-name: fadeOut;
|
||||
-webkit-animation-duration: .3s;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
-moz-animation-name: fadeOut;
|
||||
-moz-animation-duration: .3s;
|
||||
-moz-animation-fill-mode: forwards;
|
||||
animation-name: fadeOut;
|
||||
animation-duration: .3s;
|
||||
animation-fill-mode: forwards; }
|
||||
|
||||
.contentZoomIn {
|
||||
-webkit-animation-name: zoomIn;
|
||||
-webkit-animation-duration: .2s;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
-moz-animation-name: zoomIn;
|
||||
-moz-animation-duration: .2s;
|
||||
-moz-animation-fill-mode: forwards;
|
||||
animation-name: zoomIn;
|
||||
animation-duration: .2s;
|
||||
animation-fill-mode: forwards; }
|
||||
|
||||
.contentZoomOut {
|
||||
-webkit-animation-name: zoomOut;
|
||||
-webkit-animation-duration: .2s;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
-moz-animation-name: zoomOut;
|
||||
-moz-animation-duration: .2s;
|
||||
-moz-animation-fill-mode: forwards;
|
||||
animation-name: zoomOut;
|
||||
animation-duration: .2s;
|
||||
animation-fill-mode: forwards; }
|
||||
|
||||
/* moveUp ------------------------------------------------*/
|
||||
@-webkit-keyframes moveUp {
|
||||
0% {
|
||||
-webkit-transform: translateY(30px);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes moveUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes moveUp {
|
||||
0% {
|
||||
transform: translateY(30px);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* fadeIn ------------------------------------------------*/
|
||||
@-webkit-keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* fadeOut ------------------------------------------------*/
|
||||
@-webkit-keyframes fadeOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes fadeOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fadeOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* moveBackground ------------------------------------------------*/
|
||||
@-webkit-keyframes moveBackground {
|
||||
0% {
|
||||
background-position-x: 0px;
|
||||
}
|
||||
100% {
|
||||
background-position-x: -100px;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes moveBackground {
|
||||
0% {
|
||||
background-position-x: 0px;
|
||||
}
|
||||
100% {
|
||||
background-position-x: -100px;
|
||||
}
|
||||
}
|
||||
@keyframes moveBackground {
|
||||
0% {
|
||||
background-position-x: 0px;
|
||||
}
|
||||
100% {
|
||||
background-position-x: -100px;
|
||||
}
|
||||
}
|
||||
|
||||
/* zoomIn ------------------------------------------------*/
|
||||
@-webkit-keyframes zoomIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes zoomIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes zoomIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* zoomOut ------------------------------------------------*/
|
||||
@-webkit-keyframes zoomOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.8);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes zoomOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes zoomOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: scale(.8);
|
||||
}
|
||||
}
|
||||
|
||||
/* popIn ------------------------------------------------*/
|
||||
@-webkit-keyframes popIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes popIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-moz-transform: scale(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-moz-transform: scale(1);
|
||||
}
|
||||
}
|
||||
@keyframes popIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* pulse ------------------------------------------------*/
|
||||
@-webkit-keyframes pulse {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes pulse {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* rotate ------------------------------------------------
|
||||
@-webkit-keyframes rotate {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes rotate {
|
||||
0% {
|
||||
-moz-transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-moz-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
} */
|
@ -0,0 +1,256 @@
|
||||
/**
|
||||
* @name content.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
#content::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
background-image: -webkit-linear-gradient(top, #262626, #222);
|
||||
background-image: -moz-linear-gradient(top, #262626, #222);
|
||||
background-image: -ms-linear-gradient(top, #262626, #222);
|
||||
background-image: linear-gradient(top, #262626, #222);
|
||||
border-top: 1px solid #333;
|
||||
}
|
||||
|
||||
/* Modes ------------------------------------------------*/
|
||||
#content.view::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#content {
|
||||
position: absolute;
|
||||
padding: 50px 0px 33px 0px;
|
||||
width: 100%;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/* Photo ------------------------------------------------*/
|
||||
.photo {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
width: 206px;
|
||||
height: 206px;
|
||||
margin: 30px 0px 0px 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.photo img {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: #222;
|
||||
border-radius: 2px;
|
||||
border: 2px solid #ccc;
|
||||
}
|
||||
.photo:hover img,
|
||||
.photo.active img {
|
||||
box-shadow: 0px 0px 5px #005ecc;
|
||||
}
|
||||
.photo:active {
|
||||
-webkit-transition-duration: .1s;
|
||||
-webkit-transform: scale(.98);
|
||||
-moz-transition-duration: .1s;
|
||||
-moz-transform: scale(.98);
|
||||
transition-duration: .1s;
|
||||
transform: scale(.98);
|
||||
}
|
||||
|
||||
/* Album ------------------------------------------------*/
|
||||
.album {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
width: 204px;
|
||||
height: 204px;
|
||||
margin: 30px 0px 0px 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.album img:first-child,
|
||||
.album img:nth-child(2) {
|
||||
-webkit-transform: rotate(0deg) translateY(0px) translateX(0px);
|
||||
-moz-transform: rotate(0deg) translateY(0px) translateX(0px);
|
||||
transform: rotate(0deg) translateY(0px) translateX(0px);
|
||||
opacity: 0;
|
||||
}
|
||||
.album:hover img:first-child {
|
||||
-webkit-transform: rotate(-2deg) translateY(10px) translateX(-12px);
|
||||
-moz-transform: rotate(-2deg) translateY(10px) translateX(-12px);
|
||||
transform: rotate(-2deg) translateY(10px) translateX(-12px);
|
||||
opacity: 1;
|
||||
}
|
||||
.album:hover img:nth-child(2) {
|
||||
-webkit-transform: rotate(5deg) translateY(-8px) translateX(12px);
|
||||
-moz-transform: rotate(5deg) translateY(-8px) translateX(12px);
|
||||
transform: rotate(5deg) translateY(-8px) translateX(12px);
|
||||
opacity: 1;
|
||||
}
|
||||
.album img {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: #222;
|
||||
border-radius: 2px;
|
||||
border: 2px solid #ccc;
|
||||
}
|
||||
.album:hover img,
|
||||
.album.active img {
|
||||
box-shadow: 0px 0px 5px #005ecc;
|
||||
}
|
||||
|
||||
/* Album/Photo Overlay ------------------------------------------------*/
|
||||
.album .overlay,
|
||||
.photo .overlay {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin: 2px;
|
||||
}
|
||||
.album .overlay {
|
||||
background: -moz-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 20%, rgba(0,0,0,0.9) 100%); /* FF3.6+ */
|
||||
background: -webkit-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 20%,rgba(0,0,0,0.9) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -ms-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 20%,rgba(0,0,0,0.9) 100%); /* IE10+ */
|
||||
background: linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 20%,rgba(0,0,0,0.9) 100%); /* W3C */
|
||||
}
|
||||
.photo .overlay {
|
||||
background: rgba(0, 0, 0, .6);
|
||||
opacity: 0;
|
||||
}
|
||||
.photo:hover .overlay,
|
||||
.photo.active .overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
.album .overlay h1,
|
||||
.photo .overlay h1 {
|
||||
min-height: 19px;
|
||||
width: 190px;
|
||||
margin: 153px 0px 3px 15px;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
}
|
||||
.album .overlay a,
|
||||
.photo .overlay a {
|
||||
font-size: 11px;
|
||||
color: #aaa;
|
||||
}
|
||||
.album .overlay a {
|
||||
margin-left: 15px;
|
||||
}
|
||||
.photo .overlay a {
|
||||
margin: 155px 0px 5px 15px;
|
||||
}
|
||||
|
||||
/* Badges ------------------------------------------------*/
|
||||
.album .badge,
|
||||
.photo .badge {
|
||||
position: absolute;
|
||||
margin-top: -1px;
|
||||
margin-left: 12px;
|
||||
padding: 12px 7px 3px 7px;
|
||||
box-shadow: 0px 0px 3px #000;
|
||||
border-radius: 0px 0px 3px 3px;
|
||||
border: 1px solid #fff;
|
||||
border-top: none;
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
text-shadow: 0px 1px 0px #000;
|
||||
opacity: .9;
|
||||
}
|
||||
.album .badge.icon-star,
|
||||
.photo .badge.icon-star {
|
||||
padding: 12px 8px 3px 8px;
|
||||
}
|
||||
.album .badge.icon-share,
|
||||
.photo .badge.icon-share {
|
||||
padding: 12px 6px 3px 8px;
|
||||
}
|
||||
.album .badge::after,
|
||||
.photo .badge::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
margin-top: -12px;
|
||||
margin-left: -26px;
|
||||
width: 38px;
|
||||
height: 5px;
|
||||
background: -moz-linear-gradient(top, rgba(0,0,0,1) 0%, rgba(0,0,0,0) 100%); /* FF3.6+ */
|
||||
background: -webkit-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(0,0,0,0) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -ms-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(0,0,0,0) 100%); /* IE10+ */
|
||||
background: linear-gradient(top, rgba(0,0,0,1) 0%,rgba(0,0,0,0) 100%); /* W3C */
|
||||
opacity: .4;
|
||||
}
|
||||
.album .badge.icon-star::after,
|
||||
.photo .badge.icon-star::after {
|
||||
margin-left: -29px;
|
||||
}
|
||||
.album .badge.icon-share::after,
|
||||
.photo .badge.icon-share::after {
|
||||
margin-left: -31px;
|
||||
}
|
||||
.album .badge.icon-reorder::after {
|
||||
margin-left: -30px;
|
||||
}
|
||||
.album .badge:nth-child(2n),
|
||||
.photo .badge:nth-child(2n) {
|
||||
margin-left: 57px;
|
||||
}
|
||||
.album .badge.red,
|
||||
.photo .badge.red {
|
||||
background: #d64b4b;
|
||||
background: -webkit-linear-gradient(top, #d64b4b, #ab2c2c);
|
||||
background: -moz-linear-gradient(top, #d64b4b, #ab2c2c);
|
||||
background: -ms-linear-gradient(top, #d64b4b, #ab2c2c);
|
||||
}
|
||||
.album .badge.blue,
|
||||
.photo .badge.blue {
|
||||
background: #d64b4b;
|
||||
background: -webkit-linear-gradient(top, #347cd6, #2945ab);
|
||||
background: -moz-linear-gradient(top, #347cd6, #2945ab);
|
||||
background: -ms-linear-gradient(top, #347cd6, #2945ab);
|
||||
}
|
||||
|
||||
/* Divider ------------------------------------------------*/
|
||||
.divider {
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-top: 50px;
|
||||
opacity: 0;
|
||||
border-top: 1px solid #2E2E2E;
|
||||
box-shadow: 0px -1px 0px #151515;
|
||||
}
|
||||
.divider:first-child {
|
||||
margin-top: 0px;
|
||||
border-top: none;
|
||||
}
|
||||
.divider h1 {
|
||||
float: left;
|
||||
margin: 20px 0px 0px 30px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0px -1px 0px #000;
|
||||
}
|
||||
|
||||
/* No Content ------------------------------------------------*/
|
||||
.no_content {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
height: 160px;
|
||||
width: 180px;
|
||||
margin-top: -80px;
|
||||
margin-left: -90px;
|
||||
padding-top: 20px;
|
||||
color: rgba(20, 20, 20, 1);
|
||||
text-shadow: 0px 1px 0px rgba(255, 255, 255, .05);
|
||||
text-align: center;
|
||||
}
|
||||
.no_content .icon {
|
||||
font-size: 120px;
|
||||
}
|
||||
.no_content p {
|
||||
font-size: 18px;
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @name contextmenu.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
.contextmenu_bg {
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
}
|
||||
.contextmenu {
|
||||
position: fixed;
|
||||
top: 110%;
|
||||
left: 110%;
|
||||
padding: 5px 0px 6px 0px;
|
||||
background-color: #393939;
|
||||
background-image: -webkit-linear-gradient(top, #444, #2d2d2d);
|
||||
background-image: -moz-linear-gradient(top, #393939, #2d2d2d);
|
||||
background-image: -ms-linear-gradient(top, #393939, #2d2d2d);
|
||||
background-image: linear-gradient(top, #393939, #2d2d2d);
|
||||
border: 1px solid rgba(0,0,0,0.7);
|
||||
border-bottom: 1px solid rgba(0,0,0,.9);
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 4px 5px rgba(0,0,0,0.3), inset 0px 1px 0px rgba(255,255,255,0.15), inset 1px 0px 0px rgba(255,255,255,0.05), inset -1px 0px 0px rgba(255,255,255,0.05);
|
||||
opacity: .98;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
/* Items ------------------------------------------------*/
|
||||
.contextmenu tr {
|
||||
font-size: 14px;
|
||||
color: #eee;
|
||||
text-shadow: 0px -1px 0px rgba(0,0,0,.6);
|
||||
cursor: pointer;
|
||||
}
|
||||
.contextmenu tr:hover {
|
||||
background-color: #6a84f2;
|
||||
background-image: -webkit-linear-gradient(top, #6a84f2, #3959ef);
|
||||
background-image: -moz-linear-gradient(top, #6a84f2, #3959ef);
|
||||
background-image: -ms-linear-gradient(top, #6a84f2, #3959ef);
|
||||
background-image: linear-gradient(top, #6a84f2, #3959ef);
|
||||
}
|
||||
.contextmenu tr.no_hover:hover {
|
||||
cursor: inherit;
|
||||
background-color: inherit;
|
||||
background-image: none;
|
||||
}
|
||||
.contextmenu tr.separator {
|
||||
float: left;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background-color: #1c1c1c;
|
||||
border-bottom: 1px solid #4a4a4a;
|
||||
margin: 5px 0px;
|
||||
cursor: inherit;
|
||||
}
|
||||
.contextmenu tr.separator:hover {
|
||||
background-color: #222;
|
||||
background-image: none;
|
||||
}
|
||||
.contextmenu tr td {
|
||||
padding: 7px 30px 6px 12px;
|
||||
white-space: nowrap;
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
.contextmenu tr:hover td {
|
||||
color: #fff;
|
||||
box-shadow: inset 0px 1px 0px rgba(255,255,255,.05);
|
||||
text-shadow: 0px -1px 0px rgba(0,0,0,.4);
|
||||
}
|
||||
.contextmenu tr.no_hover:hover td {
|
||||
box-shadow: none;
|
||||
}
|
||||
.contextmenu tr a {
|
||||
float: left;
|
||||
width: 10px;
|
||||
margin-right: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Direct Link Input ------------------------------------------------*/
|
||||
.contextmenu #link {
|
||||
float: right;
|
||||
width: 140px;
|
||||
margin: 0px -17px -1px 0px;
|
||||
padding: 4px 6px 5px 6px;
|
||||
background-color: #444;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border: 1px solid #111;
|
||||
box-shadow: 0px 1px 0px rgba(255,255,255,.1);
|
||||
outline: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.contextmenu tr a#link_icon {
|
||||
padding-top: 4px;
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
/**
|
||||
* @name _header.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
header {
|
||||
position: fixed;
|
||||
height: 49px;
|
||||
width: 100%;
|
||||
background-image: -webkit-linear-gradient(top, #3E3E3E, #282828);
|
||||
background-image: -moz-linear-gradient(top, #3E3E3E, #282828);
|
||||
background-image: -ms-linear-gradient(top, #3E3E3E, #282828);
|
||||
background-image: linear-gradient(top, #3E3E3E, #282828);
|
||||
border-bottom: 1px solid #161616;
|
||||
z-index: 1;
|
||||
|
||||
-webkit-transition: -webkit-transform .3s ease-out;
|
||||
-moz-transition: -moz-transform .3s ease-out;
|
||||
transition: transform .3s ease-out;
|
||||
}
|
||||
|
||||
/* Modes ------------------------------------------------*/
|
||||
header.hidden {
|
||||
-webkit-transform: translateY(-60px);
|
||||
-moz-transform: translateY(-60px);
|
||||
transform: translateY(-60px);
|
||||
}
|
||||
header.loading {
|
||||
-webkit-transform: translateY(2px);
|
||||
-moz-transform: translateY(2px);
|
||||
transform: translateY(2px);
|
||||
}
|
||||
header.error {
|
||||
-webkit-transform: translateY(40px);
|
||||
-moz-transform: translateY(40px);
|
||||
transform: translateY(40px);
|
||||
}
|
||||
header.view.error {
|
||||
background-color: rgba(10,10,10,.99);
|
||||
}
|
||||
header.view {
|
||||
background-image: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
header.view .button,
|
||||
header.view #title,
|
||||
header.view .tools {
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
/* Title ------------------------------------------------*/
|
||||
header #title {
|
||||
position: absolute;
|
||||
margin: 0px 30%;
|
||||
width: 40%;
|
||||
padding: 15px 0px;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
}
|
||||
header #title.editable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Button ------------------------------------------------*/
|
||||
header .button {
|
||||
color: #888;
|
||||
font-family: 'FontAwesome';
|
||||
font-size: 21px;
|
||||
font-weight: bold;
|
||||
text-decoration: none !important;
|
||||
cursor: pointer;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
}
|
||||
header .button.left {
|
||||
float: left;
|
||||
position: absolute;
|
||||
padding: 16px 10px 8px 18px;
|
||||
}
|
||||
header .button.right {
|
||||
float: right;
|
||||
position: relative;
|
||||
padding: 16px 19px 13px 11px;
|
||||
}
|
||||
header .button:hover {
|
||||
color: #fff;
|
||||
}
|
||||
header #tools_albums,
|
||||
header #tools_album,
|
||||
header #tools_photo,
|
||||
header #button_signin {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Button Divider ------------------------------------------------*/
|
||||
header .button_divider {
|
||||
float: right;
|
||||
position: relative;
|
||||
width: 14px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
/* Search ------------------------------------------------*/
|
||||
header #search {
|
||||
float: right;
|
||||
width: 80px;
|
||||
margin: 12px 12px 0px 0px;
|
||||
padding: 5px 12px 6px 12px;
|
||||
background-color: #383838;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border: 1px solid #131313;
|
||||
box-shadow: 0px 1px 0px rgba(255,255,255,.1);
|
||||
outline: none;
|
||||
border-radius: 50px;
|
||||
opacity: .6;
|
||||
|
||||
-webkit-transition: opacity .3s ease-out, -webkit-transform .3s ease-out, box-shadow .3s, width .2s ease-out;
|
||||
-moz-transition: opacity .3s ease-out, -moz-transform .3s ease-out, box-shadow .3s, width .2s ease-out;
|
||||
transition: opacity .3s ease-out, transform .3s ease-out, box-shadow .3s, width .2s ease-out;
|
||||
}
|
||||
header #search:focus {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
/* Tools ------------------------------------------------*/
|
||||
header .tools:first-of-type {
|
||||
margin-right: 6px;
|
||||
}
|
||||
header .tools {
|
||||
float: right;
|
||||
padding: 14px 8px;
|
||||
color: #888;
|
||||
font-size: 21px;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
cursor: pointer;
|
||||
}
|
||||
header .tools:hover a {
|
||||
color: #fff;
|
||||
}
|
||||
header .tools .icon-star {
|
||||
color: #f0ef77;
|
||||
}
|
||||
header .tools .icon-share.active {
|
||||
color: #ff9737;
|
||||
}
|
||||
|
||||
/* Hosted with Lychee ------------------------------------------------*/
|
||||
header #hostedwith {
|
||||
float: right;
|
||||
padding: 5px 10px;
|
||||
margin: 13px 9px;
|
||||
color: #888;
|
||||
font-size: 13px;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
header #hostedwith:hover {
|
||||
background-color: rgba(0, 0, 0, .2);
|
||||
border-radius: 100px;
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @name imageview.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
#imageview {
|
||||
position: fixed;
|
||||
display: none;
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
background-color: rgba(10,10,10,.99);
|
||||
|
||||
-webkit-transition: background-color .3s;
|
||||
}
|
||||
|
||||
/* Modes ------------------------------------------------*/
|
||||
#imageview.view {
|
||||
background-color: inherit;
|
||||
}
|
||||
#imageview.full {
|
||||
background-color: #040404;
|
||||
}
|
||||
|
||||
/* ImageView ------------------------------------------------*/
|
||||
#imageview #image {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
right: 30px;
|
||||
bottom: 30px;
|
||||
left: 30px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% 50%;
|
||||
background-size: contain;
|
||||
|
||||
-webkit-transition: top .3s, bottom .3s, margin-top .3s;
|
||||
|
||||
-webkit-animation-name: zoomIn;
|
||||
-webkit-animation-duration: .3s;
|
||||
-moz-animation-name: zoomIn;
|
||||
-moz-animation-duration: .3s;
|
||||
animation-name: zoomIn;
|
||||
animation-duration: .3s;
|
||||
}
|
||||
#imageview #image.small {
|
||||
top: 50%;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
/* Previous/Next Buttons ------------------------------------------------*/
|
||||
#imageview .arrow_wrapper {
|
||||
position: fixed;
|
||||
width: 20%;
|
||||
height: calc(100% - 60px);
|
||||
top: 60px;
|
||||
z-index: 1;
|
||||
}
|
||||
#imageview .arrow_wrapper.previous {
|
||||
left: 0;
|
||||
}
|
||||
#imageview .arrow_wrapper.next {
|
||||
right: 0;
|
||||
}
|
||||
#imageview .arrow_wrapper a {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
margin-top: -10px;
|
||||
color: #fff;
|
||||
font-size: 50px;
|
||||
text-shadow: 0px 1px 2px #000;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
z-index: 2;
|
||||
-webkit-transition: opacity .2s;
|
||||
-moz-transition: opacity .2s;
|
||||
transition: opacity .2s;
|
||||
}
|
||||
#imageview .arrow_wrapper:hover a {
|
||||
opacity: .2;
|
||||
}
|
||||
#imageview .arrow_wrapper a#previous {
|
||||
left: 20px;
|
||||
}
|
||||
#imageview .arrow_wrapper a#next {
|
||||
right: 20px;
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
/**
|
||||
* @name infobox.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
#infobox_overlay {
|
||||
z-index: 3;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
background-color: rgba(0,0,0,.85);
|
||||
}
|
||||
#infobox {
|
||||
z-index: 4;
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
background-color: rgba(20,20,20,0.98);
|
||||
box-shadow: -1px 0px 2px rgba(0,0,0,.8);
|
||||
display: none;
|
||||
|
||||
-webkit-transform: translateX(320px);
|
||||
-moz-transform: translateX(320px);
|
||||
transform: translateX(320px);
|
||||
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
user-select: text;
|
||||
|
||||
-webkit-transition: -webkit-transform .5s cubic-bezier(.225,.5,.165,1);
|
||||
-moz-transition: -moz-transform .5s cubic-bezier(.225,.5,.165,1);
|
||||
transition: transform .5s cubic-bezier(.225,.5,.165,1);
|
||||
}
|
||||
#infobox.active {
|
||||
-webkit-transform: translateX(0px);
|
||||
-moz-transform: translateX(0px);
|
||||
transform: translateX(0px);
|
||||
}
|
||||
|
||||
/* Misc ------------------------------------------------*/
|
||||
#infobox .wrapper {
|
||||
float: left;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
#infobox .edit {
|
||||
display: inline;
|
||||
margin-left: 3px;
|
||||
width: 20px;
|
||||
height: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
#infobox .bumper {
|
||||
float: left;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
/* Header ------------------------------------------------*/
|
||||
#infobox .header {
|
||||
float: left;
|
||||
height: 49px;
|
||||
width: 100%;
|
||||
background-color: #1d1d1d;
|
||||
background-image: -webkit-linear-gradient(top, #2A2A2A, #131313);
|
||||
background-image: -moz-linear-gradient(top, #2A2A2A, #131313);
|
||||
background-image: -ms-linear-gradient(top, #2A2A2A, #131313);
|
||||
background-image: linear-gradient(top, #2A2A2A, #131313);
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
#infobox .header h1 {
|
||||
position: absolute;
|
||||
margin: 15px 30%;
|
||||
width: 40%;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
text-shadow: 0px -1px 0px #000;
|
||||
}
|
||||
#infobox .header a {
|
||||
float: right;
|
||||
padding: 15px 15px;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0px -1px 0px #000;
|
||||
opacity: .5;
|
||||
cursor: pointer;
|
||||
}
|
||||
#infobox .header a:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Seperator ------------------------------------------------*/
|
||||
#infobox .separator {
|
||||
float: left;
|
||||
width: 100%;
|
||||
border-top: 1px solid rgba(255,255,255,.04);
|
||||
box-shadow: 0px -1px 0px #000;
|
||||
}
|
||||
#infobox .separator h1 {
|
||||
margin: 20px 0px 5px 20px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0px -1px 0px #000;
|
||||
}
|
||||
|
||||
/* Table ------------------------------------------------*/
|
||||
#infobox table {
|
||||
float: left;
|
||||
margin: 10px 0px 15px 20px;
|
||||
}
|
||||
#infobox table tr td {
|
||||
padding: 5px 0px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
line-height: 19px;
|
||||
}
|
||||
#infobox table tr td:first-child {
|
||||
width: 110px;
|
||||
}
|
||||
#infobox table tr td:last-child {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* Tags ------------------------------------------------*/
|
||||
#infobox #tags {
|
||||
margin: 20px 20px 15px 20px;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
}
|
||||
#infobox .tag {
|
||||
float: left;
|
||||
padding: 4px 7px;
|
||||
margin: 0px 6px 8px 0px;
|
||||
background-color: rgba(0,0,0,.5);
|
||||
border: 2px solid rgba(255,255,255,.3);
|
||||
border-radius: 100px;
|
||||
font-size: 12px;
|
||||
-webkit-transition: border .3s;
|
||||
-moz-transition: border .3s;
|
||||
transition: border .3s;
|
||||
}
|
||||
#infobox .tag:hover {
|
||||
border: 2px solid #aaa;
|
||||
}
|
||||
#infobox .tag span {
|
||||
float: right;
|
||||
width: 0px;
|
||||
padding: 0px;
|
||||
margin: 0px 0px -2px 0px;
|
||||
color: red;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
-webkit-transition: width .3s, margin .3s, -webkit-transform .3s;
|
||||
-moz-transition: width .3s, margin .3s;
|
||||
transition: width .3s, margin .3s, transform .3s;
|
||||
}
|
||||
#infobox .tag:hover span {
|
||||
width: 10px;
|
||||
margin: 0px 0px -2px 6px;
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @name loading.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
#loading {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background-size: 100px 3px;
|
||||
background-repeat: repeat-x;
|
||||
border-bottom: 1px solid rgba(0,0,0,.3);
|
||||
display: none;
|
||||
|
||||
/* Animation */
|
||||
-webkit-animation-name: moveBackground;
|
||||
-webkit-animation-duration: .3s;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
-webkit-animation-timing-function: linear;
|
||||
-moz-animation-name: moveBackground;
|
||||
-moz-animation-duration: .3s;
|
||||
-moz-animation-iteration-count: infinite;
|
||||
-moz-animation-timing-function: linear;
|
||||
animation-name: moveBackground;
|
||||
animation-duration: .3s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: linear;
|
||||
}
|
||||
|
||||
/* Modes ------------------------------------------------*/
|
||||
#loading.loading {
|
||||
background-image: -webkit-linear-gradient(left, #153674 0%, #153674 47%, #2651AE 53%, #2651AE 100%);
|
||||
background-image: -moz-linear-gradient(left, #153674 0%, #153674 47%, #2651AE 53%, #2651AE 100%);
|
||||
background-image: linear-gradient(left right, #153674 0%, #153674 47%, #2651AE 53%, #2651AE 100%);
|
||||
z-index: 2;
|
||||
}
|
||||
#loading.error {
|
||||
background-color: #2f0d0e;
|
||||
background-image: -webkit-linear-gradient(left, #451317 0%, #451317 47%, #AA3039 53%, #AA3039 100%);
|
||||
background-image: -moz-linear-gradient(left, #451317 0%, #451317 47%, #AA3039 53%, #AA3039 100%);
|
||||
background-image: linear-gradient(left right, #451317 0%, #451317 47%, #AA3039 53%, #AA3039 100%);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Content ------------------------------------------------*/
|
||||
#loading h1 {
|
||||
margin: 13px;
|
||||
color: #ddd;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0px 1px 0px #000;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
#loading h1 span {
|
||||
margin-left: 10px;
|
||||
font-weight: normal;
|
||||
text-transform: none;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @name mediaquery.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
@media only screen and (max-width: 900px) {
|
||||
|
||||
#title {
|
||||
margin: 0px 20% !important;
|
||||
width: 40% !important;
|
||||
}
|
||||
#title.view {
|
||||
margin: 0px 20% !important;
|
||||
width: 60% !important;
|
||||
}
|
||||
#title span {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
}
|
||||
@media only screen and (max-width: 640px) {
|
||||
|
||||
#title {
|
||||
display: none !important;
|
||||
}
|
||||
#title.view {
|
||||
display: block !important;
|
||||
width: 70% !important;
|
||||
margin: 0px 20% 0px 10% !important;
|
||||
}
|
||||
#button_move {
|
||||
display: none !important;
|
||||
}
|
||||
#button_archive {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.center {
|
||||
top: 0px !important;
|
||||
left: 0px !important;
|
||||
}
|
||||
|
||||
.album, .photo {
|
||||
margin: 40px 0px 0px 50px !important;
|
||||
}
|
||||
|
||||
.message {
|
||||
position: fixed !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
margin: 1px 0px 0px 0px !important;
|
||||
border-radius: 0px !important;
|
||||
|
||||
/* Animation */
|
||||
-webkit-animation: moveUp .3s !important;
|
||||
-moz-animation: moveUp .3s !important;
|
||||
animation: moveUp .3s !important;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
/**
|
||||
* @name message.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
.message_overlay {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
background-color: rgba(0,0,0,.85);
|
||||
z-index: 1000;
|
||||
}
|
||||
.message {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
width: 500px;
|
||||
margin-left: -250px;
|
||||
margin-top: -95px;
|
||||
background-color: #444;
|
||||
background-image: -webkit-linear-gradient(top, rgb(75, 75, 75), rgb(45, 45, 45));
|
||||
background-image: -moz-linear-gradient(top, rgb(75, 75, 75), rgb(45, 45, 45));
|
||||
background-image: -ms-linear-gradient(top, rgb(75, 75, 75), rgb(45, 45, 45));
|
||||
background-image: linear-gradient(top, rgb(75, 75, 75), rgb(45, 45, 45));
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 0px 5px #000, inset 0px 1px 0px rgba(255,255,255,.08), inset 1px 0px 0px rgba(255,255,255,.03), inset -1px 0px 0px rgba(255,255,255,.03);
|
||||
|
||||
/* Animation */
|
||||
-webkit-animation-name: moveUp;
|
||||
-webkit-animation-duration: .3s;
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
-moz-animation-name: moveUp;
|
||||
-moz-animation-duration: .3s;
|
||||
-moz-animation-timing-function: ease-out;
|
||||
animation-name: moveUp;
|
||||
animation-duration: .3s;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
|
||||
/* Header ------------------------------------------------*/
|
||||
.message h1 {
|
||||
float: left;
|
||||
width: 100%;
|
||||
padding: 12px 0px;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
text-align: center;
|
||||
}
|
||||
.message .close {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
padding: 12px 14px 6px 7px;
|
||||
color: #aaa;
|
||||
font-size: 20px;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
cursor: pointer;
|
||||
}
|
||||
.message .close:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Text ------------------------------------------------*/
|
||||
.message p {
|
||||
float: left;
|
||||
width: 90%;
|
||||
margin-top: 1px;
|
||||
padding: 12px 5% 15px 5%;
|
||||
color: #eee;
|
||||
font-size: 14px;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
line-height: 20px;
|
||||
}
|
||||
.message p b {
|
||||
font-weight: bold;
|
||||
}
|
||||
.message p a {
|
||||
color: #eee;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dashed #888;
|
||||
}
|
||||
|
||||
/* Button ------------------------------------------------*/
|
||||
.message .button {
|
||||
float: right;
|
||||
margin: 15px 15px 15px 0px;
|
||||
padding: 6px 10px 8px 10px;
|
||||
background-color: #4e4e4e;
|
||||
background-image: -webkit-linear-gradient(top, rgb(60, 60, 60), rgb(45, 45, 45));
|
||||
background-image: -moz-linear-gradient(top, rgb(60, 60, 60), rgb(45, 45, 45));
|
||||
background-image: -ms-linear-gradient(top, rgb(60, 60, 60), rgb(45, 45, 45));
|
||||
background-image: linear-gradient(top, rgb(60, 60, 60), rgb(45, 45, 45));
|
||||
color: #ccc;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #191919;
|
||||
box-shadow: inset 0px 1px 0px rgba(255,255,255,.1), 0px 1px 0px rgba(255,255,255,.1);
|
||||
cursor: pointer;
|
||||
}
|
||||
.message .button:first-of-type {
|
||||
margin: 15px 5% 18px 0px !important;
|
||||
}
|
||||
.message .button.active {
|
||||
color: #fff;
|
||||
box-shadow: inset 0px 1px 0px rgba(255,255,255,.1), 0px 1px 0px rgba(255,255,255,.1), 0px 0px 4px #005ecc;
|
||||
}
|
||||
.message .button:hover {
|
||||
background-color: #565757;
|
||||
background-image: -webkit-linear-gradient(top, rgb(80, 80, 80), rgb(57, 57, 57));
|
||||
background-image: -moz-linear-gradient(top, rgb(80, 80, 80), rgb(57, 57, 57));
|
||||
background-image: -ms-linear-gradient(top, rgb(80, 80, 80), rgb(57, 57, 57));
|
||||
background-image: linear-gradient(top, rgb(80, 80, 80), rgb(57, 57, 57));
|
||||
}
|
||||
.message .button:active,
|
||||
.message .button.pressed {
|
||||
background-color: #393939;
|
||||
background-image: -webkit-linear-gradient(top, rgb(57, 57, 57), rgb(70, 70, 70));
|
||||
background-image: -moz-linear-gradient(top, rgb(57, 57, 57), rgb(70, 70, 70));
|
||||
background-image: -ms-linear-gradient(top, rgb(57, 57, 57), rgb(70, 70, 70));
|
||||
background-image: linear-gradient(top, rgb(57, 57, 57), rgb(70, 70, 70));
|
||||
}
|
||||
|
||||
/* Sign in ------------------------------------------------*/
|
||||
.sign_in {
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-top: 1px;
|
||||
padding: 5px 0px;
|
||||
color: #eee;
|
||||
font-size: 14px;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
line-height: 20px;
|
||||
}
|
||||
.sign_in input {
|
||||
float: left;
|
||||
width: 88%;
|
||||
padding: 7px 1% 9px 1%;
|
||||
margin: 0px 5%;
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
border: none;
|
||||
border-bottom: 1px solid #222;
|
||||
box-shadow: 0px 1px 0px rgba(255,255,255,.1);
|
||||
border-radius: 0px;
|
||||
outline: none;
|
||||
}
|
||||
.sign_in input:first-of-type {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.sign_in input.error:focus {
|
||||
box-shadow: 0px 1px 0px rgba(204, 0, 7, 0.6);
|
||||
}
|
||||
.message #version {
|
||||
display: inline-block;
|
||||
margin-top: 23px;
|
||||
margin-left: 5%;
|
||||
color: #888;
|
||||
text-shadow: 0px -1px 0px #111;
|
||||
}
|
||||
.message #version span {
|
||||
display: none;
|
||||
}
|
||||
.message #version span a {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
/* Input Misc ------------------------------------------------*/
|
||||
.message input.text {
|
||||
float: left;
|
||||
width: calc(100% - 10px);
|
||||
padding: 17px 5px 9px 5px;
|
||||
margin-top: 10px;
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
text-shadow: 0px -1px 0px #222;
|
||||
border: none;
|
||||
box-shadow: 0px 1px 0px rgba(255,255,255,.1);
|
||||
border-bottom: 1px solid #222;
|
||||
border-radius: 0px;
|
||||
outline: none;
|
||||
}
|
||||
.message input.less {
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
.message input.more {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.message .copylink {
|
||||
margin-bottom: 20px;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @name misc.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
html,
|
||||
body {
|
||||
min-height: 100%;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
body {
|
||||
background-color: #222;
|
||||
font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-smoothing: antialiased;
|
||||
}
|
||||
body.view {
|
||||
background-color: #0f0f0f;
|
||||
}
|
||||
.center {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top:50%;
|
||||
}
|
||||
* {
|
||||
-webkit-transition: color .3s, opacity .3s ease-out, -webkit-transform .3s ease-out, box-shadow .3s;
|
||||
-moz-transition: opacity .3s ease-out, -moz-transform .3s ease-out, box-shadow .3s;
|
||||
transition: color .3s, opacity .3s ease-out, transform .3s ease-out, box-shadow .3s;
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @name tooltip.css
|
||||
*/
|
||||
|
||||
.tipsy {
|
||||
padding: 4px;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
z-index: 100000;
|
||||
|
||||
/* Animation */
|
||||
-webkit-animation-name: fadeIn;
|
||||
-webkit-animation-duration: .3s;
|
||||
-moz-animation-name: fadeIn;
|
||||
-moz-animation-duration: .3s;
|
||||
animation-name: fadeIn;
|
||||
animation-duration: .3s;
|
||||
}
|
||||
.tipsy-inner {
|
||||
padding: 8px 10px 7px;
|
||||
color: #fff;
|
||||
max-width: 200px;
|
||||
text-align: center;
|
||||
background: rgba(0, 0, 0, .8);
|
||||
border-radius: 25px;
|
||||
}
|
||||
.tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed rgba(0, 0, 0, .8); }
|
||||
.tipsy-arrow-n { border-bottom-color: rgba(0, 0, 0, .8); }
|
||||
.tipsy-arrow-s { border-top-color: rgba(0, 0, 0, .8); }
|
||||
.tipsy-arrow-e { border-left-color: rgba(0, 0, 0, .8); }
|
||||
.tipsy-arrow-w { border-right-color: rgba(0, 0, 0, .8); }
|
||||
.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
|
||||
.tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
|
||||
.tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-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; }
|
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* @name upload.css
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
#upload {
|
||||
display: none;
|
||||
}
|
||||
.upload_overlay {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
background-color: rgba(0,0,0,.85);
|
||||
z-index: 1000;
|
||||
}
|
||||
.upload_message {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
margin-left: -100px;
|
||||
margin-top: -85px;
|
||||
background-color: #444;
|
||||
background-image: -webkit-linear-gradient(top, rgb(75, 75, 75), rgb(45, 45, 45));
|
||||
background-image: -moz-linear-gradient(top, rgb(75, 75, 75), rgb(45, 45, 45));
|
||||
background-image: -ms-linear-gradient(top, rgb(75, 75, 75), rgb(45, 45, 45));
|
||||
background-image: linear-gradient(top, rgb(75, 75, 75), rgb(45, 45, 45));
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 0px 5px #000, inset 0px 1px 0px rgba(255,255,255,.08), inset 1px 0px 0px rgba(255,255,255,.03), inset -1px 0px 0px rgba(255,255,255,.03);
|
||||
|
||||
/* Animation */
|
||||
-webkit-animation-name: moveUp;
|
||||
-webkit-animation-duration: .3s;
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
-moz-animation-name: moveUp;
|
||||
-moz-animation-duration: .3s;
|
||||
-moz-animation-timing-function: ease-out;
|
||||
animation-name: moveUp;
|
||||
animation-duration: .3s;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
|
||||
/* Icon ------------------------------------------------*/
|
||||
.upload_message a {
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin: 35px 0px 5px 0px;
|
||||
color: #fff;
|
||||
font-size: 70px;
|
||||
text-shadow: 0px 1px 2px rgba(0,0,0,.5);
|
||||
text-align: center;
|
||||
|
||||
-webkit-animation-name: pulse;
|
||||
-webkit-animation-duration: 2s;
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
-moz-animation-name: pulse;
|
||||
-moz-animation-duration: 2s;
|
||||
-moz-animation-timing-function: ease-in-out;
|
||||
-moz-animation-iteration-count: infinite;
|
||||
animation-name: pulse;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
/* Text ------------------------------------------------*/
|
||||
.upload_message p {
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin: 10px 0px 35px 0px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
text-shadow: 0px -1px 0px rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
/* Progress ------------------------------------------------*/
|
||||
.upload_message .progressbar {
|
||||
float: left;
|
||||
width: 170px;
|
||||
height: 25px;
|
||||
margin: 15px;
|
||||
background-size: 50px 25px;
|
||||
background-repeat: repeat-x;
|
||||
background-image: -webkit-linear-gradient(left, #191919 0%, #191919 47%, #1D1D1D 53%, #1D1D1D 100%);
|
||||
background-image: -moz-linear-gradient(left, #191919 0%, #191919 47%, #1D1D1D 53%, #1D1D1D 100%);
|
||||
background-image: linear-gradient(left right, #191919 0%, #191919 47%, #1D1D1D 53%, #1D1D1D 100%);
|
||||
border: 1px solid #090909;
|
||||
box-shadow: 0 1px 0 rgba(255,255,255,.06), inset 0px 0px 2px #222;
|
||||
border-radius: 50px;
|
||||
|
||||
/* Animation */
|
||||
-webkit-animation-name: moveBackground;
|
||||
-webkit-animation-duration: 1s;
|
||||
-webkit-animation-timing-function: linear;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
-moz-animation-name: moveBackground;
|
||||
-moz-animation-duration: 1s;
|
||||
-moz-animation-timing-function: linear;
|
||||
-moz-animation-iteration-count: infinite;
|
||||
animation-name: moveBackground;
|
||||
animation-duration: 1s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
.upload_message .progressbar div {
|
||||
float: left;
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
box-shadow: 0 1px 0 #000, 1px 0px 2px #000;
|
||||
background-color: #f5f2f7;
|
||||
background-image: -webkit-linear-gradient(top, #f5f2f7, #c7c6c8);
|
||||
background-image: -moz-linear-gradient(top, #f5f2f7, #c7c6c8);
|
||||
background-image: -ms-linear-gradient(top, #f5f2f7, #c7c6c8);
|
||||
background-image: linear-gradient(top, #f5f2f7, #c7c6c8);
|
||||
border-radius: 50px;
|
||||
-webkit-transition: width .2s, opacity .5;
|
||||
-moz-transition: width .2s, opacity .5;
|
||||
transition: width .2s, opacity .5;
|
||||
}
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 662 B |
@ -0,0 +1,410 @@
|
||||
/**
|
||||
* @name Build Module
|
||||
* @description This module is used to generate HTML-Code.
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
build = {
|
||||
|
||||
divider: function(title) {
|
||||
|
||||
return "<div class='divider fadeIn'><h1>" + title + "</h1></div>";
|
||||
|
||||
},
|
||||
|
||||
editIcon: function(id) {
|
||||
|
||||
return "<div id='" + id + "' class='edit'><a class='icon-pencil'></a></div>";
|
||||
|
||||
},
|
||||
|
||||
album: function(albumJSON) {
|
||||
|
||||
if (!albumJSON) return "";
|
||||
|
||||
var album = "",
|
||||
title = albumJSON.title;
|
||||
|
||||
if (title.length>18) title = albumJSON.title.substr(0, 18) + "...";
|
||||
|
||||
album += "<div class='album' data-id='" + albumJSON.id + "' data-password='" + albumJSON.password + "'>";
|
||||
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'>";
|
||||
|
||||
if (albumJSON.password&&!lychee.publicMode) album += "<h1><span class='icon-lock'></span> " + title + "</h1>";
|
||||
else album += "<h1>" + title + "</h1>";
|
||||
|
||||
album += "<a>" + albumJSON.sysdate + "</a>";
|
||||
album += "</div>";
|
||||
|
||||
if(!lychee.publicMode&&albumJSON.star==1) album += "<a class='badge red icon-star'></a>";
|
||||
if(!lychee.publicMode&&albumJSON.public==1) album += "<a class='badge red icon-share'></a>";
|
||||
if(!lychee.publicMode&&albumJSON.unsorted==1) album += "<a class='badge red icon-reorder'></a>";
|
||||
|
||||
album += "</div>";
|
||||
|
||||
return album;
|
||||
|
||||
},
|
||||
|
||||
photo: function(photoJSON) {
|
||||
|
||||
if (!photoJSON) return "";
|
||||
|
||||
var photo = "",
|
||||
title = photoJSON.title;
|
||||
|
||||
if (title.length>18) title = photoJSON.title.substr(0, 18) + "...";
|
||||
|
||||
photo += "<div class='photo' data-album-id='" + photoJSON.album + "' data-id='" + photoJSON.id + "'>";
|
||||
photo += "<img src='" + photoJSON.thumbUrl + "' width='200' height='200' alt='thumb'>";
|
||||
photo += "<div class='overlay'>";
|
||||
photo += "<h1>" + title + "</h1>";
|
||||
photo += "<a>" + photoJSON.sysdate + "</a>";
|
||||
photo += "</div>";
|
||||
|
||||
if (photoJSON.star==1) photo += "<a class='badge red icon-star'></a>";
|
||||
if (!lychee.publicMode&&photoJSON.public==1&&album.json.public!=1) photo += "<a class='badge red icon-share'></a>";
|
||||
|
||||
photo += "</div>";
|
||||
|
||||
return photo;
|
||||
|
||||
},
|
||||
|
||||
imageview: function(photoJSON, isSmall, visibleControls) {
|
||||
|
||||
if (!photoJSON) return "";
|
||||
|
||||
var view = "";
|
||||
|
||||
view += "<div class='arrow_wrapper previous'><a id='previous' class='icon-caret-left'></a></div>";
|
||||
view += "<div class='arrow_wrapper next'><a id='next' class='icon-caret-right'></a></div>";
|
||||
|
||||
if (isSmall) {
|
||||
|
||||
if (visibleControls)
|
||||
view += "<div id='image' class='small' style='background-image: url(" + photoJSON.url + "); width: " + photoJSON.width + "px; height: " + photoJSON.height + "px; margin-top: -" + parseInt(photoJSON.height/2-20) + "px; margin-left: -" + photoJSON.width/2 + "px;'></div>";
|
||||
else
|
||||
view += "<div id='image' class='small' style='background-image: url(" + photoJSON.url + "); width: " + photoJSON.width + "px; height: " + photoJSON.height + "px; margin-top: -" + parseInt(photoJSON.height/2) + "px; margin-left: -" + photoJSON.width/2 + "px;'></div>";
|
||||
|
||||
} else {
|
||||
|
||||
if (visibleControls)
|
||||
view += "<div id='image' style='background-image: url(" + photoJSON.url + ")'></div>";
|
||||
else
|
||||
view += "<div id='image' style='background-image: url(" + photoJSON.url + "); top: 0px; right: 0px; bottom: 0px; left: 0px;'></div>";
|
||||
|
||||
}
|
||||
|
||||
return view;
|
||||
|
||||
},
|
||||
|
||||
no_content: function(typ) {
|
||||
|
||||
var no_content = "";
|
||||
|
||||
no_content += "<div class='no_content fadeIn'>";
|
||||
no_content += "<a class='icon icon-" + typ + "'></a>";
|
||||
|
||||
if (typ==="search") no_content += "<p>No results</p>";
|
||||
else if (typ==="picture") no_content += "<p>No public albums</p>";
|
||||
else if (typ==="cog") no_content += "<p>No Configuration!</p>";
|
||||
|
||||
no_content += "</div>";
|
||||
|
||||
return no_content;
|
||||
|
||||
},
|
||||
|
||||
modal: function(title, text, button, marginTop, closeButton) {
|
||||
|
||||
var modal = "",
|
||||
custom_style = "";
|
||||
|
||||
if (marginTop) custom_style = "style='margin-top: " + marginTop + "px;'";
|
||||
|
||||
modal += "<div class='message_overlay fadeIn'>";
|
||||
modal += "<div class='message center'" + custom_style + ">";
|
||||
modal += "<h1>" + title + "</h1>";
|
||||
|
||||
if (closeButton!=false) {
|
||||
|
||||
modal += "<a class='close icon-remove-sign'></a>";
|
||||
|
||||
}
|
||||
|
||||
modal += "<p>" + text + "</p>";
|
||||
|
||||
$.each(button, function(index) {
|
||||
|
||||
if (this[0]!="") {
|
||||
|
||||
if (index===0) modal += "<a class='button active'>" + this[0] + "</a>";
|
||||
else modal += "<a class='button'>" + this[0] + "</a>";
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
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 += "<a class='close icon-remove-sign'></a>";
|
||||
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 + "<span> – <a target='_blank' href='" + lychee.updateURL + "'>Update available!</a><span></div>";
|
||||
modal += "<a onclick='lychee.login()' class='button active'>Sign in</a>";
|
||||
modal += "</div>";
|
||||
modal += "</div>";
|
||||
|
||||
return modal;
|
||||
|
||||
},
|
||||
|
||||
uploadModal: function(icon, text) {
|
||||
|
||||
var modal = "";
|
||||
|
||||
modal += "<div class='upload_overlay fadeIn'>";
|
||||
modal += "<div class='upload_message center'>";
|
||||
modal += "<a class='icon-" + icon + "'></a>";
|
||||
|
||||
if (text!==undefined) modal += "<p>" + text + "</p>";
|
||||
else modal += "<div class='progressbar'><div></div></div>";
|
||||
|
||||
modal += "</div>";
|
||||
modal += "</div>";
|
||||
|
||||
return modal;
|
||||
|
||||
},
|
||||
|
||||
contextMenu: function(items, orientation) {
|
||||
|
||||
var menu = "";
|
||||
|
||||
menu += "<div class='contextmenu_bg'></div>";
|
||||
menu += "<div class='contextmenu " + orientation + "'>";
|
||||
menu += "<table>";
|
||||
menu += "<tbody>";
|
||||
|
||||
$.each(items, function(index) {
|
||||
|
||||
if (items[index][0]==="separator"&&items[index][1]===-1) menu += "<tr class='separator'></tr>";
|
||||
else if (items[index][1]===-1) menu += "<tr class='no_hover'><td>" + items[index][0] + "</td></tr>";
|
||||
else if (items[index][2]!=undefined) menu += "<tr><td onclick='" + items[index][2] + "; window.contextMenu.close();'>" + items[index][0] + "</td></tr>";
|
||||
else menu += "<tr><td onclick='window.contextMenu.fns[" + items[index][1] + "](); window.contextMenu.close();'>" + items[index][0] + "</td></tr>";
|
||||
|
||||
});
|
||||
|
||||
menu += "</tbody>";
|
||||
menu += "</table>";
|
||||
menu += "</div>";
|
||||
|
||||
return menu;
|
||||
|
||||
},
|
||||
|
||||
infoboxPhoto: function(photoJSON, forView) {
|
||||
|
||||
if (!photoJSON) return "";
|
||||
|
||||
var infobox = "",
|
||||
public,
|
||||
editTitleHTML,
|
||||
editDescriptionHTML,
|
||||
infos;
|
||||
|
||||
infobox += "<div class='header'><h1>About</h1><a class='icon-remove-sign'></a></div>";
|
||||
infobox += "<div class='wrapper'>";
|
||||
|
||||
switch (photoJSON.public) {
|
||||
case "0":
|
||||
public = "Private";
|
||||
break;
|
||||
case "1":
|
||||
public = "Public";
|
||||
break;
|
||||
case "2":
|
||||
public = "Public (Album)";
|
||||
break;
|
||||
default:
|
||||
public = "-";
|
||||
break;
|
||||
}
|
||||
|
||||
editTitleHTML = (forView===true||lychee.publicMode) ? "" : " " + build.editIcon("edit_title");
|
||||
editDescriptionHTML = (forView===true||lychee.publicMode) ? "" : " " + build.editIcon("edit_description");
|
||||
|
||||
//["Tags", "<a class='tag'>Abstract<span class='icon-remove'></span></a><a class='tag'>Colors<span class='icon-remove'></span></a><a class='tag'>Photoshop<span class='icon-remove'></span></a><a class='tag'>Something<span class='icon-remove'></span></a><a class='tag'>Lychee<span class='icon-remove'></span></a><a class='tag'>Tags<span class='icon-remove'></span></a><a class='tag icon-plus'></a>"]
|
||||
infos = [
|
||||
["", "Basics"],
|
||||
["Name", photoJSON.title + editTitleHTML],
|
||||
["Uploaded", photoJSON.sysdate],
|
||||
["Description", photoJSON.description + editDescriptionHTML],
|
||||
["", "Image"],
|
||||
["Size", photoJSON.size],
|
||||
["Format", photoJSON.type],
|
||||
["Resolution", photoJSON.width + " x " + photoJSON.height]
|
||||
];
|
||||
|
||||
if ((photoJSON.takedate+photoJSON.make+photoJSON.model+photoJSON.shutter+photoJSON.aperture+photoJSON.focal+photoJSON.iso)!="") {
|
||||
|
||||
infos = infos.concat([
|
||||
["", "Camera"],
|
||||
["Captured", photoJSON.takedate],
|
||||
["Make", photoJSON.make],
|
||||
["Type/Model", photoJSON.model],
|
||||
["Shutter Speed", photoJSON.shutter],
|
||||
["Aperture", photoJSON.aperture],
|
||||
["Focal Length", photoJSON.focal],
|
||||
["ISO", photoJSON.iso]
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
infos = infos.concat([
|
||||
["", "Share"],
|
||||
["Visibility", public]
|
||||
]);
|
||||
|
||||
$.each(infos, function(index) {
|
||||
|
||||
if (infos[index][1]===""||infos[index][1]==undefined||infos[index][1]==null) infos[index][1] = "-";
|
||||
|
||||
switch (infos[index][0]) {
|
||||
|
||||
case "": // Separator
|
||||
infobox += "</table>";
|
||||
infobox += "<div class='separator'><h1>" + infos[index][1] + "</h1></div>";
|
||||
infobox += "<table>";
|
||||
break;
|
||||
|
||||
case "Tags": // Tags
|
||||
infobox += "</table>";
|
||||
infobox += "<div class='separator'><h1>" + infos[index][0] + "</h1></div>";
|
||||
infobox += "<tr>";
|
||||
infobox += "<div id='tags'>" + infos[index][1] + "</div>";
|
||||
infobox += "</tr>";
|
||||
break;
|
||||
|
||||
default: // Item
|
||||
infobox += "<tr>";
|
||||
infobox += "<td>" + infos[index][0] + "</td>";
|
||||
infobox += "<td class='attr_" + infos[index][0].toLowerCase() + "'>" + infos[index][1] + "</td>";
|
||||
infobox += "</tr>";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
infobox += "</table>";
|
||||
infobox += "<div class='bumper'></div>";
|
||||
infobox += "</div>";
|
||||
|
||||
return infobox;
|
||||
|
||||
},
|
||||
|
||||
infoboxAlbum: function(albumJSON, forView) {
|
||||
|
||||
if (!albumJSON) return "";
|
||||
|
||||
var infobox = "",
|
||||
public,
|
||||
password,
|
||||
editTitleHTML,
|
||||
editDescriptionHTML,
|
||||
infos;
|
||||
|
||||
infobox += "<div class='header'><h1>About</h1><a class='icon-remove-sign'></a></div>";
|
||||
infobox += "<div class='wrapper'>";
|
||||
|
||||
switch (albumJSON.public) {
|
||||
case "0":
|
||||
public = "Private";
|
||||
break;
|
||||
case "1":
|
||||
public = "Public";
|
||||
break;
|
||||
default:
|
||||
public = "-";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (albumJSON.password) {
|
||||
case false:
|
||||
password = "No";
|
||||
break;
|
||||
case true:
|
||||
password = "Yes";
|
||||
break;
|
||||
default:
|
||||
password = "-";
|
||||
break;
|
||||
}
|
||||
|
||||
editTitleHTML = (forView===true||lychee.publicMode) ? "" : " " + build.editIcon("edit_title_album");
|
||||
editDescriptionHTML = (forView===true||lychee.publicMode) ? "" : " " + build.editIcon("edit_description_album");
|
||||
|
||||
infos = [
|
||||
["", "Basics"],
|
||||
["Name", albumJSON.title + editTitleHTML],
|
||||
["Description", albumJSON.description + editDescriptionHTML],
|
||||
["", "Album"],
|
||||
["Created", albumJSON.sysdate],
|
||||
["Images", albumJSON.num],
|
||||
["", "Share"],
|
||||
["Visibility", public],
|
||||
["Password", password]
|
||||
];
|
||||
|
||||
$.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='separator'><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,138 @@
|
||||
/**
|
||||
* @name Init Module
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
/* Event Name */
|
||||
var event_name = (mobileBrowser()) ? "touchend" : "click";
|
||||
|
||||
/* Notifications */
|
||||
if (window.webkitNotifications) window.webkitNotifications.requestPermission();
|
||||
|
||||
/* Tooltips */
|
||||
if (!mobileBrowser()) $(".tools").tipsy({gravity: 'n', fade: false, delayIn: 0, opacity: 1});
|
||||
|
||||
/* Header */
|
||||
$("#hostedwith").on(event_name, function() { window.open(lychee.website,"_newtab") });
|
||||
$("#button_signin").on(event_name, lychee.loginDialog);
|
||||
$("#button_settings").on(event_name, contextMenu.settings);
|
||||
$("#button_share").on(event_name, function(e) {
|
||||
if (photo.json.public==1||photo.json.public==2) contextMenu.sharePhoto(photo.getID(), e);
|
||||
else photo.setPublic(photo.getID(), e);
|
||||
});
|
||||
$("#button_share_album").on(event_name, function(e) {
|
||||
if (album.json.public==1) contextMenu.shareAlbum(album.getID(), e);
|
||||
else modal.show("Share Album", "All photos inside this album will be public and visible for everyone. Existing public photos will have the same sharing permission as this album. Are your sure you want to share this album? <input class='text' type='password' placeholder='password (optional)' value=''>", [["Share Album", function() { album.setPublic(album.getID(), e) }], ["Cancel", function() {}]]);
|
||||
});
|
||||
$("#button_download").on(event_name, function() { window.open(photo.getDirectLink(),"_newtab") });
|
||||
$("#button_trash_album").on(event_name, function() { album.delete(album.getID()) });
|
||||
$("#button_move").on(event_name, function(e) { contextMenu.move(photo.getID(), e) });
|
||||
$("#button_trash").on(event_name, function() { photo.delete(photo.getID()) });
|
||||
$("#button_info_album").on(event_name, function() { view.infobox.show() });
|
||||
$("#button_info").on(event_name, function() { view.infobox.show() });
|
||||
$("#button_archive").on(event_name, function() { album.getArchive(album.getID()) });
|
||||
$("#button_star").on(event_name, function() { photo.setStar(photo.getID()) });
|
||||
|
||||
/* Search */
|
||||
$("#search").on("keyup click", function() { search.find($(this).val()) });
|
||||
|
||||
/* Back Buttons */
|
||||
$("#button_back_home").on(event_name, function() { lychee.goto("") });
|
||||
$("#button_back").on(event_name, function() { lychee.goto(album.getID()) });
|
||||
|
||||
/* Image View */
|
||||
lychee.imageview
|
||||
.on(event_name, ".arrow_wrapper.previous", function() {
|
||||
if (album.json&&album.json.content[photo.getID()]&&album.json.content[photo.getID()].previousPhoto!=="") lychee.goto(album.getID() + "/" + album.json.content[photo.getID()].previousPhoto)
|
||||
})
|
||||
.on(event_name, ".arrow_wrapper.next", function() {
|
||||
if (album.json&&album.json.content[photo.getID()]&&album.json.content[photo.getID()].nextPhoto!=="") lychee.goto(album.getID() + "/" + album.json.content[photo.getID()].nextPhoto)
|
||||
});
|
||||
|
||||
/* Infobox */
|
||||
$("#infobox")
|
||||
.on(event_name, ".header a", function() { view.infobox.hide() })
|
||||
.on(event_name, "#edit_title_album", function() { album.setTitle(album.getID()) })
|
||||
.on(event_name, "#edit_description_album", function() { album.setDescription(album.getID()) })
|
||||
.on(event_name, "#edit_title", function() { photo.setTitle(photo.getID()) })
|
||||
.on(event_name, "#edit_description", function() { photo.setDescription(photo.getID()) });
|
||||
|
||||
/* Keyboard */
|
||||
Mousetrap
|
||||
.bind('u', function() { $("#upload_files").click() })
|
||||
.bind('s', function() { if (visible.photo()) $("#button_star").click() })
|
||||
.bind('f', function() { if (visible.photo()) $("#button_download").click() })
|
||||
.bind('command+backspace', function() { if (visible.photo()&&!visible.message()) photo.delete(photo.getID()) })
|
||||
.bind('left', function() { if (visible.photo()) $("#imageview a#previous").click() })
|
||||
.bind('right', function() { if (visible.photo()) $("#imageview a#next").click() })
|
||||
.bind('i', function() {
|
||||
if (visible.infobox()) view.infobox.hide();
|
||||
else if (!visible.albums()) view.infobox.show();
|
||||
});
|
||||
|
||||
Mousetrap.bindGlobal('enter', function() {
|
||||
if ($(".message .button.active").length) $(".message .button.active").addClass("pressed").click()
|
||||
});
|
||||
|
||||
Mousetrap.bindGlobal(['esc', 'command+up'], function(e) {
|
||||
e.preventDefault();
|
||||
if (visible.message()&&$(".message .close").length>0) modal.close();
|
||||
else if (visible.contextMenu()) contextMenu.close();
|
||||
else if (visible.infobox()) view.infobox.hide();
|
||||
else if (visible.photo()) lychee.goto(album.getID());
|
||||
else if (visible.album()) lychee.goto("");
|
||||
else if (visible.albums()&&$("#search").val().length!==0) search.reset();
|
||||
});
|
||||
|
||||
/* Document */
|
||||
$(document)
|
||||
|
||||
/* Login */
|
||||
.on("keyup", "#password", function() { if ($(this).val().length>0) $(this).removeClass("error") })
|
||||
|
||||
/* Header */
|
||||
.on(event_name, "#title.editable", function() {
|
||||
if (visible.photo()) photo.setTitle(photo.getID());
|
||||
else album.setTitle(album.getID());
|
||||
})
|
||||
|
||||
/* Navigation */
|
||||
.on("click", ".album", function() { lychee.goto($(this).attr("data-id")) })
|
||||
.on("click", ".photo", function() { lychee.goto(album.getID() + "/" + $(this).attr("data-id")) })
|
||||
|
||||
/* Modal */
|
||||
.on(event_name, ".message .close", modal.close)
|
||||
.on(event_name, ".message .button:first", function() { if (modal.fns!=null) modal.fns[0](); if (!visible.signin()) modal.close() })
|
||||
.on(event_name, ".message .button:last", function() { if (modal.fns!=null) modal.fns[1](); if (!visible.signin()) modal.close() })
|
||||
|
||||
/* Add Dialog */
|
||||
.on(event_name, ".button_add", function(e) { contextMenu.add(e) })
|
||||
|
||||
/* Upload */
|
||||
.on("change", "#upload_files", function() { modal.close(); upload.start.local(this.files) })
|
||||
|
||||
/* Context Menu */
|
||||
.on("contextmenu", ".photo", function(e) { contextMenu.photo(photo.getID(), e) })
|
||||
.on("contextmenu", ".album", function(e) { contextMenu.album(album.getID(), e) })
|
||||
.on(event_name, ".contextmenu_bg", contextMenu.close)
|
||||
|
||||
/* Infobox */
|
||||
.on(event_name, "#infobox_overlay", view.infobox.hide)
|
||||
|
||||
/* Upload */
|
||||
.on("dragover", function(e) { e.preventDefault(); }, false)
|
||||
.on("drop", function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (e.originalEvent.dataTransfer.files.length>0) upload.start.local(e.originalEvent.dataTransfer.files);
|
||||
else if (e.originalEvent.dataTransfer.getData('Text').length>3) upload.start.url(e.originalEvent.dataTransfer.getData('Text'));
|
||||
return true;
|
||||
});
|
||||
|
||||
/* Init */
|
||||
lychee.init();
|
||||
|
||||
});
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @name Modal Module
|
||||
* @description Build, show and hide a modal.
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
modal = {
|
||||
|
||||
fns: null,
|
||||
|
||||
show: function(title, text, buttons, marginTop, closeButton) {
|
||||
|
||||
if (!buttons) {
|
||||
var buttons = [
|
||||
["", function() {}],
|
||||
["", function() {}]
|
||||
];
|
||||
}
|
||||
|
||||
modal.fns = [buttons[0][1], buttons[1][1]];
|
||||
$("body").append(build.modal(title, text, buttons, marginTop, closeButton));
|
||||
$(".message input:first-child").focus();
|
||||
|
||||
},
|
||||
|
||||
close: function() {
|
||||
|
||||
modal.fns = null;
|
||||
$(".message_overlay").removeClass("fadeIn").css("opacity", 0);
|
||||
setTimeout(function() { $(".message_overlay").remove() }, 300);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,315 @@
|
||||
/**
|
||||
* @name Photo Module
|
||||
* @description Takes care of every action a photo can handle and execute.
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
photo = {
|
||||
|
||||
json: null,
|
||||
|
||||
getID: function() {
|
||||
|
||||
var id;
|
||||
|
||||
if (photo.json) id = photo.json.id;
|
||||
else id = $(".photo:hover, .photo.active").attr("data-id");
|
||||
|
||||
if (id) return id;
|
||||
else return false;
|
||||
|
||||
},
|
||||
|
||||
load: function(photoID, albumID) {
|
||||
|
||||
var params,
|
||||
checkPasswd;
|
||||
|
||||
params = "getPhoto&photoID=" + photoID + "&albumID=" + albumID + "&password=" + password.value;
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data==="Warning: Wrong password!") {
|
||||
checkPasswd = function() {
|
||||
if (password.value!=="") photo.load(photoID, albumID);
|
||||
else setTimeout(checkPasswd, 250);
|
||||
}
|
||||
checkPasswd();
|
||||
return false;
|
||||
}
|
||||
|
||||
photo.json = data;
|
||||
if (!visible.photo()) view.photo.show();
|
||||
view.photo.init();
|
||||
|
||||
lychee.imageview.show();
|
||||
setTimeout(function() { lychee.content.show() }, 300);
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
parse: function() {
|
||||
|
||||
if (!photo.json.title) photo.json.title = "Untitled";
|
||||
photo.json.url = lychee.upload_path_big + photo.json.url;
|
||||
|
||||
},
|
||||
|
||||
delete: function(photoID) {
|
||||
|
||||
var params,
|
||||
buttons,
|
||||
photoTitle;
|
||||
|
||||
if (!photoID) return false;
|
||||
|
||||
if (visible.photo()) photoTitle = photo.json.title;
|
||||
else photoTitle = album.json.content[photoID].title;
|
||||
if (photoTitle=="") photoTitle = "Untitled";
|
||||
|
||||
buttons = [
|
||||
["Delete Photo", function() {
|
||||
|
||||
// Change reference for the next and previous photo
|
||||
if (album.json.content[photoID].nextPhoto!==""||album.json.content[photoID].previousPhoto!=="") {
|
||||
|
||||
nextPhoto = album.json.content[photoID].nextPhoto;
|
||||
previousPhoto = album.json.content[photoID].previousPhoto;
|
||||
|
||||
album.json.content[previousPhoto].nextPhoto = nextPhoto;
|
||||
album.json.content[nextPhoto].previousPhoto = previousPhoto;
|
||||
|
||||
}
|
||||
|
||||
album.json.content[photoID] = null;
|
||||
|
||||
view.album.content.delete(photoID);
|
||||
|
||||
// Only when search is not active
|
||||
if (!visible.albums()) lychee.goto(album.getID());
|
||||
|
||||
params = "deletePhoto&photoID=" + photoID;
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data!==true) lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
}],
|
||||
["Keep Photo", function() {}]
|
||||
];
|
||||
modal.show("Delete Photo", "Are you sure you want to delete the photo '" + photoTitle + "'?<br>This action can't be undone!", buttons);
|
||||
|
||||
},
|
||||
|
||||
setTitle: function(photoID) {
|
||||
|
||||
var oldTitle = "",
|
||||
newTitle,
|
||||
params,
|
||||
buttons;
|
||||
|
||||
if (!photoID) return false;
|
||||
if (photo.json) oldTitle = photo.json.title;
|
||||
else if (album.json) oldTitle = album.json.content[photoID].title;
|
||||
|
||||
buttons = [
|
||||
["Set Title", function() {
|
||||
|
||||
newTitle = $(".message input.text").val();
|
||||
|
||||
if (photoID!=null&&photoID&&newTitle.length<31) {
|
||||
|
||||
if (visible.photo()) {
|
||||
photo.json.title = (newTitle==="") ? "Untitled" : newTitle;
|
||||
view.photo.title(oldTitle);
|
||||
}
|
||||
|
||||
album.json.content[photoID].title = newTitle;
|
||||
view.album.content.title(photoID);
|
||||
|
||||
params = "setPhotoTitle&photoID=" + photoID + "&title=" + escape(encodeURI(newTitle));
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data!==true) lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
} else if (newTitle.length>0) loadingBar.show("error", "New title to short or too long. Please try another one!");
|
||||
|
||||
}],
|
||||
["Cancel", function() {}]
|
||||
];
|
||||
modal.show("Set Title", "Please enter a new title for this photo: <input class='text' type='text' placeholder='Title' value='" + oldTitle + "'>", buttons);
|
||||
|
||||
},
|
||||
|
||||
setAlbum: function(albumID, photoID) {
|
||||
|
||||
var params;
|
||||
|
||||
if (albumID>=0) {
|
||||
|
||||
if (visible.photo) lychee.goto(album.getID());
|
||||
album.json.content[photoID] = null;
|
||||
view.album.content.delete(photoID);
|
||||
|
||||
params = "setAlbum&photoID=" + photoID + "&albumID=" + albumID;
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data!==true) lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
setStar: function(photoID) {
|
||||
|
||||
var params;
|
||||
|
||||
if (visible.photo()) {
|
||||
photo.json.star = (photo.json.star==0) ? 1 : 0;
|
||||
view.photo.star();
|
||||
}
|
||||
|
||||
album.json.content[photoID].star = (album.json.content[photoID].star==0) ? 1 : 0;
|
||||
view.album.content.star(photoID);
|
||||
|
||||
params = "setPhotoStar&photoID=" + photoID;
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data!==true) lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
setPublic: function(photoID, e) {
|
||||
|
||||
var params;
|
||||
|
||||
if (photo.json.public==2) {
|
||||
|
||||
modal.show("Public Album", "This photo is located in a public album. To make this photo private or public, edit the visibility of the associated album.", [["Show Album", function() { lychee.goto(photo.json.original_album) }], ["Close", function() {}]]);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (visible.photo()) {
|
||||
|
||||
photo.json.public = (photo.json.public==0) ? 1 : 0;
|
||||
view.photo.public();
|
||||
if (photo.json.public==1) contextMenu.sharePhoto(photoID, e);
|
||||
|
||||
}
|
||||
|
||||
album.json.content[photoID].public = (album.json.content[photoID].public==0) ? 1 : 0;
|
||||
view.album.content.public(photoID);
|
||||
|
||||
params = "setPhotoPublic&photoID=" + photoID + "&url=" + photo.getViewLink(photoID);
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data!==true) lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
setDescription: function(photoID) {
|
||||
|
||||
var oldDescription = photo.json.description,
|
||||
description,
|
||||
params,
|
||||
buttons;
|
||||
|
||||
buttons = [
|
||||
["Set Description", function() {
|
||||
|
||||
description = $(".message input.text").val();
|
||||
|
||||
if (description.length<800) {
|
||||
|
||||
if (visible.photo()) {
|
||||
photo.json.description = description;
|
||||
view.photo.description();
|
||||
}
|
||||
|
||||
params = "setPhotoDescription&photoID=" + photoID + "&description=" + escape(description);
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data!==true) lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
} else loadingBar.show("error", "Description too long. Please try again!");
|
||||
|
||||
}],
|
||||
["Cancel", function() {}]
|
||||
];
|
||||
modal.show("Set Description", "Please enter a description for this photo: <input class='text' type='text' placeholder='Description' value='" + oldDescription + "'>", buttons);
|
||||
|
||||
},
|
||||
|
||||
share: function(photoID, service) {
|
||||
|
||||
var link = "",
|
||||
url = photo.getViewLink(photoID),
|
||||
filename = "unknown";
|
||||
|
||||
switch (service) {
|
||||
case 0:
|
||||
link = "https://twitter.com/share?url=" + encodeURI(url);
|
||||
break;
|
||||
case 1:
|
||||
link = "http://www.facebook.com/sharer.php?u=" + encodeURI(url) + "&t=" + encodeURI(photo.json.title);
|
||||
break;
|
||||
case 2:
|
||||
link = "mailto:?subject=" + encodeURI(photo.json.title) + "&body=" + encodeURI(url);
|
||||
break;
|
||||
case 3:
|
||||
lychee.loadDropbox(function() {
|
||||
filename = photo.json.title + "." + photo.getDirectLink().split('.').pop();
|
||||
Dropbox.save(photo.getDirectLink(), filename);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
link = "";
|
||||
break;
|
||||
}
|
||||
|
||||
if (link.length>5) location.href = link;
|
||||
|
||||
},
|
||||
|
||||
isSmall: function() {
|
||||
|
||||
var size = [
|
||||
["width", false],
|
||||
["height", false]
|
||||
];
|
||||
|
||||
if (photo.json.width<$(window).width()-60) size["width"] = true;
|
||||
if (photo.json.height<$(window).height()-100) size["height"] = true;
|
||||
|
||||
if (size["width"]&&size["height"]) return true;
|
||||
else return false;
|
||||
|
||||
},
|
||||
|
||||
getDirectLink: function() {
|
||||
|
||||
return $("#imageview #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
|
||||
|
||||
},
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,238 @@
|
||||
/**
|
||||
* @name Settings Module
|
||||
* @description Lets you change settings.
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
var settings = {
|
||||
|
||||
createConfig: function() {
|
||||
|
||||
var dbName,
|
||||
dbUser,
|
||||
dbPassword,
|
||||
dbHost,
|
||||
buttons;
|
||||
|
||||
buttons = [
|
||||
["Connect", function() {
|
||||
|
||||
dbHost = $(".message input.text#dbHost").val();
|
||||
dbUser = $(".message input.text#dbUser").val();
|
||||
dbPassword = $(".message input.text#dbPassword").val();
|
||||
dbName = $(".message input.text#dbName").val();
|
||||
|
||||
if (dbHost.length<1) dbHost = "localhost";
|
||||
if (dbName.length<1) dbName = "lychee";
|
||||
|
||||
params = "createConfig&dbName=" + escape(dbName) + "&dbUser=" + escape(dbUser) + "&dbPassword=" + escape(dbPassword) + "&dbHost=" + escape(dbHost);
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data!==true) {
|
||||
|
||||
// Configuration failed
|
||||
setTimeout(function() {
|
||||
|
||||
// Connection failed
|
||||
if (data.indexOf("Warning: Connection failed!")!==-1) {
|
||||
|
||||
buttons = [
|
||||
["Retry", function() { setTimeout(settings.createConfig, 400) }],
|
||||
["", function() {}]
|
||||
];
|
||||
modal.show("Connection Failed", "Unable to connect to host database because access was denied. Double-check your host, username and password and ensure that access from your current location is permitted.", buttons, null, false);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// Could not create file
|
||||
if (data.indexOf("Warning: Could not create file!")!==-1) {
|
||||
|
||||
buttons = [
|
||||
["Retry", function() { setTimeout(settings.createConfig, 400) }],
|
||||
["", function() {}]
|
||||
];
|
||||
modal.show("Saving Failed", "Unable to save this configuration. Permission denied in <b>'php/'</b>. Please set the read, write and execute rights for others in <b>'php/'</b> and <b>'uploads/'</b>. Take a look the readme for more information.", buttons, null, false);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// Something went wrong
|
||||
buttons = [
|
||||
["Retry", function() { setTimeout(settings.createConfig, 400) }],
|
||||
["", function() {}]
|
||||
];
|
||||
modal.show("Configuration Failed", "Something unexpected happened. Please try again and check your installation and server. Take a look the readme for more information.", buttons, null, false);
|
||||
return false;
|
||||
|
||||
}, 400);
|
||||
|
||||
} else {
|
||||
|
||||
// Configuration successful
|
||||
lychee.api("update", function(data) { window.location.reload() });
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}],
|
||||
["", function() {}]
|
||||
];
|
||||
modal.show("Configuration", "Enter your database connection details below: <input id='dbHost' class='text less' type='text' placeholder='Host (optional)' value=''><input id='dbUser' class='text less' type='text' placeholder='Username' value=''><input id='dbPassword' class='text more' type='password' placeholder='Password' value=''><br>Lychee will create its own database. If required, you can enter the name of an existing database instead:<input id='dbName' class='text more' type='text' placeholder='Database (optional)' value=''>", buttons, -215, false);
|
||||
|
||||
},
|
||||
|
||||
createLogin: function() {
|
||||
|
||||
var username,
|
||||
password,
|
||||
params,
|
||||
buttons;
|
||||
|
||||
buttons = [
|
||||
["Create Login", function() {
|
||||
|
||||
username = $(".message input.text#username").val();
|
||||
password = $(".message input.text#password").val();
|
||||
|
||||
if (username.length<1||password.length<1) {
|
||||
|
||||
setTimeout(function() {
|
||||
|
||||
buttons = [
|
||||
["Retry", function() { setTimeout(settings.createLogin, 400) }],
|
||||
["", function() {}]
|
||||
];
|
||||
modal.show("Wrong Input", "The username or password you entered is not long enough. Please try again with another username and password!", buttons, null, false);
|
||||
return false;
|
||||
|
||||
}, 400);
|
||||
|
||||
} else {
|
||||
|
||||
params = "setLogin&username=" + escape(username) + "&password=" + hex_md5(password);
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data!==true) {
|
||||
|
||||
setTimeout(function() {
|
||||
|
||||
buttons = [
|
||||
["Retry", function() { setTimeout(settings.createLogin, 400) }],
|
||||
["", function() {}]
|
||||
];
|
||||
modal.show("Creation Failed", "Unable to save login. Please try again with another username and password!", buttons, null, false);
|
||||
return false;
|
||||
|
||||
}, 400);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}],
|
||||
["", function() {}]
|
||||
];
|
||||
modal.show("Create Login", "Enter a username and password for your installation: <input id='username' class='text less' type='text' placeholder='New Username' value=''><input id='password' class='text' type='password' placeholder='New Password' value=''>", buttons, -122, false);
|
||||
|
||||
},
|
||||
|
||||
setLogin: function() {
|
||||
|
||||
var old_password,
|
||||
username,
|
||||
password,
|
||||
params,
|
||||
buttons;
|
||||
|
||||
buttons = [
|
||||
["Change Login", function() {
|
||||
|
||||
old_password = $(".message input.text#old_password").val();
|
||||
username = $(".message input.text#username").val();
|
||||
password = $(".message input.text#password").val();
|
||||
|
||||
if (old_password.length<1) {
|
||||
loadingBar.show("error", "Your old password was entered incorrectly. Please try again!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (username.length<1) {
|
||||
loadingBar.show("error", "Your new username was entered incorrectly. Please try again!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password.length<1) {
|
||||
loadingBar.show("error", "Your new password was entered incorrectly. Please try again!");
|
||||
return false;
|
||||
}
|
||||
|
||||
params = "setLogin&oldPassword=" + hex_md5(old_password) + "&username=" + escape(username) + "&password=" + hex_md5(password);
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data!==true) lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
}],
|
||||
["Cancel", function() {}]
|
||||
];
|
||||
modal.show("Change Login", "Enter your current password: <input id='old_password' class='text more' type='password' placeholder='Current Password' value=''><br>Your username and password will be changed to the following: <input id='username' class='text less' type='text' placeholder='New Username' value=''><input id='password' class='text' type='password' placeholder='New Password' value=''>", buttons, -171);
|
||||
|
||||
},
|
||||
|
||||
setSorting: function() {
|
||||
|
||||
var buttons,
|
||||
sorting;
|
||||
|
||||
buttons = [
|
||||
["Change Sorting", function() {
|
||||
|
||||
sorting[0] = $("select#settings_type").val();
|
||||
sorting[1] = $("select#settings_order").val();
|
||||
|
||||
params = "setSorting&type=" + sorting[0] + "&order=" + sorting[1];
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
if (data===true) {
|
||||
lychee.sorting = "ORDER BY " + sorting[0] + " " + sorting[1];
|
||||
lychee.load();
|
||||
} else lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
}],
|
||||
["Cancel", function() {}]
|
||||
];
|
||||
modal.show("Change Sorting",
|
||||
"Sort photos by \
|
||||
<select id='settings_type'> \
|
||||
<option value='id'>Upload Time</option> \
|
||||
<option value='title'>Title</option> \
|
||||
<option value='description'>Description</option> \
|
||||
<option value='public'>Public</option> \
|
||||
<option value='star'>Star</option> \
|
||||
<option value='type'>Photo Format</option> \
|
||||
</select> \
|
||||
in an \
|
||||
<select id='settings_order'> \
|
||||
<option value='ASC'>Ascending</option> \
|
||||
<option value='DESC'>Descending</option> \
|
||||
</select> \
|
||||
order.\
|
||||
", buttons);
|
||||
|
||||
if (lychee.sorting!="") {
|
||||
sorting = lychee.sorting.replace("ORDER BY ", "").replace(" ", ";").split(";");
|
||||
$("select#settings_type").val(sorting[0]);
|
||||
$("select#settings_order").val(sorting[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,253 @@
|
||||
/**
|
||||
* @name Album Module
|
||||
* @description Takes care of every action an album can handle and execute.
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
upload = {
|
||||
|
||||
show: function(icon, text) {
|
||||
|
||||
if (icon===undefined) icon = "upload";
|
||||
|
||||
upload.close(true);
|
||||
$("body").append(build.uploadModal(icon, text));
|
||||
|
||||
},
|
||||
|
||||
setIcon: function(icon) {
|
||||
|
||||
$(".upload_message a").remove();
|
||||
$(".upload_message").prepend("<a class='icon-" + icon + "'></a>");
|
||||
|
||||
},
|
||||
|
||||
setProgress: function(progress) {
|
||||
|
||||
$(".progressbar div").css("width", progress + "%");
|
||||
|
||||
},
|
||||
|
||||
setText: function(text) {
|
||||
|
||||
$(".progressbar").remove();
|
||||
$(".upload_message").append("<p>" + text + "</p>");
|
||||
|
||||
},
|
||||
|
||||
start: {
|
||||
|
||||
local: function(files) {
|
||||
|
||||
var pre_progress = 0,
|
||||
formData = new FormData(),
|
||||
xhr = new XMLHttpRequest(),
|
||||
albumID = album.getID(),
|
||||
popup,
|
||||
progress;
|
||||
|
||||
if (files.length<=0) return false;
|
||||
if (albumID===false) albumID = 0;
|
||||
|
||||
formData.append("function", "upload");
|
||||
formData.append("albumID", albumID);
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
|
||||
if (files[i].type!=="image/jpeg"&&files[i].type!=="image/jpg"&&files[i].type!=="image/png"&&files[i].type!=="image/gif") {
|
||||
loadingBar.show("error", "The file format of " + files[i].name + " is not supported.");
|
||||
return false;
|
||||
} else {
|
||||
formData.append(i, files[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
upload.show();
|
||||
|
||||
window.onbeforeunload = function() { return "Lychee is currently uploading!"; };
|
||||
|
||||
xhr.open("POST", lychee.api_path);
|
||||
|
||||
xhr.onload = function() {
|
||||
|
||||
if (xhr.status===200) {
|
||||
|
||||
upload.close();
|
||||
|
||||
// WebKit Notification
|
||||
if (window.webkitNotifications&&BrowserDetect.browser==="Safari") {
|
||||
popup = window.webkitNotifications.createNotification("", "Upload complete", "You can now manage your new photo.");
|
||||
popup.show();
|
||||
}
|
||||
|
||||
window.onbeforeunload = null;
|
||||
|
||||
if (album.getID()===false) lychee.goto("0");
|
||||
else album.load(albumID);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
xhr.upload.onprogress = function(e) {
|
||||
|
||||
if (e.lengthComputable) {
|
||||
|
||||
progress = (e.loaded / e.total * 100 | 0);
|
||||
|
||||
if (progress>pre_progress) {
|
||||
upload.setProgress(progress);
|
||||
pre_progress = progress;
|
||||
}
|
||||
|
||||
if (progress>=100) {
|
||||
upload.setIcon("cog");
|
||||
upload.setText("Processing photos");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$("#upload_files").val("");
|
||||
|
||||
xhr.send(formData);
|
||||
|
||||
},
|
||||
|
||||
url: function() {
|
||||
|
||||
var albumID = album.getID(),
|
||||
params,
|
||||
extension,
|
||||
buttons;
|
||||
|
||||
if (albumID===false) albumID = 0;
|
||||
|
||||
buttons = [
|
||||
["Import", function() {
|
||||
|
||||
link = $(".message input.text").val();
|
||||
|
||||
if (link&&link.length>3) {
|
||||
|
||||
extension = link.split('.').pop();
|
||||
if (extension!=="jpeg"&&extension!=="jpg"&&extension!=="png"&&extension!=="gif") {
|
||||
loadingBar.show("error", "The file format of this link is not supported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
modal.close();
|
||||
upload.show("cog", "Importing from URL");
|
||||
|
||||
params = "importUrl&url=" + escape(encodeURI(link)) + "&albumID=" + albumID;
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
upload.close();
|
||||
|
||||
if (album.getID()===false) lychee.goto("0");
|
||||
else album.load(albumID);
|
||||
|
||||
if (data!==true) lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
} else loadingBar.show("error", "Link to short or too long. Please try another one!");
|
||||
|
||||
}],
|
||||
["Cancel", function() {}]
|
||||
];
|
||||
modal.show("Import from Link", "Please enter the direct link to a photo to import it: <input class='text' type='text' placeholder='http://' value='http://'>", buttons);
|
||||
|
||||
},
|
||||
|
||||
server: function() {
|
||||
|
||||
var albumID = album.getID(),
|
||||
params,
|
||||
buttons;
|
||||
|
||||
if (albumID===false) albumID = 0;
|
||||
|
||||
buttons = [
|
||||
["Import", function() {
|
||||
|
||||
modal.close();
|
||||
upload.show("cog", "Importing photos");
|
||||
|
||||
params = "importServer&albumID=" + albumID;
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
upload.close();
|
||||
|
||||
if (album.getID()===false) lychee.goto("0");
|
||||
else album.load(albumID);
|
||||
|
||||
if (data==="Warning: Folder empty!") lychee.error("Folder empty. No photos imported!", params, data);
|
||||
else if (data!==true) lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
}],
|
||||
["Cancel", function() {}]
|
||||
];
|
||||
modal.show("Import from Server", "This action will import all photos which are located in <b>'uploads/import/'</b> of your Lychee installation.", buttons);
|
||||
|
||||
},
|
||||
|
||||
dropbox: function() {
|
||||
|
||||
var albumID = album.getID(),
|
||||
params;
|
||||
|
||||
if (albumID===false) albumID = 0;
|
||||
|
||||
lychee.loadDropbox(function() {
|
||||
Dropbox.choose({
|
||||
linkType: "direct",
|
||||
multiselect: true,
|
||||
success: function(files) {
|
||||
|
||||
if (files.length>1) {
|
||||
|
||||
for (var i = 0; i < files.length; i++) files[i] = files[i].link;
|
||||
|
||||
} else files = files[0].link;
|
||||
|
||||
upload.show("cog", "Importing photos");
|
||||
|
||||
params = "importUrl&url=" + escape(files) + "&albumID=" + albumID;
|
||||
lychee.api(params, function(data) {
|
||||
|
||||
upload.close();
|
||||
|
||||
if (album.getID()===false) lychee.goto("0");
|
||||
else album.load(albumID);
|
||||
|
||||
if (data!==true) lychee.error(null, params, data);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
close: function(force) {
|
||||
|
||||
if (force===true) {
|
||||
$(".upload_overlay").remove();
|
||||
} else {
|
||||
upload.setProgress(100);
|
||||
$(".upload_overlay").removeClass("fadeIn").css("opacity", 0);
|
||||
setTimeout(function() { $(".upload_overlay").remove() }, 300);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,485 +0,0 @@
|
||||
/**
|
||||
* @name animations.css
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2013 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
/* bounceInDown ------------------------------------------------*/
|
||||
@-webkit-keyframes bounceInDown {
|
||||
0% {
|
||||
-webkit-transform: translateY(-2000px);
|
||||
}
|
||||
60% {
|
||||
-webkit-transform: translateY(30px);
|
||||
}
|
||||
80% {
|
||||
-webkit-transform: translateY(-10px);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes bounceInDown {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes bounceInDown {
|
||||
0% {
|
||||
-ms-transform: translateY(-2000px);
|
||||
}
|
||||
60% {
|
||||
-ms-transform: translateY(30px);
|
||||
}
|
||||
80% {
|
||||
-ms-transform: translateY(-10px);
|
||||
}
|
||||
100% {
|
||||
-ms-transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@-o-keyframes bounceInDown {
|
||||
0% {
|
||||
-o-transform: translateY(-2000px);
|
||||
}
|
||||
60% {
|
||||
-o-transform: translateY(30px);
|
||||
}
|
||||
80% {
|
||||
-o-transform: translateY(-10px);
|
||||
}
|
||||
100% {
|
||||
-o-transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@keyframes bounceInDown {
|
||||
0% {
|
||||
transform: translateY(-2000px);
|
||||
}
|
||||
60% {
|
||||
transform: translateY(30px);
|
||||
}
|
||||
80% {
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* bounceOutUp ------------------------------------------------*/
|
||||
@-webkit-keyframes bounceOutUp {
|
||||
0% {
|
||||
-webkit-transform: translateY(0);
|
||||
}
|
||||
20% {
|
||||
-webkit-transform: translateY(20px);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: translateY(-2000px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes bounceOutUp {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes bounceOutUp {
|
||||
0% {
|
||||
-ms-transform: translateY(0);
|
||||
}
|
||||
20% {
|
||||
-ms-transform: translateY(20px);
|
||||
}
|
||||
100% {
|
||||
-ms-transform: translateY(-2000px);
|
||||
}
|
||||
}
|
||||
@-o-keyframes bounceOutUp {
|
||||
0% {
|
||||
-o-transform: translateY(0);
|
||||
}
|
||||
20% {
|
||||
-o-transform: translateY(20px);
|
||||
}
|
||||
100% {
|
||||
-o-transform: translateY(-2000px);
|
||||
}
|
||||
}
|
||||
@keyframes bounceOutUp {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
20% {
|
||||
transform: translateY(20px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(-2000px);
|
||||
}
|
||||
}
|
||||
|
||||
/* moveUp ------------------------------------------------*/
|
||||
@-webkit-keyframes moveUp {
|
||||
0% {
|
||||
-webkit-transform: translateY(1000px);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes moveUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes moveUp {
|
||||
0% {
|
||||
-ms-transform: translateY(1000px);
|
||||
}
|
||||
100% {
|
||||
-ms-transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
@-o-keyframes moveUp {
|
||||
0% {
|
||||
-o-transform: translateY(1000px);
|
||||
}
|
||||
100% {
|
||||
-o-transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
@keyframes moveUp {
|
||||
0% {
|
||||
transform: translateY(1000px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
|
||||
/* moveDown ------------------------------------------------*/
|
||||
@-webkit-keyframes moveDown {
|
||||
0% {
|
||||
-webkit-transform: translateY(-100px);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes moveDown {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes moveDown {
|
||||
0% {
|
||||
-ms-transform: translateY(-100px);
|
||||
}
|
||||
100% {
|
||||
-ms-transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@-o-keyframes moveDown {
|
||||
0% {
|
||||
-o-transform: translateY(-100px);
|
||||
}
|
||||
100% {
|
||||
-o-transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@keyframes moveDown {
|
||||
0% {
|
||||
transform: translateY(-100px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* fadeIn ------------------------------------------------*/
|
||||
@-webkit-keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-o-keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* fadeOut ------------------------------------------------*/
|
||||
@-webkit-keyframes fadeOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes fadeOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes fadeOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-o-keyframes fadeOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fadeOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* moveBackground ------------------------------------------------*/
|
||||
@-webkit-keyframes moveBackground {
|
||||
0% {
|
||||
background-position-x: 0px;
|
||||
}
|
||||
100% {
|
||||
background-position-x: -33px;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes moveBackground {
|
||||
0% {
|
||||
background-position-x: 0px;
|
||||
}
|
||||
100% {
|
||||
background-position-x: -33px;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes moveBackground {
|
||||
0% {
|
||||
background-position-x: 0px;
|
||||
}
|
||||
100% {
|
||||
background-position-x: -33px;
|
||||
}
|
||||
}
|
||||
@-o-keyframes moveBackground {
|
||||
0% {
|
||||
background-position-x: 0px;
|
||||
}
|
||||
100% {
|
||||
background-position-x: -33px;
|
||||
}
|
||||
}
|
||||
@keyframes moveBackground {
|
||||
0% {
|
||||
background-position-x: 0px;
|
||||
}
|
||||
100% {
|
||||
background-position-x: -33px;
|
||||
}
|
||||
}
|
||||
|
||||
/* zoomOut ------------------------------------------------*/
|
||||
@-webkit-keyframes zoomOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.5);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes zoomOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes zoomOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-o-keyframes zoomOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes zoomOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: scale(.5);
|
||||
}
|
||||
}
|
||||
|
||||
/* zoomIn ------------------------------------------------*/
|
||||
@-webkit-keyframes zoomIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(.5);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes zoomIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes zoomIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-o-keyframes zoomIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes zoomIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(.5);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* pulse ------------------------------------------------*/
|
||||
@-webkit-keyframes pulse {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes pulse {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-ms-keyframes pulse {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-o-keyframes pulse {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 79 KiB |
@ -0,0 +1 @@
|
||||
Entypo
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>app</key>
|
||||
<string>com.bohemiancoding.sketch</string>
|
||||
<key>build</key>
|
||||
<integer>5302</integer>
|
||||
<key>commit</key>
|
||||
<string>9460a4bc62af5e9ba50dd4143578fd9401710ce5</string>
|
||||
<key>version</key>
|
||||
<integer>18</integer>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1 @@
|
||||
18
|
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 9.4 KiB |
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>app</key>
|
||||
<string>com.bohemiancoding.sketch</string>
|
||||
<key>build</key>
|
||||
<integer>5302</integer>
|
||||
<key>commit</key>
|
||||
<string>9460a4bc62af5e9ba50dd4143578fd9401710ce5</string>
|
||||
<key>version</key>
|
||||
<integer>18</integer>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1 @@
|
||||
18
|
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
folderCSS="../assets/css"
|
||||
folderJS="../assets/js"
|
||||
|
||||
if [ -e "$folderCSS/modules/" ]
|
||||
then
|
||||
|
||||
echo "Compiling CSS ..."
|
||||
awk 'FNR==1{print ""}1' $folderCSS/modules/*.css > $folderCSS/min/main.css
|
||||
csso $folderCSS/min/main.css $folderCSS/min/main.css
|
||||
echo "CSS compiled!"
|
||||
|
||||
else
|
||||
|
||||
echo "CSS files not found in $folderCSS"
|
||||
|
||||
fi
|
||||
|
||||
if [ -e "$folderJS/modules/" ]
|
||||
then
|
||||
|
||||
echo "Compiling JS ..."
|
||||
awk 'FNR==1{print ""}1' $folderJS/modules/*.js > $folderJS/min/main.js
|
||||
uglifyjs $folderJS/min/main.js -o $folderJS/min/main.js
|
||||
echo "JS compiled!"
|
||||
|
||||
else
|
||||
|
||||
echo "JS files not found in $folderJS"
|
||||
|
||||
fi
|
@ -0,0 +1,40 @@
|
||||
#!/bin/sh
|
||||
|
||||
VERSION='1.3.2'
|
||||
|
||||
echo 'Press ENTER to continue or any other key to abort'
|
||||
read -s -n 1 key
|
||||
|
||||
if [[ "$key" = "" ]]
|
||||
then
|
||||
|
||||
if [ -e Lychee-$VERSION ]
|
||||
then
|
||||
|
||||
echo "The folder 'Lychee-$VERSION' already exists. Please delete it before you try to install Lychee."
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
if [ -e lychee ]
|
||||
then
|
||||
|
||||
echo "The folder 'lychee' already exists. Please delete it before you try to install Lychee."
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
echo 'Downloading and installing Lychee...' && \
|
||||
curl -sS https://codeload.github.com/electerious/Lychee/zip/v$VERSION > lychee.zip && \
|
||||
echo 'Downloaded.' && \
|
||||
echo 'Unzipping...' && \
|
||||
unzip lychee.zip && \
|
||||
rm lychee.zip && \
|
||||
mv Lychee-$VERSION lychee && \
|
||||
cd lychee && \
|
||||
echo 'The required directories will be made writable and executable for others. Please enter your password if prompted to do so.' && \
|
||||
sudo chmod -R 777 uploads php && \
|
||||
echo 'Installation successful!' && \
|
||||
exit 0
|
||||
|
||||
fi
|
@ -0,0 +1,16 @@
|
||||
### v2.0
|
||||
- All new redefined interface
|
||||
- Faster animations and transitions
|
||||
- Import from Dropbox
|
||||
- Import from Server
|
||||
- Download public albums
|
||||
- Several sorting options
|
||||
- Installation assistent
|
||||
- Infobox and description for albums
|
||||
- Faster loading and improved performance
|
||||
- Better file handling and upload
|
||||
- Album covers are chosen intelligent
|
||||
- Prettier URLs
|
||||
- Massive changes under the hood
|
||||
- IPTC support (Headline and Caption)
|
||||
- EXIF Orientation support
|
@ -0,0 +1,44 @@
|
||||
#### Lychee is not working
|
||||
If Lychee is not working properly, try to open `plugins/check.php`. This script will display all errors it can find. Everything should work if you can see the message "Lychee is ready. Lets rock!".
|
||||
|
||||
#### What do I need to run Lychee on my server?
|
||||
To run Lychee, everything you need is a web-server with PHP 5.3 or later and a MySQL-Database.
|
||||
|
||||
#### I can't upload multiple photos at once
|
||||
If you experience problems uploading large amounts of photos, you might want to change the PHP parameters in `.htaccess` (if you are using the PHP Apache module) or in `.user.ini` (if you are using PHP >= 5.3 with CGI or FastCGI).
|
||||
If possible, change these settings directly in your `php.ini`. We recommend to increase the values of the following properties:
|
||||
|
||||
max_execution_time = 200
|
||||
post_max_size = 200M
|
||||
upload_max_size = 200M
|
||||
upload_max_filesize = 20M
|
||||
max_file_uploads = 100
|
||||
|
||||
#### Which browsers are supported?
|
||||
Lychee supports the latest versions of Google Chrome, Apple Safari, Mozilla Firefox and Opera. Photos you share with others can be viewed from every browser.
|
||||
|
||||
#### How can I set thumbnails for my albums?
|
||||
Thumbnails are choosen automatically by the photos you have starred and in the order you uploaded them. Star a photo inside a album to set it as an thumbnail.
|
||||
|
||||
#### What is new?
|
||||
Take a look at the [Changelog](Changelog.md) to see whats new.
|
||||
|
||||
#### How can I backup my installation?
|
||||
To backup your Lychee installation you need to do the following steps:
|
||||
|
||||
1. Create a copy of the whole Lychee folder
|
||||
2. Run the following MySQL Queries:
|
||||
- CREATE TABLE lychee_albums_backup LIKE lychee_albums;
|
||||
- INSERT INTO lychee_albums_backup SELECT * FROM lychee_albums;
|
||||
- CREATE TABLE lychee_photos_backup LIKE lychee_photos;
|
||||
- INSERT INTO lychee_photos_backup SELECT * FROM lychee_photos;
|
||||
- CREATE TABLE lychee_settings_backup LIKE lychee_settings;
|
||||
- INSERT INTO lychee_settings_backup SELECT * FROM lychee_settings;
|
||||
|
||||
#### How to update?
|
||||
|
||||
1. Replace all files, excluding `uploads/`
|
||||
2. Open Lychee and enter your database details
|
||||
|
||||
#### Can I upload videos?
|
||||
No. Video support is not planned.
|
@ -0,0 +1,13 @@
|
||||
### Import from server
|
||||
|
||||
To import photos from your server (photos you have uploaded via FTP to your server), sign in and click the add-icon on the top right. Then choose 'Import from Server'.
|
||||
|
||||
### Upload and share single photos
|
||||
|
||||
You can upload photos directly with every FTP client into Lychee. This feature helps you to share single images quickly with others.
|
||||
|
||||
1. Upload an image to `uploads/import/`
|
||||
2. 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 with the filename of your uploaded file.
|
||||
3. Share the link.
|
||||
|
||||
Lychee will import the file as an public image, delete the original (unused) file and display it in the browser. [Sample FTP configuration](http://l.electerious.com/view.php?p=13657692738813).
|
@ -0,0 +1,29 @@
|
||||
### Requirements
|
||||
Everything you need is a web-server with PHP 5.3 or later and a MySQL-Database.
|
||||
|
||||
### PHP configuration `php.ini`
|
||||
|
||||
The following extensions must be activated:
|
||||
|
||||
extension = php_mbstring.dll
|
||||
extension = php_exif.dll
|
||||
extension = php_gd2.dll
|
||||
|
||||
To use Lychee without restrictions, we recommend to increase the values of the following properties:
|
||||
|
||||
max_execution_time = 200
|
||||
post_max_size = 200M
|
||||
upload_max_size = 200M
|
||||
upload_max_filesize = 20M
|
||||
max_file_uploads = 100
|
||||
|
||||
### Folder permissions
|
||||
|
||||
Change the permissions of `uploads/` and `php/` to 777, including all subfolders:
|
||||
|
||||
chmod -R 777 uploads/ php/
|
||||
|
||||
### Lychee installation
|
||||
|
||||
Open Lychee in your browser and follow the given steps.
|
||||
If you have trouble, take a look at the [FAQ](FAQ.md).
|
@ -0,0 +1,17 @@
|
||||
### Everywhere
|
||||
| Key | Action |
|
||||
|:-----------|:------------|
|
||||
| `enter` | Confirm Dialog |
|
||||
| `u` | Upload photo |
|
||||
| `esc` | Close/Back |
|
||||
| `cmd`+`up` | Close/Back |
|
||||
|
||||
### Photoview
|
||||
| Key | Action |
|
||||
|:-----------|:------------|
|
||||
| `s` | Star photo |
|
||||
| `i` | Show information |
|
||||
| `f` | Show photo in new tab
|
||||
| `cmd`+`backspace` | Delete photo
|
||||
| `left` | Previous photo
|
||||
| `right` | Next photo
|
@ -0,0 +1,41 @@
|
||||
### Database Details
|
||||
|
||||
Your MySQL details are stored in `php/config.php`. This file doesn't exist until you installed Lychee. If you need to change your connection details, you can edit this file manually.
|
||||
|
||||
|
||||
|
||||
$dbHost = Your MySQL host (in most cases you can use localhost)
|
||||
$dbUser = Your MySQL username
|
||||
$dbPassword = Your MySQL password
|
||||
$dbName = The name of the database you want to use
|
||||
|
||||
Fill these properties with your MySQL information. Lychee will create the database and tables for you, if they doesn't exist.
|
||||
|
||||
### Settings
|
||||
|
||||
All settings are stored in the database. You can change the properties manually, but we recommend to use the menu in Lychee. You can find this menu on the top left corner after you signed in.
|
||||
|
||||
#### Login
|
||||
|
||||
username = Username for Lychee
|
||||
password = Password for Lychee, saved as an md5 hash
|
||||
|
||||
Your photos and albums are protected by a username and password you need to set. If both rows are empty, Lychee will prompt you to set them.
|
||||
|
||||
#### Thumb Quality
|
||||
|
||||
thumbQuality = [0-100]
|
||||
|
||||
Less means a inferiority quality of your thumbs, but faster loading. More means a better quality of your thumbs, but slower loading. The default value is 90. The allowed values are between 0 and 100.
|
||||
|
||||
#### Check For Updates
|
||||
|
||||
checkForUpdates = [0|1]
|
||||
|
||||
If `1`, Lychee will check if you are using the latest version. The notice will be displayed beside the version-number when you sign in.
|
||||
|
||||
#### Sorting
|
||||
|
||||
sorting = ORDER BY [row] [ASC|DESC]
|
||||
|
||||
A typical part of an MySQL statement. This string will be appended to mostly every MySQL query.
|
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 184 B |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 113 B |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 4.4 KiB |
@ -1,147 +0,0 @@
|
||||
/**
|
||||
* @name main.js
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2013 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
/* Init */
|
||||
lychee.init();
|
||||
|
||||
/* Event Name */
|
||||
var event_name = (mobileBrowser()) ? "touchend" : "click";
|
||||
|
||||
/* Notifications */
|
||||
if (window.webkitNotifications) window.webkitNotifications.requestPermission();
|
||||
|
||||
/* Tooltips */
|
||||
if (!mobileBrowser()) $(".tools").tipsy({gravity: 'n'});
|
||||
|
||||
/* Header */
|
||||
$("#button_share").on(event_name, function(e) {
|
||||
if (photo.json.public==1||photo.json.public==2) contextMenu.sharePhoto(photo.getID(), e);
|
||||
else photo.setPublic(photo.getID(), e);
|
||||
});
|
||||
$("#button_share_album").on(event_name, function(e) {
|
||||
if (album.json.public==1) contextMenu.shareAlbum(album.getID(), e);
|
||||
else modal.show("Share Album", "All photos inside this album will be public and visible for everyone. Existing public photos will have the same sharing permission as this album. Are your sure you want to share this album? <input class='password' type='password' placeholder='password (optional)' value=''>", [["Share Album", function() { album.setPublic(album.getID(), e) }], ["Cancel", function() {}]]);
|
||||
});
|
||||
$("#button_signout").on(event_name, lychee.logout);
|
||||
$("#button_download").on(event_name, function() { window.open(photo.getDirectLink(),"_newtab") });
|
||||
$("#button_trash_album").on(event_name, function() { album.delete(album.getID()) });
|
||||
$("#button_move").on(event_name, function(e) { contextMenu.move(photo.getID(), e) });
|
||||
$("#button_trash").on(event_name, function() { photo.delete() });
|
||||
$("#button_edit_album").on(event_name, function() { album.setTitle() });
|
||||
$("#button_edit").on(event_name, function() { photo.setTitle(photo.getID()) });
|
||||
$("#button_info").on(event_name, function() { view.photo.showInfobox() });
|
||||
$("#button_archive").on(event_name, function() { album.getArchive(album.getID()) });
|
||||
$("#button_star").on(event_name, function() { photo.setStar(photo.getID()) });
|
||||
|
||||
/* Search */
|
||||
$("#search").on("keyup click", function() { search.find($(this).val()) });
|
||||
|
||||
/* Back Buttons */
|
||||
$("#button_back_home").on(event_name, function() { lychee.goto("") });
|
||||
$("#button_back").on(event_name, function() { lychee.goto("a" + album.getID()) });
|
||||
|
||||
/* Image View */
|
||||
lychee.imageview
|
||||
.on(event_name, "a#previous", function() {
|
||||
if (photo.json&&photo.json.previousPhoto) lychee.goto("a" + album.getID() + "p" + photo.json.previousPhoto)
|
||||
})
|
||||
.on(event_name, "a#next", function() {
|
||||
if (photo.json&&photo.json.nextPhoto) lychee.goto("a" + album.getID() + "p" + photo.json.nextPhoto)
|
||||
});
|
||||
|
||||
/* Infobox */
|
||||
$("#infobox")
|
||||
.on(event_name, ".header a", function() { view.photo.hideInfobox() })
|
||||
.on(event_name, "#edit_title", function() { photo.setTitle(photo.getID()) })
|
||||
.on(event_name, "#edit_description", function() { photo.setDescription(photo.getID()) });
|
||||
|
||||
/* Keyboard */
|
||||
Mousetrap
|
||||
.bind('n', function(e) { if (!visible.message()) $("body").append(build.addModal) })
|
||||
.bind('u', function(e) { $("#auswahl").html(""); $("#upload_files").click() })
|
||||
.bind('s', function(e) { if (visible.photo()) $("#button_star").click() })
|
||||
.bind('f', function(e) { if (visible.photo()) $("#button_download").click() })
|
||||
.bind('command+backspace', function(e) { if (visible.photo()&&!visible.message()) photo.delete() })
|
||||
.bind('left', function(e) { if (visible.photo()) $("#imageview a#previous").click() })
|
||||
.bind('right', function(e) { if (visible.photo()) $("#imageview a#next").click() })
|
||||
.bind('i', function(e) {
|
||||
if (visible.infobox()) view.photo.hideInfobox();
|
||||
else if (visible.photo()) view.photo.showInfobox();
|
||||
});
|
||||
|
||||
Mousetrap.bindGlobal('enter', function(e) {
|
||||
if ($(".message .button.active").length) $(".message .button.active").addClass("pressed").click()
|
||||
});
|
||||
|
||||
Mousetrap.bindGlobal(['esc', 'command+up'], function(e) {
|
||||
e.preventDefault();
|
||||
if (visible.message()) modal.close();
|
||||
else if (visible.contextMenu()) contextMenu.close();
|
||||
else if (visible.infobox()) view.photo.hideInfobox();
|
||||
else if (visible.photo()) lychee.goto("a" + album.getID());
|
||||
else if (visible.album()) lychee.goto("");
|
||||
else if (visible.albums()&&$("#search").val().length!=0) search.reset();
|
||||
});
|
||||
|
||||
/* Document */
|
||||
$(document)
|
||||
|
||||
/* Login */
|
||||
.on(event_name, "#button_signin", function() { lychee.loginDialog() })
|
||||
.on("keyup", "#password", function() { if ($(this).val().length>0) $(this).removeClass("error") })
|
||||
|
||||
/* Header */
|
||||
.on(event_name, "#title.editable", function() {
|
||||
if (visible.photo()) photo.setTitle(photo.getID());
|
||||
else album.setTitle();
|
||||
})
|
||||
|
||||
/* Navigation */
|
||||
.on("click", ".album", function() { lychee.goto("a" + $(this).attr("data-id")) })
|
||||
.on("click", ".photo", function() { lychee.goto("a" + album.getID() + "p" + $(this).attr("data-id")) })
|
||||
|
||||
/* Modal */
|
||||
.on(event_name, ".message .close", modal.close)
|
||||
.on(event_name, ".message .button:first", function() { modal.fns[0](); modal.close(); })
|
||||
.on(event_name, ".message .button:last", function() { modal.fns[1](); modal.close(); })
|
||||
|
||||
/* Add Dialog */
|
||||
.on(event_name, ".button_add", function() { $("body").append(build.addModal) })
|
||||
.on(event_name, "#add_album", album.add)
|
||||
.on(event_name, "#add_link", function() { photo.add.url() })
|
||||
.on(event_name, "#add_photo", function() { $("#auswahl").html(""); $("#upload_files").click() })
|
||||
|
||||
/* Upload */
|
||||
.on("change", "#upload_files", function() { modal.close(); photo.add.files(this.files); })
|
||||
|
||||
/* Context Menu */
|
||||
.on("contextmenu", ".photo", contextMenu.photo)
|
||||
.on("contextmenu", ".album", contextMenu.album)
|
||||
.on(event_name, ".contextmenu_bg", contextMenu.close)
|
||||
|
||||
/* Infobox */
|
||||
.on(event_name, "#infobox_overlay", function() { view.photo.hideInfobox() })
|
||||
|
||||
/* Controls */
|
||||
.bind("mouseenter", view.header.show)
|
||||
.bind("mouseleave", view.header.hide)
|
||||
|
||||
/* Upload */
|
||||
.on("dragover", function(e) { e.preventDefault(); }, false)
|
||||
.on("drop", function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
photo.add.files(e.originalEvent.dataTransfer.files);
|
||||
return true;
|
||||
});
|
||||
|
||||
/* Run */
|
||||
lychee.run();
|
||||
|
||||
});
|
@ -1,288 +0,0 @@
|
||||
/**
|
||||
* @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 "";
|
||||
|
||||
var album = ""
|
||||
title = albumJSON.title;
|
||||
|
||||
if (title.length>18) title = albumJSON.title.substr(0, 18) + "...";
|
||||
|
||||
album += "<div class='album' data-id='" + albumJSON.id + "' data-password='" + albumJSON.password + "'>";
|
||||
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'>";
|
||||
|
||||
if (albumJSON.password&&!lychee.publicMode) album += "<h1><span class='icon-lock'></span> " + title + "</h1>";
|
||||
else album += "<h1>" + title + "</h1>";
|
||||
|
||||
album += "<a>" + albumJSON.sysdate + "</a>";
|
||||
album += "</div>";
|
||||
|
||||
if(!lychee.publicMode&&albumJSON.star==1) album += "<a class='badge red icon-star'></a>";
|
||||
if(!lychee.publicMode&&albumJSON.public==1) album += "<a class='badge red icon-share'></a>";
|
||||
if(!lychee.publicMode&&albumJSON.unsorted==1) album += "<a class='badge red icon-reorder'></a>";
|
||||
|
||||
album += "</div>";
|
||||
|
||||
return album;
|
||||
|
||||
},
|
||||
|
||||
photo: function(photoJSON) {
|
||||
|
||||
if (!photoJSON) return "";
|
||||
|
||||
var photo = "",
|
||||
title = photoJSON.title;
|
||||
|
||||
if (title.length>18) title = photoJSON.title.substr(0, 18) + "...";
|
||||
|
||||
photo += "<div class='photo' data-album-id='" + photoJSON.album + "' data-id='" + photoJSON.id + "'>";
|
||||
photo += "<img src='" + photoJSON.thumbUrl + "' width='200' height='200' alt='thumb'>";
|
||||
photo += "<div class='overlay'>";
|
||||
photo += "<h1>" + title + "</h1>";
|
||||
photo += "<a>" + photoJSON.sysdate + "</a>";
|
||||
photo += "</div>";
|
||||
|
||||
if (photoJSON.star==1) photo += "<a class='badge red icon-star'></a>";
|
||||
if (!lychee.publicMode&&photoJSON.public==1&&album.json.public!=1) photo += "<a class='badge red icon-share'></a>";
|
||||
|
||||
photo += "</div>";
|
||||
|
||||
return photo;
|
||||
|
||||
},
|
||||
|
||||
no_content: function(typ) {
|
||||
|
||||
var no_content = "";
|
||||
|
||||
no_content += "<div class='no_content fadeIn'>";
|
||||
no_content += "<a class='icon icon-" + typ + "'></a>";
|
||||
|
||||
if (typ=="search") no_content += "<p>No results</p>";
|
||||
else if (typ=="picture") no_content += "<p>No public albums</p>";
|
||||
|
||||
no_content += "</div>";
|
||||
|
||||
return no_content;
|
||||
|
||||
},
|
||||
|
||||
modal: function(title, text, button) {
|
||||
|
||||
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 (this[0]!="") {
|
||||
|
||||
if (index==0) modal += "<a class='button active'>" + this[0] + "</a>";
|
||||
else modal += "<a class='button'>" + this[0] + "</a>";
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
modal += "</div>";
|
||||
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>New Album</a>";
|
||||
modal += "</div>";
|
||||
modal += "<div id='add_link' class='add_album'>";
|
||||
modal += "<div class='icon icon-link'></div>";
|
||||
modal += "<a>Import Link</a>";
|
||||
modal += "</div>";
|
||||
modal += "<div id='add_photo' class='add_album'>";
|
||||
modal += "<div class='icon icon-picture'></div>";
|
||||
modal += "<a>Upload 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 + "<span> – <a target='_blank' href='" + lychee.updateURL + "'>Update available!</a><span></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][0]=="separator"&&items[index][1]==-1) menu += "<tr class='separator'></tr>";
|
||||
else if (items[index][1]==-1) menu += "<tr class='no_hover'><td>" + items[index][0] + "</td></tr>";
|
||||
else if (items[index][2]!=undefined) menu += "<tr><td onclick='" + items[index][2] + "; window.contextMenu.close();'>" + items[index][0] + "</td></tr>";
|
||||
else menu += "<tr><td onclick='window.contextMenu.fns[" + items[index][1] + "](); window.contextMenu.close();'>" + items[index][0] + "</td></tr>";
|
||||
|
||||
});
|
||||
|
||||
menu += "</tbody>";
|
||||
menu += "</table>";
|
||||
menu += "</div>";
|
||||
|
||||
return menu;
|
||||
|
||||
},
|
||||
|
||||
infobox: function(photoJSON, forView) {
|
||||
|
||||
if (!photoJSON) return "";
|
||||
|
||||
var infobox = "",
|
||||
public,
|
||||
editTitleHTML,
|
||||
editDescriptionHTML,
|
||||
infos;
|
||||
|
||||
infobox += "<div class='header'><h1>About</h1><a class='icon-remove-sign'></a></div>";
|
||||
infobox += "<div class='wrapper'>";
|
||||
|
||||
switch (photoJSON.public) {
|
||||
case "0":
|
||||
public = "Private";
|
||||
break;
|
||||
case "1":
|
||||
public = "Public";
|
||||
break;
|
||||
case "2":
|
||||
public = "Public (Album)";
|
||||
break;
|
||||
default:
|
||||
public = "-";
|
||||
break;
|
||||
}
|
||||
|
||||
editTitleHTML = (forView==true||lychee.publicMode) ? "" : " <div id='edit_title'><a class='icon-pencil'></a></div>";
|
||||
editDescriptionHTML = (forView==true||lychee.publicMode) ? "" : " <div id='edit_description'><a class='icon-pencil'></a></div>";
|
||||
|
||||
infos = [
|
||||
["", "Basics"],
|
||||
["Name", photoJSON.title + editTitleHTML],
|
||||
["Uploaded", photoJSON.sysdate],
|
||||
["Description", photoJSON.description + editDescriptionHTML],
|
||||
["", "Image"],
|
||||
["Size", photoJSON.size],
|
||||
["Format", photoJSON.type],
|
||||
["Resolution", photoJSON.width + " x " + photoJSON.height],
|
||||
["", "Camera"],
|
||||
["Captured", photoJSON.takedate],
|
||||
["Make", photoJSON.make],
|
||||
["Type/Model", photoJSON.model],
|
||||
["Shutter Speed", photoJSON.shutter],
|
||||
["Aperture", photoJSON.aperture],
|
||||
["Focal Length", photoJSON.focal],
|
||||
["ISO", photoJSON.iso],
|
||||
["", "Share"],
|
||||
["Visibility", public]
|
||||
];
|
||||
|
||||
$.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;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/**
|
||||
* @name modal.js
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2013 by Philipp Maurer, Tobias Reich
|
||||
*
|
||||
* Modal Module
|
||||
* Build, show and hide a modal.
|
||||
*/
|
||||
|
||||
modal = {
|
||||
|
||||
fns: null,
|
||||
|
||||
show: function(title, text, buttons) {
|
||||
|
||||
if (!buttons) {
|
||||
var buttons = [];
|
||||
buttons[0] = ["", function() {}];
|
||||
buttons[1] = ["", function() {}];
|
||||
}
|
||||
|
||||
modal.fns = [buttons[0][1], buttons[1][1]];
|
||||
$("body").append(build.modal(title, text, buttons));
|
||||
$(".message input").focus();
|
||||
|
||||
},
|
||||
|
||||
close: function() {
|
||||
|
||||
modal.fns = null;
|
||||
$(".message_overlay").removeClass("fadeIn").css("opacity", 0);
|
||||
setTimeout(function() { $(".message_overlay").remove() }, 300);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,403 +0,0 @@
|
||||
/**
|
||||
* @name photo.js
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2013 by Philipp Maurer, Tobias Reich
|
||||
*
|
||||
* Photo Module
|
||||
* Takes care of every action a photo can handle and execute.
|
||||
*/
|
||||
|
||||
photo = {
|
||||
|
||||
json: null,
|
||||
|
||||
getID: function() {
|
||||
|
||||
var id;
|
||||
|
||||
if (photo.json) id = photo.json.id;
|
||||
else id = $(".photo:hover, .photo.active").attr("data-id");
|
||||
|
||||
if (id) return id;
|
||||
else return false;
|
||||
|
||||
},
|
||||
|
||||
load: function(photoID, albumID) {
|
||||
|
||||
var params,
|
||||
checkPasswd;
|
||||
|
||||
params = "getPhoto&photoID=" + photoID + "&albumID=" + albumID + "&password=" + password.value;
|
||||
lychee.api(params, "json", function(data) {
|
||||
|
||||
if (data=="HTTP/1.1 403 Wrong password!") {
|
||||
checkPasswd = function() {
|
||||
if (password.value!="") photo.load(photoID, albumID);
|
||||
else setTimeout(checkPasswd, 250);
|
||||
}
|
||||
checkPasswd();
|
||||
return false;
|
||||
}
|
||||
|
||||
photo.json = data;
|
||||
view.photo.init();
|
||||
|
||||
lychee.imageview.show();
|
||||
setTimeout(function() { lychee.content.show() }, 300);
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
parse: function() {
|
||||
|
||||
if (!photo.json.title) photo.json.title = "Untitled";
|
||||
photo.json.url = lychee.upload_path_big + photo.json.url;
|
||||
|
||||
},
|
||||
|
||||
add: {
|
||||
|
||||
files: function(files) {
|
||||
|
||||
var pre_progress = 0,
|
||||
formData = new FormData(),
|
||||
xhr = new XMLHttpRequest(),
|
||||
popup,
|
||||
progress;
|
||||
|
||||
$(".upload_overlay").remove();
|
||||
$("body").append(build.uploadModal());
|
||||
|
||||
window.onbeforeunload = function() { return "Lychee is currently uploading!"; };
|
||||
|
||||
for (var i = 0; i < files.length; i++) formData.append(i, files[i]);
|
||||
|
||||
formData.append("function", "upload");
|
||||
|
||||
if (album.getID()=="") formData.append("albumID", 0);
|
||||
else formData.append("albumID", album.getID());
|
||||
|
||||
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);
|
||||
setTimeout(function() { $(".upload_overlay").remove() }, 300);
|
||||
|
||||
if (window.webkitNotifications&&BrowserDetect.browser=="Safari") {
|
||||
popup = window.webkitNotifications.createNotification("", "Upload complete", "You can now manage your new photo.");
|
||||
popup.show();
|
||||
}
|
||||
|
||||
window.onbeforeunload = null;
|
||||
|
||||
if (album.getID()=="") lychee.goto("a0");
|
||||
else album.load(album.getID());
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
xhr.upload.onprogress = function(event) {
|
||||
|
||||
if (event.lengthComputable) {
|
||||
|
||||
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);
|
||||
|
||||
},
|
||||
|
||||
url: function(link) {
|
||||
|
||||
var albumID = album.getID();
|
||||
|
||||
if (!link) link = prompt("Please enter the direct link to a photo to import it:", "");
|
||||
if (album.getID()=="") albumID = 0;
|
||||
|
||||
if (link&&link.length>3) {
|
||||
|
||||
modal.close();
|
||||
|
||||
$(".upload_overlay").remove();
|
||||
$("body").append(build.uploadModal());
|
||||
$(".progressbar div").css({
|
||||
"opacity": 0.2,
|
||||
"width": "100%"
|
||||
});
|
||||
|
||||
params = "importUrl&url=" + escape(link) + "&albumID=" + albumID;
|
||||
lychee.api(params, "text", function(data) {
|
||||
|
||||
$(".upload_overlay").removeClass("fadeIn").css("opacity", 0);
|
||||
setTimeout(function() { $(".upload_overlay").remove() }, 300);
|
||||
|
||||
if (data) {
|
||||
if (album.getID()=="") lychee.goto("a0");
|
||||
else album.load(album.getID());
|
||||
} else loadingBar.show("error");
|
||||
|
||||
});
|
||||
|
||||
} else if (link.length>0) loadingBar.show("error", "Error", "Link to short or too long. Please try another one!");
|
||||
|
||||
},
|
||||
|
||||
dropbox: function() {
|
||||
|
||||
lychee.loadDropbox(function() {
|
||||
Dropbox.choose({
|
||||
linkType: "direct",
|
||||
multiselect: false,
|
||||
success: function(files) { photo.add.url(files[0].link) }
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
delete: function(photoID) {
|
||||
|
||||
var params,
|
||||
buttons,
|
||||
photoTitle;
|
||||
|
||||
if (!photoID) photoID = photo.getID();
|
||||
|
||||
if (visible.photo()) photoTitle = photo.json.title;
|
||||
else photoTitle = album.json.content[photoID].title;
|
||||
if (photoTitle=="") photoTitle = "Untitled";
|
||||
|
||||
buttons = [
|
||||
["Delete Photo", function() {
|
||||
|
||||
album.json.content[photoID] = null;
|
||||
view.album.content.delete(photoID);
|
||||
|
||||
// Only when search is not active
|
||||
if (!visible.albums()) lychee.goto("a" + album.getID());
|
||||
|
||||
params = "deletePhoto&photoID=" + photoID;
|
||||
lychee.api(params, "text", function(data) {
|
||||
|
||||
if (!data) loadingBar.show("error");
|
||||
|
||||
});
|
||||
|
||||
}],
|
||||
["Keep Photo", function() {}]
|
||||
];
|
||||
modal.show("Delete Photo", "Are you sure you want to delete the photo '" + photoTitle + "'?<br>This action can't be undone!", buttons);
|
||||
|
||||
},
|
||||
|
||||
setTitle: function(photoID) {
|
||||
|
||||
var oldTitle = "",
|
||||
newTitle,
|
||||
params;
|
||||
|
||||
if (!photoID) photoID = photo.getID();
|
||||
if (photo.json) oldTitle = photo.json.title;
|
||||
else if (album.json) oldTitle = album.json.content[photoID].title;
|
||||
|
||||
newTitle = prompt("Please enter a new title for this photo:", oldTitle);
|
||||
|
||||
if (photoID!=null&&photoID&&newTitle.length<31) {
|
||||
|
||||
if (visible.photo()) {
|
||||
photo.json.title = (newTitle=="") ? "Untitled" : newTitle;
|
||||
view.photo.title(oldTitle);
|
||||
}
|
||||
|
||||
album.json.content[photoID].title = newTitle;
|
||||
view.album.content.title(photoID);
|
||||
|
||||
params = "setPhotoTitle&photoID=" + photoID + "&title=" + escape(encodeURI(newTitle));
|
||||
lychee.api(params, "text", function(data) {
|
||||
|
||||
if (!data) loadingBar.show("error");
|
||||
|
||||
});
|
||||
|
||||
} else if (newTitle.length>0) loadingBar.show("error", "Error", "New title to short or too long. Please try another one!");
|
||||
|
||||
},
|
||||
|
||||
setAlbum: function(albumID, photoID) {
|
||||
|
||||
var params;
|
||||
|
||||
if (albumID>=0) {
|
||||
|
||||
if (visible.photo) lychee.goto("a" + album.getID());
|
||||
album.json.content[photoID] = null;
|
||||
view.album.content.delete(photoID);
|
||||
|
||||
params = "setAlbum&photoID=" + photoID + "&albumID=" + albumID;
|
||||
lychee.api(params, "text", function(data) {
|
||||
|
||||
if (!data) loadingBar.show("error");
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
setStar: function(photoID) {
|
||||
|
||||
var params;
|
||||
|
||||
if (visible.photo()) {
|
||||
photo.json.star = (photo.json.star==0) ? 1 : 0;
|
||||
view.photo.star();
|
||||
}
|
||||
|
||||
album.json.content[photoID].star = (album.json.content[photoID].star==0) ? 1 : 0;
|
||||
view.album.content.star(photoID);
|
||||
|
||||
params = "setPhotoStar&photoID=" + photoID;
|
||||
lychee.api(params, "text", function(data) {
|
||||
|
||||
if (!data) loadingBar.show("error");
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
setPublic: function(photoID, e) {
|
||||
|
||||
var params;
|
||||
|
||||
if (photo.json.public==2) {
|
||||
|
||||
modal.show("Public Album", "This photo is located in a public album. To make this photo private or public, edit the visibility of the associated album.", [["Show Album", function() { lychee.goto("a" + photo.json.original_album) }], ["Close", function() {}]]);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (visible.photo()) {
|
||||
|
||||
photo.json.public = (photo.json.public==0) ? 1 : 0;
|
||||
view.photo.public();
|
||||
if (photo.json.public==1) contextMenu.sharePhoto(photoID, e);
|
||||
|
||||
}
|
||||
|
||||
album.json.content[photoID].public = (album.json.content[photoID].public==0) ? 1 : 0;
|
||||
view.album.content.public(photoID);
|
||||
|
||||
params = "setPhotoPublic&photoID=" + photoID + "&url=" + photo.getViewLink(photoID);
|
||||
lychee.api(params, "text", function(data) {
|
||||
|
||||
if (!data) loadingBar.show("error");
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
setDescription: function(photoID) {
|
||||
|
||||
var oldDescription = photo.json.description,
|
||||
description = prompt("Please enter a description for this photo:", oldDescription),
|
||||
params;
|
||||
|
||||
if (description.length>0&&description.length<160) {
|
||||
|
||||
if (visible.photo()) {
|
||||
photo.json.description = description;
|
||||
view.photo.description(oldDescription);
|
||||
}
|
||||
|
||||
params = "setPhotoDescription&photoID=" + photoID + "&description=" + escape(description);
|
||||
lychee.api(params, "text", function(data) {
|
||||
|
||||
if (!data) loadingBar.show("error");
|
||||
|
||||
});
|
||||
|
||||
} else if (description.length>0) loadingBar.show("error", "Error", "Description to short or too long. Please try another one!");
|
||||
|
||||
},
|
||||
|
||||
share: function(photoID, service) {
|
||||
|
||||
var link = "",
|
||||
url = photo.getViewLink(photoID),
|
||||
params,
|
||||
filename = "unknown";
|
||||
|
||||
switch (service) {
|
||||
case 0:
|
||||
link = "https://twitter.com/share?url=" + encodeURI(url);
|
||||
break;
|
||||
case 1:
|
||||
link = "http://www.facebook.com/sharer.php?u=" + encodeURI(url) + "&t=" + encodeURI(photo.json.title);
|
||||
break;
|
||||
case 2:
|
||||
link = "mailto:?subject=" + encodeURI(photo.json.title) + "&body=" + encodeURI(url);
|
||||
break;
|
||||
case 3:
|
||||
lychee.loadDropbox(function() {
|
||||
filename = photo.json.title + "." + photo.getDirectLink().split('.').pop();
|
||||
Dropbox.save(photo.getDirectLink(), filename);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
link = "";
|
||||
break;
|
||||
}
|
||||
|
||||
if (link.length>5) location.href = link;
|
||||
|
||||
},
|
||||
|
||||
isSmall: function() {
|
||||
|
||||
var size = [
|
||||
["width", false],
|
||||
["height", false]
|
||||
];
|
||||
|
||||
if (photo.json.width<$(window).width()-60) size["width"] = true;
|
||||
if (photo.json.height<$(window).height()-100) size["height"] = true;
|
||||
|
||||
if (size["width"]&&size["height"]) return true;
|
||||
else return false;
|
||||
|
||||
},
|
||||
|
||||
getDirectLink: function() {
|
||||
|
||||
return $("#imageview #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
|
||||
|
||||
},
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,431 +0,0 @@
|
||||
/**
|
||||
* @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
|
||||
|
||||
/*password = localStorage.getItem("album" + albumID);
|
||||
if (password==null) {
|
||||
if (lychee.publicMode) password = prompt("Please enter a password for this album:", ""); else password = "";
|
||||
if (password!="") password = hex_md5(password);
|
||||
localStorage.setItem("album" + albumID, password);
|
||||
}*/
|
||||
|
||||
password = "";
|
||||
|
||||
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 + "&password=" + password;
|
||||
lychee.api(params, "json", function(data) {
|
||||
|
||||
if (data=="HTTP/1.1 403 Wrong password!") {
|
||||
localStorage.removeItem("album" + albumID);
|
||||
photos.load(albumID, refresh);
|
||||
return false;
|
||||
}
|
||||
|
||||
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, password);
|
||||
|
||||
}
|
||||
|
||||
}, false);
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
loadInfo: function(photoID, albumID) {
|
||||
|
||||
/*password = localStorage.getItem("album" + albumID);
|
||||
if (password==null) {
|
||||
if (lychee.publicMode) password = prompt("Please enter a password for this album:", ""); else password = "";
|
||||
if (password!="") password = hex_md5(password);
|
||||
localStorage.setItem("album" + albumID, password);
|
||||
}*/
|
||||
|
||||
password = "";
|
||||
|
||||
photos.showView();
|
||||
|
||||
params = "getPhotoInfo&photoID=" + photoID + "&password=" + password;
|
||||
lychee.api(params, "json", function(data) {
|
||||
|
||||
if (data=="HTTP/1.1 403 Wrong password!") {
|
||||
localStorage.removeItem("album" + albumID);
|
||||
photos.loadInfo(photoID, albumID);
|
||||
return false;
|
||||
}
|
||||
|
||||
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", "Share Photo");
|
||||
} else {
|
||||
$("#button_share a").removeClass("active");
|
||||
$("#button_share").attr("title", "Make Public");
|
||||
}
|
||||
|
||||
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(); });
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
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) {
|
||||
|
||||
params = "deletePhoto&photoID=" + photoID;
|
||||
lychee.api(params, "text", function(data) {
|
||||
|
||||
if (data) {
|
||||
|
||||
photos.hide(photoID);
|
||||
lychee.goto("a" + lychee.content.attr("data-id"));
|
||||
|
||||
} 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);
|
||||
|
||||
},
|
||||
|
||||
setTitle: 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) {
|
||||
|
||||
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);
|
||||
} else loadingBar.show("error");
|
||||
|
||||
});
|
||||
|
||||
} else if (newTitle.length>0) loadingBar.show("error", "Error", "New title to short or too long. Please try another one!");
|
||||
|
||||
},
|
||||
|
||||
setAlbum: function(photoID, albumID) {
|
||||
|
||||
if (albumID>=0) {
|
||||
|
||||
params = "setAlbum&photoID=" + photoID + "&albumID=" + albumID;
|
||||
lychee.api(params, "text", function(data) {
|
||||
|
||||
if (data) {
|
||||
photos.hide(photoID);
|
||||
lychee.goto("a" + lychee.content.attr("data-id"));
|
||||
} else loadingBar.show("error");
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
setStar: function() {
|
||||
|
||||
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);
|
||||
|
||||
} else loadingBar.show("error");
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
setPublic: function(e) {
|
||||
|
||||
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 Public");
|
||||
$("#infobox .attr_visibility").html("Private");
|
||||
} else {
|
||||
$("#button_share a").addClass("active");
|
||||
$("#button_share").attr("title", "Share Photo");
|
||||
$("#infobox .attr_visibility").html("Public");
|
||||
contextMenu.share(photoID, e.pageX, e.pageY);
|
||||
}
|
||||
|
||||
photos.load(lychee.content.attr("data-id"), true);
|
||||
|
||||
} 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) {
|
||||
|
||||
params = "setPhotoDescription&photoID=" + photoID + "&description=" + escape(description);
|
||||
lychee.api(params, "text", function(data) {
|
||||
|
||||
if (data) {
|
||||
$("#infobox .attr_description").html(description + " <div id='edit_description'><a class='icon-pencil'></a></div>");
|
||||
} 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) {
|
||||
|
||||
link = "";
|
||||
url = photos.getViewLink(photoID);
|
||||
|
||||
switch (service) {
|
||||
case 0:
|
||||
link = "https://twitter.com/share?url=" + encodeURI(url);
|
||||
break;
|
||||
case 1:
|
||||
link = "http://www.facebook.com/sharer.php?u=" + encodeURI(url) + "&t=" + encodeURI(lychee.title());
|
||||
break;
|
||||
case 2:
|
||||
link = "mailto:?subject=" + encodeURI(lychee.title()) + "&body=" + encodeURI("Hi! Check this out: " + url);
|
||||
break;
|
||||
case 3:
|
||||
modal = build.modal("Copy Link", "Everyone can view your public photos, but only you can edit them. Use this link to share your photo with others: <input class='copylink' value='" + url + "'>", ["Close"], [""]);
|
||||
$("body").append(modal);
|
||||
$(".copylink").focus();
|
||||
break;
|
||||
case 4:
|
||||
params = "getShortlink&photoID=" + photoID;
|
||||
lychee.api(params, "text", function(data) {
|
||||
if (data=="") data = "Something went wrong!";
|
||||
modal = build.modal("Copy Shortlink", "Everyone can view your public photos, but only you can edit them. Use this link to share your photo with others: <input class='copylink' value='" + data + "'>", ["Close"], [""]);
|
||||
$("body").append(modal);
|
||||
$(".copylink").focus();
|
||||
});
|
||||
break;
|
||||
default:
|
||||
link = "";
|
||||
break;
|
||||
}
|
||||
|
||||
if (link.length>5) location.href = link;
|
||||
|
||||
},
|
||||
|
||||
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);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `lychee_albums` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`title` varchar(50) NOT NULL,
|
||||
`sysdate` varchar(10) NOT NULL,
|
||||
`public` TINYINT(1) DEFAULT '0',
|
||||
`password` VARCHAR(100),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `lychee_photos` (
|
||||
`id` bigint(14) NOT NULL,
|
||||
`title` varchar(50) NOT NULL,
|
||||
`description` varchar(160) NOT NULL,
|
||||
`url` varchar(100) NOT NULL,
|
||||
`public` tinyint(1) NOT NULL,
|
||||
`shortlink` varchar(20) NOT NULL,
|
||||
`type` varchar(10) NOT NULL,
|
||||
`width` int(11) NOT NULL,
|
||||
`height` int(11) NOT NULL,
|
||||
`size` varchar(10) NOT NULL,
|
||||
`sysdate` varchar(10) NOT NULL,
|
||||
`systime` varchar(8) NOT NULL,
|
||||
`iso` varchar(15) NOT NULL,
|
||||
`aperture` varchar(10) NOT NULL,
|
||||
`make` varchar(20) NOT NULL,
|
||||
`model` varchar(50) NOT NULL,
|
||||
`shutter` varchar(10) NOT NULL,
|
||||
`focal` varchar(10) NOT NULL,
|
||||
`takedate` varchar(10) NOT NULL,
|
||||
`taketime` varchar(8) NOT NULL,
|
||||
`star` tinyint(1) NOT NULL,
|
||||
`thumbUrl` varchar(50) NOT NULL,
|
||||
`album` varchar(30) NOT NULL DEFAULT '0',
|
||||
`import_name` varchar(100) DEFAULT '',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
@ -1,115 +1,282 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name api.php
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2013 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
if (floatval(phpversion())<5.2) die('Please upgrade to PHP 5.2 or higher!');
|
||||
|
||||
if (!empty($_POST['function'])||!empty($_GET['function'])) {
|
||||
|
||||
session_start();
|
||||
define('LYCHEE', true);
|
||||
|
||||
require('config.php');
|
||||
require('functions.php');
|
||||
|
||||
// Security
|
||||
if (isset($_POST['albumID'])&&($_POST['albumID']==''||$_POST['albumID']<0)) exit('Wrong parameter type for albumID!');
|
||||
if (isset($_POST['photoID'])&&$_POST['photoID']=='') exit('Wrong parameter type for photoID!');
|
||||
|
||||
//Connect to DB
|
||||
$database = dbConnect();
|
||||
|
||||
if (isset($_SESSION['login'])&&$_SESSION['login']==true) {
|
||||
|
||||
/**
|
||||
* Admin Mode
|
||||
* Full access to Lychee. Only with correct password.
|
||||
*/
|
||||
|
||||
// Album Functions
|
||||
if ($_POST['function']=='getAlbums') echo json_encode(getAlbums(false));
|
||||
if ($_POST['function']=='getSmartInfo') echo json_encode(getSmartInfo());
|
||||
if ($_POST['function']=='getAlbum'&&isset($_POST['albumID'])) echo json_encode(getAlbum($_POST['albumID']));
|
||||
if ($_POST['function']=='addAlbum'&&isset($_POST['title'])) echo addAlbum($_POST['title']);
|
||||
if ($_POST['function']=='setAlbumTitle'&&isset($_POST['albumID'])&&isset($_POST['title'])) echo setAlbumTitle($_POST['albumID'], $_POST['title']);
|
||||
if ($_POST['function']=='setAlbumPublic'&&isset($_POST['albumID'])) echo setAlbumPublic($_POST['albumID'], $_POST['password']);
|
||||
if ($_POST['function']=='setAlbumPassword'&&isset($_POST['albumID'])&&isset($_POST['password'])) echo setAlbumPassword($_POST['albumID'], $_POST['password']);
|
||||
if ($_POST['function']=='deleteAlbum'&&isset($_POST['albumID'])&&isset($_POST['delAll'])) echo deleteAlbum($_POST['albumID'], $_POST['delAll']);
|
||||
if (isset($_GET['function'])&&$_GET['function']=='getAlbumArchive'&&isset($_GET['albumID'])) getAlbumArchive($_GET['albumID']);
|
||||
|
||||
// Photo Functions
|
||||
if ($_POST['function']=='getPhoto'&&isset($_POST['photoID'])&&isset($_POST['albumID'])) echo json_encode(getPhoto($_POST['photoID'], $_POST['albumID']));
|
||||
if ($_POST['function']=='deletePhoto'&&isset($_POST['photoID'])) echo deletePhoto($_POST['photoID']);
|
||||
if ($_POST['function']=='setAlbum'&&isset($_POST['photoID'])&&isset($_POST['albumID'])) echo setAlbum($_POST['photoID'], $_POST['albumID']);
|
||||
if ($_POST['function']=='setPhotoTitle'&&isset($_POST['photoID'])&&isset($_POST['title'])) echo setPhotoTitle($_POST['photoID'], $_POST['title']);
|
||||
if ($_POST['function']=='setPhotoStar'&&isset($_POST['photoID'])) echo setPhotoStar($_POST['photoID']);
|
||||
if ($_POST['function']=='setPhotoPublic'&&isset($_POST['photoID'])&&isset($_POST['url'])) echo setPhotoPublic($_POST['photoID'], $_POST['url']);
|
||||
if ($_POST['function']=='setPhotoDescription'&&isset($_POST['photoID'])&&isset($_POST['description'])) echo setPhotoDescription($_POST['photoID'], $_POST['description']);
|
||||
|
||||
// Add Function
|
||||
if ($_POST['function']=='upload'&&isset($_FILES)&&isset($_POST['albumID'])) echo upload($_FILES, $_POST['albumID']);
|
||||
if ($_POST['function']=='importUrl'&&isset($_POST['url'])&&isset($_POST['albumID'])) echo importUrl($_POST['url'], $_POST['albumID']);
|
||||
|
||||
// Search Function
|
||||
if ($_POST['function']=='search'&&isset($_POST['term'])) echo json_encode(search($_POST['term']));
|
||||
|
||||
// Session Functions
|
||||
if ($_POST['function']=='init') echo json_encode(init('admin'));
|
||||
if ($_POST['function']=='login') echo login($_POST['user'], $_POST['password']);
|
||||
if ($_POST['function']=='logout') logout();
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* Public Mode
|
||||
* Access to view all public folders and photos in Lychee.
|
||||
*/
|
||||
|
||||
// Album Functions
|
||||
if ($_POST['function']=='getAlbums') echo json_encode(getAlbums(true));
|
||||
if ($_POST['function']=='getAlbum'&&isset($_POST['albumID'])&&isset($_POST['password'])) {
|
||||
if (isAlbumPublic($_POST['albumID'])) {
|
||||
// Album Public
|
||||
if (checkAlbumPassword($_POST['albumID'], $_POST['password'])) echo json_encode(getAlbum($_POST['albumID']));
|
||||
else echo json_encode('HTTP/1.1 403 Wrong password!');
|
||||
} else {
|
||||
// Album Private
|
||||
echo json_encode('HTTP/1.1 403 Album private!');
|
||||
}
|
||||
}
|
||||
if ($_POST['function']=='checkAlbumAccess'&&isset($_POST['albumID'])&&isset($_POST['password'])) {
|
||||
if (isAlbumPublic($_POST['albumID'])) {
|
||||
// Album Public
|
||||
if (checkAlbumPassword($_POST['albumID'], $_POST['password'])) echo true;
|
||||
else echo false;
|
||||
} else {
|
||||
// Album Private
|
||||
echo false;
|
||||
}
|
||||
}
|
||||
|
||||
// Photo Functions
|
||||
if ($_POST['function']=='getPhoto'&&isset($_POST['photoID'])&&isset($_POST['albumID'])&&isset($_POST['password'])) {
|
||||
if (isPhotoPublic($_POST['photoID'], $_POST['password'])) echo json_encode(getPhoto($_POST['photoID'], $_POST['albumID']));
|
||||
else echo json_encode('HTTP/1.1 403 Wrong password!');
|
||||
}
|
||||
|
||||
// Session Functions
|
||||
if ($_POST['function']=='init') echo json_encode(init('public'));
|
||||
if ($_POST['function']=='login') echo login($_POST['user'], $_POST['password']);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
die('Error: No permission!');
|
||||
|
||||
}
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name API
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
@ini_set('max_execution_time', '200');
|
||||
@ini_set('post_max_size', '200M');
|
||||
@ini_set('upload_max_size', '200M');
|
||||
@ini_set('upload_max_filesize', '20M');
|
||||
@ini_set('max_file_uploads', '100');
|
||||
|
||||
if (!empty($_POST['function'])||!empty($_GET['function'])) {
|
||||
|
||||
session_start();
|
||||
define('LYCHEE', true);
|
||||
|
||||
require('modules/db.php');
|
||||
require('modules/session.php');
|
||||
require('modules/settings.php');
|
||||
require('modules/upload.php');
|
||||
require('modules/album.php');
|
||||
require('modules/photo.php');
|
||||
require('modules/misc.php');
|
||||
|
||||
if (file_exists('config.php')) require('config.php');
|
||||
else {
|
||||
|
||||
/**
|
||||
* Installation Mode
|
||||
* Limited access to configure Lychee. Only available when the config.php file is missing.
|
||||
*/
|
||||
|
||||
switch ($_POST['function']) {
|
||||
|
||||
case 'createConfig': if (isset($_POST['dbHost'])&&isset($_POST['dbUser'])&&isset($_POST['dbPassword'])&&isset($_POST['dbName']))
|
||||
echo createConfig($_POST['dbHost'], $_POST['dbUser'], $_POST['dbPassword'], $_POST['dbName']);
|
||||
break;
|
||||
|
||||
default: echo 'Warning: No configuration!';
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
exit();
|
||||
|
||||
}
|
||||
|
||||
// Connect to DB
|
||||
$database = dbConnect();
|
||||
|
||||
// Get Settings
|
||||
$settings = getSettings();
|
||||
|
||||
// Security
|
||||
if (isset($_POST['albumID'])&&($_POST['albumID']==''||$_POST['albumID']<0)) exit('Error: Wrong parameter type for albumID!');
|
||||
if (isset($_POST['photoID'])&&$_POST['photoID']=='') exit('Error: Wrong parameter type for photoID!');
|
||||
foreach(array_keys($_POST) as $key) $_POST[$key] = mysqli_real_escape_string($database, urldecode($_POST[$key]));
|
||||
|
||||
if (isset($_SESSION['login'])&&$_SESSION['login']==true) {
|
||||
|
||||
/**
|
||||
* Admin Mode
|
||||
* Full access to Lychee. Only with correct password/session.
|
||||
*/
|
||||
|
||||
switch ($_POST['function']) {
|
||||
|
||||
// Album Functions
|
||||
|
||||
case 'getAlbums': echo json_encode(getAlbums(false));
|
||||
break;
|
||||
|
||||
case 'getAlbum': if (isset($_POST['albumID']))
|
||||
echo json_encode(getAlbum($_POST['albumID']));
|
||||
break;
|
||||
|
||||
case 'addAlbum': if (isset($_POST['title']))
|
||||
echo addAlbum($_POST['title']);
|
||||
break;
|
||||
|
||||
case 'setAlbumTitle': if (isset($_POST['albumID'])&&isset($_POST['title']))
|
||||
echo setAlbumTitle($_POST['albumID'], $_POST['title']);
|
||||
break;
|
||||
|
||||
case 'setAlbumDescription': if (isset($_POST['albumID'])&&isset($_POST['description']))
|
||||
echo setAlbumDescription($_POST['albumID'], $_POST['description']);
|
||||
break;
|
||||
|
||||
case 'setAlbumPublic': if (isset($_POST['albumID']))
|
||||
echo setAlbumPublic($_POST['albumID'], $_POST['password']);
|
||||
break;
|
||||
|
||||
case 'setAlbumPassword':if (isset($_POST['albumID'])&&isset($_POST['password']))
|
||||
echo setAlbumPassword($_POST['albumID'], $_POST['password']);
|
||||
break;
|
||||
|
||||
case 'deleteAlbum': if (isset($_POST['albumID'])&&isset($_POST['delAll']))
|
||||
echo deleteAlbum($_POST['albumID'], $_POST['delAll']);
|
||||
break;
|
||||
|
||||
// Photo Functions
|
||||
|
||||
case 'getPhoto': if (isset($_POST['photoID'])&&isset($_POST['albumID']))
|
||||
echo json_encode(getPhoto($_POST['photoID'], $_POST['albumID']));
|
||||
break;
|
||||
|
||||
case 'deletePhoto': if (isset($_POST['photoID']))
|
||||
echo deletePhoto($_POST['photoID']);
|
||||
break;
|
||||
|
||||
case 'setAlbum': if (isset($_POST['photoID'])&&isset($_POST['albumID']))
|
||||
echo setAlbum($_POST['photoID'], $_POST['albumID']);
|
||||
break;
|
||||
|
||||
case 'setPhotoTitle': if (isset($_POST['photoID'])&&isset($_POST['title']))
|
||||
echo setPhotoTitle($_POST['photoID'], $_POST['title']);
|
||||
break;
|
||||
|
||||
case 'setPhotoStar': if (isset($_POST['photoID']))
|
||||
echo setPhotoStar($_POST['photoID']);
|
||||
break;
|
||||
|
||||
case 'setPhotoPublic': if (isset($_POST['photoID'])&&isset($_POST['url']))
|
||||
echo setPhotoPublic($_POST['photoID'], $_POST['url']);
|
||||
break;
|
||||
|
||||
case 'setPhotoDescription': if (isset($_POST['photoID'])&&isset($_POST['description']))
|
||||
echo setPhotoDescription($_POST['photoID'], $_POST['description']);
|
||||
break;
|
||||
|
||||
// Add Functions
|
||||
|
||||
case 'upload': if (isset($_FILES)&&isset($_POST['albumID']))
|
||||
echo upload($_FILES, $_POST['albumID']);
|
||||
break;
|
||||
|
||||
case 'importUrl': if (isset($_POST['url'])&&isset($_POST['albumID']))
|
||||
echo importUrl($_POST['url'], $_POST['albumID']);
|
||||
break;
|
||||
|
||||
case 'importServer': if (isset($_POST['albumID']))
|
||||
echo importServer($_POST['albumID']);
|
||||
break;
|
||||
|
||||
// Search Function
|
||||
|
||||
case 'search': if (isset($_POST['term']))
|
||||
echo json_encode(search($_POST['term']));
|
||||
break;
|
||||
|
||||
// Session Function
|
||||
|
||||
case 'init': echo json_encode(init('admin'));
|
||||
break;
|
||||
|
||||
case 'login': if (isset($_POST['user'])&&isset($_POST['password']))
|
||||
echo login($_POST['user'], $_POST['password']);
|
||||
break;
|
||||
|
||||
case 'logout': logout();
|
||||
break;
|
||||
|
||||
// Settings
|
||||
|
||||
case 'setLogin': if (isset($_POST['username'])&&isset($_POST['password']))
|
||||
echo setLogin($_POST['oldPassword'], $_POST['username'], $_POST['password']);
|
||||
break;
|
||||
|
||||
case 'setSorting': if (isset($_POST['type'])&&isset($_POST['order']))
|
||||
echo setSorting($_POST['type'], $_POST['order']);
|
||||
break;
|
||||
|
||||
// Miscellaneous
|
||||
|
||||
case 'update': echo update();
|
||||
|
||||
default: if (isset($_GET['function'])&&$_GET['function']=='getAlbumArchive'&&isset($_GET['albumID']))
|
||||
// Album Archive
|
||||
getAlbumArchive($_GET['albumID']);
|
||||
else if (isset($_GET['function'])&&$_GET['function']=='update')
|
||||
// Update Lychee
|
||||
echo update();
|
||||
else
|
||||
exit('Error: Function not found! Please check the spelling of the called function.');
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* Public Mode
|
||||
* Access to view all public folders and photos in Lychee.
|
||||
*/
|
||||
|
||||
switch ($_POST['function']) {
|
||||
|
||||
// Album Functions
|
||||
|
||||
case 'getAlbums': echo json_encode(getAlbums(true));
|
||||
break;
|
||||
|
||||
case 'getAlbum': if (isset($_POST['albumID'])&&isset($_POST['password'])) {
|
||||
if (isAlbumPublic($_POST['albumID'])) {
|
||||
// Album Public
|
||||
if (checkAlbumPassword($_POST['albumID'], $_POST['password']))
|
||||
echo json_encode(getAlbum($_POST['albumID']));
|
||||
else
|
||||
echo 'Warning: Wrong password!';
|
||||
} else {
|
||||
// Album Private
|
||||
echo 'Warning: Album private!';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'checkAlbumAccess':if (isset($_POST['albumID'])&&isset($_POST['password'])) {
|
||||
if (isAlbumPublic($_POST['albumID'])) {
|
||||
// Album Public
|
||||
if (checkAlbumPassword($_POST['albumID'], $_POST['password']))
|
||||
echo true;
|
||||
else
|
||||
echo false;
|
||||
} else {
|
||||
// Album Private
|
||||
echo false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Photo Functions
|
||||
|
||||
case 'getPhoto': if (isset($_POST['photoID'])&&isset($_POST['albumID'])&&isset($_POST['password'])) {
|
||||
if (isPhotoPublic($_POST['photoID'], $_POST['password']))
|
||||
echo json_encode(getPhoto($_POST['photoID'], $_POST['albumID']));
|
||||
else
|
||||
echo 'Warning: Wrong password!';
|
||||
}
|
||||
break;
|
||||
|
||||
// Session Functions
|
||||
|
||||
case 'init': echo json_encode(init('public'));
|
||||
break;
|
||||
|
||||
case 'login': if (isset($_POST['user'])&&isset($_POST['password']))
|
||||
echo login($_POST['user'], $_POST['password']);
|
||||
break;
|
||||
|
||||
// Miscellaneous
|
||||
|
||||
default: if (isset($_GET['function'])&&$_GET['function']=='getAlbumArchive'&&isset($_GET['albumID'])&&isset($_GET['password'])) {
|
||||
if (isAlbumPublic($_GET['albumID'])) {
|
||||
// Album Public
|
||||
if (checkAlbumPassword($_GET['albumID'], $_GET['password']))
|
||||
getAlbumArchive($_GET['albumID']);
|
||||
else
|
||||
echo 'Warning: Wrong password!';
|
||||
} else {
|
||||
// Album Private
|
||||
echo 'Warning: Album private or not downloadable!';
|
||||
}
|
||||
} else {
|
||||
exit('Error: Function not found! Please check the spelling of the called function.');
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
exit('Error: No permission!');
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
define('LYCHEE', true);
|
||||
|
||||
// Declare
|
||||
$error = '';
|
||||
|
||||
// Include
|
||||
require('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');
|
||||
|
||||
// Additional Config
|
||||
//if ($checkForUpdates!=true&&heckForUpdates!=false) $error .= ('Error 306: No property for \$checkForUpdates in config.php.<br>\n');
|
||||
if (!is_numeric($thumbQuality)||$thumbQuality<=0||$thumbQuality>=100) $error .= ('Error 307: Wrong property for \$thumbQuality in config.php.<br>\n');
|
||||
if ($sorting!='ASC'&&$sorting!='DESC') $error .= ('Error 308: Wrong property for \$sorting 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 (substr(sprintf('%o', fileperms('../uploads/')), -4)!='0777') $error .= ('Error 503: Wrong permissions for \'/uploads\' (777 required).<br>\n');
|
||||
|
||||
if ($error=='') echo('Lychee is ready!'); else echo $error;
|
||||
|
||||
?>
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name config.php
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2013 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
if(!defined('LYCHEE')) die('Direct access is not allowed!');
|
||||
|
||||
// Database configurations
|
||||
$db = 'lychee'; //Database name
|
||||
$dbUser = 'lychee'; //Username of the database
|
||||
$dbPassword = 'lychee_passwd'; //Password of the Database
|
||||
$dbHost = 'localhost'; //Host of the Database
|
||||
|
||||
// Admin Login
|
||||
$user = 'lychee'; //Admin Username
|
||||
$password = '1234'; //Admin Password
|
||||
|
||||
// Additional settings
|
||||
$checkForUpdates = true;
|
||||
$thumbQuality = 95; //Quality of the Thumbs (0-100). Default: 95
|
||||
$sorting = 'DESC'; //ASC or DESC sorting of albums and photos
|
||||
|
||||
?>
|
@ -1,801 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name functions.php
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2013 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
if (!defined('LYCHEE')) die('Direct access is not allowed!');
|
||||
|
||||
// Database Functions
|
||||
function dbConnect() {
|
||||
global $db, $dbUser, $dbPassword, $dbHost;
|
||||
$database = new mysqli($dbHost, $dbUser, $dbPassword);
|
||||
if (mysqli_connect_errno() != 0) {
|
||||
echo mysqli_connect_errno().': '.mysqli_connect_error();
|
||||
return false;
|
||||
}
|
||||
if (!$database->select_db($db)) {
|
||||
createDatabase($db, $database);
|
||||
}
|
||||
$query = "SELECT * FROM lychee_photos, lychee_albums;";
|
||||
if (!$database->query($query)) createTables($database);
|
||||
return $database;
|
||||
}
|
||||
function dbClose() {
|
||||
global $database;
|
||||
if (!$database->close()) {
|
||||
echo "Closing the connection failed!";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function createDatabase($db, $database) {
|
||||
$result = $database->query("CREATE DATABASE IF NOT EXISTS $db;");
|
||||
$database->select_db($db);
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
}
|
||||
function createTables($database) {
|
||||
$query = "CREATE TABLE IF NOT EXISTS `lychee_albums` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`title` varchar(50) NOT NULL,
|
||||
`sysdate` varchar(10) NOT NULL,
|
||||
`public` TINYINT(1) DEFAULT '0',
|
||||
`password` VARCHAR(100),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
|
||||
$query = "CREATE TABLE `lychee_photos` (
|
||||
`id` bigint(14) NOT NULL,
|
||||
`title` varchar(50) NOT NULL,
|
||||
`description` varchar(160) NOT NULL,
|
||||
`url` varchar(100) NOT NULL,
|
||||
`public` tinyint(1) NOT NULL,
|
||||
`type` varchar(10) NOT NULL,
|
||||
`width` int(11) NOT NULL,
|
||||
`height` int(11) NOT NULL,
|
||||
`size` varchar(10) NOT NULL,
|
||||
`sysdate` varchar(10) NOT NULL,
|
||||
`systime` varchar(8) NOT NULL,
|
||||
`iso` varchar(15) NOT NULL,
|
||||
`aperture` varchar(10) NOT NULL,
|
||||
`make` varchar(20) NOT NULL,
|
||||
`model` varchar(50) NOT NULL,
|
||||
`shutter` varchar(20) NOT NULL,
|
||||
`focal` varchar(10) NOT NULL,
|
||||
`takedate` varchar(10) NOT NULL,
|
||||
`taketime` varchar(8) NOT NULL,
|
||||
`star` tinyint(1) NOT NULL,
|
||||
`thumbUrl` varchar(50) NOT NULL,
|
||||
`album` varchar(30) NOT NULL DEFAULT '0',
|
||||
`import_name` varchar(100) DEFAULT '',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Upload Functions
|
||||
function upload($files, $albumID) {
|
||||
|
||||
global $database;
|
||||
|
||||
switch($albumID) {
|
||||
// s for public (share)
|
||||
case 's':
|
||||
$public = 1;
|
||||
$star = 0;
|
||||
$albumID = 0;
|
||||
break;
|
||||
// f for starred (fav)
|
||||
case 'f':
|
||||
$star = 1;
|
||||
$public = 0;
|
||||
$albumID = 0;
|
||||
break;
|
||||
default:
|
||||
$star = 0;
|
||||
$public = 0;
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
|
||||
$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];
|
||||
|
||||
// Import if not uploaded via web
|
||||
if (!is_uploaded_file($file)) {
|
||||
if (copy($tmp_name, "../uploads/big/" . md5($id) . ".$data")) {
|
||||
unlink($tmp_name);
|
||||
$import_name = $tmp_name;
|
||||
}
|
||||
} else {
|
||||
move_uploaded_file($tmp_name, "../uploads/big/" . md5($id) . ".$data");
|
||||
$import_name = "";
|
||||
}
|
||||
|
||||
// Create Thumb
|
||||
createThumb(md5($id).".".$data);
|
||||
|
||||
// Read infos
|
||||
$info = getCamera(md5($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, description, type, width, height, size, sysdate, systime, iso, aperture, make, model, shutter, focal, takedate, taketime, thumbUrl, album, public, star, import_name)
|
||||
VALUES ('$id', '$title', '" . md5($id) . ".$data', '', '$type', '$width', '$height', '$size', '$sysdate', '$systime', '$iso', '$aperture', '$make', '$model', '$shutter', '$focal', '$takeDate', '$takeTime', '" . md5($id) . ".$data', '$albumID', '$public', '$star', '$import_name');";
|
||||
$result = $database->query($query);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
function getCamera($filename) {
|
||||
global $database;
|
||||
$url = "../uploads/big/$filename";
|
||||
$type = getimagesize($url);
|
||||
$type = $type['mime'];
|
||||
|
||||
if (($type == "image/jpeg") && function_exists('exif_read_data') ){
|
||||
|
||||
$exif = exif_read_data($url, "EXIF", 0);
|
||||
|
||||
// General information
|
||||
$return['name'] = $exif['FileName'];
|
||||
$generalInfos = getimagesize($url);
|
||||
$return['type'] = $generalInfos['mime'];
|
||||
$return['width'] = $generalInfos[0];
|
||||
$return['height'] = $generalInfos[1];
|
||||
$size = (filesize($url) / 1024);
|
||||
if ($size >= 1024){$size=round($size/1024,1)." MB";} else {$size=round($size,1)." KB";}
|
||||
$return['size'] = $size;
|
||||
$return['date'] = date("d.m.Y",filectime($url));
|
||||
$return['time'] = date("H:i:s",filectime($url));
|
||||
|
||||
// Camera Information
|
||||
if (isset($exif['ISOSpeedRatings'])){$return['iso']="ISO-".$exif['ISOSpeedRatings'];}
|
||||
if (isset($exif['COMPUTED']['ApertureFNumber'])){$return['aperture']=$exif['COMPUTED']['ApertureFNumber'];}
|
||||
if (isset($exif['Make'])){$return['make']=$exif['Make'];}
|
||||
if (isset($exif['Model'])){$return['model']=$exif['Model'];}
|
||||
if (isset($exif['ExposureTime'])){$return['shutter']=$exif['ExposureTime']." Sek.";}
|
||||
if (isset($exif['FocalLength'])){$return['focal']=($exif['FocalLength']/1)." mm";}
|
||||
if (isset($exif['Software'])){$return['software']=$exif['Software'];}
|
||||
if (isset($exif['DateTimeOriginal'])) {
|
||||
$exifDate = explode(" ",$exif['DateTimeOriginal']);
|
||||
$date = explode(":", $exifDate[0]); $return['takeDate'] = $date[2].".".$date[1].".".$date[0];
|
||||
$return['takeTime'] = $exifDate[1];
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$exif = getimagesize($url);
|
||||
$return['type'] = $exif['mime'];
|
||||
$return['width'] = $exif[0];
|
||||
$return['height'] = $exif[1];
|
||||
$size = (filesize($url) / 1024);
|
||||
if ($size >= 1024){$size=round($size/1024,1)." MB";} else {$size=round($size,1)." KB";}
|
||||
$return['size'] = $size;
|
||||
$return['date'] = date("d.m.Y",filectime($url));
|
||||
$return['time'] = date("H:i:s",filectime($url));
|
||||
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
function createThumb($filename, $width = 200, $width2x = 400, $height = 200, $height2x = 400) {
|
||||
|
||||
global $database, $thumbQuality;
|
||||
$photoUrl = "../uploads/big/$filename";
|
||||
$newUrl = "../uploads/thumb/$filename";
|
||||
$thumbPhotoName = explode(".", $filename);
|
||||
$newUrl2x = "../uploads/thumb/".$thumbPhotoName[0]."@2x.".$thumbPhotoName[1];
|
||||
$oldImg = getimagesize($photoUrl);
|
||||
$type = $oldImg['mime'];
|
||||
|
||||
// Set position and size
|
||||
$thumb = imagecreatetruecolor($width, $height);
|
||||
$thumb2x = imagecreatetruecolor($width2x, $height2x);
|
||||
if ($oldImg[0]<$oldImg[1]) {
|
||||
$newSize = $oldImg[0];
|
||||
$startWidth = 0;
|
||||
$startHeight = $oldImg[1]/2 - $oldImg[0]/2;
|
||||
} else {
|
||||
$newSize = $oldImg[1];
|
||||
$startWidth = $oldImg[0]/2 - $oldImg[1]/2;
|
||||
$startHeight = 0;
|
||||
}
|
||||
|
||||
// Create new image
|
||||
switch($type) {
|
||||
case "image/jpeg": $sourceImg = imagecreatefromjpeg($photoUrl); break;
|
||||
case "image/png": $sourceImg = imagecreatefrompng($photoUrl); break;
|
||||
case "image/gif": $sourceImg = imagecreatefromgif($photoUrl); break;
|
||||
default: return false;
|
||||
}
|
||||
imagecopyresampled($thumb,$sourceImg,0,0,$startWidth,$startHeight,$width,$height,$newSize,$newSize);
|
||||
imagecopyresampled($thumb2x,$sourceImg,0,0,$startWidth,$startHeight,$width2x,$height2x,$newSize,$newSize);
|
||||
switch($type) {
|
||||
case "image/jpeg": imagejpeg($thumb,$newUrl,$thumbQuality); imagejpeg($thumb2x,$newUrl2x,$thumbQuality); break;
|
||||
case "image/png": imagepng($thumb,$newUrl); imagepng($thumb2x,$newUrl2x); break;
|
||||
case "image/gif": imagegif($thumb,$newUrl); imagegif($thumb2x,$newUrl2x); break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// Session Functions
|
||||
function init($mode) {
|
||||
global $checkForUpdates;
|
||||
$return["config"]["checkForUpdates"] = $checkForUpdates;
|
||||
if ($mode=="admin") $return["loggedIn"] = true;
|
||||
else $return["loggedIn"] = false;
|
||||
return $return;
|
||||
}
|
||||
function login($loginUser, $loginPassword) {
|
||||
global $database, $user, $password;
|
||||
if ($loginUser==$user&&$loginPassword==md5($password)) {
|
||||
// Admin Login
|
||||
$_SESSION['login'] = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function logout() {
|
||||
session_destroy();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Album Functions
|
||||
function addAlbum($title) {
|
||||
global $database;
|
||||
$title = mysqli_real_escape_string($database, urldecode($title));
|
||||
if (strlen($title)<1||strlen($title)>30) return false;
|
||||
$sysdate = date("d.m.Y");
|
||||
$query = "INSERT INTO lychee_albums (title, sysdate) VALUES ('$title', '$sysdate');";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
return $database->insert_id;
|
||||
}
|
||||
function getAlbums($public) {
|
||||
global $database, $sorting;
|
||||
|
||||
// Smart Albums
|
||||
if (!$public) $return = getSmartInfo();
|
||||
|
||||
// Albums
|
||||
if ($public) $query = "SELECT * FROM lychee_albums WHERE public = 1 ORDER BY id $sorting;";
|
||||
else $query = "SELECT * FROM lychee_albums ORDER BY id $sorting;";
|
||||
$result = $database->query($query) OR die("Error: $result <br>".$database->error);
|
||||
$i=0;
|
||||
while($row = $result->fetch_object()) {
|
||||
$return["content"][$row->id]['id'] = $row->id;
|
||||
$return["content"][$row->id]['title'] = $row->title;
|
||||
$return["content"][$row->id]['public'] = $row->public;
|
||||
$return["content"][$row->id]['sysdate'] = $row->sysdate;
|
||||
if ($row->password=="") $return["content"][$row->id]['password'] = false;
|
||||
else $return["content"][$row->id]['password'] = true;
|
||||
|
||||
// Thumbs
|
||||
if (($public&&$row->password=="")||(!$public)) {
|
||||
$albumID = $row->id;
|
||||
$query = "SELECT thumbUrl FROM lychee_photos WHERE album = '$albumID' ORDER BY id $sorting LIMIT 0, 3;";
|
||||
$result2 = $database->query($query);
|
||||
$k = 0;
|
||||
while($row2 = $result2->fetch_object()){
|
||||
$return["content"][$row->id]["thumb$k"] = $row2->thumbUrl;
|
||||
$k++;
|
||||
}
|
||||
if (!isset($return["content"][$row->id]["thumb0"])) $return["content"][$row->id]["thumb0"]="";
|
||||
if (!isset($return["content"][$row->id]["thumb1"])) $return["content"][$row->id]["thumb1"]="";
|
||||
if (!isset($return["content"][$row->id]["thumb2"])) $return["content"][$row->id]["thumb2"]="";
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if ($i==0) $return["albums"] = false;
|
||||
else $return["albums"] = true;
|
||||
return $return;
|
||||
}
|
||||
function getAlbum($albumID) {
|
||||
global $database, $sorting;
|
||||
switch($albumID) {
|
||||
case "f":
|
||||
$return['public'] = false;
|
||||
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE star = 1 ORDER BY id $sorting;";
|
||||
break;
|
||||
case "s":
|
||||
$return['public'] = false;
|
||||
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE public = 1 ORDER BY id $sorting;";
|
||||
break;
|
||||
case 0:
|
||||
$return['public'] = false;
|
||||
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE album = 0 ORDER BY id $sorting;";
|
||||
default:
|
||||
$result = $database->query("SELECT title, public, password FROM lychee_albums WHERE id = '$albumID';");
|
||||
$row = $result->fetch_object();
|
||||
$return['title'] = $row->title;
|
||||
$return['public'] = $row->public;
|
||||
if ($row->password=="") $return['password'] = false;
|
||||
else $return['password'] = true;
|
||||
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE album = '$albumID' ORDER BY id $sorting;";
|
||||
break;
|
||||
}
|
||||
$result = $database->query($query);
|
||||
$i = 0;
|
||||
while($row = $result->fetch_array()) {
|
||||
$return['content'][$row['id']] = $row;
|
||||
$i++;
|
||||
}
|
||||
if ($i==0) $return['content'] = false;
|
||||
$return['id'] = $albumID;
|
||||
$return['num'] = $i;
|
||||
return $return;
|
||||
}
|
||||
function getSmartInfo() {
|
||||
|
||||
global $database, $sorting;
|
||||
|
||||
// Unsorted
|
||||
$query = "SELECT * FROM lychee_photos WHERE album = 0 ORDER BY id $sorting;";
|
||||
$result = $database->query($query);
|
||||
$i = 0;
|
||||
while($row = $result->fetch_object()) {
|
||||
if ($i<3) $return["unsortedThumb$i"] = $row->thumbUrl;
|
||||
$i++;
|
||||
}
|
||||
$return['unsortedNum'] = $i;
|
||||
|
||||
// Public
|
||||
$query2 = "SELECT * FROM lychee_photos WHERE public = 1 ORDER BY id $sorting;";
|
||||
$result2 = $database->query($query2);
|
||||
$i = 0;
|
||||
while($row2 = $result2->fetch_object()) {
|
||||
if ($i<3) $return["publicThumb$i"] = $row2->thumbUrl;
|
||||
$i++;
|
||||
}
|
||||
$return['publicNum'] = $i;
|
||||
|
||||
// Starred
|
||||
$query3 = "SELECT * FROM lychee_photos WHERE star = 1 ORDER BY id $sorting;";
|
||||
$result3 = $database->query($query3);
|
||||
$i = 0;
|
||||
while($row3 = $result3->fetch_object()) {
|
||||
if ($i<3) $return["starredThumb$i"] = $row3->thumbUrl;
|
||||
$i++;
|
||||
}
|
||||
$return['starredNum'] = $i;
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
function setAlbumTitle($albumID, $title) {
|
||||
global $database;
|
||||
$title = mysqli_real_escape_string($database, urldecode($title));
|
||||
if (strlen($title)<1||strlen($title)>30) return false;
|
||||
$query = "UPDATE lychee_albums SET title = '$title' WHERE id = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
}
|
||||
function deleteAlbum($albumID, $delAll) {
|
||||
global $database;
|
||||
if ($delAll=="true") {
|
||||
$query = "SELECT id FROM lychee_photos WHERE album = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
$error = false;
|
||||
while($row = $result->fetch_object()) {
|
||||
if (!deletePhoto($row->id)) $error = true;
|
||||
}
|
||||
} else {
|
||||
$query = "UPDATE lychee_photos SET album = '0' WHERE album = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
}
|
||||
if ($albumID!=0) {
|
||||
$query = "DELETE FROM lychee_albums WHERE id = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
}
|
||||
if ($error) return false;
|
||||
return true;
|
||||
}
|
||||
function getAlbumArchive($albumID) {
|
||||
global $database;
|
||||
switch($albumID) {
|
||||
case 's':
|
||||
$query = "SELECT * FROM lychee_photos WHERE public = '1';";
|
||||
$zipTitle = "Public";
|
||||
break;
|
||||
case 'f':
|
||||
$query = "SELECT * FROM lychee_photos WHERE star = '1';";
|
||||
$zipTitle = "Starred";
|
||||
break;
|
||||
default:
|
||||
$query = "SELECT * FROM lychee_photos WHERE album = '$albumID';";
|
||||
$zipTitle = "Unsorted";
|
||||
}
|
||||
$result = $database->query($query);
|
||||
$files = array();
|
||||
$i=0;
|
||||
while($row = $result->fetch_object()) {
|
||||
$files[$i] = "../uploads/big/".$row->url;
|
||||
$i++;
|
||||
}
|
||||
$query = "SELECT * FROM lychee_albums WHERE id = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
$row = $result->fetch_object();
|
||||
if ($albumID!=0&&is_numeric($albumID))$zipTitle = $row->title;
|
||||
$filename = "../uploads/".$zipTitle.".zip";
|
||||
|
||||
$zip = new ZipArchive();
|
||||
|
||||
if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($files AS $zipFile) {
|
||||
$newFile = explode("/",$zipFile);
|
||||
$newFile = array_reverse($newFile);
|
||||
$zip->addFile($zipFile, $zipTitle."/".$newFile[0]);
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
header("Content-Type: application/zip");
|
||||
header("Content-Disposition: attachment; filename=\"$zipTitle.zip\"");
|
||||
header("Content-Length: ".filesize($filename));
|
||||
readfile($filename);
|
||||
unlink($filename);
|
||||
|
||||
return true;
|
||||
}
|
||||
function setAlbumPublic($albumID, $password) {
|
||||
global $database;
|
||||
$query = "SELECT public FROM lychee_albums WHERE id = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
$row = $result->fetch_object();
|
||||
if ($row->public == 0){
|
||||
$public = 1;
|
||||
} else {
|
||||
$public = 0;
|
||||
}
|
||||
$query = "UPDATE lychee_albums SET public = '$public', password = NULL WHERE id = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
if ($public==1) {
|
||||
$query = "UPDATE lychee_photos SET public = 0 WHERE album = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
}
|
||||
if (strlen($password)>0) return setAlbumPassword($albumID, $password);
|
||||
else return true;
|
||||
}
|
||||
function setAlbumPassword($albumID, $password) {
|
||||
global $database;
|
||||
$query = "UPDATE lychee_albums SET password = '$password' WHERE id = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
}
|
||||
function checkAlbumPassword($albumID, $password) {
|
||||
global $database;
|
||||
$query = "SELECT public, password FROM lychee_albums WHERE id = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
$row = $result->fetch_object();
|
||||
if ($row->password=="") return true;
|
||||
else if ($row->password==$password) return true;
|
||||
else return false;
|
||||
}
|
||||
function isAlbumPublic($albumID) {
|
||||
global $database;
|
||||
$query = "SELECT public, password FROM lychee_albums WHERE id = '$albumID';";
|
||||
$result = $database->query($query);
|
||||
$row = $result->fetch_object();
|
||||
if ($row->public==1) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
// Photo Functions
|
||||
function getPhoto($photoID, $albumID) {
|
||||
global $database;
|
||||
if (!is_numeric($photoID)) {
|
||||
$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, 's');
|
||||
}
|
||||
if (is_file("../uploads/import/$photoID")) {
|
||||
importPhoto($photoID, 's');
|
||||
}
|
||||
$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();
|
||||
|
||||
if ($albumID!='false') {
|
||||
|
||||
if ($return['album']!=0) {
|
||||
|
||||
$result = $database->query("SELECT public FROM lychee_albums WHERE id = " . $return['album'] . ";");
|
||||
$return_album = $result->fetch_array();
|
||||
if ($return_album['public']=="1") $return['public'] = "2";
|
||||
|
||||
}
|
||||
|
||||
$return['original_album'] = $return['album'];
|
||||
$return['album'] = $albumID;
|
||||
|
||||
$nextPhoto = getNextPhotoID($photoID, $albumID, false);
|
||||
if ($nextPhoto==$photoID) $return['nextPhoto'] = false;
|
||||
else $return['nextPhoto'] = $nextPhoto;
|
||||
|
||||
$previousPhoto = getPreviousPhotoID($photoID, $albumID, false);
|
||||
if ($previousPhoto==$photoID) $return['previousPhoto'] = false;
|
||||
else $return['previousPhoto'] = $previousPhoto;
|
||||
|
||||
}
|
||||
|
||||
unset($return['album_public']);
|
||||
|
||||
return $return;
|
||||
}
|
||||
function setPhotoPublic($photoID, $url) {
|
||||
global $database;
|
||||
$query = "SELECT public FROM lychee_photos WHERE id = '$photoID';";
|
||||
$result = $database->query($query);
|
||||
$row = $result->fetch_object();
|
||||
if ($row->public == 0){
|
||||
$public = 1;
|
||||
} else {
|
||||
$public = 0;
|
||||
}
|
||||
$query = "UPDATE lychee_photos SET public = '$public' WHERE id = '$photoID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
}
|
||||
function setPhotoStar($photoID) {
|
||||
global $database;
|
||||
$query = "SELECT star FROM lychee_photos WHERE id = '$photoID';";
|
||||
$result = $database->query($query);
|
||||
$row = $result->fetch_object();
|
||||
if ($row->star == 0) {
|
||||
$star = 1;
|
||||
} else {
|
||||
$star = 0;
|
||||
}
|
||||
$query = "UPDATE lychee_photos SET star = '$star' WHERE id = '$photoID';";
|
||||
$result = $database->query($query);
|
||||
return true;
|
||||
}
|
||||
function getNextPhotoID($photoID, $albumID, $innerCall) {
|
||||
global $database, $sorting;
|
||||
if (!$innerCall&&$sorting=="ASC") return getPreviousPhotoID($photoID, $albumID, true);
|
||||
switch($albumID) {
|
||||
case 'f': $query = "SELECT id FROM lychee_photos WHERE id < '$photoID' AND star = '1' ORDER BY id DESC LIMIT 0, 1;";
|
||||
break;
|
||||
case 's': $query = "SELECT id FROM lychee_photos WHERE id < '$photoID' AND public = '1' ORDER BY id DESC LIMIT 0, 1;";
|
||||
break;
|
||||
default: $query = "SELECT id FROM lychee_photos WHERE id < '$photoID' AND album = '$albumID' ORDER BY id DESC LIMIT 0, 1;";
|
||||
}
|
||||
$result = $database->query($query);
|
||||
$return = $result->fetch_array();
|
||||
if (!$return || ($return==0)) {
|
||||
switch($albumID) {
|
||||
case 'f': $query = "SELECT id FROM lychee_photos WHERE star = '1' ORDER BY id DESC LIMIT 0, 1;";
|
||||
break;
|
||||
case 's': $query = "SELECT id FROM lychee_photos WHERE public = '1' ORDER BY id DESC LIMIT 0, 1;";
|
||||
break;
|
||||
default: $query = "SELECT id FROM lychee_photos WHERE album = '$albumID' ORDER BY id DESC LIMIT 0, 1;";
|
||||
}
|
||||
$result = $database->query($query);
|
||||
$return = $result->fetch_array();
|
||||
}
|
||||
return $return['id'];
|
||||
}
|
||||
function getPreviousPhotoID($photoID, $albumID, $innerCall) {
|
||||
global $database, $sorting;
|
||||
if (!$innerCall&&$sorting=="ASC") return getNextPhotoID($photoID, $albumID, true);
|
||||
switch($albumID) {
|
||||
case 'f': $query = "SELECT id FROM lychee_photos WHERE id > '$photoID' AND star = '1' ORDER BY id LIMIT 0, 1;";
|
||||
break;
|
||||
case 's': $query = "SELECT id FROM lychee_photos WHERE id > '$photoID' AND public = '1' ORDER BY id LIMIT 0, 1;";
|
||||
break;
|
||||
default: $query = "SELECT id FROM lychee_photos WHERE id > '$photoID' AND album = '$albumID' ORDER BY id LIMIT 0, 1;";
|
||||
}
|
||||
$result = $database->query($query);
|
||||
$return = $result->fetch_array();
|
||||
if (!$return || ($return==0)) {
|
||||
switch($albumID) {
|
||||
case 'f': $query = "SELECT id FROM lychee_photos WHERE star = '1' ORDER BY id LIMIT 0, 1;";
|
||||
break;
|
||||
case 's': $query = "SELECT id FROM lychee_photos WHERE public = '1' ORDER BY id LIMIT 0, 1;";
|
||||
break;
|
||||
default: $query = "SELECT id FROM lychee_photos WHERE album = '$albumID' ORDER BY id LIMIT 0, 1;";
|
||||
}
|
||||
$result = $database->query($query);
|
||||
$return = $result->fetch_array();
|
||||
}
|
||||
return $return['id'];
|
||||
}
|
||||
function setAlbum($photoID, $newAlbum) {
|
||||
global $database;
|
||||
$query = "UPDATE lychee_photos SET album = '$newAlbum' WHERE id = '$photoID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
else return true;
|
||||
}
|
||||
function setPhotoTitle($photoID, $title) {
|
||||
global $database;
|
||||
$title = mysqli_real_escape_string($database, urldecode($title));
|
||||
if (strlen($title)>30) return false;
|
||||
$query = "UPDATE lychee_photos SET title = '$title' WHERE id = '$photoID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
else return true;
|
||||
}
|
||||
function setPhotoDescription($photoID, $description) {
|
||||
global $database;
|
||||
$description = mysqli_real_escape_string($database, htmlentities($description));
|
||||
if (strlen($description)>160) return false;
|
||||
$query = "UPDATE lychee_photos SET description = '$description' WHERE id = '$photoID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
}
|
||||
function deletePhoto($photoID) {
|
||||
global $database;
|
||||
$query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
|
||||
$result = $database->query($query);
|
||||
if (!$result) return false;
|
||||
$row = $result->fetch_object();
|
||||
$retinaUrl = explode(".", $row->thumbUrl);
|
||||
$unlink1 = unlink("../uploads/big/".$row->url);
|
||||
$unlink2 = unlink("../uploads/thumb/".$row->thumbUrl);
|
||||
$unlink3 = unlink("../uploads/thumb/".$retinaUrl[0].'@2x.'.$retinaUrl[1]);
|
||||
$query = "DELETE FROM lychee_photos WHERE id = '$photoID';";
|
||||
$result = $database->query($query);
|
||||
if (!$unlink1 || !$unlink2 || !$unlink3) return false;
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
}
|
||||
function importPhoto($name, $albumID) {
|
||||
$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, $albumID)) return false;
|
||||
else return true;
|
||||
}
|
||||
function importUrl($url, $albumID) {
|
||||
if (@getimagesize($url)) {
|
||||
$pathinfo = pathinfo($url);
|
||||
$filename = $pathinfo['filename'].".".$pathinfo['extension'];
|
||||
$tmp_name = "../uploads/import/$filename";
|
||||
copy($url, $tmp_name);
|
||||
return importPhoto($filename, $albumID);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Share Functions
|
||||
function facebookHeader($photoID) {
|
||||
$database = dbConnect();
|
||||
if (!is_numeric($photoID)) return false;
|
||||
$query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
|
||||
$result = $database->query($query);
|
||||
$row = $result->fetch_object();
|
||||
|
||||
$parseUrl = parse_url("http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
|
||||
$thumb = $parseUrl['scheme']."://".$parseUrl['host'].$parseUrl['path']."/../uploads/big/".$row->thumbUrl;
|
||||
|
||||
$return .= '<!-- General Meta Data -->';
|
||||
$return = '<meta name="title" content="'.$row->title.'" />';
|
||||
$return .= '<meta name="description" content="'.$row->description.' - via Lychee" />';
|
||||
$return .= '<link rel="image_src" type="image/jpeg" href="'.$thumb.'" />';
|
||||
|
||||
$return .= '<!-- Twitter Meta Data -->';
|
||||
$return .= '<meta name="twitter:card" content="photo">';
|
||||
$return .= '<meta name="twitter:title" content="'.$row->title.'">';
|
||||
$return .= '<meta name="twitter:image:src" content="'.$thumb.'">';
|
||||
|
||||
$return .= '<!-- Facebook Meta Data -->';
|
||||
$return .= '<meta property="og:title" content="'.$row->title.'">';
|
||||
$return .= '<meta property="og:image" content="'.$thumb.'">';
|
||||
|
||||
return $return;
|
||||
}
|
||||
function isPhotoPublic($photoID, $password) {
|
||||
global $database;
|
||||
$photoID = mysqli_real_escape_string($database, $photoID);
|
||||
if (is_numeric($photoID)) {
|
||||
$query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
|
||||
} 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 {
|
||||
$cAP = checkAlbumPassword($row->album, $password);
|
||||
$iAP = isAlbumPublic($row->album);
|
||||
if ($iAP&&$cAP) return true;
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Search Function
|
||||
function search($term) {
|
||||
global $database, $sorting;
|
||||
$return["albums"] = "";
|
||||
$term = mysqli_real_escape_string($database, $term);
|
||||
|
||||
$query = "SELECT * FROM lychee_photos WHERE title like '%$term%' OR description like '%$term%';";
|
||||
$result = $database->query($query);
|
||||
while($row = $result->fetch_array()) {
|
||||
$return['photos'][$row['id']] = $row;
|
||||
}
|
||||
|
||||
$query = "SELECT * FROM lychee_albums WHERE title like '%$term%';";
|
||||
$result = $database->query($query);
|
||||
$i=0;
|
||||
while($row = $result->fetch_object()) {
|
||||
|
||||
$return["albums"][$row->id]['id'] = $row->id;
|
||||
$return["albums"][$row->id]['title'] = $row->title;
|
||||
$return["albums"][$row->id]['public'] = $row->public;
|
||||
$return["albums"][$row->id]['sysdate'] = $row->sysdate;
|
||||
if ($row->password=="") $return["albums"][$row->id]['password'] = false;
|
||||
else $return["albums"][$row->id]['password'] = true;
|
||||
|
||||
$query2 = "SELECT thumbUrl FROM lychee_photos WHERE album = '".$row->id."' ORDER BY id $sorting LIMIT 0, 3;";
|
||||
$result2 = $database->query($query2);
|
||||
$k = 0;
|
||||
while($row2 = $result2->fetch_object()){
|
||||
$return['albums'][$row->id]["thumb$k"] = $row2->thumbUrl;
|
||||
$k++;
|
||||
}
|
||||
$i++;
|
||||
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,354 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name Album Module
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
|
||||
|
||||
function addAlbum($title) {
|
||||
|
||||
global $database;
|
||||
|
||||
if (strlen($title)<1||strlen($title)>30) return false;
|
||||
$sysdate = date("d.m.Y");
|
||||
$result = $database->query("INSERT INTO lychee_albums (title, sysdate) VALUES ('$title', '$sysdate');");
|
||||
if (!$result) return false;
|
||||
|
||||
return $database->insert_id;
|
||||
|
||||
}
|
||||
|
||||
function getAlbums($public) {
|
||||
|
||||
global $database, $settings;
|
||||
|
||||
// Smart Albums
|
||||
if (!$public) $return = getSmartInfo();
|
||||
|
||||
// Albums
|
||||
if ($public) $query = "SELECT * FROM lychee_albums WHERE public = 1";
|
||||
else $query = "SELECT * FROM lychee_albums";
|
||||
$result = $database->query($query) OR exit("Error: $result <br>".$database->error);
|
||||
$i = 0;
|
||||
while($row = $result->fetch_object()) {
|
||||
|
||||
// Info
|
||||
$return["content"][$row->id]['id'] = $row->id;
|
||||
$return["content"][$row->id]['title'] = $row->title;
|
||||
$return["content"][$row->id]['public'] = $row->public;
|
||||
$return["content"][$row->id]['sysdate'] = date('F Y', strtotime($row->sysdate));
|
||||
if ($row->password=="") $return["content"][$row->id]['password'] = false;
|
||||
else $return["content"][$row->id]['password'] = true;
|
||||
|
||||
// Thumbs
|
||||
if (($public&&$row->password=="")||(!$public)) {
|
||||
$albumID = $row->id;
|
||||
$result2 = $database->query("SELECT thumbUrl FROM lychee_photos WHERE album = '$albumID' ORDER BY star DESC, " . substr($settings['sorting'], 9) . " LIMIT 0, 3");
|
||||
$k = 0;
|
||||
while($row2 = $result2->fetch_object()){
|
||||
$return["content"][$row->id]["thumb$k"] = $row2->thumbUrl;
|
||||
$k++;
|
||||
}
|
||||
if (!isset($return["content"][$row->id]["thumb0"])) $return["content"][$row->id]["thumb0"] = "";
|
||||
if (!isset($return["content"][$row->id]["thumb1"])) $return["content"][$row->id]["thumb1"] = "";
|
||||
if (!isset($return["content"][$row->id]["thumb2"])) $return["content"][$row->id]["thumb2"] = "";
|
||||
}
|
||||
|
||||
// Album count
|
||||
$i++;
|
||||
|
||||
}
|
||||
|
||||
$return["num"] = $i;
|
||||
|
||||
if ($i==0) $return["albums"] = false;
|
||||
else $return["albums"] = true;
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
function getSmartInfo() {
|
||||
|
||||
global $database, $settings;
|
||||
|
||||
// Unsorted
|
||||
$result = $database->query("SELECT thumbUrl FROM lychee_photos WHERE album = 0 " . $settings['sorting']);
|
||||
$i = 0;
|
||||
while($row = $result->fetch_object()) {
|
||||
if ($i<3) $return["unsortedThumb$i"] = $row->thumbUrl;
|
||||
$i++;
|
||||
}
|
||||
$return['unsortedNum'] = $i;
|
||||
|
||||
// Public
|
||||
$result2 = $database->query("SELECT thumbUrl FROM lychee_photos WHERE public = 1 " . $settings['sorting']);
|
||||
$i = 0;
|
||||
while($row2 = $result2->fetch_object()) {
|
||||
if ($i<3) $return["publicThumb$i"] = $row2->thumbUrl;
|
||||
$i++;
|
||||
}
|
||||
$return['publicNum'] = $i;
|
||||
|
||||
// Starred
|
||||
$result3 = $database->query("SELECT thumbUrl FROM lychee_photos WHERE star = 1 " . $settings['sorting']);
|
||||
$i = 0;
|
||||
while($row3 = $result3->fetch_object()) {
|
||||
if ($i<3) $return["starredThumb$i"] = $row3->thumbUrl;
|
||||
$i++;
|
||||
}
|
||||
$return['starredNum'] = $i;
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
function getAlbum($albumID) {
|
||||
|
||||
global $database, $settings;
|
||||
|
||||
// Get album information
|
||||
switch($albumID) {
|
||||
|
||||
case "f": $return['public'] = false;
|
||||
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE star = 1 " . $settings['sorting'];
|
||||
break;
|
||||
|
||||
case "s": $return['public'] = false;
|
||||
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE public = 1 " . $settings['sorting'];
|
||||
break;
|
||||
|
||||
case 0: $return['public'] = false;
|
||||
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE album = 0 " . $settings['sorting'];
|
||||
|
||||
default: $result = $database->query("SELECT * FROM lychee_albums WHERE id = '$albumID';");
|
||||
$row = $result->fetch_object();
|
||||
$return['title'] = $row->title;
|
||||
$return['description'] = $row->description;
|
||||
$return['sysdate'] = date('d M. Y', strtotime($row->sysdate));
|
||||
$return['public'] = $row->public;
|
||||
if ($row->password=="") $return['password'] = false;
|
||||
else $return['password'] = true;
|
||||
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE album = '$albumID' " . $settings['sorting'];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Get photos
|
||||
$result = $database->query($query);
|
||||
$previousPhotoID = "";
|
||||
$i = 0;
|
||||
while($row = $result->fetch_array()) {
|
||||
|
||||
$return['content'][$row['id']]['id'] = $row['id'];
|
||||
$return['content'][$row['id']]['title'] = $row['title'];
|
||||
$return['content'][$row['id']]['sysdate'] = date('d F Y', strtotime($row['sysdate']));
|
||||
$return['content'][$row['id']]['public'] = $row['public'];
|
||||
$return['content'][$row['id']]['star'] = $row['star'];
|
||||
$return['content'][$row['id']]['album'] = $row['album'];
|
||||
$return['content'][$row['id']]['thumbUrl'] = $row['thumbUrl'];
|
||||
|
||||
$return['content'][$row['id']]['previousPhoto'] = $previousPhotoID;
|
||||
$return['content'][$row['id']]['nextPhoto'] = "";
|
||||
if ($previousPhotoID!="") $return['content'][$previousPhotoID]['nextPhoto'] = $row['id'];
|
||||
|
||||
$previousPhotoID = $row['id'];
|
||||
$i++;
|
||||
|
||||
}
|
||||
|
||||
if ($i==0) {
|
||||
|
||||
// Empty album
|
||||
$return['content'] = false;
|
||||
|
||||
} else {
|
||||
|
||||
// Enable next and previous for the first and last photo
|
||||
$lastElement = end($return['content']);
|
||||
$lastElementId = $lastElement['id'];
|
||||
$firstElement = reset($return['content']);
|
||||
$firstElementId = $firstElement['id'];
|
||||
|
||||
if ($lastElementId!==$firstElementId) {
|
||||
$return['content'][$lastElementId]['nextPhoto'] = $firstElementId;
|
||||
$return['content'][$firstElementId]['previousPhoto'] = $lastElementId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$return['id'] = $albumID;
|
||||
$return['num'] = $i;
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
function setAlbumTitle($albumID, $title) {
|
||||
|
||||
global $database;
|
||||
|
||||
if (strlen($title)<1||strlen($title)>30) return false;
|
||||
$result = $database->query("UPDATE lychee_albums SET title = '$title' WHERE id = '$albumID';");
|
||||
if (!$result) return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function setAlbumDescription($albumID, $description) {
|
||||
|
||||
global $database;
|
||||
|
||||
$description = htmlentities($description);
|
||||
if (strlen($description)>800) return false;
|
||||
$result = $database->query("UPDATE lychee_albums SET description = '$description' WHERE id = '$albumID';");
|
||||
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function deleteAlbum($albumID, $delAll) {
|
||||
|
||||
global $database;
|
||||
|
||||
if ($delAll=="true") {
|
||||
$result = $database->query("SELECT id FROM lychee_photos WHERE album = '$albumID';");
|
||||
$error = false;
|
||||
while($row = $result->fetch_object()) {
|
||||
if (!deletePhoto($row->id)) $error = true;
|
||||
}
|
||||
} else {
|
||||
$result = $database->query("UPDATE lychee_photos SET album = '0' WHERE album = '$albumID';");
|
||||
if (!$result) return false;
|
||||
}
|
||||
|
||||
if ($albumID!=0) {
|
||||
$result = $database->query("DELETE FROM lychee_albums WHERE id = '$albumID';");
|
||||
if (!$result) return false;
|
||||
}
|
||||
|
||||
if ($error) return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function getAlbumArchive($albumID) {
|
||||
|
||||
global $database;
|
||||
|
||||
switch($albumID) {
|
||||
case 's':
|
||||
$query = "SELECT * FROM lychee_photos WHERE public = '1';";
|
||||
$zipTitle = "Public";
|
||||
break;
|
||||
case 'f':
|
||||
$query = "SELECT * FROM lychee_photos WHERE star = '1';";
|
||||
$zipTitle = "Starred";
|
||||
break;
|
||||
default:
|
||||
$query = "SELECT * FROM lychee_photos WHERE album = '$albumID';";
|
||||
$zipTitle = "Unsorted";
|
||||
}
|
||||
|
||||
$result = $database->query($query);
|
||||
$files = array();
|
||||
$i=0;
|
||||
while($row = $result->fetch_object()) {
|
||||
$files[$i] = "../uploads/big/".$row->url;
|
||||
$i++;
|
||||
}
|
||||
$result = $database->query("SELECT * FROM lychee_albums WHERE id = '$albumID';");
|
||||
$row = $result->fetch_object();
|
||||
if ($albumID!=0&&is_numeric($albumID))$zipTitle = $row->title;
|
||||
$filename = "../uploads/".$zipTitle.".zip";
|
||||
|
||||
$zip = new ZipArchive();
|
||||
|
||||
if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($files AS $zipFile) {
|
||||
$newFile = explode("/",$zipFile);
|
||||
$newFile = array_reverse($newFile);
|
||||
$zip->addFile($zipFile, $zipTitle."/".$newFile[0]);
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
header("Content-Type: application/zip");
|
||||
header("Content-Disposition: attachment; filename=\"$zipTitle.zip\"");
|
||||
header("Content-Length: ".filesize($filename));
|
||||
readfile($filename);
|
||||
unlink($filename);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function setAlbumPublic($albumID, $password) {
|
||||
|
||||
global $database;
|
||||
|
||||
$result = $database->query("SELECT public FROM lychee_albums WHERE id = '$albumID';");
|
||||
$row = $result->fetch_object();
|
||||
if ($row->public == 0){
|
||||
$public = 1;
|
||||
} else {
|
||||
$public = 0;
|
||||
}
|
||||
$result = $database->query("UPDATE lychee_albums SET public = '$public', password = NULL WHERE id = '$albumID';");
|
||||
if (!$result) return false;
|
||||
if ($public==1) {
|
||||
$result = $database->query("UPDATE lychee_photos SET public = 0 WHERE album = '$albumID';");
|
||||
if (!$result) return false;
|
||||
}
|
||||
|
||||
if (strlen($password)>0) return setAlbumPassword($albumID, $password);
|
||||
else return true;
|
||||
|
||||
}
|
||||
|
||||
function setAlbumPassword($albumID, $password) {
|
||||
|
||||
global $database;
|
||||
|
||||
$result = $database->query("UPDATE lychee_albums SET password = '$password' WHERE id = '$albumID';");
|
||||
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function checkAlbumPassword($albumID, $password) {
|
||||
|
||||
global $database;
|
||||
|
||||
$result = $database->query("SELECT password FROM lychee_albums WHERE id = '$albumID';");
|
||||
$row = $result->fetch_object();
|
||||
if ($row->password=="") return true;
|
||||
|
||||
else if ($row->password==$password) return true;
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
function isAlbumPublic($albumID) {
|
||||
|
||||
global $database;
|
||||
|
||||
$result = $database->query("SELECT public FROM lychee_albums WHERE id = '$albumID';");
|
||||
$row = $result->fetch_object();
|
||||
|
||||
if ($row->public==1) return true;
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name DB Module
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
|
||||
|
||||
function dbConnect() {
|
||||
|
||||
global $dbUser, $dbPassword, $dbHost, $dbName;
|
||||
|
||||
$database = new mysqli($dbHost, $dbUser, $dbPassword);
|
||||
|
||||
if (mysqli_connect_errno()) {
|
||||
echo mysqli_connect_errno().': '.mysqli_connect_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$database->select_db($dbName))
|
||||
if (!createDatabase($dbName, $database)) exit('Error: Could not create database!');
|
||||
if (!$database->query("SELECT * FROM lychee_photos, lychee_albums, lychee_settings;"))
|
||||
if (!createTables($database)) exit('Error: Could not create tables!');
|
||||
|
||||
return $database;
|
||||
|
||||
}
|
||||
|
||||
function dbClose() {
|
||||
|
||||
global $database;
|
||||
|
||||
if (!$database->close()) exit("Error: Closing the connection failed!");
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function createConfig($dbHost = 'localhost', $dbUser, $dbPassword, $dbName = 'lychee') {
|
||||
|
||||
$dbPassword = urldecode($dbPassword);
|
||||
$database = new mysqli($dbHost, $dbUser, $dbPassword);
|
||||
|
||||
if (mysqli_connect_errno()||$dbUser=="") return "Warning: Connection failed!";
|
||||
else {
|
||||
|
||||
$config = "<?php
|
||||
|
||||
/**
|
||||
* @name Config
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
if(!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
|
||||
|
||||
// Database configurations
|
||||
\$dbHost = '$dbHost'; //Host of the Database
|
||||
\$dbUser = '$dbUser'; //Username of the database
|
||||
\$dbPassword = '$dbPassword'; //Password of the Database
|
||||
\$dbName = '$dbName'; //Database name
|
||||
|
||||
?>";
|
||||
|
||||
if (file_put_contents("config.php", $config)===false) return "Warning: Could not create file!";
|
||||
else {
|
||||
|
||||
$_SESSION['login'] = true;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function createDatabase($dbName, $database) {
|
||||
|
||||
$result = $database->query("CREATE DATABASE IF NOT EXISTS $dbName;");
|
||||
$database->select_db($dbName);
|
||||
|
||||
if (!$database->select_db($dbName)||!$result) return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function createTables($database) {
|
||||
|
||||
if (!$database->query("SELECT * FROM lychee_settings;")) {
|
||||
|
||||
$query = "
|
||||
|
||||
CREATE TABLE `lychee_settings` (
|
||||
`key` varchar(50) NOT NULL DEFAULT '',
|
||||
`value` varchar(50) DEFAULT ''
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
|
||||
";
|
||||
|
||||
if (!$database->query($query)) return false;
|
||||
|
||||
$query = "
|
||||
|
||||
INSERT INTO `lychee_settings` (`key`, `value`)
|
||||
VALUES
|
||||
('username',''),
|
||||
('password',''),
|
||||
('thumbQuality','90'),
|
||||
('checkForUpdates','1'),
|
||||
('sorting','ORDER BY id DESC');
|
||||
|
||||
";
|
||||
|
||||
if (!$database->query($query)) return false;
|
||||
|
||||
}
|
||||
|
||||
if (!$database->query("SELECT * FROM lychee_albums;")) {
|
||||
|
||||
$query = "
|
||||
|
||||
CREATE TABLE `lychee_albums` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`title` varchar(50) NOT NULL,
|
||||
`description` varchar(1000) DEFAULT '',
|
||||
`sysdate` varchar(10) NOT NULL,
|
||||
`public` tinyint(1) DEFAULT '0',
|
||||
`password` varchar(100) DEFAULT '',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
|
||||
";
|
||||
|
||||
if (!$database->query($query)) return false;
|
||||
|
||||
}
|
||||
|
||||
if (!$database->query("SELECT * FROM lychee_photos;")) {
|
||||
|
||||
$query = "
|
||||
|
||||
CREATE TABLE `lychee_photos` (
|
||||
`id` bigint(14) NOT NULL,
|
||||
`title` varchar(50) NOT NULL,
|
||||
`description` varchar(1000) NOT NULL DEFAULT '',
|
||||
`url` varchar(100) NOT NULL,
|
||||
`public` tinyint(1) NOT NULL,
|
||||
`type` varchar(10) NOT NULL,
|
||||
`width` int(11) NOT NULL,
|
||||
`height` int(11) NOT NULL,
|
||||
`size` varchar(20) NOT NULL,
|
||||
`sysdate` varchar(10) NOT NULL,
|
||||
`systime` varchar(8) NOT NULL,
|
||||
`iso` varchar(15) NOT NULL,
|
||||
`aperture` varchar(20) NOT NULL,
|
||||
`make` varchar(20) NOT NULL,
|
||||
`model` varchar(50) NOT NULL,
|
||||
`shutter` varchar(30) NOT NULL,
|
||||
`focal` varchar(20) NOT NULL,
|
||||
`takedate` varchar(20) NOT NULL,
|
||||
`taketime` varchar(8) NOT NULL,
|
||||
`star` tinyint(1) NOT NULL,
|
||||
`thumbUrl` varchar(50) NOT NULL,
|
||||
`album` varchar(30) NOT NULL DEFAULT '0',
|
||||
`import_name` varchar(100) DEFAULT '',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
|
||||
";
|
||||
|
||||
if (!$database->query($query)) return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name Misc Module
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
|
||||
|
||||
function openGraphHeader($photoID) {
|
||||
|
||||
global $database;
|
||||
|
||||
if (!is_numeric($photoID)) return false;
|
||||
$result = $database->query("SELECT * FROM lychee_photos WHERE id = '$photoID';");
|
||||
$row = $result->fetch_object();
|
||||
|
||||
$parseUrl = parse_url("http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
|
||||
$picture = $parseUrl['scheme']."://".$parseUrl['host'].$parseUrl['path']."/../uploads/big/".$row->url;
|
||||
|
||||
$return = '<!-- General Meta Data -->';
|
||||
$return .= '<meta name="title" content="'.$row->title.'" />';
|
||||
$return .= '<meta name="description" content="'.$row->description.' - via Lychee" />';
|
||||
$return .= '<link rel="image_src" type="image/jpeg" href="'.$picture.'" />';
|
||||
|
||||
$return .= '<!-- Twitter Meta Data -->';
|
||||
$return .= '<meta name="twitter:card" content="photo">';
|
||||
$return .= '<meta name="twitter:title" content="'.$row->title.'">';
|
||||
$return .= '<meta name="twitter:image:src" content="'.$picture.'">';
|
||||
|
||||
$return .= '<!-- Facebook Meta Data -->';
|
||||
$return .= '<meta property="og:title" content="'.$row->title.'">';
|
||||
$return .= '<meta property="og:image" content="'.$picture.'">';
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
function search($term) {
|
||||
|
||||
global $database, $settings;
|
||||
|
||||
$return["albums"] = "";
|
||||
|
||||
$result = $database->query("SELECT * FROM lychee_photos WHERE title like '%$term%' OR description like '%$term%';");
|
||||
while($row = $result->fetch_array()) {
|
||||
$return['photos'][$row['id']] = $row;
|
||||
$return['photos'][$row['id']]['sysdate'] = date('d F Y', strtotime($row['sysdate']));
|
||||
}
|
||||
|
||||
$result = $database->query("SELECT * FROM lychee_albums WHERE title like '%$term%';");
|
||||
$i=0;
|
||||
while($row = $result->fetch_object()) {
|
||||
|
||||
$return["albums"][$row->id]['id'] = $row->id;
|
||||
$return["albums"][$row->id]['title'] = $row->title;
|
||||
$return["albums"][$row->id]['public'] = $row->public;
|
||||
$return["albums"][$row->id]['sysdate'] = date('F Y', strtotime($row->sysdate));
|
||||
if ($row->password=="") $return["albums"][$row->id]['password'] = false;
|
||||
else $return["albums"][$row->id]['password'] = true;
|
||||
|
||||
$result2 = $database->query("SELECT thumbUrl FROM lychee_photos WHERE album = '" . $row->id . "' " . $settings['sorting'] . " LIMIT 0, 3;");
|
||||
$k = 0;
|
||||
while($row2 = $result2->fetch_object()){
|
||||
$return['albums'][$row->id]["thumb$k"] = $row2->thumbUrl;
|
||||
$k++;
|
||||
}
|
||||
$i++;
|
||||
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
global $database;
|
||||
|
||||
if(!$database->query("SELECT `public` FROM `lychee_albums`;")) $database->query("ALTER TABLE `lychee_albums` ADD `public` TINYINT( 1 ) NOT NULL DEFAULT '0'");
|
||||
if(!$database->query("SELECT `password` FROM `lychee_albums`;")) $database->query("ALTER TABLE `lychee_albums` ADD `password` VARCHAR( 100 ) NULL DEFAULT ''");
|
||||
if(!$database->query("SELECT `description` FROM `lychee_albums`;")) $database->query("ALTER TABLE `lychee_albums` ADD `description` VARCHAR( 1000 ) NULL DEFAULT ''");
|
||||
if($database->query("SELECT `password` FROM `lychee_albums`;")) $database->query("ALTER TABLE `lychee_albums` CHANGE `password` `password` VARCHAR( 100 ) NULL DEFAULT ''");
|
||||
|
||||
if($database->query("SELECT `description` FROM `lychee_photos`;")) $database->query("ALTER TABLE `lychee_photos` CHANGE `description` `description` VARCHAR( 1000 ) NULL DEFAULT ''");
|
||||
if($database->query("SELECT `shortlink` FROM `lychee_photos`;")) $database->query("ALTER TABLE `lychee_photos` DROP `shortlink`");
|
||||
$database->query("UPDATE `lychee_photos` SET url = replace(url, 'uploads/big/', ''), thumbUrl = replace(thumbUrl, 'uploads/thumb/', '')");
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name Photo Module
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
|
||||
|
||||
function getPhoto($photoID, $albumID) {
|
||||
|
||||
global $database;
|
||||
|
||||
if (!is_numeric($photoID)) {
|
||||
$result = $database->query("SELECT COUNT(*) AS quantity FROM lychee_photos WHERE import_name = '../uploads/import/$photoID';");
|
||||
$row = $result->fetch_object();
|
||||
if ($row->quantity == 0) {
|
||||
importPhoto($photoID, 's');
|
||||
}
|
||||
if (is_file("../uploads/import/$photoID")) {
|
||||
importPhoto($photoID, 's');
|
||||
}
|
||||
$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();
|
||||
|
||||
if ($albumID!='false') {
|
||||
|
||||
if ($return['album']!=0) {
|
||||
|
||||
$result = $database->query("SELECT public FROM lychee_albums WHERE id = " . $return['album'] . ";");
|
||||
$return_album = $result->fetch_array();
|
||||
if ($return_album['public']=="1") $return['public'] = "2";
|
||||
|
||||
}
|
||||
|
||||
$return['original_album'] = $return['album'];
|
||||
$return['album'] = $albumID;
|
||||
$return['sysdate'] = date('d M. Y', strtotime($return['sysdate']));
|
||||
if (strlen($return['takedate'])>0) $return['takedate'] = date('d M. Y', strtotime($return['takedate']));
|
||||
|
||||
}
|
||||
|
||||
unset($return['album_public']);
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
function setPhotoPublic($photoID, $url) {
|
||||
|
||||
global $database;
|
||||
|
||||
$result = $database->query("SELECT public FROM lychee_photos WHERE id = '$photoID';");
|
||||
$row = $result->fetch_object();
|
||||
if ($row->public == 0){
|
||||
$public = 1;
|
||||
} else {
|
||||
$public = 0;
|
||||
}
|
||||
$result = $database->query("UPDATE lychee_photos SET public = '$public' WHERE id = '$photoID';");
|
||||
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function setPhotoStar($photoID) {
|
||||
|
||||
global $database;
|
||||
|
||||
$result = $database->query("SELECT star FROM lychee_photos WHERE id = '$photoID';");
|
||||
$row = $result->fetch_object();
|
||||
if ($row->star == 0) {
|
||||
$star = 1;
|
||||
} else {
|
||||
$star = 0;
|
||||
}
|
||||
$result = $database->query("UPDATE lychee_photos SET star = '$star' WHERE id = '$photoID';");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function setAlbum($photoID, $newAlbum) {
|
||||
|
||||
global $database;
|
||||
|
||||
$result = $database->query("UPDATE lychee_photos SET album = '$newAlbum' WHERE id = '$photoID';");
|
||||
|
||||
if (!$result) return false;
|
||||
else return true;
|
||||
|
||||
}
|
||||
|
||||
function setPhotoTitle($photoID, $title) {
|
||||
|
||||
global $database;
|
||||
|
||||
if (strlen($title)>30) return false;
|
||||
$result = $database->query("UPDATE lychee_photos SET title = '$title' WHERE id = '$photoID';");
|
||||
|
||||
if (!$result) return false;
|
||||
else return true;
|
||||
|
||||
}
|
||||
|
||||
function setPhotoDescription($photoID, $description) {
|
||||
|
||||
global $database;
|
||||
|
||||
$description = htmlentities($description);
|
||||
if (strlen($description)>800) return false;
|
||||
$result = $database->query("UPDATE lychee_photos SET description = '$description' WHERE id = '$photoID';");
|
||||
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function deletePhoto($photoID) {
|
||||
|
||||
global $database;
|
||||
|
||||
$result = $database->query("SELECT * FROM lychee_photos WHERE id = '$photoID';");
|
||||
if (!$result) return false;
|
||||
$row = $result->fetch_object();
|
||||
$retinaUrl = explode(".", $row->thumbUrl);
|
||||
$unlink1 = unlink("../uploads/big/".$row->url);
|
||||
$unlink2 = unlink("../uploads/thumb/".$row->thumbUrl);
|
||||
$unlink3 = unlink("../uploads/thumb/".$retinaUrl[0].'@2x.'.$retinaUrl[1]);
|
||||
$result = $database->query("DELETE FROM lychee_photos WHERE id = '$photoID';");
|
||||
if (!$unlink1 || !$unlink2 || !$unlink3) return false;
|
||||
if (!$result) return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function isPhotoPublic($photoID, $password) {
|
||||
|
||||
global $database;
|
||||
|
||||
if (is_numeric($photoID)) {
|
||||
$query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
|
||||
} 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 {
|
||||
$cAP = checkAlbumPassword($row->album, $password);
|
||||
$iAP = isAlbumPublic($row->album);
|
||||
if ($iAP&&$cAP) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name Session Module
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
|
||||
|
||||
function init($mode) {
|
||||
|
||||
global $settings;
|
||||
|
||||
$return['config'] = $settings;
|
||||
unset($return['config']['password']);
|
||||
|
||||
// No login
|
||||
if ($settings['username']===''&&$settings['password']==='') $return['config']['login'] = false;
|
||||
else $return['config']['login'] = true;
|
||||
|
||||
if ($mode==='admin') {
|
||||
$return['loggedIn'] = true;
|
||||
} else {
|
||||
unset($return['config']['username']);
|
||||
unset($return['config']['thumbQuality']);
|
||||
unset($return['config']['sorting']);
|
||||
unset($return['config']['login']);
|
||||
$return['loggedIn'] = false;
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
function login($username, $password) {
|
||||
|
||||
global $database, $settings;
|
||||
|
||||
// Check login
|
||||
if ($username===$settings['username']&&$password===$settings['password']) {
|
||||
$_SESSION['login'] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// No login
|
||||
if ($settings['username']===''&&$settings['password']==='') {
|
||||
$_SESSION['login'] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function logout() {
|
||||
|
||||
session_destroy();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name Settings Module
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Tobias Reich
|
||||
*/
|
||||
|
||||
if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
|
||||
|
||||
function getSettings() {
|
||||
|
||||
global $database;
|
||||
|
||||
$result = $database->query('SELECT * FROM lychee_settings;');
|
||||
|
||||
while($row = $result->fetch_object()) {
|
||||
$return[$row->key] = $row->value;
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
function setLogin($oldPassword = '', $username, $password) {
|
||||
|
||||
global $settings;
|
||||
|
||||
if ($oldPassword==$settings['password']) {
|
||||
|
||||
if (!setUsername($username)) exit('Error: Updating username failed!');
|
||||
if (!setPassword($password)) exit('Error: Updating password failed!');
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
exit('Error: Current password entered incorrectly!');
|
||||
|
||||
}
|
||||
|
||||
function setUsername($username) {
|
||||
|
||||
global $database;
|
||||
|
||||
$username = htmlentities($username);
|
||||
if (strlen($username)>50) return false;
|
||||
|
||||
$result = $database->query("UPDATE lychee_settings SET value = '$username' WHERE `key` = 'username';");
|
||||
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function setPassword($password) {
|
||||
|
||||
global $database;
|
||||
|
||||
if (strlen($password)<1||strlen($password)>50) return false;
|
||||
|
||||
$result = $database->query("UPDATE lychee_settings SET value = '$password' WHERE `key` = 'password';");
|
||||
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/*function setCheckForUpdates() {
|
||||
|
||||
global $database;
|
||||
|
||||
$result = $database->query("SELECT value FROM lychee_settings WHERE `key` = 'checkForUpdates';");
|
||||
$row = $result->fetch_object();
|
||||
|
||||
if ($row->value==0) $checkForUpdates = 1;
|
||||
else $checkForUpdates = 0;
|
||||
|
||||
$result = $database->query("UPDATE lychee_settings SET value = '$checkForUpdates' WHERE `key` = 'checkForUpdates';");
|
||||
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
|
||||
}*/
|
||||
|
||||
function setSorting($type, $order) {
|
||||
|
||||
global $database;
|
||||
|
||||
$sorting = 'ORDER BY ';
|
||||
|
||||
switch ($type) {
|
||||
|
||||
case 'id': $sorting .= 'id';
|
||||
break;
|
||||
|
||||
case 'title': $sorting .= 'title';
|
||||
break;
|
||||
|
||||
case 'description': $sorting .= 'description';
|
||||
break;
|
||||
|
||||
case 'public': $sorting .= 'public';
|
||||
break;
|
||||
|
||||
case 'type': $sorting .= 'type';
|
||||
break;
|
||||
|
||||
case 'star': $sorting .= 'star';
|
||||
break;
|
||||
|
||||
default: exit('Error: Unknown type for sorting!');
|
||||
|
||||
}
|
||||
|
||||
$sorting .= ' ';
|
||||
|
||||
switch ($order) {
|
||||
|
||||
case 'ASC': $sorting .= 'ASC';
|
||||
break;
|
||||
|
||||
case 'DESC': $sorting .= 'DESC';
|
||||
break;
|
||||
|
||||
default: exit('Error: Unknown order for sorting!');
|
||||
|
||||
}
|
||||
|
||||
$result = $database->query("UPDATE lychee_settings SET value = '$sorting' WHERE `key` = 'sorting';");
|
||||
|
||||
if (!$result) return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,378 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name Upload Module
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Philipp Maurer, Tobias Reich
|
||||
*/
|
||||
|
||||
if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
|
||||
|
||||
function upload($files, $albumID) {
|
||||
|
||||
global $database;
|
||||
|
||||
switch($albumID) {
|
||||
// s for public (share)
|
||||
case 's':
|
||||
$public = 1;
|
||||
$star = 0;
|
||||
$albumID = 0;
|
||||
break;
|
||||
// f for starred (fav)
|
||||
case 'f':
|
||||
$star = 1;
|
||||
$public = 0;
|
||||
$albumID = 0;
|
||||
break;
|
||||
default:
|
||||
$star = 0;
|
||||
$public = 0;
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
|
||||
$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 = array_reverse(explode('.', $file["name"]));
|
||||
$data = $data[0];
|
||||
|
||||
$photo_name = md5($id) . ".$data";
|
||||
|
||||
// Import if not uploaded via web
|
||||
if (!is_uploaded_file($tmp_name)) {
|
||||
if (copy($tmp_name, "../uploads/big/" . $photo_name)) {
|
||||
unlink($tmp_name);
|
||||
$import_name = $tmp_name;
|
||||
}
|
||||
} else {
|
||||
move_uploaded_file($tmp_name, "../uploads/big/" . $photo_name);
|
||||
$import_name = "";
|
||||
}
|
||||
|
||||
// Read infos
|
||||
$info = getInfo($photo_name);
|
||||
|
||||
// Set orientation based on EXIF data
|
||||
if (isset($info['orientation'])&&isset($info['width'])&&isset($info['height'])) {
|
||||
|
||||
if ($info['orientation']==3||$info['orientation']==6||$info['orientation']==8) {
|
||||
|
||||
$newWidth = $info['width'];
|
||||
$newHeight = $info['height'];
|
||||
|
||||
$sourceImg = imagecreatefromjpeg("../uploads/big/$photo_name");
|
||||
|
||||
switch($info['orientation']){
|
||||
|
||||
case 2:
|
||||
// mirror
|
||||
// not yet implemented
|
||||
break;
|
||||
|
||||
case 3:
|
||||
$sourceImg = imagerotate($sourceImg, -180, 0);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// rotate 180 and mirror
|
||||
// not yet implemented
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// rotate 90 and mirror
|
||||
// not yet implemented
|
||||
break;
|
||||
|
||||
case 6:
|
||||
$sourceImg = imagerotate($sourceImg, -90, 0);
|
||||
$newWidth = $info['height'];
|
||||
$newHeight = $info['width'];
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// rotate -90 and mirror
|
||||
// not yet implemented
|
||||
break;
|
||||
|
||||
case 8:
|
||||
$sourceImg = imagerotate($sourceImg, 90, 0);
|
||||
$newWidth = $info['height'];
|
||||
$newHeight = $info['width'];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
$newSourceImg = imagecreatetruecolor($newWidth, $newHeight);
|
||||
|
||||
imagecopyresampled($newSourceImg, $sourceImg, 0, 0, 0, 0, $newWidth, $newHeight, $newWidth, $newHeight);
|
||||
imagejpeg($newSourceImg, "../uploads/big/$photo_name", 100);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create Thumb
|
||||
if (!createThumb($photo_name)) return false;
|
||||
|
||||
// Save to DB
|
||||
$query = "INSERT INTO lychee_photos (id, title, url, description, type, width, height, size, sysdate, systime, iso, aperture, make, model, shutter, focal, takedate, taketime, thumbUrl, album, public, star, import_name)
|
||||
VALUES (
|
||||
'" . $id . "',
|
||||
'" . $info['title'] . "',
|
||||
'" . $photo_name . "',
|
||||
'" . $info['description'] . "',
|
||||
'" . $info['type'] . "',
|
||||
'" . $info['width'] . "',
|
||||
'" . $info['height'] . "',
|
||||
'" . $info['size'] . "',
|
||||
'" . $info['date'] . "',
|
||||
'" . $info['time'] . "',
|
||||
'" . $info['iso'] . "',
|
||||
'" . $info['aperture'] . "',
|
||||
'" . $info['make'] . "',
|
||||
'" . $info['model'] . "',
|
||||
'" . $info['shutter'] . "',
|
||||
'" . $info['focal'] . "',
|
||||
'" . $info['takeDate'] . "',
|
||||
'" . $info['takeTime'] . "',
|
||||
'" . md5($id) . ".jpeg',
|
||||
'" . $albumID . "',
|
||||
'" . $public . "',
|
||||
'" . $star . "',
|
||||
'" . $import_name . "');";
|
||||
$result = $database->query($query);
|
||||
|
||||
if (!$result) return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function getInfo($filename) {
|
||||
|
||||
global $database;
|
||||
|
||||
$url = '../uploads/big/' . $filename;
|
||||
$iptcArray = array();
|
||||
$info = getimagesize($url, $iptcArray);
|
||||
|
||||
// General information
|
||||
$return['type'] = $info['mime'];
|
||||
$return['width'] = $info[0];
|
||||
$return['height'] = $info[1];
|
||||
$return['date'] = date('d.m.Y', filectime($url));
|
||||
$return['time'] = date('H:i:s', filectime($url));
|
||||
|
||||
// Size
|
||||
$size = filesize($url)/1024;
|
||||
if ($size>=1024) $return['size'] = round($size/1024, 1) . ' MB';
|
||||
else $return['size'] = round($size, 1) . ' KB';
|
||||
|
||||
// IPTC Metadata Fallback
|
||||
$return['title'] = '';
|
||||
$return['description'] = '';
|
||||
|
||||
// IPTC Metadata
|
||||
$iptcInfo = iptcparse($iptcArray['APP13']);
|
||||
if (is_array($iptcInfo)) {
|
||||
|
||||
$temp = $iptcInfo['2#105'][0];
|
||||
if (isset($temp)&&strlen($temp)>0) $return['title'] = $temp;
|
||||
|
||||
$temp = $iptcInfo['2#120'][0];
|
||||
if (isset($temp)&&strlen($temp)>0) $return['description'] = $temp;
|
||||
|
||||
}
|
||||
|
||||
// EXIF Metadata Fallback
|
||||
$return['orientation'] = '';
|
||||
$return['iso'] = '';
|
||||
$return['aperture'] = '';
|
||||
$return['make'] = '';
|
||||
$return['model'] = '';
|
||||
$return['shutter'] = '';
|
||||
$return['focal'] = '';
|
||||
$return['takeDate'] = '';
|
||||
$return['takeTime'] = '';
|
||||
|
||||
// EXIF Metadata
|
||||
if ($info['mime']=='image/jpeg'&&function_exists('exif_read_data')&&@exif_read_data($url, 'EXIF', 0)) {
|
||||
|
||||
$exif = exif_read_data($url, 'EXIF', 0);
|
||||
|
||||
$temp = $exif['Orientation'];
|
||||
if (isset($temp)) $return['orientation'] = $temp;
|
||||
|
||||
$temp = $exif['ISOSpeedRatings'];
|
||||
if (isset($temp)) $return['iso'] = $temp;
|
||||
|
||||
$temp = $exif['COMPUTED']['ApertureFNumber'];
|
||||
if (isset($temp)) $return['aperture'] = $temp;
|
||||
|
||||
$temp = $exif['Make'];
|
||||
if (isset($temp)) $return['make'] = $exif['Make'];
|
||||
|
||||
$temp = $exif['Model'];
|
||||
if (isset($temp)) $return['model'] = $temp;
|
||||
|
||||
$temp = $exif['ExposureTime'];
|
||||
if (isset($temp)) $return['shutter'] = $exif['ExposureTime'] . ' Sec.';
|
||||
|
||||
$temp = $exif['FocalLength'];
|
||||
if (isset($temp)) $return['focal'] = ($temp/1) . ' mm';
|
||||
|
||||
$temp = $exif['DateTimeOriginal'];
|
||||
if (isset($temp)) {
|
||||
$exifDate = explode(' ', $temp);
|
||||
$date = explode(':', $exifDate[0]);
|
||||
$return['takeDate'] = $date[2].'.'.$date[1].'.'.$date[0];
|
||||
$return['takeTime'] = $exifDate[1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Security
|
||||
foreach(array_keys($return) as $key) $return[$key] = mysqli_real_escape_string($database, $return[$key]);
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
function createThumb($filename, $width = 200, $height = 200) {
|
||||
|
||||
global $settings;
|
||||
|
||||
$url = "../uploads/big/$filename";
|
||||
$info = getimagesize($url);
|
||||
|
||||
$photoName = explode(".", $filename);
|
||||
$newUrl = "../uploads/thumb/".$photoName[0].".jpeg";
|
||||
$newUrl2x = "../uploads/thumb/".$photoName[0]."@2x.jpeg";
|
||||
|
||||
// Set position and size
|
||||
$thumb = imagecreatetruecolor($width, $height);
|
||||
$thumb2x = imagecreatetruecolor($width*2, $height*2);
|
||||
if ($info[0]<$info[1]) {
|
||||
$newSize = $info[0];
|
||||
$startWidth = 0;
|
||||
$startHeight = $info[1]/2 - $info[0]/2;
|
||||
} else {
|
||||
$newSize = $info[1];
|
||||
$startWidth = $info[0]/2 - $info[1]/2;
|
||||
$startHeight = 0;
|
||||
}
|
||||
|
||||
// Create new image
|
||||
switch($info['mime']) {
|
||||
case 'image/jpeg': $sourceImg = imagecreatefromjpeg($url); break;
|
||||
case 'image/png': $sourceImg = imagecreatefrompng($url); break;
|
||||
case 'image/gif': $sourceImg = imagecreatefromgif($url); break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
imagecopyresampled($thumb,$sourceImg,0,0,$startWidth,$startHeight,$width,$height,$newSize,$newSize);
|
||||
imagecopyresampled($thumb2x,$sourceImg,0,0,$startWidth,$startHeight,$width*2,$height*2,$newSize,$newSize);
|
||||
|
||||
imagejpeg($thumb,$newUrl,$settings['thumbQuality']);
|
||||
imagejpeg($thumb2x,$newUrl2x,$settings['thumbQuality']);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function importPhoto($name, $albumID = 0) {
|
||||
|
||||
$tmp_name = "../uploads/import/$name";
|
||||
$info = getimagesize($tmp_name);
|
||||
$size = filesize($tmp_name);
|
||||
$nameFile = array(array());
|
||||
$nameFile[0]['name'] = $name;
|
||||
$nameFile[0]['type'] = $info['mime'];
|
||||
$nameFile[0]['tmp_name'] = $tmp_name;
|
||||
$nameFile[0]['error'] = 0;
|
||||
$nameFile[0]['size'] = $size;
|
||||
|
||||
if (upload($nameFile, $albumID)) return true;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function importUrl($url, $albumID = 0) {
|
||||
|
||||
if (strpos($url, ',')!==false) {
|
||||
|
||||
// Multiple photos
|
||||
|
||||
$url = explode(',', $url);
|
||||
|
||||
foreach ($url as &$key) {
|
||||
|
||||
$key = str_replace(' ', '%20', $key);
|
||||
|
||||
if (@getimagesize($key)) {
|
||||
|
||||
$pathinfo = pathinfo($key);
|
||||
$filename = $pathinfo['filename'].".".$pathinfo['extension'];
|
||||
$tmp_name = "../uploads/import/$filename";
|
||||
copy($key, $tmp_name);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return importServer($albumID);
|
||||
|
||||
} else {
|
||||
|
||||
// One photo
|
||||
|
||||
$url = str_replace(' ', '%20', $url);
|
||||
|
||||
if (@getimagesize($url)) {
|
||||
|
||||
$pathinfo = pathinfo($url);
|
||||
$filename = $pathinfo['filename'].".".$pathinfo['extension'];
|
||||
$tmp_name = "../uploads/import/$filename";
|
||||
copy($url, $tmp_name);
|
||||
return importPhoto($filename, $albumID);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function importServer($albumID = 0) {
|
||||
|
||||
global $database;
|
||||
|
||||
$i = 0;
|
||||
$files = glob('../uploads/import/*');
|
||||
|
||||
foreach ($files as $file) {
|
||||
|
||||
if (@getimagesize($file)) {
|
||||
if (!importPhoto(basename($file), $albumID)) return false;
|
||||
$i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($i===0) return "Warning: Folder empty!";
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
define('LYCHEE', true);
|
||||
|
||||
// Include
|
||||
require('check.php');
|
||||
|
||||
if($error=='') {
|
||||
if(!$database->query("SELECT `public` FROM `lychee_albums`;")) $database->query("ALTER TABLE `lychee_albums` ADD `public` TINYINT( 1 ) NOT NULL DEFAULT '0'");
|
||||
if(!$database->query("SELECT `password` FROM `lychee_albums`;")) $database->query("ALTER TABLE `lychee_albums` ADD `password` VARCHAR( 100 ) NULL DEFAULT NULL");
|
||||
$database->query("UPDATE `lychee_photos` SET url = replace(url, 'uploads/big/', ''), thumbUrl = replace(thumbUrl, 'uploads/thumb/', '')");
|
||||
echo "\nUpdate complete!";
|
||||
} else {
|
||||
echo "\nCould not Update!";
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @name check.php
|
||||
* @author Philipp Maurer
|
||||
* @author Tobias Reich
|
||||
* @copyright 2014 by Philipp Maurer, Tobias Reich
|
||||
* @description This file takes a look at your Lychee-configuration and displays all errors it can find.
|
||||
* Everything should work if you can see the message 'Lychee is ready!'.
|
||||
*/
|
||||
|
||||
define('LYCHEE', true);
|
||||
header('content-type: text/plain');
|
||||
|
||||
// Declare
|
||||
$error = '';
|
||||
|
||||
// Include
|
||||
if (!file_exists('../php/config.php')) exit('Error 001: Configuration not found. Please install Lychee first.');
|
||||
require('../php/config.php');
|
||||
require('../php/modules/settings.php');
|
||||
|
||||
// Database
|
||||
$database = new mysqli($dbHost, $dbUser, $dbPassword, $dbName);
|
||||
if (mysqli_connect_errno()!=0) $error .= ('Error 100: ' . mysqli_connect_errno() . ': ' . mysqli_connect_error() . '' . PHP_EOL);
|
||||
|
||||
// Get Settings
|
||||
$settings = getSettings();
|
||||
|
||||
// PHP Version
|
||||
if (floatval(phpversion())<5.2) $error .= ('Error 200: Please upgrade to PHP 5.2 or higher!' . PHP_EOL);
|
||||
|
||||
// Extensions
|
||||
if (!extension_loaded('exif')) $error .= ('Error 300: PHP exif extension not activated' . PHP_EOL);
|
||||
if (!extension_loaded('mbstring')) $error .= ('Error 301: PHP mbstring extension not activated' . PHP_EOL);
|
||||
if (!extension_loaded('gd')) $error .= ('Error 302: PHP gd extension not activated' . PHP_EOL);
|
||||
if (!extension_loaded('mysqli')) $error .= ('Error 303: PHP mysqli extension not activated' . PHP_EOL);
|
||||
|
||||
// Config
|
||||
if (!isset($dbName)||$dbName=='') $error .= ('Error 400: No property for $dbName in config.php' . PHP_EOL);
|
||||
if (!isset($dbUser)||$dbUser=='') $error .= ('Error 401: No property for $dbUser in config.php' . PHP_EOL);
|
||||
if (!isset($dbPassword)) $error .= ('Error 402: No property for $dbPassword in config.php' . PHP_EOL);
|
||||
if (!isset($dbHost)||$dbHost=='') $error .= ('Error 403: No property for $dbHost in config.php' . PHP_EOL);
|
||||
|
||||
// Database Config
|
||||
if (!$settings['username']||$settings['username']=='') $error .= ('Error 404: Username empty or not set' . PHP_EOL);
|
||||
if (!$settings['password']||$settings['password']=='') $error .= ('Error 405: Password empty or not set' . PHP_EOL);
|
||||
if (!$settings['checkForUpdates']||($settings['checkForUpdates']!='0'&&$settings['checkForUpdates']!='1')) $error .= ('Error 406: No or wrong property for checkForUpdates' . PHP_EOL);
|
||||
if (!$settings['thumbQuality']||$settings['thumbQuality']=='') $error .= ('Error 407: No or wrong property for thumbQuality' . PHP_EOL);
|
||||
if (!$settings['sorting']||$settings['sorting']=='') $error .= ('Error 408: Wrong property for sorting' . PHP_EOL);
|
||||
|
||||
// Permissions
|
||||
if (substr(sprintf('%o', @fileperms('../uploads/big/')), -4)!='0777') $error .= ('Error 500: Wrong permissions for \'uploads/big\' (777 required)' . PHP_EOL);
|
||||
if (substr(sprintf('%o', @fileperms('../uploads/thumb/')), -4)!='0777') $error .= ('Error 501: Wrong permissions for \'uploads/thumb\' (777 required)' . PHP_EOL);
|
||||
if (substr(sprintf('%o', @fileperms('../uploads/import/')), -4)!='0777') $error .= ('Error 502: Wrong permissions for \'uploads/import\' (777 required)' . PHP_EOL);
|
||||
if (substr(sprintf('%o', @fileperms('../uploads/')), -4)!='0777') $error .= ('Error 503: Wrong permissions for \'uploads/\' (777 required)' . PHP_EOL);
|
||||
if (substr(sprintf('%o', @fileperms('../php/')), -4)!='0777') $error .= ('Error 504: Wrong permissions for \'php/\' (777 required)' . PHP_EOL);
|
||||
|
||||
if ($error=='') echo('Lychee is ready. Lets rock!' . PHP_EOL); else echo $error;
|
||||
|
||||
// Check php.ini Settings
|
||||
if (ini_get('max_execution_time')<200&&ini_set('upload_max_filesize', '20M')!==true) echo('Warning: You may experience problems when uploading a large amount of photos. Take a look in the FAQ for details.' . PHP_EOL);
|
||||
|
||||
|
||||
?>
|