Преглед изворни кода

Initial version (mostly working)

k4be пре 1 година
комит
96e73ab11e
22 измењених фајлова са 1043 додато и 0 уклоњено
  1. 6 0
      .gitignore
  2. 49 0
      admin.js
  3. 84 0
      admin.php
  4. 41 0
      dir.php
  5. 48 0
      dirfill.php
  6. 34 0
      dirlist.php
  7. BIN
      gora.png
  8. BIN
      gorah.png
  9. 80 0
      image.php
  10. 18 0
      include/config-example.php
  11. 208 0
      include/db.php
  12. 29 0
      index.php
  13. BIN
      k4.png
  14. BIN
      k4h.png
  15. 188 0
      md5.js
  16. BIN
      nast.png
  17. BIN
      nasth.png
  18. 120 0
      obrazki.js
  19. BIN
      poprz.png
  20. BIN
      poprzh.png
  21. 43 0
      simg.php
  22. 95 0
      style.css

+ 6 - 0
.gitignore

@@ -0,0 +1,6 @@
+*/*.jpg
+*/*.JPG
+*/*.png
+*/*.gif
+miniatury/
+

+ 49 - 0
admin.js

@@ -0,0 +1,49 @@
+
+function dirfill_submit(e) {
+	e.preventDefault();
+	for (var i=0; i<dirlist.length; i++) {
+		var dir = dirlist[i].name;
+		var dirselect = md5(dir);
+		if (!$('#'+dirselect+'-add').is(':checked'))
+			continue;
+		var postData = {
+			path: dir,
+			name: $('#'+dirselect+'-name').val(),
+			date: $('#'+dirselect+'-date').val(),
+			comment: $('#'+dirselect+'-comment').val(),
+			tags: '',
+			isnew: ($('#'+dirselect+'-new').val() == 1)?'true':'false',
+		};
+		console.log('ajax', postData);
+		$.ajax({
+			url: 'dirfill.php',
+			method: 'post',
+			data: postData,
+			dataType: 'text',
+			error: function(e) {
+				console.error('dirfill_submit error:', e);
+			},
+			complete: function(data) {
+				console.log(data.responseText);
+			},
+		});
+	}
+	
+	return false;
+}
+
+function addSelectAll(e) {
+	e.preventDefault();
+	$('.addBox').prop('checked', true);
+}
+
+function addDeselectAll(e) {
+	e.preventDefault();
+	$('.addBox').prop('checked', false);
+}
+
+$( document ).ready(function() {
+	$('#addSelectAll').click(addSelectAll);
+	$('#addDeselectAll').click(addDeselectAll);
+});
+

+ 84 - 0
admin.php

