commit aa20a83284d9a705b47da339b1a1a954eeb27a33 Author: Stefan Brand Date: Sat Jan 8 17:22:16 2022 +0100 Initial Git Commit diff --git a/cache/.gitkeep b/cache/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/conf/config.php b/conf/config.php new file mode 100644 index 0000000..8f1f94a --- /dev/null +++ b/conf/config.php @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..3ede6b8 --- /dev/null +++ b/css/style.css @@ -0,0 +1,91 @@ +body { + background-color: #000000; + font-family: sans; +} +.content { + padding: 4px; + position: relative; + width: 92vw; + height: 92vh; + background-color: #000000; +} +.single { + height: 92vh; +} +.single-image { + position: absolute; +} +.multi-image { + float: left; + padding: 6px; + width: 200px; + height: 200px; +} +.clickable { + display: block; + width: 39%; + height: 80%; + position: relative; + z-index: 9; + opacity: 0; + background-color: #000000; + float: left; +} +.clickable-center { + width: 20%; + height: 50%; + margin-left: 1%; + margin-right: 1%; + float: center; +} +.clickable-right { + float: right; + height: 80%; +} + .single-image img { + object-fit: contain; + width: 98vw; + height: 92vh; +} + +.multi-image img { + object-fit: contain; + width: 200px; + height: 200px; +} +.footer { + width: 100%; + display: block; + clear: both; + text-align: center; +} + +.footer a { + margin-left: 0.5em; + margin-right: 0.5em; + font-size: 3em; + font-weight: bold; + color: #ffffff; +} + +.footer .info { + margin-left: 0.5em; + margin-right: 0.5em; + font-size: 3em; + font-weight: bold; + color: #ffffff; +} + +.footer .tag { + margin-left: 0.5em; + margin-right: 0.5em; + font-size: 0.4em !important; + font-weight: normal !important; + color: #00ff00; +} + +.search { + text-align: center; + font-weight: bold; + color: #ffffff; +} diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..ec35188 Binary files /dev/null and b/favicon.ico differ diff --git a/index.php b/index.php new file mode 100644 index 0000000..45cd99b --- /dev/null +++ b/index.php @@ -0,0 +1,94 @@ + ceil(count($files)/$slice)) + $data['next_page'] = $page; +$data['last_page'] = ceil(count($files)/$slice); + +// Prepare Mode Specific Data and Render Template +if ($slice > 1) { + foreach ($curfiles as $index => $image) { + $tmp['n'] = $image; + $tmp['i'] = $index+1; + $tmp['t'] = $thumburl.$t->get_thumb($image); + $data['images'][] = $tmp; + } + Template::view('tpl/gallery.html', $data); +} else { + $data['gallery_page'] = ceil($page/$gslice); + $data['gallery_slice'] = $gslice; + foreach ($curfiles as $index => $image) { + $data['imageurl'] = $imageurl.$dir.'/'.$image; + $data['imagename'] = $image; + $data['tags'] = explode(" ", pathinfo(trim(strstr(strtolower($image), ' - '), " -"))['filename']); + } + + + Template::view('tpl/single.html', $data); +} + +?> diff --git a/js/shortcut.js b/js/shortcut.js new file mode 100644 index 0000000..df1763f --- /dev/null +++ b/js/shortcut.js @@ -0,0 +1,223 @@ +/** + * http://www.openjs.com/scripts/events/keyboard_shortcuts/ + * Version : 2.01.B + * By Binny V A + * License : BSD + */ + shortcut = { + 'all_shortcuts':{},//All the shortcuts are stored in this array + 'add': function(shortcut_combination,callback,opt) { + //Provide a set of default options + var default_options = { + 'type':'keydown', + 'propagate':false, + 'disable_in_input':false, + 'target':document, + 'keycode':false + } + if(!opt) opt = default_options; + else { + for(var dfo in default_options) { + if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo]; + } + } + + var ele = opt.target; + if(typeof opt.target == 'string') ele = document.getElementById(opt.target); + var ths = this; + shortcut_combination = shortcut_combination.toLowerCase(); + + //The function to be called at keypress + var func = function(e) { + e = e || window.event; + + if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields + var element; + if(e.target) element=e.target; + else if(e.srcElement) element=e.srcElement; + if(element.nodeType==3) element=element.parentNode; + + if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return; + } + + //Find Which key is pressed + if (e.keyCode) code = e.keyCode; + else if (e.which) code = e.which; + var character = String.fromCharCode(code).toLowerCase(); + + if(code == 188) character=","; //If the user presses , when the type is onkeydown + if(code == 190) character="."; //If the user presses , when the type is onkeydown + + var keys = shortcut_combination.split("+"); + //Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked + var kp = 0; + + //Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken + var shift_nums = { + "`":"~", + "1":"!", + "2":"@", + "3":"#", + "4":"$", + "5":"%", + "6":"^", + "7":"&", + "8":"*", + "9":"(", + "0":")", + "-":"_", + "=":"+", + ";":":", + "'":"\"", + ",":"<", + ".":">", + "/":"?", + "\\":"|" + } + //Special Keys - and their codes + var special_keys = { + 'esc':27, + 'escape':27, + 'tab':9, + 'space':32, + 'return':13, + 'enter':13, + 'backspace':8, + + 'scrolllock':145, + 'scroll_lock':145, + 'scroll':145, + 'capslock':20, + 'caps_lock':20, + 'caps':20, + 'numlock':144, + 'num_lock':144, + 'num':144, + + 'pause':19, + 'break':19, + + 'insert':45, + 'home':36, + 'delete':46, + 'end':35, + + 'pageup':33, + 'page_up':33, + 'pu':33, + + 'pagedown':34, + 'page_down':34, + 'pd':34, + + 'left':37, + 'up':38, + 'right':39, + 'down':40, + + 'f1':112, + 'f2':113, + 'f3':114, + 'f4':115, + 'f5':116, + 'f6':117, + 'f7':118, + 'f8':119, + 'f9':120, + 'f10':121, + 'f11':122, + 'f12':123 + } + + var modifiers = { + shift: { wanted:false, pressed:false}, + ctrl : { wanted:false, pressed:false}, + alt : { wanted:false, pressed:false}, + meta : { wanted:false, pressed:false} //Meta is Mac specific + }; + + if(e.ctrlKey) modifiers.ctrl.pressed = true; + if(e.shiftKey) modifiers.shift.pressed = true; + if(e.altKey) modifiers.alt.pressed = true; + if(e.metaKey) modifiers.meta.pressed = true; + + for(var i=0; k=keys[i],i 1) { //If it is a special key + if(special_keys[k] == code) kp++; + + } else if(opt['keycode']) { + if(opt['keycode'] == code) kp++; + + } else { //The special keys did not match + if(character == k) kp++; + else { + if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase + character = shift_nums[character]; + if(character == k) kp++; + } + } + } + } + + if(kp == keys.length && + modifiers.ctrl.pressed == modifiers.ctrl.wanted && + modifiers.shift.pressed == modifiers.shift.wanted && + modifiers.alt.pressed == modifiers.alt.wanted && + modifiers.meta.pressed == modifiers.meta.wanted) { + callback(e); + + if(!opt['propagate']) { //Stop the event + //e.cancelBubble is supported by IE - this will kill the bubbling process. + e.cancelBubble = true; + e.returnValue = false; + + //e.stopPropagation works in Firefox. + if (e.stopPropagation) { + e.stopPropagation(); + e.preventDefault(); + } + return false; + } + } + } + this.all_shortcuts[shortcut_combination] = { + 'callback':func, + 'target':ele, + 'event': opt['type'] + }; + //Attach the function with the event + if(ele.addEventListener) ele.addEventListener(opt['type'], func, false); + else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func); + else ele['on'+opt['type']] = func; + }, + + //Remove the shortcut - just specify the shortcut and I will remove the binding + 'remove':function(shortcut_combination) { + shortcut_combination = shortcut_combination.toLowerCase(); + var binding = this.all_shortcuts[shortcut_combination]; + delete(this.all_shortcuts[shortcut_combination]) + if(!binding) return; + var type = binding['event']; + var ele = binding['target']; + var callback = binding['callback']; + + if(ele.detachEvent) ele.detachEvent('on'+type, callback); + else if(ele.removeEventListener) ele.removeEventListener(type, callback, false); + else ele['on'+type] = false; + } +} \ No newline at end of file diff --git a/lib/helpers.class.php b/lib/helpers.class.php new file mode 100644 index 0000000..4219cda --- /dev/null +++ b/lib/helpers.class.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/lib/template.class.php b/lib/template.class.php new file mode 100644 index 0000000..5a539d4 --- /dev/null +++ b/lib/template.class.php @@ -0,0 +1,87 @@ +' . PHP_EOL . $code); + } + return $cached_file; + } + + static function clearCache() { + foreach(glob(self::$cache_path . '*') as $file) { + unlink($file); + } + } + + static function compileCode($code) { + $code = self::compileBlock($code); + $code = self::compileYield($code); + $code = self::compileEscapedEchos($code); + $code = self::compileEchos($code); + $code = self::compilePHP($code); + return $code; + } + + static function includeFiles($file) { + $code = file_get_contents($file); + preg_match_all('/{% ?(extends|include) ?\'?(.*?)\'? ?%}/i', $code, $matches, PREG_SET_ORDER); + foreach ($matches as $value) { + $code = str_replace($value[0], self::includeFiles($value[2]), $code); + } + $code = preg_replace('/{% ?(extends|include) ?\'?(.*?)\'? ?%}/i', '', $code); + return $code; + } + + static function compilePHP($code) { + return preg_replace('~\{%\s*(.+?)\s*\%}~is', '', $code); + } + + static function compileEchos($code) { + return preg_replace('~\{{\s*(.+?)\s*\}}~is', '', $code); + } + + static function compileEscapedEchos($code) { + return preg_replace('~\{{{\s*(.+?)\s*\}}}~is', '', $code); + } + + static function compileBlock($code) { + preg_match_all('/{% ?block ?(.*?) ?%}(.*?){% ?endblock ?%}/is', $code, $matches, PREG_SET_ORDER); + foreach ($matches as $value) { + if (!array_key_exists($value[1], self::$blocks)) self::$blocks[$value[1]] = ''; + if (strpos($value[2], '@parent') === false) { + self::$blocks[$value[1]] = $value[2]; + } else { + self::$blocks[$value[1]] = str_replace('@parent', self::$blocks[$value[1]], $value[2]); + } + $code = str_replace($value[0], '', $code); + } + return $code; + } + + static function compileYield($code) { + foreach(self::$blocks as $block => $value) { + $code = preg_replace('/{% ?yield ?' . $block . ' ?%}/', $value, $code); + } + $code = preg_replace('/{% ?yield ?(.*?) ?%}/i', '', $code); + return $code; + } + +} +?> \ No newline at end of file diff --git a/lib/thumbs.class.php b/lib/thumbs.class.php new file mode 100644 index 0000000..745aa1c --- /dev/null +++ b/lib/thumbs.class.php @@ -0,0 +1,78 @@ + [ + 'load' => 'imagecreatefromjpeg', + 'save' => 'imagejpeg', + 'quality' => 100 + ], + IMAGETYPE_PNG => [ + 'load' => 'imagecreatefrompng', + 'save' => 'imagepng', + 'quality' => 0 + ], + IMAGETYPE_GIF => [ + 'load' => 'imagecreatefromgif', + 'save' => 'imagegif', + 'quality' => 0 + ], + IMAGETYPE_WEBP => [ + 'load' => 'imagecreatefromwebp', + 'save' => 'imagecreatewebp', + 'quality' => 90 + ] + ]; + + public function __construct($idir, $tdir, $width, $heigth) { + $this->imagedir = $idir; + $this->thumbdir = $tdir; + $this->w = $width; + $this->h = $heigth; + } + + public function get_thumb($iname) { + $src = $this->imagedir.$iname; + $ext = pathinfo($iname, PATHINFO_EXTENSION); + $dstname = hash('sha256', $iname); + $dstpath = $this->thumbdir.$dstname.'.'.$ext; + + + if (!file_exists($dstpath)) { + $type = exif_imagetype($src); + $image = call_user_func(self::IMAGE_HANDLERS[$type]['load'], $src); + + $srcwidth = imagesx($image); + $srcheight = imagesy($image); + + + $ratio = min($this->w / $srcwidth, $this->h / $srcheight); + $width = round($srcwidth*$ratio); + $height = round($srcheight*$ratio); + + $thumbnail = imagecreatetruecolor($width, $height); + + if ($type == IMAGETYPE_GIF || $type == IMAGETYPE_PNG) { + imagecolortransparent($thumbnail, imagecolorallocate($thumbnail, 0, 0, 0)); + if ($type == IMAGETYPE_PNG) { + imagealphablending($thumbnail, false); + imagesavealpha($thumbnail, true); + } + } + + imagecopyresampled($thumbnail, $image, 0, 0, 0, 0, $width, $height, $srcwidth, $srcheight); + call_user_func(self::IMAGE_HANDLERS[$type]['save'],$thumbnail,$dstpath,self::IMAGE_HANDLERS[$type]['quality']); + imagedestroy($image); + imagedestroy($thumbnail); + } + return $dstname.'.'.$ext; + } +} + +?> diff --git a/tpl/gallery.html b/tpl/gallery.html new file mode 100644 index 0000000..d1a3ced --- /dev/null +++ b/tpl/gallery.html @@ -0,0 +1,32 @@ +{% extends tpl/layout.html %} + +{% block title %}Gallery{% endblock %} + +{% block content %} +
+ +{% foreach($images as $image): %} + +{% endforeach %} + +
+{% endblock %} diff --git a/tpl/layout.html b/tpl/layout.html new file mode 100644 index 0000000..a51bf75 --- /dev/null +++ b/tpl/layout.html @@ -0,0 +1,23 @@ + + + + + + + + + {% yield title %} + + + + {% yield content %} + + + + \ No newline at end of file diff --git a/tpl/single.html b/tpl/single.html new file mode 100644 index 0000000..6248bc1 --- /dev/null +++ b/tpl/single.html @@ -0,0 +1,27 @@ +{% extends tpl/layout.html %} + +{% block title %}{{ $page }}/{{ $last_page }} | {{ $imagename }}{% endblock %} + +{% block content %} + +
+
+ +
+ + +
+
+ +
+ + +{% endblock %}