diff --git a/docker_dev/mysql_schema.sql b/docker_dev/mysql_schema.sql index 869935a..6801fcd 100644 --- a/docker_dev/mysql_schema.sql +++ b/docker_dev/mysql_schema.sql @@ -10,46 +10,22 @@ CREATE TABLE posts ( post_path_depth INTEGER NOT NULL DEFAULT 0, post_create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - post_update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - - post_access_count INTEGER DEFAULT 0, + post_update_time DATETIME NOT NULL + DEFAULT CURRENT_TIMESTAMP + ON UPDATE CURRENT_TIMESTAMP, post_metadata JSON NOT NULL, - post_settings_cache JSON DEFAULT NULL, post_content MEDIUMTEXT, PRIMARY KEY(post_id), CONSTRAINT unique_post_path UNIQUE (post_path), - INDEX(post_path), - INDEX(post_path_depth, post_path), - INDEX(post_create_time), - INDEX(post_update_time) + INDEX(post_path, post_update_time), + INDEX(post_path, post_create_time), + INDEX(post_path_depth, post_path) ); -CREATE TABLE path_access_counts ( - access_time DATETIME NOT NULL, - post_path VARCHAR(255), - agent VARCHAR(255), - referrer VARCHAR(255), - - path_access_count INTEGER DEFAULT 0, - path_processing_time DOUBLE PRECISION DEFAULT 0, - - PRIMARY KEY(access_time, post_path, agent, referrer) -); - -CREATE TABLE feed_cache ( - search_path VARCHAR(255), - export_type VARCHAR(255), - - feed_created_on DATETIME DEFAULT CURRENT_TIMESTAMP, - - feed_content MEDIUMTEXT, - - PRIMARY KEY(search_path, export_type) -); INSERT INTO posts (post_path, post_path_depth, post_metadata, post_content) VALUES ( diff --git a/test_entries/README.md b/test_entries/README.md deleted file mode 100644 index 01c17d1..0000000 --- a/test_entries/README.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -settings: - colourscheme: fun - post_style: generic - banners: - - src: /banner/0.png - - src: /banner/1.png ---- \ No newline at end of file diff --git a/test_entries/about/neira/Neira_Queen.png b/test_entries/about/neira/Neira_Queen.png deleted file mode 100644 index 078fba6..0000000 Binary files a/test_entries/about/neira/Neira_Queen.png and /dev/null differ diff --git a/test_entries/about/neira/README.md b/test_entries/about/neira/README.md deleted file mode 100644 index 9faac34..0000000 --- a/test_entries/about/neira/README.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -directory: - settings: - banners: - - src: /about/neira/Neira_Queen.png - from: 0.5 - to: 0.95 ---- - -# She is soft~<3 \ No newline at end of file diff --git a/test_entries/about/neira/really_long_pathname_oh_god/README.md b/test_entries/about/neira/really_long_pathname_oh_god/README.md deleted file mode 100644 index 0571644..0000000 --- a/test_entries/about/neira/really_long_pathname_oh_god/README.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Oh, the pain ---- - -# AAA \ No newline at end of file diff --git a/test_entries/test/the/images/README.md b/test_entries/test/the/images/README.md index c92c2dd..7b9fd95 100644 --- a/test_entries/test/the/images/README.md +++ b/test_entries/test/the/images/README.md @@ -1,10 +1,5 @@ --- title: A little image test idea -directory: - settings: - colourscheme: spicy - banners: - - src: /about/neira/Neira_Queen.png --- # README concept diff --git a/www/.htaccess b/www/.htaccess index d624f34..3ceba7d 100644 --- a/www/.htaccess +++ b/www/.htaccess @@ -1,7 +1,5 @@ AddType text/plain .md -AddType text/plain .atom -AddType text/plain .rss php_value upload_max_filesize 40M php_value post_max_size 42M @@ -9,7 +7,7 @@ php_value post_max_size 42M RewriteEngine On RewriteBase / -RewriteCond %{REQUEST_URI} !^/?(static|raw|robots\.txt).* +RewriteCond %{REQUEST_URI} !^/?(static|raw)/.* RewriteRule (.*) router.php Allow from all diff --git a/www/composer.json b/www/composer.json index eb01954..752d618 100644 --- a/www/composer.json +++ b/www/composer.json @@ -3,7 +3,6 @@ "twig/twig": "^3.0", "twig/markdown-extra": "^3.6", "league/commonmark": "^2.4", - "spatie/yaml-front-matter": "^2.0", - "laminas/laminas-feed": "^2.6" + "spatie/yaml-front-matter": "^2.0" } } diff --git a/www/fontawesome.php b/www/fontawesome.php deleted file mode 100644 index 61f4c87..0000000 --- a/www/fontawesome.php +++ /dev/null @@ -1,10 +0,0 @@ - '', - 'image' => '', - 'folder' => '', - 'rss' => '' -]; - -?> \ No newline at end of file diff --git a/www/mysql_adapter.php b/www/mysql_adapter.php index e9bdb5d..5d5de2f 100644 --- a/www/mysql_adapter.php +++ b/www/mysql_adapter.php @@ -29,38 +29,21 @@ class MySQLAdapter { } } - function _sanitize_path($post_path) { - $post_path = chop($post_path, '/'); - - if($post_path == "") { - return ""; - } - - if(!preg_match('/^(?:\/[\w-]+)+(?:\.[\w-]+)*$/', $post_path)) { - echo "Post path match against " . $post_path . " failed!"; - die(); - } - - return $post_path; - } - - function _exec($qery, $argtypes = '', ...$args) { + function _exec($qery, $argtypes, ...$args) { $stmt = $this->raw->prepare($qery); - if($argtypes != ""){ - $stmt->bind_param($argtypes, ...$args); - } + $stmt->bind_param($argtypes, ...$args); $stmt->execute(); return $stmt->get_result(); } function _normalize_post_data($post_data) { - $post_data ??= ['found' => null]; + if($post_data == null) { + return [ + "found" => false + ]; + } - if(isset($post_data['found']) && $post_data['found'] == false) { - return $post_data; - } - $post_data["found"] = true; $post_data['post_metadata'] = json_decode($post_data["post_metadata"], true) ?? []; @@ -70,7 +53,7 @@ class MySQLAdapter { } function bump_post($post_path, $post_metadata = [], $create_dirs = true) { - $post_path = $this->_sanitize_path($post_path); + $post_path = chop($post_path, '/'); $path_depth = substr_count($post_path, "/"); if($create_dirs) { @@ -105,127 +88,18 @@ class MySQLAdapter { } } - function log_post_access($post_path, $agent, $referrer, $time) { - $post_path = $this->_sanitize_path($post_path); - - $qry = "INSERT INTO path_access_counts - (access_time, - post_path, agent, referrer, - path_access_count, - path_processing_time) - VALUES ( from_unixtime(floor(unix_timestamp(CURRENT_TIMESTAMP) / 300)*300), - ?, ?, ?, 1, ? - ) AS new - ON DUPLICATE KEY - UPDATE path_access_count=path_access_counts.path_access_count+1, - path_processing_time=path_access_counts.path_processing_time+new.path_processing_time; - "; - - $this->_exec($qry, "sssd", $post_path, $agent, $referrer, $time); - - if(preg_match('/^user/', $agent)) { - $this->_exec("UPDATE posts SET post_access_count=post_access_count+1 WHERE post_path=?", "s", $post_path); - } - } - - function get_post_access_counters() { - $qry = " - SELECT post_path, agent, path_access_count, path_processing_time - FROM path_access_counts - WHERE path_last_access_time > ( CURRENT_TIMESTAMP - INTERVAL 10 MINUTE ); - "; - - $data = $this->_exec($qry, "")->fetch_all(MYSQLI_ASSOC); - - $out_data = []; - - foreach($data AS $post_data) { - $path = $post_data['post_path']; - - $agent_data = ($out_data[$path] ?? []); - - $agent_data[$post_data['agent']] = [ - 'count' => $post_data['path_access_count'], - 'time' => round($post_data['path_processing_time'], 6) - ]; - - $out_data[$path] = $agent_data; - } - - return $out_data; - } - - function get_post_access_counters_line() { - $qry = " - SELECT access_time, post_path, agent, referrer, path_access_count, path_processing_time - FROM path_access_counts - WHERE access_time < ( CURRENT_TIMESTAMP - INTERVAL 6 MINUTE ) - ORDER BY access_time DESC; - "; - - $this->raw->begin_transaction(); - $top_access_time = null; - - try { - $data = $this->_exec($qry, "")->fetch_all(MYSQLI_ASSOC); - - $data_prefix="access_metrics,host=" . $_SERVER['SERVER_NAME']; - - $out_data = ""; - - foreach($data AS $post_data) { - $top_access_time ??= $post_data['access_time']; - - $path = $post_data['post_path']; - if($path == '') { - $path = '/'; - } - $out_data .= $data_prefix . ",agent=".$post_data['agent'].",path=".$path.",referrer=".$post_data['referrer']; - - $out_data .= " access_sum=" . $post_data['path_access_count'] . ",time_sum=" . $post_data['path_processing_time']; - $out_data .= " " . strtotime($post_data['access_time']) . "000000000\n"; - } - - - $this->_exec("DELETE FROM path_access_counts WHERE access_time <= ?", "s", $top_access_time); - - $this->raw->commit(); - return $out_data; - - } catch (\Throwable $th) { - $this->raw->rollback(); - - throw $th; - } - } - - function reset_post_settings_cache($post_path) { - $post_path = $this->_sanitize_path($post_path); - - $this->_exec(" - UPDATE posts - SET post_settings_cache=NULL - WHERE post_path LIKE ?; - ", "s", $post_path . "%"); - } - function update_or_create_post($post_path, $post_metadata, $post_content) { - $post_path = $this->_sanitize_path($post_path); + $post_path = chop($post_path, '/'); $path_depth = substr_count($post_path, "/"); $this->make_post_directory(dirname($post_path)); - $this->reset_post_settings_cache($post_path); - $qry = " INSERT INTO posts (post_path, post_path_depth, post_metadata, post_content) VALUES ( ?, ?, ?, ?) AS new - ON DUPLICATE KEY - UPDATE post_metadata=new.post_metadata, - post_content=new.post_content, - post_update_time=CURRENT_TIMESTAMP;"; + ON DUPLICATE KEY UPDATE post_metadata=new.post_metadata, post_content=new.post_content;"; $this->_exec($qry, "siss", $post_path, @@ -234,78 +108,17 @@ class MySQLAdapter { $post_content); } - function get_settings_for_path($post_path) { - $post_path = $this->_sanitize_path($post_path); + function get_post_by_path($post_path, $with_subposts = true) { + $qry = "SELECT * FROM posts WHERE post_path = ?"; - $post_settings = $this->_exec(" - SELECT post_path, post_settings_cache - FROM posts - WHERE post_path = ? - ", "s", $post_path)->fetch_assoc(); - - if(!isset($post_settings)) { - return []; - } - if(isset($post_settings['post_settings_cache'])) { - return json_decode($post_settings['post_settings_cache'], true); - } - - $parent_settings = []; - if($post_path != "") { - $parent_settings = $this->get_settings_for_path(dirname($post_path)); - } - - $post_settings = []; - $post_metadata = $this->_exec(" - SELECT post_path, post_metadata - FROM posts - WHERE post_path = ? - ", "s", $post_path)->fetch_assoc(); - - if(isset($post_metadata['post_metadata'])) { - $post_metadata = json_decode($post_metadata['post_metadata'], true); - - if(isset($post_metadata['settings'])) { - $post_settings = $post_metadata['settings']; - } - } - - $post_settings = array_merge($parent_settings, $post_settings); - - $this->_exec("UPDATE posts SET post_settings_cache=? WHERE post_path=?", "ss", - json_encode($post_settings), $post_path); - - return $post_settings; - } - - function get_post_by_path($post_path, - $with_subposts = false, $with_settings = true) { - - $qry = "SELECT * - FROM posts WHERE post_path = ? - "; - - $post_path = $this->_sanitize_path($post_path); + $post_path = chop($post_path, '/'); $post_data = $this->_exec($qry, "s", $post_path)->fetch_assoc(); - - if(!isset($post_data)) { - $post_data = ['found' => false]; - } - $post_data['post_path'] = $post_path; - $post_data = $this->_normalize_post_data($post_data); - - if(!$post_data['found']) { - return $post_data; - } if($with_subposts) { $post_data['subposts'] = $this->get_subposts_by_path($post_path); } - if($with_settings) { - $post_data['settings'] = $this->get_settings_for_path($post_path); - } return $post_data; } @@ -313,7 +126,7 @@ class MySQLAdapter { function get_subposts_by_path($path) { global $sql; - $path = $this->_sanitize_path($path); + $path = chop($path, '/'); $path_depth = substr_count($path, "/"); diff --git a/www/post_adapter.php b/www/post_adapter.php index fc0297e..ff082ec 100644 --- a/www/post_adapter.php +++ b/www/post_adapter.php @@ -3,7 +3,6 @@ require_once 'mysql_adapter.php'; use Spatie\YamlFrontMatter\YamlFrontMatter; -use Laminas\Feed\Writer\Feed; class PostHandler extends MySQLAdapter { public $data_directory; @@ -17,19 +16,12 @@ class PostHandler extends MySQLAdapter { function _normalize_post_data($post_data) { $post_data = parent::_normalize_post_data($post_data); - if(!$post_data['found']) { - return $post_data; - } - $post_data["post_basename"] = basename($post_data["post_path"]); $post_meta = $post_data['post_metadata']; $post_meta["title"] ??= basename($post_data["post_path"]); - if($post_meta["title"] == "") { - $post_meta["title"] = "root"; - } - + if(!isset($post_meta['type'])) { $type = null; @@ -39,33 +31,17 @@ class PostHandler extends MySQLAdapter { '' => 'directory', 'md' => 'text/markdown', 'png' => 'image', - 'jpg' => 'image', - 'jpeg' => 'image' ]; if(isset($ext_mapping[$ext])) { $post_meta['type'] = $ext_mapping[$ext]; } - else { - $post_meta['type'] = '?'; - } } - if(!isset($post_meta['icon'])) { - $icon_mapping = [ - '' => 'question', - 'text/markdown' => 'markdown', - 'directory' => 'folder', - 'image' => 'image' - ]; - - $post_meta['icon'] = $icon_mapping[$post_meta['type']] ?? 'question'; - } - - $post_data['post_metadata'] = $post_meta; - $post_data["post_file_dir"] = '/' . $this->data_directory . $post_data["post_path"]; + $post_data['post_metadata'] = $post_meta; + return $post_data; } @@ -77,11 +53,6 @@ class PostHandler extends MySQLAdapter { parent::make_post_directory($directory); } - function update_or_create_post(...$args) { - $this->_exec("TRUNCATE feed_cache"); - parent::update_or_create_post(...$args); - } - function save_file($post_path, $file_path) { $this->bump_post($post_path); move_uploaded_file($file_path, $this->data_directory . $post_path); @@ -89,18 +60,15 @@ class PostHandler extends MySQLAdapter { function save_markdown_post($post_path, $post_data) { $frontmatter_post = YamlFrontMatter::parse($post_data); - $post_path = $this->_sanitize_path($post_path); + $post_path = chop($post_path, '/'); $post_content = $frontmatter_post->body(); $post_metadata = $frontmatter_post->matter(); if(basename($post_path) == "README.md") { $readme_metadata = []; - if(isset($post_metadata['settings'])) { - $readme_metadata['settings'] = $post_metadata['settings']; - } - if(isset($post_metadata['directory'])) { - $readme_metadata = $post_metadata['directory']; + if(isset($post_metadata['directory_data'])) { + $readme_metadata = $post_metadata['directory_data']; } $this->update_or_create_post(dirname($post_path), @@ -126,86 +94,6 @@ class PostHandler extends MySQLAdapter { $this->save_file($post_path, $file_path); } } - - function try_get_cached_feed($path, $export_opt) { - $post_cache = $this->_exec("SELECT feed_content, feed_created_on - FROM feed_cache - WHERE search_path=? AND export_type=?", "ss", $path, $export_opt)->fetch_assoc(); - - if(!isset($post_cache)) { - return null; - } - - return ['feed' => $post_cache['feed_content'], 'feed_ts' => $post_cache['feed_created_on']]; - } - - function construct_feed($path) { - $path = $this->_sanitize_path($path); - - $feed = @new Feed; - - $feed->setTitle("DergFeed"); - $feed->setLink("https://lucidragons.de" . $path); - $feed->setFeedLink("https://lucidragons.de/feeds/atom" . $path, "atom"); - - $feed->setDateModified(time()); - - $feed->setDescription("DergenFeed for all your " . $path . " needs <3"); - - $feed_posts = $this->_exec("SELECT - post_path, - post_create_time, post_update_time, - post_content, - post_metadata - FROM posts - WHERE (post_path = ?) OR (post_path LIKE ?) - ORDER BY post_create_time DESC LIMIT 200", - "ss", $path, $path . '/%'); - - while($row = $feed_posts->fetch_array(MYSQLI_ASSOC)) { - $row = $this->_normalize_post_data($row); - $pmeta = $row['post_metadata']; - - if($pmeta['type'] == 'directory') { - continue; - } - - $entry = $feed->createEntry(); - - $entry->setTitle($row['post_path'] . '> ' . $pmeta['title']); - $entry->setLink('https://lucidragons.de' . $row['post_path']); - $entry->setDateModified(strtotime($row['post_update_time'])); - $entry->setDateCreated(strtotime($row['post_create_time'])); - - $entry->setDescription($pmeta['brief'] ?? $pmeta['title']); - - $feed->addEntry($entry); - } - - return $feed; - } - - function get_laminas_feed($path, $export_opt) { - $path = $this->_sanitize_path($path); - - $feed_cache = $this->try_get_cached_feed($path, $export_opt); - - if(isset($feed_cache)) { - return $feed_cache; - } - - $feed = $this->construct_feed($path); - - $this->_exec("INSERT INTO feed_cache - (search_path, export_type, feed_content) - VALUES - (?, 'atom', ?), - (?, 'rss', ?)", - "ssss", $path, $feed->export('atom'), - $path, $feed->export('rss')); - - return $this->try_get_cached_feed($path, $export_opt); - } } ?> \ No newline at end of file diff --git a/www/robots.txt b/www/robots.txt deleted file mode 100644 index 14267e9..0000000 --- a/www/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Allow: / \ No newline at end of file diff --git a/www/router.php b/www/router.php index 4f2f0d8..04388c8 100644 --- a/www/router.php +++ b/www/router.php @@ -1,14 +1,20 @@ '; +// echo 'Error number: ' . mysqli_connect_errno() . '
'; +// echo 'Error message: ' . mysqli_connect_error() . '
'; +// die(); +// } + $loader = new \Twig\Loader\FilesystemLoader(['./templates', './user_content']); $twig = new \Twig\Environment($loader,['debug' => true]); @@ -18,42 +24,6 @@ use Twig\Extra\Markdown\DefaultMarkdown; use Twig\Extra\Markdown\MarkdownRuntime; use Twig\RuntimeLoader\RuntimeLoaderInterface; -function deduce_user_agent() { - $real_agent=$_SERVER['HTTP_USER_AGENT']; - - if(preg_match('/(Googlebot|\w*Google\w*)/', $real_agent, $match)) { - return "bot/google/" . $match[1]; - } - elseif(preg_match('/(Mozilla|Chrome|Chromium)/', $real_agent, $match)) { - return "user/" . $match[1]; - } - else { - return "unidentified"; - } -} - -function log_and_die($path, $die_code = 0, $referrer = null) { - global $data_time_start; - global $adapter; - - $data_time_end = microtime(true); - - if(!isset($referrer)) { - $referrer = 'magic'; - - if(isset($_SERVER['HTTP_REFERER'])) { - $referrer = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST); - } - } - - $adapter->log_post_access($path, - deduce_user_agent(), - $referrer, - $data_time_end - $data_time_start); - - die($die_code); -} - $twig->addRuntimeLoader(new class implements RuntimeLoaderInterface { public function load($class) { if (MarkdownRuntime::class === $class) { @@ -62,156 +32,86 @@ $twig->addRuntimeLoader(new class implements RuntimeLoaderInterface { } }); -function render_twig($template, $args = []) { - global $twig; - global $FONT_AWESOME_ARRAY; +$SURI = $_SERVER['REQUEST_URI']; - $args['fa'] = $FONT_AWESOME_ARRAY; - - $post = $args['post'] ?? []; - $settings = $post['settings'] ?? []; - $meta = $post['post_metadata'] ?? []; - - $args['banner'] ??= $settings['banners'] ?? [ - ["src"=> "/static/banner/0.png"], - ["src" => "/static/banner/1.png"] - ]; - - $args['og'] = array_merge([ - "title" => $meta['title'] ?? "Dergennibble", - "url" => $_SERVER['REQUEST_URI'], - "description" => $meta['description'] - ?? $settings['description'] - ?? "The softest spot to find dragons on" - ], $args['og'] ?? []); - - if(($meta['type'] ?? '') == 'image') { - $args['og']['image'] ??= "https://lucidragons.de" . $post['post_file_dir']; +if($SURI == '/') { + echo $twig->render('root.html'); +} elseif(preg_match('/^\/api\/admin/', $SURI)) { + header('Content-Type: application/json'); + + $user_api_key = ''; + if(isset($_GET['api_key'])) { + $user_api_key = $_GET['api_key']; + } + if(isset($_POST['api_key'])) { + $user_api_key = $_POST['api_key']; } - $args['og']['image'] ??= 'https://lucidragons.de' . $args['banner'][0]["src"]; + if($user_api_key != file_get_contents('secrets/api_admin_key')) { + http_response_code(401); - $args['banner'] = json_encode($args['banner']); + echo json_encode([ + "authorized" => false + ]); - echo $twig->render($template, $args); -} + die(); + } -function try_render_post($SURI) { - global $adapter; + if($SURI = '/api/admin/upload') { + $adapter->handle_upload($_POST['post_path'], $_FILES['post_data']['tmp_name']); + echo json_encode(["ok" => true]); + } +} elseif(preg_match('/^\/api/', $SURI)) { + if(preg_match('/^\/api\/posts(.*)$/', $SURI, $match)) { + + header('Content-Type: application/json'); + echo json_encode($adapter->get_post_by_path($match[1])); + + } elseif(preg_match('/^\/api\/subposts(.*)$/', $SURI, $match)) { + + header('Content-Type: application/json'); + echo json_encode(get_subposts($match[1])); + } elseif($SURI == '/api/upload') { + + echo $twig->render('upload.html'); + } +} elseif($_SERVER['HTTP_SEC_FETCH_DEST'] == 'image') { + header('Location: /raw' . $SURI); + exit(0); +} elseif(true) { $post = $adapter->get_post_by_path($SURI); - if(!$post['found']) { - echo render_twig('post_types/rrror.html',[ - "error_code" => '404 Hoard not found!', - "error_description" => "Well, we searched - far and wide for `" . $SURI . "` but - somehow it must have gotten lost... Sorry!", - "post" => array_merge($post, [ - "post_metadata" => ["title" => "404 ???"] - ]) - ]); - - log_and_die('/404', referrer: ($_SERVER['HTTP_REFERER'] ?? 'magic')); - } - - switch($post['post_metadata']['type']) { - case 'directory': + if($post['post_metadata']['type'] == 'directory') { if(preg_match('/^(.*[^\/])((?:#.*)?)$/', $SURI, $match)) { header('Location: ' . $match[1] . '/' . $match[2]); - - die(); + exit(0); } - echo render_twig('post_types/directory.html', [ + echo $twig->render('post_types/directory.html', [ "post" => $post, - "subposts" => $adapter->get_subposts_by_path($SURI) + "subposts" => $post['subposts'] ]); - - break; - - case 'text/markdown': - echo render_twig('post_types/markdown.html', [ + } + elseif($post['post_metadata']['type'] == 'text/markdown') { + echo $twig->render('post_types/markdown.html', [ + "post" => $post, + "subposts" => $post['subposts'] + ]); + } + elseif($post['post_metadata']['type'] == 'image') { + echo $twig->render('post_types/image.html', [ "post" => $post ]); - break; - - case 'image': - echo render_twig('post_types/image.html', [ - "post" => $post, - ]); - break; } + +} else { + echo $twig->render('rrror.html',[ + "error_code" => '404 Hoard not found!', + "error_description" => "Well, we searched + far and wide for `" . $SURI . "` but + somehow it must have gotten lost... Sorry!" + ]); } -function generate_website($SURI) { - global $adapter; - global $FONT_AWESOME_ARRAY; - - if(preg_match('/^\/api\/admin/', $SURI)) { - header('Content-Type: application/json'); - - $user_api_key = ''; - if(isset($_GET['api_key'])) { - $user_api_key = $_GET['api_key']; - } - if(isset($_POST['api_key'])) { - $user_api_key = $_POST['api_key']; - } - - if($user_api_key != file_get_contents('secrets/api_admin_key')) { - http_response_code(401); - - echo json_encode([ - "authorized" => false - ]); - - log_and_die('/api/401'); - } - - if($SURI = '/api/admin/upload') { - $adapter->handle_upload($_POST['post_path'], $_FILES['post_data']['tmp_name']); - - echo json_encode(["ok" => true]); - } - } elseif(preg_match('/^\/api/', $SURI)) { - if($SURI == '/api/post_counters') { - header('Content-Type: application/json'); - echo json_encode($adapter->get_post_access_counters()); - } elseif($SURI == '/api/metrics') { - header('Content-Type: application/line'); - echo $adapter->get_post_access_counters_line(); - } elseif(preg_match('/^\/api\/posts(.*)$/', $SURI, $match)) { - - header('Content-Type: application/json'); - echo json_encode($adapter->get_post_by_path($match[1])); - - } elseif(preg_match('/^\/api\/subposts(.*)$/', $SURI, $match)) { - - header('Content-Type: application/json'); - echo json_encode(get_subposts($match[1])); - } elseif($SURI == '/api/upload') { - - echo $twig->render('upload.html'); - } - } elseif(preg_match('/^\/feed(?:\/(rss|atom)(.*))?$/', $SURI, $match)) { - $feed = $adapter->get_laminas_feed($match[2] ?? '/', $match[1] ?? 'rss'); - - header('Content-Type: application/xml'); - header('Cache-Control: max-age=1800'); - header('Etag: W/"' . $SURI . '/' . strtotime($feed['feed_ts']) . '"'); - - echo $feed['feed']; - } elseif(preg_match('/^\s*image/', $_SERVER['HTTP_ACCEPT'])) { - header('Location: /raw' . $SURI); - exit(0); - } elseif(true) { - try_render_post($SURI); - } -} - -generate_website($_SERVER['REQUEST_URI']); - -log_and_die($_SERVER['REQUEST_URI']); - ?> diff --git a/www/static/banner.js b/www/static/banner.js index 7af1dc4..256d683 100644 --- a/www/static/banner.js +++ b/www/static/banner.js @@ -1,160 +1,69 @@ -const BANNER_TIME = 600 * 1000.0 -const BANNER_ANIMATION = "opacity 0.8s linear, transform 0.1s linear" +const banner_show_time = 600 * 1000.0 +const banner_animated_style = "opacity 0.8s linear, transform 0.1s linear" -class BannerHandler { - constructor(banner_container, banner_image, banner_link) { - this.bannerContainerDOM = banner_container - this.bannerDOM = banner_image - this.bannerLinkDOM = banner_link +var banner_current_src = localStorage.getItem('main_banner_img') - this.bannerUpdateTimer = null - this.currentPhase = 0 +function getBannerTime() { + return (new Date()).getTime() / banner_show_time +} +function getBannerSrc() { + return "/static/banner/" + Math.floor(getBannerTime() + 1000/banner_show_time) % 2 + ".png" +} +function update_banner_top(banner, banner_container) { + const banner_top_max = 0 + const banner_top_min = -banner.clientHeight + banner_container.clientHeight - this.currentBannerData = null - try { - this.currentBannerData = JSON.parse(localStorage.getItem('main_banner_img')) - } catch(e) {} + const banner_top = (1-(getBannerTime()%1)) * banner_top_min + banner.style.transform = "translateY(" + banner_top + 'px' + ")" +} - this.currentBannerData ||= {} +let banner_update_src = banner_current_src +function update_banner(banner, banner_container) { - this.bannerDOM.onload=() => { this.onBannerLoaded() } - this.bannerDOM.onerror=() => { - this.fadeOut(); - setTimeout(() => this.loadNextBanner(), 1000); - } - } + image_select = getBannerSrc() - startUpdateTick() { - if(this.bannerUpdateTimer !== null) { - return - } + update_banner_top(banner, banner_container) - console.log("Starting tick") + if(image_select != banner_update_src) { + banner.style.opacity = 0 - this.bannerUpdateTimer = setInterval(() => { this.updateTick() }, 100); - } - stopUpdateTick() { - if(this.bannerUpdateTimer === null) { - return - } - - console.log("Stopping tick!") - - clearInterval(this.bannerUpdateTimer); - this.bannerUpdateTimer = null - } - - getPhase() { - return (new Date()).getTime() / BANNER_TIME; - } - - getTargetBanner() { - if(window.dergBannerOptions == null) { - return {} - } - - var banner_index = Math.floor(this.getPhase()) % window.dergBannerOptions.length - var banner_choice = window.dergBannerOptions[banner_index] - - return banner_choice - } - - updateTranslation() { - const bannerTranslateMax = -this.bannerDOM.clientHeight + this.bannerContainerDOM.clientHeight - - const bannerPercentageFrom = this.currentBannerData.from || 0; - const bannerPercentageTo = this.currentBannerData.to || 1; - - const bannerPercentage = (bannerPercentageFrom + (bannerPercentageTo - bannerPercentageFrom) * this.currentPhase) - - const banner_top = (1-bannerPercentage) * bannerTranslateMax - this.bannerDOM.style.transform = "translateY(" + banner_top + 'px' + ")" - } - - fadeOut() { - this.bannerDOM.style.opacity = 0; - } - fadeIn() { - this.bannerDOM.style.opacity = 0.3; - } - - loadNextBanner() { - this.currentBannerData = this.getTargetBanner() - this.currentBannerData.bannerTime = new Date() - - this.loadBanner() - } - - loadBanner() { - console.log("Target banner:"); - console.log(this.currentBannerData); - - localStorage.setItem("main_banner_img", JSON.stringify(this.currentBannerData)) - - this.currentPhase = 0 - - if((this.currentBannerData === null) - || (this.currentBannerData.src === undefined)) { - - this.onBannerLoaded() - return - } - - this.bannerDOM.src = this.currentBannerData.src - this.bannerLinkDOM.href = this.currentBannerData.href || this.currentBannerData.src - } - onBannerLoaded() { - console.log("Loaded?"); - - this.currentPhase = this.getPhase() % 1 - - this.updateTranslation() - this.fadeIn() - setTimeout(() => { - this.animateOn() + banner.src = image_select + }, 1000) - this.startUpdateTick() - }, 10) - } + banner_update_src = image_select + localStorage.setItem('main_banner_img', image_select) - updateTick() { - console.log("tick") - - const nextPhase = this.getPhase() % 1; - - if((nextPhase > this.currentPhase) - && (this.currentBannerData.src == this.getTargetBanner().src)) { - - this.currentPhase = nextPhase; - this.updateTranslation(); - } else { - this.fadeOut() - setTimeout(() => { - this.loadNextBanner() - }, 1000); - - this.stopUpdateTick() - } - } - - animateOn() { - this.bannerDOM.style.transition = BANNER_ANIMATION - } - - start() { - this.fadeIn() - - this.loadBanner() + document.getElementById("main_banner_img_link").href = "/gallery/test" } } -var bannerHandler = new BannerHandler( - document.getElementById("main_header"), - document.getElementById("main_banner_img"), - document.getElementById("main_banner_img_link")) +const banner_container = document.getElementById("main_header") +const banner = document.getElementById("main_banner_img") + + +banner.addEventListener('load', () => { + update_banner_top(banner, banner_container) + + const next_banner_src = getBannerSrc() + + if(banner_current_src != next_banner_src) { + banner.style.transition = banner_animated_style + setTimeout(() => banner.style.opacity = 0.3, 1000) + } + else { + banner.style.opacity = 0.3 + setTimeout(() => banner.style.transition = banner_animated_style, 0) + } + + banner_current_src = next_banner_src +}) -bannerHandler.start() +document.addEventListener("DOMContentLoaded", function () { + banner.src = getBannerSrc() + document.getElementById("main_banner_img_link").href = "/gallery/test" +}) -// addEventListener("resize", () => update_banner(banner, banner_container)); +setInterval(() => update_banner(banner, banner_container), 100) +addEventListener("resize", () => update_banner(banner, banner_container)); diff --git a/test_entries/banner/0.png b/www/static/banner/0.png similarity index 100% rename from test_entries/banner/0.png rename to www/static/banner/0.png diff --git a/www/static/banner/1.png b/www/static/banner/1.png new file mode 100644 index 0000000..6e5069f Binary files /dev/null and b/www/static/banner/1.png differ diff --git a/test_entries/banner/banner0.jpeg b/www/static/banner/banner0.jpeg similarity index 100% rename from test_entries/banner/banner0.jpeg rename to www/static/banner/banner0.jpeg diff --git a/www/static/dergstyle.css b/www/static/dergstyle.css index 6051215..810a46c 100644 --- a/www/static/dergstyle.css +++ b/www/static/dergstyle.css @@ -6,11 +6,6 @@ padding: 0; } -svg { - fill: var(--text_1); - padding-top: 0.1rem; -} - body { --bg_1: #0e0a2a; --bg_2: #2c2943; @@ -31,13 +26,6 @@ body { padding-bottom: 4rem; } -@media only screen and (max-width: 600px) { - .hsmol_hide { - display: none !important; - visibility: hidden !important; - } -} - :link { color: var(--highlight_1); font-style: italic; @@ -165,11 +153,6 @@ a:hover { display: flex; flex-direction: row; list-style-type: none; - - overflow-x: scroll; - overflow-y: hidden; - - white-space: nowrap; } #post_file_path a { color: var(--text_1); @@ -203,17 +186,6 @@ a:hover { margin-left: auto; } -#content_footer { - display: block; - max-width: 100%; - - margin-top: 0.5em; - - font-size: 0.8em; - border-top: solid 1px darkgrey; - opacity: 0.7; -} - #main_footer { display: flex; diff --git a/www/static/directorystyle.css b/www/static/directorystyle.css index d762c6f..79a8bfc 100644 --- a/www/static/directorystyle.css +++ b/www/static/directorystyle.css @@ -33,4 +33,11 @@ table.directory tr.entry .entry_title { table.directory .entry_update_time { display: block; width: 12rem; +} + +@media only screen and (max-width: 600px) { + table.directory .entry_update_time { + visibility: hidden; + display: none; + } } \ No newline at end of file diff --git a/www/templates/fragments/filepath_bar.html b/www/templates/fragments/filepath_bar.html index 31b5265..cff3d04 100644 --- a/www/templates/fragments/filepath_bar.html +++ b/www/templates/fragments/filepath_bar.html @@ -8,9 +8,12 @@ {% set split_post = post.post_path |split('/') %} {% for i in range(0, split_post|length - 1) %}
  • + {% if i != 0 %} + > + {% endif %} {% if i != 0 %} - > {{ split_post[i] }} + {{ split_post[i] }} {% else %} root @@ -19,15 +22,9 @@ {% endfor %} -
  • +
  • raw api
  • -
  • - - {{ fa['rss']|raw }} - -
  • \ No newline at end of file diff --git a/www/templates/pathed_content.html b/www/templates/pathed_content.html index 7ac1cdf..df143f4 100644 --- a/www/templates/pathed_content.html +++ b/www/templates/pathed_content.html @@ -2,11 +2,6 @@ {% extends "root.html" %} -{% block feed_links %} - - -{% endblock %} - {% block second_title %}

    {{ post.post_metadata.title }}

    {% endblock %} @@ -18,10 +13,6 @@
    {%block content_article %} {%endblock%} - - - This article was created on {{ post.post_create_time }}, last edited {{ post.post_update_time }}, and was viewed {{ post.post_access_count }} times~ -
    {%endblock%} diff --git a/www/templates/post_types/directory.html b/www/templates/post_types/directory.html index 2872ab4..5fa62fc 100644 --- a/www/templates/post_types/directory.html +++ b/www/templates/post_types/directory.html @@ -14,12 +14,12 @@ Name Title - Modified + Modified {% for subpost in subposts %} - {{ fa[subpost.post_metadata.icon] | raw }} + ICN {{subpost.post_basename}} @@ -27,7 +27,7 @@ {{ subpost.post_metadata.title }} - + {{ subpost.post_update_time }} diff --git a/www/templates/post_types/image.html b/www/templates/post_types/image.html index 00ea107..60ef590 100644 --- a/www/templates/post_types/image.html +++ b/www/templates/post_types/image.html @@ -6,14 +6,6 @@ {%endblock%} -{% block opengraph_tags %} - {{ parent() }} - - - - -{%endblock %} - {%block content_article%}
    diff --git a/www/templates/post_types/markdown.html b/www/templates/post_types/markdown.html index f874fbc..d4e79a4 100644 --- a/www/templates/post_types/markdown.html +++ b/www/templates/post_types/markdown.html @@ -2,12 +2,6 @@ {% extends "pathed_content.html" %} -{% block opengraph_tags %} - {{ parent() }} - - -{%endblock %} - {%block content_article%} {{ post['post_content']|markdown_to_html }} {% endblock %} \ No newline at end of file diff --git a/www/templates/post_types/rrror.html b/www/templates/post_types/rrror.html deleted file mode 100644 index 0e258e1..0000000 --- a/www/templates/post_types/rrror.html +++ /dev/null @@ -1,19 +0,0 @@ - -{% extends "pathed_content.html" %} - -{% block extra_head %} - -{% endblock %} - -{% block second_title %} -

    (Broken)

    -{% endblock %} - -{% block content_article %} -

    The Dergs are confused:

    -

    {{ error_code }}

    - -
    - {{ error_description|markdown_to_html }} -
    -{% endblock %} \ No newline at end of file diff --git a/www/templates/root.html b/www/templates/root.html index 13ba701..0bb44f5 100644 --- a/www/templates/root.html +++ b/www/templates/root.html @@ -1,44 +1,21 @@ - The Dergsite - {{og.title}} + Lucidragons' Fire - {% block feed_links %} - - {% endblock %} - {% block extra_head %}{% endblock %} - {% block opengraph_tags %} - - - - - - - - - - - - - {% endblock %} - - - + +
    full picture - -

    {% block big_title %}The dergsite{%endblock%}

    {% block second_title %}{% endblock %}
    diff --git a/www/templates/rrror.html b/www/templates/rrror.html new file mode 100644 index 0000000..f9f3ff9 --- /dev/null +++ b/www/templates/rrror.html @@ -0,0 +1,21 @@ + +{% extends "root.html" %} + +{% block extra_head %} + +{% endblock %} + +{% block second_title %} +

    (Broken)

    +{% endblock %} + +{% block main_content %} +
    +

    The Dergs are confused:

    +

    {{ error_code }}

    + +
    + {{ error_description|markdown_to_html }} +
    +
    +{% endblock %} \ No newline at end of file diff --git a/www/user_content/about.md b/www/user_content/about.md new file mode 100644 index 0000000..b83b2e5 --- /dev/null +++ b/www/user_content/about.md @@ -0,0 +1,15 @@ +# About the dergens + +### Who we are +Just little things, but it does feel good. + + +No spacing, huh... + +### What we like to do + +nom Nom Nom test? +Though I don't understand why this is not quite functional... + + +Markdown truly is a delight to work with! \ No newline at end of file