@@ -0,0 +1,84 @@
+<?php
+require_once('include/config.php');
+require_once('include/db.php');
+
+$content = '';
+$script = '';
+
+$mode = @$_GET['mode'];
+
+switch ($mode) {
+	default: admin_main_menu(); break;
+	case 'dirfill': admin_dir_fill(); break;
+}
+
+function admin_main_menu() {
+	global $content;
+	$content = '<a href="admin.php?mode=dirfill">Automagiczne uzupełnianie katalogów</a>';
+}
+
+
+function admin_dir_fill() {
+	global $content;
+	global $config;
+	global $script;
+	
+	$path = $config['basedir'];
+	$dir_handle = @opendir($path) or die('Błąd otwarcia basedir');
+	$dirlist = [];
+	while ($file = readdir($dir_handle)) {
+		if(!is_dir($path.$file)) continue;
+		if (in_array($file, array('miniatury', '.', '..')))
+			continue;
+		$dirlist[] = array('name' => $file, 'date' => filemtime($path.$file));
+	}
+	usort($dirlist, 'dir_compare');
+	$content .= '<form id="dirfillForm" onsubmit="return dirfill_submit(event)"><table><tr><th>Ścieżka</th><th>Nazwa</th><th>Data</th><th>Komentarz</th><th>Już jest</th><th>Dodaj<br><a id="addSelectAll" href="#">Zaznacz wszystko<br><a id="addDeselectAll" href="#">Odznacz wszystko</a></th></tr>';
+	foreach($dirlist as $dir) {
+		$dirinfo = get_dir_info($dir['name']);
+		$dirname = htmlspecialchars($dir['name']);
+		$dirselect = md5($dir['name']);
+		if ($dirinfo) {
+			$content .= '<tr><td>' . $dirname . '</td>';
+			$content .= '<td><input type="text" id="' . $dirselect . '-name" value="' . htmlspecialchars($dirinfo['name']) . '"></td>';
+			$content .= '<td>Baza danych: <input type="text" id="' . $dirselect . '-date" value="' . $dirinfo['date'] . '"><br>Katalog: ' . $dir['date'] . '</td>';
+			$content .= '<td><textarea id="'  . $dirselect . '-comment">' . htmlspecialchars($dirinfo['comment']) . '</textarea></td>';
+			$content .= '<td>Tak</td><td><input type="checkbox" id="'  . $dirselect . '-add" class="addBox">(tylko brakujące pliki)</td></tr>';
+			$content .= '<input type="hidden" id="'  . $dirselect . '-new" value="0">';
+		} else {
+			$content .= '<tr><td>' . $dirname . '</td>';
+			$content .= '<td><input type="text" id="' . $dirselect . '-name" value="' . $dirname . '"></td>';
+			$content .= '<td><input type="text" id="' . $dirselect . '-date" value="' . $dir['date'] . '"></input></td>';
+			$content .= '<td><textarea id="'  . $dirselect . '-comment"></textarea></td>';
+			$content .= '<td>Nie</td><td><input type="checkbox" checked="checked" id="'  . $dirselect . '-add" class="addBox"></td></tr>';
+			$content .= '<input type="hidden" id="'  . $dirselect . '-new" value="1">';
+		}
+	}
+	$content .= '</table><input type="submit" value="OK"></form>';
+//	$content = '<pre>' . print_r($dirlist, true) . '</pre>';
+	$dirlist_json = json_encode($dirlist);
+	$script = 'const dirlist = ' . $dirlist_json . ';';
+}
+
+function dir_compare($a, $b){
+	return $b['date']-$a['date'];
+}
+
+?><!DOCTYPE html>
+<html>
+<head>
+<title>Obrazki: Admin</title>
+<link rel="stylesheet" href="/obrazki/style.css" type="text/css">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<script type="text/javascript" src="https://k4be.pl/jquery/jquery-3.6.3.min.js"></script>
+<script type="text/javascript" src="admin.js"></script>
+<script type="text/javascript" src="md5.js"></script>
+<script type="text/javascript">
+<?=$script?>
+</script>
+</head>
+<body>
+<?=$content?>
+</body>
+</html>
+

+ 41 - 0
dir.php

@@ -0,0 +1,41 @@
+<?php
+require_once('include/config.php');
+require_once('include/db.php');
+
+$dir = @$_GET['dir'];
+if (empty($dir)) {
+	die('Niepoprawne żądanie');
+}
+
+$dirinfo = get_dir_info($dir);
+if (!$dirinfo) {
+	die('Nie ma katalogu');
+}
+$images = get_dir_images($dir);
+$content = '';
+foreach ($images as $image) {
+	$path = urlencode($image['path']);
+	$content .= '<a href="image.php?dir='.$dir.'&amp;file='.$path.'"><img src="' . $config['thumbnailpath'] . urlencode($dir) . '/' . $config['thumbnailsize'] . '-' . $path . '" alt="Obrazek"/></a>';
+}
+
+if (!$images || count($images) == 0) {
+	$content = 'Katalog jest pusty!';
+}
+
+$dirname = htmlspecialchars($dirinfo['name']);
+
+?><!DOCTYPE html>
+<html>
+<head>
+<title>Obrazki: <?=$dirname?></title>
+<link rel="stylesheet" href="/obrazki/style.css" type="text/css">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+<body>
+<h1>Obrazki: <?=$dirname?></h1>
+<a class="gora" href="."></a><h2>... wybierz dowolny obrazek, najlepiej pierwszy.</h2>
+<?=$content?>
+<a class="k4" href="http://k4be.pl/"></a>
+</body>
+</html>
+

+ 48 - 0
dirfill.php

@@ -0,0 +1,48 @@
+<?php
+require_once('include/config.php');
+require_once('include/db.php');
+
+$isnew = @$_POST['isnew'];
+$dirpath = @$_POST['path'];
+
+if (empty($dirpath))
+	die('Invalid request');
+
+if ($isnew == 'true') {
+	create_db_dir($dirpath, $_POST['name'], $_POST['comment'], $_POST['tags'], $_POST['date']);
+} else {
+	update_db_dir($dirpath, $_POST['name'], $_POST['comment'], $_POST['tags'], $_POST['date']);
+}
+
+$dirid = get_dir_info($dirpath)['id'];
+$images = get_dir_images($dirpath);
+
+$path = $config['basedir'].$dirpath.'/';
+$dir_handle = @opendir($path) or die('Directory open error');
+$i=0;
+$files = [];
+while ($file = readdir($dir_handle)) {
+	if(is_dir($file))
+		continue;
+	$files[] = array('name' => $file, 'date' => filemtime($path.$file));
+}
+closedir($dir_handle);
+
+foreach($files as $file) {
+	if (image_in_dir($file['name'], $images))
+		continue;
+	add_db_image($dirid, '', '', '', $file['name'], $file['date']);
+}
+
+$count = get_dir_count($dirpath);
+update_dir_count($dirpath, $count);
+
+function image_in_dir($path, $images) {
+	foreach($images as $image) {
+		if ($image['path'] == $path)
+			return true;
+	}
+	return false;
+}
+
+?>DONE

