my website banner

[FEAT] custom HTTP code messages, RFC 2324, server migration
authorDavid Polakovic <email@dpolakovic.space>
Fri, 19 Dec 2025 20:11:02 +0000 (21:11 +0100)
committerDavid Polakovic <email@dpolakovic.space>
Fri, 19 Dec 2025 20:11:02 +0000 (21:11 +0100)
14 files changed:
.htaccess [changed mode: 0644->0755]
README.txt
Styles/styles.css
blog.php
clicky-images.js
dead-drop.php
dir.php
error/error.php [new file with mode: 0644]
fruit.js
index.php
license.js [new file with mode: 0644]
mars-clock.php
php/config.php
php/dd2.php

old mode 100644 (file)
new mode 100755 (executable)
index fcc6cd4..4e5e71a
--- a/.htaccess
+++ b/.htaccess
@@ -1,19 +1,51 @@
-RewriteEngine on
+RewriteEngine On
+
+# Handle BREW method FIRST before HTTPS redirect
+RewriteCond %{REQUEST_METHOD} ^BREW$
+RewriteRule ^ brew.php [L]
+
+# HTTPS redirect
+RewriteCond %{HTTPS} off
+RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
+
+# Handle /error/### URLs - capture the error code and pass it to error.php
+RewriteCond %{REQUEST_URI} ^/error/(\d+)/?$
+RewriteRule ^error/(\d+)/?$ /error/error.php?code=$1 [L]
+
+# Your existing rules
+RewriteRule ^6e69636520747279$ /6E69636520747279 [R=301,L]
 
 RewriteCond %{THE_REQUEST} \s/([^.]+)\.php [NC]
 RewriteRule ^ /%1 [NE,L,R]
+
 RewriteCond %{REQUEST_FILENAME}.php -f
 RewriteRule ^(.*)/?$ /$1.php  [L]
 
-
 RewriteCond %{THE_REQUEST} \s/([^.]+)\.html [NC]
 RewriteRule ^ /%1 [NE,L,R]
+
 RewriteCond %{REQUEST_FILENAME}.html -f
 RewriteRule ^(.*)/?$ /$1.html  [L]
 
-
 RewriteCond %{REQUEST_URI} !^/blogs/ [NC]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule ^(.*)$ blogs/$1 [L]
 
+Options -Indexes
+
+# ErrorDocument declarations - all point to error.php in error/ folder
+
+# 400
+ErrorDocument 400 /error/error.php
+ErrorDocument 403 /error/error.php
+ErrorDocument 404 /error/error.php
+ErrorDocument 408 /error/error.php
+#ErrorDocument 418 /error/error.php
+ErrorDocument 429 /error/error.php
+
+# 500
+ErrorDocument 500 /error/error.php
+ErrorDocument 502 /error/error.php
+ErrorDocument 503 /error/error.php
+ErrorDocument 504 /error/error.php
\ No newline at end of file
index f2f5da4f47dfdc31fd049583c19cbe85382faaae..471396ea3db0affeb4f20092727c9187cde0c8e9 100755 (executable)
@@ -1,20 +1,20 @@
 my-website
-A simple website that I run. Check it out on https://dpolakovic.space
-Copyright 2023-2024, David Polakovic
+A simple website that I run. Check it out on https://www.dpolakovic.space
+Copyright 2023-2025, David Polakovic
 
 ABOUT:
-This is my static, old school, 90's, web 1.0 website. I despise the responsiveness,
+This is my old school, 90's, web 1.0 website. I despise the responsiveness,
 mobile design and client side computing. So I made html/php site to occupy little
 piece of cyberspace. Here is description of the files:
 
-.htaccess - config file, so I don't have to write .php/.html in url
-index.php - the "About page" with contacts (not much going on here)
-blog.php  - echoes blogs from blogs/
-dir.php   - some links
-lib.php   - my book library in one table
-gpg.html  - page with my email gpg key
-test.php  - default test page for troubleshooting new features
-rss.xml   - RSS file for blog site (to be used with RSS reader)
+.htaccess  - config file, so I don't have to write .php/.html in url
+index.php  - the "About page" with contacts (not much going on here)
+blog.php   - echoes blogs from blogs/
+dir.php    - useful links
+gpg.html   - page with my email gpg key
+mars-clock - shows time on Mars
+dead-drop  - anonymous message exchange
+rss.xml    - RSS file for blog site (to be used with RSS reader)
 
 blogs/pics/ - pictures for blogs
 blogs/      - here I store the blogs
@@ -22,6 +22,7 @@ php/        - php backend for this web + text files which I echo
 Pictures/   - directory with all pictures for sites (except the blogs)
 Styles/     - dir with font I use and CSS style file
 Zax/        - files for my other domain https://www.zax-game.com
+error/     - dir with error.php file for custom HTTP status code messages
 
 NOTE:
 There are few more files (sites and config files) which run on the server. These
index ba191f0a26cbd61bdcfdbc8e7fb8bcc372dbcd67..718c358018cda0322cbd1fc8afbe6b5b47bc676c 100755 (executable)
@@ -293,6 +293,10 @@ display: block;
     color: #545454;
 }
 