+ 34 - 0
dirlist.php

@@ -0,0 +1,34 @@
+<?php
+require_once('include/config.php');
+require_once('include/db.php');
+
+function dirlist($dir) {
+	if (empty($dir)) {
+		throw new Exception('Niepoprawne żądanie');
+	}
+
+	$images = get_dir_images($dir);
+	if (!$images) {
+		throw new Exception('Brak wyników');
+	}
+	$id = 0;
+	$res = [];
+	foreach ($images as $image) {
+		$res[] = array('id' => $id, 'name' => $image['path']);
+		$id++;
+	}
+	return $res;
+}
+
+$output = [];
+
+try {
+	$output = dirlist(@$_GET['dir']);
+} catch (Exception $e) {
+	$output['error'] = true;
+	$output['exception'] = $e;
+}
+
+header("Content-Type: application/json");
+echo json_encode($output);
+?>



+ 80 - 0
image.php

@@ -0,0 +1,80 @@
+<?php
+require_once('include/config.php');
+require_once('include/db.php');
+
+$dir = @$_GET['dir'];
+$file = @$_GET['file'];
+if (empty($dir) || empty($file)) {
+	die('Niepoprawne żądanie');
+}
+
+$dirinfo = get_dir_info($dir);
+if (!$dirinfo) {
+	die('Nie ma katalogu');
+}
+$images = get_dir_images($dir);
+
+$found = false;
+$prev = null;
+$next = null;
+$fileinfo = null;
+
+foreach ($images as $image) { // finding prev and next
+	if (!$found) { // find current and previous one
+		if ($image['path'] == $file) { // the current one
+			$fileinfo = $image;
+			$found = true;
+			continue;
+		}
+		$prev = $image;
+	} else {
+		$next = $image;
+		break;
+	}
+}
+
+if (!$fileinfo) {
+	die('File not found');
+}
+
+$dirhtml = urlencode($dirinfo['path']);
+$filehtml = urlencode($fileinfo['path']);
+
+$content = '<div><a class="gora" href="dir.php?dir='.$dirhtml.'"></a><a id="poprz" ';
+if ($prev) {
+	$prevhtml = urlencode($prev['path']);
+	$content .= 'href="image.php?file='.$prevhtml.'&amp;dir='.$dirhtml.'"';
+} else {
+	$content .= 'style="display:none;"';
+}
+
+$content .= '></a><div><a id="imagelink"';
+if ($next) {
+	$nexthtml = urlencode($next['path']);
+	$content .= ' href="image.php?file='.$nexthtml.'&amp;dir='.$dirhtml.'"';
+}
+$content .= '><img id="image" src="'.$config['imagepath'] . $dirhtml.'/'.$filehtml.'" class="pelny"/></a><a id="nast" ';
+if ($next) {
+	$content .= 'href="image.php?file='.$nexthtml.'&amp;dir='.$dirhtml.'"';
+} else {
+	$content .= 'style="display:none;"';
+}
+$content .= '></a>';
+
+$dirname = htmlspecialchars($dirinfo['name']);
+
+?><!DOCTYPE html>
+<html>
+<head>
+<title>Obrazki: <?=$dirname?></title>
+<link rel="stylesheet" href="/obrazki/style.css" type="text/css">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<script type="text/javascript" src="https://k4be.pl/jquery/jquery-3.6.3.min.js"></script>
+<script type="text/javascript" src="obrazki.js"></script>
+</head>
+<body>
+<h1>Obrazki: <?=$dirname?></h1>
+<?=$content?>
+<a class="k4" href="http://k4be.pl/"></a>
+</body>
+</html>

+ 18 - 0
include/config-example.php

@@ -0,0 +1,18 @@
+<?php
+ini_set('display_errors', 1);
+ini_set('display_startup_errors', 1);
+error_reporting(E_ALL);
+
+$config = [
+	'host' => 'localhost',	// mysql hostname
+	'user' => 'login',	// mysql username
+	'passwd' => 'password',	// mysql password
+	'db' => 'database',	// database name
+	'port' => '3306',	// mysql port
+	'basedir' => '/home/user/public_html/obrazki/',	// filesystem path (keep the trailing /)
+	'basepath' => '/obrazki/',	// webroot path for scripts (keep the trailing /)
+	'imagepath' => '/obrazki/',	// webroot path for image dirs (keep the trailing /)
+	'thumbnailpath' => '/obrazki/miniatury/',	// webroot path for thumbnails (keep the trailing / and do not change for now)
+	'thumbnailsize' => 70,		// thumbnail width in pixels, do not change for now)
+];
+?>

+ 208 - 0
include/db.php

@@ -0,0 +1,208 @@
+<?php
+$pdo = null;
+$dsn = 'mysql:host=' . $config['host'] . ';dbname=' . $config['db'];
+try { 
+	/* PDO object creation */
+	$pdo = new PDO($dsn, $config['user'], $config['passwd']);
+
+	/* Enable exceptions on errors */
+	$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+} catch (PDOException $e) {
+	/* If there is an error an exception is thrown */
+	echo 'Connection failed<br>';
+	echo 'Error number: ' . $e->getCode() . '<br>';
+	echo 'Error message: ' . $e->getMessage() . '<br>';
+	die();
+}
+
+function get_dir_info($dir) {
+	global $pdo;
+
+	$sql = 'SELECT * FROM dirs WHERE path = :dir';
+	$values = array(
+		':dir' => $dir
+	);
+	try {
+		$res = $pdo->prepare($sql);
+		$res->execute($values);
+	} catch (PDOException $e) {
+		echo 'Query error: ' . $e->getMessage();
+		die();
+	}
+	if(!($row = $res->fetch(PDO::FETCH_ASSOC))) {
+		return null;
+	}
+	return $row;
+}
+
+function get_dir_list() {
+	global $pdo;
+	$dir = [];
+
+	$query = 'SELECT * FROM dirs ORDER BY date DESC';
+	try {
+		$res = $pdo->query($query);
+	} catch (PDOException $e) {
+		echo 'Query error: ' . $e->getMessage();
+		die();
+	}
+	while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+		$dir[] = $row;
+
+	}
+	return $dir;
+}
+
+function get_dir_count($dir) {
+        global $pdo;
+
+        $sql = 'SELECT id FROM dirs WHERE path = :dir';
+        $values = array(
+                ':dir' => $dir
+        );
+        try {
+                $res = $pdo->prepare($sql);
+                $res->execute($values);
+        } catch (PDOException $e) {
+                echo 'Query error: ' . $e->getMessage();
+                die();
+        }
+        if(!($row = $res->fetch(PDO::FETCH_ASSOC))) {
+                return 0;
+        }
+
+	$dirid = $row['id'];
+
+	$sql = 'SELECT count(*) AS count FROM images WHERE dir = :dirid';
+	$values = array(
+		':dirid' => $dirid
+	);
+        try {
+                $res = $pdo->prepare($sql);
+                $res->execute($values);
+        } catch (PDOException $e) {
+                echo 'Query error: ' . $e->getMessage();
+                die();
+        }
+
+        if(!($row = $res->fetch(PDO::FETCH_ASSOC))) {
+                return 0;
+        }
+
+        return $row['count'];
+}
+
+function update_dir_count($dirpath, $count) {
+        global $pdo;
+
+        $sql = 'UPDATE dirs SET count = :count WHERE path = :path';
+        $values = array(
+                ':path' => $dirpath,
+                ':count' => $count,
+        );
+        try {
+                $res = $pdo->prepare($sql);
+                return $res->execute($values);
+        } catch (PDOException $e) {
+                echo 'Query error: ' . $e->getMessage();
+                die();
+        }
+
+}
+
+function get_dir_images($dir) {
+	global $pdo;
+	$images = [];
+
+	$sql = 'SELECT images.id, images.name, images.comment, images.views, images.likes, images.tags, images.path, dirs.name AS dir_name, dirs.comment AS dir_comment, dirs.views AS dir_views, dirs.likes AS dir_likes, dirs.tags AS dir_tags, dirs.path AS dir_path FROM images INNER JOIN dirs ON dirs.id=images.dir WHERE dirs.path = :path ORDER BY images.date ASC';
+	$values = array(
+		':path' => $dir
+	);
+	try {
+		$res = $pdo->prepare($sql);
+		$res->execute($values);
+	} catch (PDOException $e) {
+		echo 'Query error: ' . $e->getMessage();
+		die();
+	}
+
+	while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+		$images[] = $row;
+		$dirname = $row['dir_name']; // probably should do this only once
+	/*	echo '<pre>';
+		print_r($row);
+		echo '</pre>';
+		echo '<img src="' . $config['thumbnailpath'] . urlencode($dir) . '/' . $config['thumbnailsize'] . '-' . urlencode($row['path']) . '">';*/
+	}
+	return $images;
+}
+
+function make_dir_path($dir) {
+	global $config;
+	return $config['basepath'] . '/' . $dir['path'] . '/';
+}
+
+function create_db_dir($path, $name, $comment, $tags, $date) {
+	global $pdo;
+
+	$sql = 'INSERT INTO dirs (name, comment, tags, path, date, lastmodified) VALUES (:name, :comment, :tags, :path, :date, :currentdate)';
+	$values = array(
+		':name' => $name,
+		':comment' => $comment,
+		':tags' => $tags,
+		':path' => $path,
+		':date' => $date,
+		':currentdate' => time()
+	);
+	try {
+		$res = $pdo->prepare($sql);
+		return $res->execute($values);
+	} catch (PDOException $e) {  
+		echo 'Query error: ' . $e->getMessage();
+		die();
+	}
+}
+
+function update_db_dir($path, $name, $comment, $tags, $date) {
+	global $pdo;
+
+	$sql = 'UPDATE dirs SET name = :name, comment = :comment, tags = :tags, date = :date, lastmodified = :currentdate WHERE path = :path';
+	$values = array(
+		':name' => $name,
+		':comment' => $comment,
+		':tags' => $tags,
+		':path' => $path,
+		':date' => $date,
+		':currentdate' => time()
+	);
+	try {
+		$res = $pdo->prepare($sql);
+		return $res->execute($values);
+	} catch (PDOException $e) {  
+		echo 'Query error: ' . $e->getMessage();
+		die();
+	}
+}
+
+function add_db_image($dirid, $name, $comment, $tags, $path, $date) {
+	global $pdo;
+
+	$sql = 'INSERT INTO images (dir, name, comment, tags, path, date, lastmodified) VALUES (:dirid, :name, :comment, :tags, :path, :date, :currentdate)';
+	$values = array(
+		':dirid' => $dirid,
+		':name' => $name,
+		':comment' => $comment,
+		':tags' => $tags,
+		':path' => $path,
+		':date' => $date,
+		':currentdate' => time()
+	);
+	try {
+		$res = $pdo->prepare($sql);
+		return $res->execute($values);
+	} catch (PDOException $e) {  
+		echo 'Query error: ' . $e->getMessage();
+		die();
+	}
+}
+?>