+.fresh-link:visited {
+    color: rgb(0, 0, 238);
+}
+
 /* Navigation bar for blog page
    So here is modified nav bar with only one option (Go back)
    I put it as a secound style, because I don't want last child
index bdbdbc1b3cf819cb99fc5258fc3f1e22e9a4be3e..24cc5175a1197137d51eee9162484298a4a800fd 100755 (executable)
--- a/blog.php
+++ b/blog.php
       </main>
 
     <!-- footer  -->
-    <footer class="footer">
-      Copyright <?php printYear() ?> David Polakovic - All publications licensed under
-      <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>
-      unless stated otherwise.<br>
-      <a href="https://www.dpolakovic.space/blogs/javascript">This web page uses limited JavaScript</a>;
-      read the
-      <a href="https://git.dpolakovic.space/?p=my-website;a=blob;f=clicky-images.js;h=16a3f0d8229515e2dbd1c94911d97ebff8830c97;hb=HEAD">source code</a> 
-      for more information.
-      Last update on <?php echo lastUpdtaded("blog.php") ?>.
+     <footer class="footer">
+      <?php printFooter(1, 0, 'blog.php', 'rss.xml'); ?>
     </footer>
     <br><br>   
   </body>
index 16a3f0d8229515e2dbd1c94911d97ebff8830c97..17485015d7e44f5512f038f3cf25aa5c60cf49f0 100644 (file)
@@ -32,13 +32,26 @@ const dpoImg = document.getElementById("toggleImagedpo");
 // Track key state
 const keysPressed = {};
 
-// Helper function to check for redirect
+// Determine if we're on index.php
+const isIndexPage = window.location.pathname.endsWith('index.php') || 
+                    window.location.pathname.endsWith('/') ||
+                    window.location.pathname === '/index.php';
+
+// Helper function to check for redirect or image change
 function checkRedirect(clickedKey) {
   const requiredKeys = [".", "d", " "];
   const otherKeys = requiredKeys.filter(k => k !== clickedKey);
   
   if (keysPressed[otherKeys[0]] && keysPressed[otherKeys[1]]) {
-    window.location.href = "https://www.dpolakovic.space/ro";
+    if (isIndexPage) {
+      // Redirect to index2.php if on index.php
+      window.location.href = "index2.php";
+    } else {
+      // Change space image to space3.png on other pages
+      if (spaceImg) {
+        spaceImg.src = "./Pictures/space2.png";
+      }
+    }
   }
 }
 
@@ -46,31 +59,33 @@ function checkRedirect(clickedKey) {
 if (dotImg) {
   dotImg.addEventListener("mousedown", () => {
     dotImg.src = "./Pictures/dot2.png";
+    keysPressed["."] = true;
     checkRedirect(".");
   });
-
   dotImg.addEventListener("mouseup", () => {
     dotImg.src = "./Pictures/dot.png";
+    delete keysPressed["."];
   });
-
   dotImg.addEventListener("mouseleave", () => {
     dotImg.src = "./Pictures/dot.png";
+    delete keysPressed["."];
   });
 }
 
 // Mouse behavior for space
 if (spaceImg) {
   spaceImg.addEventListener("mousedown", () => {
-    spaceImg.src = "../Pictures/space2.png";
+    spaceImg.src = "./Pictures/space2.png";
+    keysPressed[" "] = true;
     checkRedirect(" ");
   });
-
   spaceImg.addEventListener("mouseup", () => {
     spaceImg.src = "./Pictures/space.png";
+    delete keysPressed[" "];
   });
-
   spaceImg.addEventListener("mouseleave", () => {
     spaceImg.src = "./Pictures/space.png";
+    delete keysPressed[" "];
   });
 }
 
@@ -78,22 +93,23 @@ if (spaceImg) {
 if (dpoImg) {
   dpoImg.addEventListener("mousedown", () => {
     dpoImg.src = "./Pictures/dpo2.png";
+    keysPressed["d"] = true;
     checkRedirect("d");
   });
-
   dpoImg.addEventListener("mouseup", () => {
     dpoImg.src = "./Pictures/dpolakovic.png";
+    delete keysPressed["d"];
   });
-
   dpoImg.addEventListener("mouseleave", () => {
     dpoImg.src = "./Pictures/dpolakovic.png";
+    delete keysPressed["d"];
   });
 }
 
 // Keyboard behavior
 document.addEventListener("keydown", (event) => {
   keysPressed[event.key] = true;
-
+  
   if (dotImg && event.key === ".") {
     dotImg.src = "./Pictures/dot2.png";
   }
@@ -103,16 +119,24 @@ document.addEventListener("keydown", (event) => {
   if (dpoImg && event.key === "d") {
     dpoImg.src = "./Pictures/dpo2.png";
   }
-
+  
   // Check if all three keys are pressed
   if (keysPressed["."] && keysPressed["d"] && keysPressed[" "]) {
-    window.location.href = "https://www.dpolakovic.space/ro";
+    if (isIndexPage) {
+      // Redirect to index2.php if on index.php
+      window.location.href = "index2.php";
+    } else {
+      // Change space image to space3.png on other pages
+      if (spaceImg) {
+        spaceImg.src = "./Pictures/space2.png";
+      }
+    }
   }
 });
 
 document.addEventListener("keyup", (event) => {
   delete keysPressed[event.key];
-
+  
   if (dotImg && event.key === ".") {
     dotImg.src = "./Pictures/dot.png";
   }
index a0872618bd057ad2d4c66ed8b7c74ba7a92ccc60..e09d50c806f8637741a89b6aa0c576617be90da8 100755 (executable)
 
     <!-- footer  -->
     <footer class="footer">
-      Copyright <?php printYear() ?> David Polakovic - All publications licensed under
-      <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>
-      unless stated otherwise.<br>
-      <a href="https://www.dpolakovic.space/blogs/javascript">This web page uses limited JavaScript</a>;
-      read the
-      <a href="https://git.dpolakovic.space/?p=my-website;a=blob;f=clicky-images.js;h=16a3f0d8229515e2dbd1c94911d97ebff8830c97;hb=HEAD">source code</a> 
-      for more information.
-      Last update on <?php echo lastUpdtaded("dead-drop.php") ?>.
+      <?php printFooter(1, 1, 'php/dd2.php','php/captcha.php','dead-drop.php'); ?>
     </footer>
     <br><br>
     
diff --git a/dir.php b/dir.php
index b71fc555521f82535bef5226f7741743575d5a75..fd7efb0a2a2b8e92d20b22a001557bc1e8ce61e7 100755 (executable)
--- a/dir.php
+++ b/dir.php
            <a href="https://www.floppydisk.com">Floppydisk.com</a>
            - new and refurbished floppies for okay prices [3]<br>              
                <a href="https://www.starringthecomputer.com/">Starring the computer</a>
-           - all computers from silver screen<br>      
+           - all computers from the silver screen<br>  
                <a href="https://www.retrojunk.com/">Retrojunk.com</a> 
                - center of old, forgotten and some lost media<br>
            <a href="https://en.uesp.net/wiki/Morrowind:Morrowind#Quest_Information">UESP wiki</a>
 
     <!-- footer  -->
     <footer class="footer">
-      Copyright <?php printYear() ?> David Polakovic - All publications licensed under
-      <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>
-      unless stated otherwise.<br>
-      <a href="https://www.dpolakovic.space/blogs/javascript">This web page uses limited JavaScript</a>;
-      read the
-      <a href="https://git.dpolakovic.space/?p=my-website;a=blob;f=clicky-images.js;h=16a3f0d8229515e2dbd1c94911d97ebff8830c97;hb=HEAD">source code</a> 
-      for more information.
-      Last update on <?php echo lastUpdtaded("dir.php") ?>.
+               <?php printFooter(1, 0, 'dir.php'); ?>
     </footer>
     <br><br>
     
diff --git a/error/error.php b/error/error.php
new file mode 100644 (file)
index 0000000..4a4599f
--- /dev/null
@@ -0,0 +1,308 @@
+<?php
+if (isset($_GET['code'])) {
+    // Manual invocation via /error/###
+    $error_code = $_GET['code'];
+} elseif (isset($_SERVER['REDIRECT_STATUS'])) {
+    // Triggered by Apache ErrorDocument
+    $error_code = $_SERVER['REDIRECT_STATUS'];
+} else {
+    // Default fallback
+    $error_code = '500';
+}
+
+$errors = [
+        // *******
+        // * 100 *
+        // *******
+    '100' => [
+        'title' => '100: Continue',
+        'message' => 'Begin you may. Ready to receive more, the server is.'
+    ],
+    '101' => [
+        'title' => '101: Switching Protocols',
+        'message' => 'Switch protocols, we shall. Agreed to your upgrade request, the server has.'
+    ],
+    '102' => [
+        'title' => '102: Processing',
+        'message' => 'Processing your request, we are. Patience you must have. Time, this will take.'
+    ],
+    '103' => [
+        'title' => '103: Early Hints',
+        'message' => 'Early hints, I give you. While the response prepares, preload resources you can.'
+    ],            
+
+        // *******
+        // * 200 *
+        // *******
+    '200' => [
+        'title' => '200: OK',
+        'message' => 'What you sought, received you have.'
+    ],
+    '201' => [
+        'title' => '201: Created',
+        'message' => 'Created, a new resource has been.'
+    ],
+    '202' => [
+        'title' => '202: Accepted',
+        'message' => 'Accepted for processing, your request is. Complete yet, it is not. Patience, you must have.'
+    ],
+    '203' => [
+        'title' => '203: Non-Authoritative Information',
+        'message' => 'Information you receive, but from the source directly, it comes not. Trust it carefully, you should.'
+    ],
+    '204' => [
+        'title' => '204: No Content',
+        'message' => 'Successful, your request was. But content to show you, there is none.'
+    ],
+    '205' => [
+        'title' => '205: Reset Content',
+        'message' => 'Reset your view, you must. Successful the request was, but refresh your document, you should.'
+    ], 
+    '206' => [
+        'title' => '206: Partial Content',
+        'message' => 'Only part of what you requested, delivered it is. The rest, await it does.'
+    ],
+    '207' => [
+        'title' => '207: Multi-Status',
+        'message' => 'Multiple operations performed, we have. Different outcomes, each one has.'
+    ],
+    '208' => [
+        'title' => '208: Already Reported',
+        'message' => 'Already reported in this response, these results were. Repeat them, we will not.'
+    ],
+    '226' => [
+        'title' => '226: IM Used',
+        'message' => 'Instance manipulations applied, we have. Transformed, the resource is.'
+    ],                               
+        // *******
+        // * 300 *
+        // *******
+    '300' => [
+        'title' => '300: Multiple Choices',
+        'message' => 'Many paths before you lie. Choose wisely, you must.'
+    ],
+    '301' => [
+        'title' => '301: Moved Permanently',
+        'message' => 'Moved, this page has. Forever gone from here, it is. Follow the new path, you must.'
+    ], 
+    '302' => [
+        'title' => '302: Found',
+        'message' => 'Found elsewhere, what you seek is. Temporarily moved, it has. Follow, you should.'
+    ],       
+    '303' => [
+        'title' => '303: See Other',
+        'message' => 'Look elsewhere, you must. Another location, the answer awaits.'
+    ], 
+    '304' => [
+        'title' => '304: Not Modified',
+        'message' => 'Changed, nothing has. Your cached version, still good it is.'
+    ], 
+    '305' => [
+        'title' => '305: Use Proxy',
+        'message' => 'Through a proxy, your path must go. Direct access, allowed it is not.'
+    ], 
+
+        // *******
+        // * 400 *
+        // *******
+    '400' => [
+        'title' => '400: Bad Request',
+        'message' => 'Understand your request, I cannot. Malformed it is, hmm.'
+    ],
+    '401' => [
+        'title' => '401: Unauthorized',
+        'message' => 'Identify yourself, you must. Access without credentials, forbidden it is.'
+    ],
+    '402' => [
+        'title' => '402: Payment Required',
+        'message' => 'Pay first, you must. Free, this resource is not'
+    ],       
+    '403' => [
+        'title' => '403: Forbidden',
+        'message' => 'Permission to enter, you have not. Forbidden this path is.'
+    ],
+    '404' => [
+        'title' => '404: Not Found',
+        'message' => 'The page you seek, exist does not. Lost in the void, it is.'
+    ],
+    '405' => [
+        'title' => '405: Method Not Allowed',
+        'message' => 'You must unlearn what you have learned. This method, the way it is not.'
+    ],
+    '406' => [
+        'title' => '406: Not Acceptable',
+        'message' => 'Difficult to see. Always in motion, acceptable formats are. Yours, compatible is not.'
+    ],  
+    '407' => [
+        'title' => '407: Proxy Authentication Required',
+        'message' => 'Through the proxy, your journey goes. But authenticate you must, before pass you may.'
+    ],                  
+    '408' => [
+        'title' => '408: Request Timeout',
+        'message' => 'Too long you have taken. Patience, the server has lost, hmm.'
+    ],
+    '409' => [
+        'title' => '409: Conflict',
+        'message' => 'Fear leads to anger. Anger leads to conflict. With current state, your request conflicts.'
+    ],
+    '410' => [
+        'title' => '410: Gone',
+        'message' => 'Once here it was. Gone forever now, it is.'
+    ],    
+    '411' => [
+        'title' => '411: Length Required',
+        'message' => 'Size matters not... but to the server, it does. Specify the length, you must.'
+    ],   
+    '412' => [
+        'title' => '412: Precondition Failed',
+        'message' => 'Met, your preconditions were not. Failed, the requirements have.'
+    ], 
+    '413' => [
+        'title' => '413: Content Too Large',
+        'message' => 'Too large, your request is. Smaller, you must make it.'
+    ],   
+    '414' => [
+        'title' => '414: URI Too Long',
+        'message' => 'Too long, your URL is. Shorten it, you must.'
+    ],  
+    '415' => [
+        'title' => '415: Unsupported Media Type',
+        'message' => 'Much to learn, you still have. This format, support the server does not.'
+    ],        
+    '416' => [
+        'title' => '416: Range Not Satisfiable',
+        'message' => 'Only what you take with you. Beyond the resource bounds, your range reaches.'
+    ],
+    '417' => [
+        'title' => '417: Expectation Failed',
+        'message' => 'Meet your expectations, the server cannot. Expect less, perhaps you should.'
+    ],                   
+    '418' => [
+        'title' => '418: I\'m a teapot',
+        'message' => 'A teapot, I am. Brew coffee, I cannot. Absurd this is, yes, hmmm!'
+    ],
+    '421' => [
+        'title' => '421: Misdirected Request',
+        'message' => 'Wrong server, you have reached. Directed elsewhere, you should be.'
+    ],    
+    '422' => [
+        'title' => '422: Unprocessable Content',
+        'message' => 'Understand your request, I do. Process it correctly, I cannot.'
+    ],  
+    '423' => [
+        'title' => '423: Locked',
+        'message' => 'Locked, this resource is. Access it now, you cannot.'
+    ],    
+    '424' => [
+        'title' => '424: Failed Dependency',
+        'message' => 'Failed, a dependency has. Complete your request, I cannot.'
+    ],       
+    '425' => [
+        'title' => '425: Too Early',
+        'message' => 'Hasty, you are. Patience, the Force requires. Too early, your request comes.'
+    ], 
+    '426' => [
+        'title' => '426: Upgrade Required',
+        'message' => 'Upgrade your protocol, you must. Old version, no longer supported is.'
+    ],   
+    '428' => [
+        'title' => '428: Precondition Required',
+        'message' => 'Conditional, your request must be. Preconditions, you must include.'
+    ],                       
+    '429' => [
+        'title' => '429: Too Many Requests',
+        'message' => 'Too eager you are. Slow down, you must. Many requests, too many!'
+    ],
+    '431' => [
+        'title' => '431: Request Header Fields Too Large',
+        'message' => 'Train yourself to let go of everything you fear to lose. Too large, your headers are. Release some, you must.'
+    ],  
+    '451' => [
+        'title' => '451: Unavailable For Legal Reasons',
+        'message' => 'The dark side of the Force surrounds the law. By legal reasons, blocked this is. Available, it is not.'
+    ],             
+
+        // *******
+        // * 500 *
+        // *******
+    
+    '500' => [
+        'title' => '500: Internal Server Error',
+        'message' => 'Wrong, something has gone. Know what it is, the server does not. Mysterious this error is.'
+    ],
+    '501' => [
+        'title' => '501: Not Implemented',
+        'message' => 'Implement this feature, the server does not. Capable of it, it is not.'
+    ],    
+    '502' => [
+        'title' => '502: Bad Gateway',
+        'message' => 'The gateway, troubled it is. A response invalid, received it has.'
+    ],
+    '503' => [
+        'title' => '503: Service Unavailable',
+        'message' => 'Available, the server is not. Overwhelmed or resting, it may be. Return later, you should.'
+    ],
+    '504' => [
+        'title' => '504: Gateway Timeout',
+        'message' => 'For another server\'s response, waited too long I have. Answer me, it did not.'
+    ],
+    '505' => [
+        'title' => '505: HTTP Version Not Supported',
+        'message' => 'Your HTTP version, too old it is. Support it, the server cannot.'
+    ],
+    '506' => [
+        'title' => '506: Variant Also Negotiates',
+        'message' => 'Circular, the negotiation has become. A proper variant, choose we cannot.'
+    ],   
+    '507' => [
+        'title' => '507: Insufficient Storage',
+        'message' => 'No more space, there is. Full, the storage has become.'
+    ],             
+     '508' => [
+        'title' => '508: Loop Detected',
+        'message' => 'Around in circles, the server goes. Break free, we must.'
+    ],   
+     '510' => [
+        'title' => '510: Not Extended',
+        'message' => 'Further extensions required are. Provided, they were not.'
+    ],  
+     '511' => [
+        'title' => '511: Network Authentication Required',
+        'message' => 'Before proceed you may, authenticate with the network, you must. Required, it is.'
+    ],             
+];
+
+if (isset($errors[$error_code])) {
+    $title = $errors[$error_code]['title'];
+    $message = $errors[$error_code]['message'];
+} else {
+    $title = $error_code . ': Is not a valid code';
+    $message = 'Stupid you are. Breed you should not.';
+}
+
+// Only set HTTP response code for 4xx and 5xx errors
+if ($error_code >= 400) {
+    http_response_code((int)$error_code);
+}
+
+// REMOVE THIS LINE - it was the duplicate causing the problem:
+// http_response_code((int)$error_code);
+?>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=400, initial-scale=1">
+<title><?php echo htmlspecialchars($error_code); ?></title>
+<link rel="author"       href="mailto:email@dpolakovic.space">
+</head>
+<body>
+<center>
+<img src="../Pictures/error.jpg" width="380" alt="Master Yoda says">
+<h2><?php echo htmlspecialchars($title); ?></h2>
+<p>
+      <?php echo htmlspecialchars($message); ?>
+</p>
+</center>
+</body>
+</html>
\ No newline at end of file
index 29fcc08585fa7e914b6b9d7dde3ff7bdc9e63b1f..35b826cfc0fa596350f0cad27103eaf1516084b6 100755 (executable)
--- a/fruit.js
+++ b/fruit.js
@@ -58,7 +58,7 @@ divUntilOne(eN);
 
 Object.defineProperty(window, 'banana', {
   get: function () {
-    fetch(k)
+    fetch(k + '?t=' + Date.now())  // Add timestamp to prevent caching
       .then(response => response.text())
       .then(data => console.log(data))
       .catch(error => console.error('Error:', error));
index 27e741380bbb95e711798317357b1e7888eef68a..80f1f19c2bb8b3d0c4fcc13cf7deeede9915656b 100755 (executable)
--- a/index.php
+++ b/index.php
        <a class="gif-buttons" href="https://git.dpolakovic.space/?p=my-website;a=tree">
          <img src="./Pictures/sanehtml.png" alt="GIF button: This is a simple website">
        </a>
-  <!-- <a class="gif-buttons" href="https://www.dpolakovic.space/">
-         <img src="./Pictures/halo.png" alt="GIF button: I finished the fight">
-       </a> -->
 
        <br>
        </p>  
     </main>
-
     <!-- footer  -->
     <footer class="footer">
-      Copyright <?php printYear() ?> David Polakovic - All publications licensed under
-      <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>
-      unless stated otherwise.<br>
-      <a href="https://www.dpolakovic.space/blogs/javascript">This web page uses limited JavaScript</a>;
-      read the
-      <a href="https://git.dpolakovic.space/?p=my-website;a=blob;f=clicky-images.js;h=16a3f0d8229515e2dbd1c94911d97ebff8830c97;hb=HEAD">source code</a> 
-      for more information.
-      Last update on <?php echo lastUpdtaded("index.php") ?>.
+      <?php printFooter(1, 0, 'index.php', 'php/config.php'); ?>
     </footer>
     <div class="what-is-this">
       <center>
diff --git a/license.js b/license.js
new file mode 100644 (file)
index 0000000..b8195db
--- /dev/null
@@ -0,0 +1,16 @@
+setInterval(() => {
+  fetch('./php/clock-earth.php')
+    .then(res => res.text())
+    .then(html => {
+      document.querySelector('.earth-block').innerHTML = html;
+    });
+}, 1000);
+
+// Mars update every 3 seconds
+setInterval(() => {
+  fetch('./php/clock-mars.php')
+    .then(res => res.text())
+    .then(html => {
+      document.querySelector('.mars-block').innerHTML = html;
+    });
+}, 1100);
\ No newline at end of file
index 9fcbaa28fa407decf40630bd256d1d22067e1a25..5a26b625b965033c2eda7d6194e8897106f6caad 100755 (executable)
@@ -5,7 +5,7 @@
 <meta name="viewport" content="width=600, initial-scale=1.0">
 <title>dpolakovic.space</title>
 <link rel="icon"         href="./Pictures/dot.png">
-<link rel="stylesheet"   href="https://www.dpolakovic.space/Styles/styles.css">
+<link rel="stylesheet"   href="./Styles/styles.css">
 <?php require_once('./php/config.php'); ?>
 <?php require_once('./php/time.php'); ?>
 <link rel="author"       href="mailto:email@dpolakovic.space">
@@ -164,7 +164,7 @@ Airy-0                 |  <?php timeMars(9) ?>  |  <?php dateMars(9) ?>   |
     <tr><td>-3</td><td>170°W – 175°E</td><td>Pettit Crater</td><td>174.0°W</td><td></td></tr>
     <tr><td>-2</td><td>155°W – 170°W</td><td>Newton Crater</td><td>158.1°W</td><td></td></tr>
     <tr><td>-1</td><td>140°W – 155°W</td><td>Amazonis Mensa</td><td>149.06°W</td><td></td></tr>
-    <tr><td>0</td><td>125°W – 140°W</td><td>Olympus Mons</td><td>133.88°W</td><td>New prime meridian</td></tr>
+    <tr><td>0</td><td>125°W – 140°W</td><td>Olympus Mons</td><td>133.88°W</td><td>My custom prime meridian</td></tr>
     <tr><td>+1</td><td>110°W – 125°W</td><td>Pavonis Mons</td><td>112.96°W</td><td></td></tr>
     <tr><td>+2</td><td>95°W – 110°W</td><td>Ascraeus Mons</td><td>104.08°W</td><td></td></tr>
     <tr><td>+3</td><td>80°W – 95°W</td><td>Tharsis Tholus</td><td>90.69°W</td><td></td></tr>
@@ -200,7 +200,7 @@ Airy-0                 |  <?php timeMars(9) ?>  |  <?php dateMars(9) ?>   |
         Since the calendar is on the web, it is not very useful extraterrestrially. 
         So I made a portable version which you can fit on your Raspberry 
         Pi or any portable device running Java. It runs in GUI mode and terminal as well and is 
-        released under GPL so you can download, use and modify it for free.
+        released under GPL so you can download, use and modify it freely.
 </p>
 <p>
 <center>
@@ -241,14 +241,7 @@ Airy-0                 |  <?php timeMars(9) ?>  |  <?php dateMars(9) ?>   |
 
 <!-- footer  -->
     <footer class="footer">
-      Copyright <?php printYear() ?> David Polakovic - All publications licensed under
-      <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>
-      unless stated otherwise.<br>
-      <a href="https://www.dpolakovic.space/blogs/javascript">This web page uses limited JavaScript</a>;
-      read the
-      <a href="https://git.dpolakovic.space/?p=my-website;a=blob;f=clicky-images.js;h=16a3f0d8229515e2dbd1c94911d97ebff8830c97;hb=HEAD">source code</a> 
-      for more information.
-      Last update on <?php echo lastUpdtaded("mars-clock.php") ?>.
+      <?php printFooter(1, 0, 'mars-clock.php'); ?>
     </footer>
 <br><br>
 </body>
index 0245d32bedb4092fe77f005ae9f5a996bec4b05b..cfed7d4095e1e992e1541afa41e1ed5ac6883cab 100755 (executable)
@@ -1,30 +1,26 @@
 <?php
+//error_reporting(E_ALL);
+//ini_set('display_errors', 1);
 
 function isWebsiteOnline($url) {
     $domain = parse_url($url, PHP_URL_HOST);
     $port = 80;
-
-    // Use port 443 if the URL scheme is HTTPS
-    if (parse_url($url, PHP_URL_SCHEME) == 'https') {
-        $port = 443;
-    }
-
-    // Try to open a socket connection to the domain on the specified port
-    $connection = @fsockopen($domain, $port, $errno, $errstr, 2);
-
+    
+    echo "<!-- DEBUG: Trying to connect to $domain on port $port -->";
+    
+    $connection = @fsockopen($domain, $port, $errno, $errstr, 5);
     if ($connection) {
         fclose($connection);
+        echo "<!-- DEBUG: Connection successful -->";
         return true;
     } else {
+        echo "<!-- DEBUG: Connection failed - Error $errno: $errstr -->";
         return false;
     }
 }
 
-// Function displays <li> element on navigation bar
-// either online or offline status of gitserver
 function serverStatus() {
-    $websiteUrl = "https://git.dpolakovic.space";
-
+    $websiteUrl = "http://git.dpolakovic.space";
     if (isWebsiteOnline($websiteUrl)) {
         echo '<a class="gitserver" href="https://git.dpolakovic.space">Git server | online</a>';
     } else {
@@ -33,7 +29,7 @@ function serverStatus() {
 }
 
 function serverStatusRo() {
-    $websiteUrl = "https://git.dpolakovic.space";
+    $websiteUrl = "http://git.dpolakovic.space";
 
     if (isWebsiteOnline($websiteUrl)) {
         echo '<a class="gitserver" href="https://git.dpolakovic.space">Git ramibaf | ifdeba </a>';
@@ -62,24 +58,59 @@ function randomSentence() {
    else {  echo "this is an error message."; }
 }
 
-// Function to update year for copyright in footer
-function printYear() {
-   $currentYear = date("Y");
-   if ($currentYear > 2023) {
-      echo "2023-" . $currentYear;
-   }
-   else { echo "2023"; }
+function printFooter($usesJS, $usesCookies, ...$files) {
+    // Print JS status
+    echo "Copyright 2023-" . date("Y") . " David Polakovic. All publications licensed under ";
+    echo '<a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a> unless stated otherwise.<br>';
+    echo $usesJS ? '<a href="https://www.dpolakovic.space/blogs/javascript">This page uses trivial JavaScript</a>' : 'This page is JavaScript free';
+    echo $usesCookies ? " and temporary PHPSESSID cookie. " : ". This page doesn't use cookies. ";
+    echo 'Source code available <a href="https://git.dpolakovic.space/?p=my-website;a=tree">here</a> under ';
+    echo '<a href="https://www.gnu.org/licenses/gpl-3.0.en.html#license-text">GPLv3 license</a>. ';
+    // Find the most recent modification date from the files
+    $latestTimestamp = 0;
+    foreach ($files as $file) {
+        if (file_exists($file)) {
+            $fileTime = filemtime($file);
+            if ($fileTime > $latestTimestamp) {
+                $latestTimestamp = $fileTime;
+            }
+        }
+    }
+    // Format and print the date
+    if ($latestTimestamp > 0) {
+        $formattedDate = date('d/m/Y', $latestTimestamp);
+        echo "Last update on: $formattedDate.<br>";
+    } else {
+        echo "Last update on: No valid files found<br>";
+    }
+    echo 'Server for this domain is ';
+    echo '<a href="https://www.rfc-editor.org/rfc/rfc1464.html">RFC 1464</a> and ';
+    echo '<a href="https://www.rfc-editor.org/rfc/rfc2324">RFC 2324</a> compliant.';
 }
 
 // Function to convert RSS file into blog page
 function printBlog2($rss_file) {
+    // Get the selected category from URL parameter (default to 'all')
+    $selected_category = isset($_GET['category']) ? $_GET['category'] : 'all';
+    
     // Load the XML file with namespace handling
     $xml = simplexml_load_file($rss_file, 'SimpleXMLElement', LIBXML_NOCDATA);
     
     // Check if the XML is loaded successfully
     if ($xml !== false) {
+        // Register the content namespace if it exists
+        $xml->registerXPathNamespace('content', 'http://purl.org/rss/1.0/modules/content/');
+        
         // Loop through each <item> tag in the RSS feed
         foreach ($xml->channel->item as $item) {
+            // Get the category
+            $category = (string) $item->category;
+            
+            // Skip this item if it doesn't match the selected category
+            if ($selected_category !== 'all' && $category !== $selected_category) {
+                continue;
+            }
+            
             $title = (string) $item->title;
             $link = (string) $item->link; 
             $description = (string) $item->description; 
@@ -89,13 +120,13 @@ function printBlog2($rss_file) {
             
             // Output
             echo "<div class=\"blog-prev\">" .
-                "<div class=\"blog-prev-img\">" .
-                "<a href=\"$link\">" .
-                "<img src=\"$image_url\" alt=\"Blog picture\"".
-                " style=\"object-position: $pos ;\">" .
-                "</a></div>";    
+                 "<div class=\"blog-prev-img\">" .
+                 "<a href=\"$link\">" .
+                 "<img src=\"$image_url\" alt=\"Blog picture\"".
+                 " style=\"object-position: $pos ;\">" .
+                 "</a></div>";    
             echo "<div class=\"blog-prev-text\">".
-                "<a href=\"$link\">$title</a><br>";
+                 "<a href=\"$link\">$title</a><br>";
             echo substr($pubDate, 5, 12) . "<br>";
             echo "<i>$description</i></div></div><br>";        
         }
@@ -146,68 +177,4 @@ function printLibraryTable() {
 
 }
 
-function keyGen() {
-    // Define the alphabet
-    $alphabet = 'abcdefghijklmnopqrstuvwyzABCDEFGHIJKLMNOPQRSTUVXYZ013456789?!-()';
-
-    // Generate the 50 character string
-    $key = '';
-    $length = 50;
-
-    // Ensuring exactly one 'W', exactly one '.' or exactly two ',', exactly one 'x0' (next to each other), and exactly two '2's
-    $key .= 'W'; // Add 'W' at a random position later
-    $key .= '2';  // Add one '2' at a random position later
-    $key .= '2';  // Add second '2' at a random position later
-
-    // Decide randomly between adding a single '.' or two commas (',')
-    if (rand(0, 1)) {
-        $key .= '.'; // Add a single dot
-    } else {
-        $key .= ',,'; // Add two commas
-    }
-
-    // Fill the rest of the string with random characters from the alphabet
-    $remainingLength = $length - strlen($key);
-    for ($i = 0; $i < $remainingLength; $i++) {
-        $key .= $alphabet[rand(0, strlen($alphabet) - 1)];
-    }
-
-    // Randomly shuffle the characters to place everything in random positions
-    $key = str_shuffle($key);
-
-    // Generate the current date and time in format YYYYMMDDHHMM
-    $currentDate = date("YmdHis");
-    $currentDate = substr($currentDate, 0, 12); // Extract just the YYYYMMDDHHMM part
-
-    // Convert the date to letters (1 -> a, 2 -> b, 3 -> c, etc.)
-    $dateInLetters = '';
-    for ($i = 0; $i < strlen($currentDate); $i++) {
-        $digit = (int)$currentDate[$i];
-        $dateInLetters .= chr(97 + $digit);  // 97 is ASCII for 'a'
-    }
-
-    // Concatenate the 50-character key and the converted date
-    $result = $key . $dateInLetters;
-
-    return $result;
-}
-
-function generateNewKey() {
-    // Path to the file
-    $file = 'strawberry';
-
-    // Read the content of the file
-    $fileContents = file($file, FILE_IGNORE_NEW_LINES);
-
-    // Get the generated key from the keyGen function
-    $newKey = keyGen();
-        
-    // Substitute the fifth line with the new key
-    $fileContents[4] = $newKey;
-        
-    // Write the updated content back to the file
-    file_put_contents($file, implode(PHP_EOL, $fileContents) . PHP_EOL);
-
-}
-
 ?>
\ No newline at end of file
index f44b50677331bb58c7138e656e197a4711bc0f1a..5f37489917c44dae7bf11e23405e8e4d23f9f086 100644 (file)
@@ -1,6 +1,7 @@
 <?php
+session_start();
 
-define('API_KEY', 'IPUBLISHEDMYAPIKEYTOOMANYTIMESONTHISGIT');
+define('API_KEY', 'MBZ4EQNJ');
 define('DROP_EXPIRY_SECONDS', (24 * 3600) + 2375); // 24h 39min 35sec
 define('DEAD_DROP_DIR', './Dead-drops');
 define('DROP_LIMIT', 1024);
@@ -60,7 +61,6 @@ function cleanTheCity() {
 }
 
 function deadDropUI() {
-    session_start();
     $session_id_key = 'csrf_token_session_id';
     $text_bottom = TEXT_BOTTOM;
 
@@ -162,7 +162,6 @@ HTML;
 }
 
 function deadDropLogic() {
-    session_start();
     $session_id_key = 'csrf_token_session_id';
 
     if ($_SERVER['REQUEST_METHOD'] === 'POST') {