+ 29 - 0
index.php

@@ -0,0 +1,29 @@
+<?php
+require_once('include/config.php');
+require_once('include/db.php');
+
+$dirs = get_dir_list();
+
+$dirs_html = '';
+
+foreach ($dirs as $dir) {
+	$dirs_html .= '<tr><td><a href="' . $config['basepath'] . 'dir.php?dir=' . urlencode($dir['path']) . '">' . htmlspecialchars($dir['name']) . '</a></td><td>' . $dir['count'] . '</td><td>' . date('j.m.Y', $dir['date']) . '</td></tr>';
+}
+
+?><!DOCTYPE html>
+<html>
+<head>
+<title>Obrazki</title>
+<link rel="stylesheet" href="/obrazki/style.css" type="text/css">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+<body>
+<h1>Dostępne katalogi z obrazkami</h1>
+Uwaga, nowy skrypt. Zgłoś problemy administratorowi.
+<table><tr><th>Nazwa</th><th>Obrazków</th><th>Utworzono</th></tr>
+<?=$dirs_html?>
+</table>
+<a class="k4" href="http://k4be.pl/"></a>
+</body>
+</html>
+



+ 188 - 0
md5.js

@@ -0,0 +1,188 @@
+/* Licence: MIT
+ * Source: https://github.com/AndreasPizsa/md5-jkmyers
+ */
+
+function md5cycle(x, k) {
+var a = x[0], b = x[1], c = x[2], d = x[3];
+
+a = ff(a, b, c, d, k[0], 7, -680876936);
+d = ff(d, a, b, c, k[1], 12, -389564586);
+c = ff(c, d, a, b, k[2], 17,  606105819);
+b = ff(b, c, d, a, k[3], 22, -1044525330);
+a = ff(a, b, c, d, k[4], 7, -176418897);
+d = ff(d, a, b, c, k[5], 12,  1200080426);
+c = ff(c, d, a, b, k[6], 17, -1473231341);
+b = ff(b, c, d, a, k[7], 22, -45705983);
+a = ff(a, b, c, d, k[8], 7,  1770035416);
+d = ff(d, a, b, c, k[9], 12, -1958414417);
+c = ff(c, d, a, b, k[10], 17, -42063);
+b = ff(b, c, d, a, k[11], 22, -1990404162);
+a = ff(a, b, c, d, k[12], 7,  1804603682);
+d = ff(d, a, b, c, k[13], 12, -40341101);
+c = ff(c, d, a, b, k[14], 17, -1502002290);
+b = ff(b, c, d, a, k[15], 22,  1236535329);
+
+a = gg(a, b, c, d, k[1], 5, -165796510);
+d = gg(d, a, b, c, k[6], 9, -1069501632);
+c = gg(c, d, a, b, k[11], 14,  643717713);
+b = gg(b, c, d, a, k[0], 20, -373897302);
+a = gg(a, b, c, d, k[5], 5, -701558691);
+d = gg(d, a, b, c, k[10], 9,  38016083);
+c = gg(c, d, a, b, k[15], 14, -660478335);
+b = gg(b, c, d, a, k[4], 20, -405537848);
+a = gg(a, b, c, d, k[9], 5,  568446438);
+d = gg(d, a, b, c, k[14], 9, -1019803690);
+c = gg(c, d, a, b, k[3], 14, -187363961);
+b = gg(b, c, d, a, k[8], 20,  1163531501);
+a = gg(a, b, c, d, k[13], 5, -1444681467);
+d = gg(d, a, b, c, k[2], 9, -51403784);
+c = gg(c, d, a, b, k[7], 14,  1735328473);
+b = gg(b, c, d, a, k[12], 20, -1926607734);
+
+a = hh(a, b, c, d, k[5], 4, -378558);
+d = hh(d, a, b, c, k[8], 11, -2022574463);
+c = hh(c, d, a, b, k[11], 16,  1839030562);
+b = hh(b, c, d, a, k[14], 23, -35309556);
+a = hh(a, b, c, d, k[1], 4, -1530992060);
+d = hh(d, a, b, c, k[4], 11,  1272893353);
+c = hh(c, d, a, b, k[7], 16, -155497632);
+b = hh(b, c, d, a, k[10], 23, -1094730640);
+a = hh(a, b, c, d, k[13], 4,  681279174);
+d = hh(d, a, b, c, k[0], 11, -358537222);
+c = hh(c, d, a, b, k[3], 16, -722521979);
+b = hh(b, c, d, a, k[6], 23,  76029189);
+a = hh(a, b, c, d, k[9], 4, -640364487);
+d = hh(d, a, b, c, k[12], 11, -421815835);
+c = hh(c, d, a, b, k[15], 16,  530742520);
+b = hh(b, c, d, a, k[2], 23, -995338651);
+
+a = ii(a, b, c, d, k[0], 6, -198630844);
+d = ii(d, a, b, c, k[7], 10,  1126891415);
+c = ii(c, d, a, b, k[14], 15, -1416354905);
+b = ii(b, c, d, a, k[5], 21, -57434055);
+a = ii(a, b, c, d, k[12], 6,  1700485571);
+d = ii(d, a, b, c, k[3], 10, -1894986606);
+c = ii(c, d, a, b, k[10], 15, -1051523);
+b = ii(b, c, d, a, k[1], 21, -2054922799);
+a = ii(a, b, c, d, k[8], 6,  1873313359);
+d = ii(d, a, b, c, k[15], 10, -30611744);
+c = ii(c, d, a, b, k[6], 15, -1560198380);
+b = ii(b, c, d, a, k[13], 21,  1309151649);
+a = ii(a, b, c, d, k[4], 6, -145523070);
+d = ii(d, a, b, c, k[11], 10, -1120210379);
+c = ii(c, d, a, b, k[2], 15,  718787259);
+b = ii(b, c, d, a, k[9], 21, -343485551);
+
+x[0] = add32(a, x[0]);
+x[1] = add32(b, x[1]);
+x[2] = add32(c, x[2]);
+x[3] = add32(d, x[3]);
+
+}
+
+function cmn(q, a, b, x, s, t) {
+a = add32(add32(a, q), add32(x, t));
+return add32((a << s) | (a >>> (32 - s)), b);
+}
+
+function ff(a, b, c, d, x, s, t) {
+return cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+
+function gg(a, b, c, d, x, s, t) {
+return cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+
+function hh(a, b, c, d, x, s, t) {
+return cmn(b ^ c ^ d, a, b, x, s, t);
+}
+
+function ii(a, b, c, d, x, s, t) {
+return cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+function md51(s) {
+txt = '';
+var n = s.length,
+state = [1732584193, -271733879, -1732584194, 271733878], i;
+for (i=64; i<=s.length; i+=64) {
+md5cycle(state, md5blk(s.substring(i-64, i)));
+}
+s = s.substring(i-64);
+var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
+for (i=0; i<s.length; i++)
+tail[i>>2] |= s.charCodeAt(i) << ((i%4) << 3);
+tail[i>>2] |= 0x80 << ((i%4) << 3);
+if (i > 55) {
+md5cycle(state, tail);
+for (i=0; i<16; i++) tail[i] = 0;
+}
+tail[14] = n*8;
+md5cycle(state, tail);
+return state;
+}
+
+/* there needs to be support for Unicode here,
+ * unless we pretend that we can redefine the MD-5
+ * algorithm for multi-byte characters (perhaps
+ * by adding every four 16-bit characters and
+ * shortening the sum to 32 bits). Otherwise
+ * I suggest performing MD-5 as if every character
+ * was two bytes--e.g., 0040 0025 = @%--but then
+ * how will an ordinary MD-5 sum be matched?
+ * There is no way to standardize text to something
+ * like UTF-8 before transformation; speed cost is
+ * utterly prohibitive. The JavaScript standard
+ * itself needs to look at this: it should start
+ * providing access to strings as preformed UTF-8
+ * 8-bit unsigned value arrays.
+ */
+function md5blk(s) { /* I figured global was faster.   */
+var md5blks = [], i; /* Andy King said do it this way. */
+for (i=0; i<64; i+=4) {
+md5blks[i>>2] = s.charCodeAt(i)
++ (s.charCodeAt(i+1) << 8)
++ (s.charCodeAt(i+2) << 16)
++ (s.charCodeAt(i+3) << 24);
+}
+return md5blks;
+}
+
+var hex_chr = '0123456789abcdef'.split('');
+
+function rhex(n)
+{
+var s='', j=0;
+for(; j<4; j++)
+s += hex_chr[(n >> (j * 8 + 4)) & 0x0F]
++ hex_chr[(n >> (j * 8)) & 0x0F];
+return s;
+}
+
+function hex(x) {
+for (var i=0; i<x.length; i++)
+x[i] = rhex(x[i]);
+return x.join('');
+}
+
+function md5(s) {
+return hex(md51(s));
+}
+
+/* this function is much faster,
+so if possible we use it. Some IEs
+are the only ones I know of that
+need the idiotic second function,
+generated by an if clause.  */
+
+function add32(a, b) {
+return (a + b) & 0xFFFFFFFF;
+}
+
+if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') {
+function add32(x, y) {
+var lsw = (x & 0xFFFF) + (y & 0xFFFF),
+msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+return (msw << 16) | (lsw & 0xFFFF);
+}
+}



+ 120 - 0
obrazki.js

@@ -0,0 +1,120 @@
+
+var imglist = null;
+var dirname = null;
+var filename = null;
+var currId = 0;
+const urlPrefix = '/obrazki/';
+
+function setLinks(e) {
+	var doPush = false;
+
+	/* browser navigation handling */
+	if (e === undefined || e.type != 'popstate') {
+		doPush = true;
+	} else {
+		currId = e.state;
+	}
+
+	/* replace the content */
+	filename = imglist[currId].name;
+	if (currId > 0) {
+		$('#poprz').attr('href', urlPrefix + 'image.php?dir=' + dirname + '&file=' + imglist[currId-1].name);
+		$('#poprz').show();
+	} else {
+		$('#poprz').hide();
+	}
+	if (currId < imglist.length - 1) {
+		var url = urlPrefix + 'image.php?dir=' + dirname + '&file=' + imglist[currId+1].name;
+		$('#nast').attr('href', url);
+		$('#imagelink').attr('href', url);
+		$('#nast').show();
+	} else {
+		$('#nast').hide();
+		$('#imagelink').removeAttr('href');
+	}
+    var image = $("#image");
+ //   image.fadeTo('fast', 0.2, function () {
+ 	image.css('opacity', '0.2');
+        image.attr('src', urlPrefix + dirname + '/' + filename);
+		image.on('load', function() {
+//		    image.fadeTo('fast', 1);
+			image.css('opacity', '1');
+		});
+        if (doPush)
+		window.history.pushState(currId, '', urlPrefix + 'image.php?dir=' + dirname + '&file=' + filename);
+//    });
+}
+
+function nextImage(e) {
+	if (e)
+		e.preventDefault();
+	if (currId >= imglist.length - 1)
+		return;
+	currId++;
+	setLinks();
+}
+
+function prevImage(e) {
+	if (e)
+		e.preventDefault();
+	if (currId == 0)
+		return;
+	currId--;
+	setLinks();
+}
+
+function imglistReceived(data) {
+	imglist = data;
+	/* find current id by url */
+	var found = false;
+	for (var i=0; i<data.length; i++) {
+		file = data[i];
+		if(file.name == filename) {
+			currId = file.id;
+			found = true;
+			break;
+		}
+	}
+	if (!found) /* don't know where i am */
+		return;
+	$('#poprz').click(prevImage);
+	$('#imagelink').click(nextImage);
+	$('#nast').click(nextImage);
+	window.onpopstate = setLinks;
+	window.history.replaceState(currId, '', urlPrefix + 'image.php?dir=' + dirname + '&file=' + filename);
+}
+
+function getImgList() {
+	var queryString = window.location.search;
+	if (URLSearchParams === undefined)
+		return; /* browser not supported */
+	var urlParams = new URLSearchParams(queryString);
+	dirname = urlParams.get('dir');
+	filename = urlParams.get('file');
+	if (dirname === null || filename === null) /* invalid params */
+		return;
+	var args = 'dir=' + dirname;
+	$.ajax({
+		dataType: 'json',
+		url: urlPrefix+'dirlist.php?'+args,
+		success: imglistReceived
+	});
+}
+
+$(document).keydown(function(e) {
+	switch (e.which) {
+		case 37:
+			prevImage();
+			return false;
+		case 39:
+			nextImage();
+			return false;
+	}
+});
+
+$(document).ready(function() {
+	getImgList();
+	$('body').on('swipeleft', nextImage);
+	$('body').on('swiperight', prevImage);
+});
+



+ 43 - 0
simg.php

@@ -0,0 +1,43 @@
+<?
+// The file
+$dir = @$_GET['dir'];
+$file = @$_GET['file'];
+$filename = $dir . '/'. $file;
+if(@$_GET['w']==0) {
+	$new_width=70;
+} else {
+	$new_width=$_GET['w'];
+};
+$mini_filename = 'miniatury/' . $dir . '/' . $new_width . '-' . $file;
+// Content type
+header('Content-type: image/jpeg');
+header('Cache-Control: public');
+if(!file_exists($mini_filename)){
+	list($width, $height) = getimagesize($filename);
+	$new_height=$height*($new_width/$width);
+
+	if(!file_exists('miniatury/'.$dir)){
+		mkdir('miniatury/'.$dir, 0755, true);
+	}
+
+	// Resample
+	$image_p = imagecreatetruecolor($new_width, $new_height);
+	if(preg_match('|\.[jJ][pP][eE]?[gG]$|',$filename)){
+		$image = imagecreatefromjpeg($filename);
+	} elseif(preg_match('|\.[gG][iI][fF]$|',$filename)){
+		$image = imagecreatefromgif($filename);
+	} elseif(preg_match('|\.[pP][nN][gG]$|',$filename)){
+		$image = imagecreatefrompng($filename);
+	}
+	imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
+
+	// Output
+	//imagejpeg($image_p, null, 70);
+	if(!file_exists('miniatury/'.$dir)){
+		mkdir('miniatury/'.$dir, 0755, true);
+	}
+	imagejpeg($image_p, $mini_filename, 70);
+}
+echo file_get_contents($mini_filename);
+?>  
+ 

+ 95 - 0
style.css

@@ -0,0 +1,95 @@
+img {
+	display: block;
+	padding: 8px;
+	margin: 8px;
+	border-color: black;
+	border-style: solid;
+	border-width: 1px;
+	float: left;
+}
+
+img:hover {
+	border-color: #88f;
+	background-color: #ddf;
+}
+
+img.pelny {
+	border-color: red;
+}
+
+#poprz,#nast,.k4,.gora {
+width : 160px;
+height : 100px;
+display: block;
+margin: 3em;
+background-repeat: no-repeat;
+}
+
+#poprz {
+float:left;
+clear: both;
+background-image : url(poprz.png);
+}
+
+#poprz:hover {
+background-image : url(poprzh.png);
+} 
+
+#nast {
+	margin-top: 17em;
+float:right;
+margin-right: 0;
+background-image : url(nast.png);
+}
+
+#nast:hover {
+background-image : url(nasth.png);
+} 
+
+.k4 {
+width: 210px;
+height : 130px;
+clear: both;
+background-image : url(k4.png);
+}
+
+.k4:hover {
+background-image : url(k4h.png);
+} 
+
+.gora {
+float: left;
+background-image : url(gora.png);
+}
+
+.gora:hover {
+background-image : url(gorah.png);
+} 
+
+div {
+	float: left;
+	width: 200px;
+}
+
+td,th {
+	border-color: black;
+	border-style: solid;
+	border-width: 3px;
+	text-align: center;
+}
+
+th {
+	border-width: 1px;
+	padding: 3px;
+}
+
+td a {
+	display: block;
+	padding: 5px;
+	font-weight: bolder;
+}
+
+td a:hover {
+	background-color: #ddf;
+}
+