1

i created a slideshow to randomly show photos on the web - and use for that a somewhat particular setup. pressing the ESCAPE key interrupts the show, and here comes the problem : i want the subsequently loaded new HTML page with its photo to correspond with the last photo shown in the slideshow, the one that was interrupted with ESCAPE - but instead equal the freshly loaded page and its photo with the very first photo in the slideshow started much beforehand.

all photos are stored on a linux apache web server. a single HTML file ./slsh.html serves as slideshow page while a random photo series is generated by periodically creating a symbolic link randomly to one of many photos kept in a subdirectory. the name of the symbolic link however never really changes and is static in that sense as ./slsh.jpg

a cronjob starts a bash script every 10 minutes that does the symbolic linking approximately every 1.5sec for some 10min. importantly photos are loaded into the browser window as background pictures every 9sec via a javascript refresh function. i had described this setup in more detail in the past here :

How to force-reload background image in <div> using CSS and Javascript

here my current HTML, CSS and JS excerpts :

<script>

  // KEYS
  window.addEventListener("keydown", keysPressed, false);
  window.addEventListener("keyup", keysReleased, false);
  var keys = [];
  function keysPressed( event) {
      keys[ event.keyCode] = true;
  
      if (event.keyCode == 27 || event.keyCode == 36) { //go to UID html : ESCAPE,HOME keys
          window.location.href = "./html/20070828-001264-012.html";
          event.preventDefault();
      }
      else if (event.keyCode == 81) { //go to main.html : q key
          window.location.href = "./main.html";
          event.preventDefault();
      }
      else if (event.keyCode == 13) { //refresh URL : ENTER
          location.reload();
          event.preventDefault();
      }
      else if (event.keyCode == 32 || event.keyCode == 39) { //load next=newest slsh.jpg : SPACEBAR,RIGHTARROW
          NextDivPic();
          event.preventDefault();
      }
  };
  
  function keysReleased(event) { // mark keys that were released
      keys[event.keyCode] = false;
  };


  // TIMER fx
  var timerId;
  var timerIdArray = [];
  timerId = setInterval('refresh()', 8888);
  timerIdArray.push( timerId);


  // REFRESH fx
  function refresh() {
      var timestamp = new Date().getTime();
      document.getElementById("a").style.backgroundImage = "url(./slsh.jpg?t=" + timestamp + ")";
  }

  // NEXT DIV PIC fx
  function NextDivPic() {
      // see -->  https://www.scaler.com/topics/javascript-clearinterval/
      for(var i=0;i<timerIdArray.length;i++){
          clearInterval(timerIdArray[i]);
      };
      timerId = setInterval('refresh()', 9000);
      timerIdArray.push( timerId);
      var timestamp = new Date().getTime();
      document.getElementById("a").style.backgroundImage = "url(./slsh.jpg?t=" + timestamp + ")";
      event.preventDefault();
  }

  // document.addEventListener('DOMContentLoaded', function NextDivPic() );

</script>
<style type="text/css">

  body, html {
      height: 100%;
      margin: 0;
  }

  .bg {

      /* The image used */
      background-image: url('./slsh.jpg');
      
      /* Full height */
      height: 100%; 
      
      /* Center and scale the image nicely */
      background-position: center;
      background-repeat: no-repeat;
      background-size: contain;
      background-color: rgb(10,10,10);

  }

</style>
<html>
<head>
  <title>20070828-001264-012</title>
</head>
<body id="body" onload="NextDivPic()">
  <div class="bg" id="a" onclick="NextDivPic()"></div>
</body>
</html>

i am aware that in the current situation no information can be reliably provided about the newest slideshow picture shown for 9sec in the browser window as it is periodically loaded via that non-specific symbolic link ./slsh.jpg. the window.location.href variable points incorrectly to : "./html/20070828-001264-012.html" which in fact was the UID of the very first photo shown many cycles earlier when the browser had started the slideshow and the HTML file ./slsh.html was loaded a first time and stored as such in the browser cache.

the aforementioned cronjob script updates both the particular HTML file every 1.5sec and inserts each time a new UID such as : "./html/19910000-000101-021.html" and also synchronously relinks the symbolic link ./slsh.jpg to the JPG file in question such as ./subdir/19910000-000101-021.jpg. it's just that the photo displayed in the browser for 9sec is not in sync with the UIDs chosen by the cronjob script every 1.5sec. therefore do the UID of the photo depicted and the UID of the current slsh.html and slsh.jpg very likely not correspond with each other at the moment of pressing the ESCAPE key !

in my setup i conveniently just reload the BACKGROUND image always under the same symbolic link name though every time linked to a new photo. reloading the entire HTML page after pressing ESCAPE wouldn't help here because things are not in sync as said above. still, how could i find out about the UID of the last depicted photo in the current scenario ? is there a way to look behind the symbolic link on the apache serve and find out about the real physical JPG file and its associated UID ? would including of the UID in the photo META data help here ? but then how do we read such data at background picture refresh time ? any suggestions ?

ADDENDUM : the reason i came up with this current perhaps a bit cumbersome design was the following - there are constraints on the server side of the following sort :

there are some 20K HTML files in some 100 SUBDIRs (./collectionX/.) while the pool of shared JPG files stored in a single subdir ./pics/. comes up to 35K photos. to save disk space, JPG files are hence all unique but are shareable between the various photo collections in their respective HTML files. IMPORTANTLY, each collectionX can run its own slideshow via its private slsh.html and slsh.jpg files which are both maintained via the same aforementioned cronjob script. remember, the script looks every 1.5sec through each of the approx 100 collectionX subdirectories to update the two local subdir slideshow files which the apache server then exports.

now, i am fairly inexperienced with javascript, somewhat reluctant to dive further into it, and can't program as with python for example. still, if i knew a way in JS to collect the names of all HTML files in a given SUBDIR on the apache server, extract the UIDs encoded in their filenames, and then periodically load their respective JPG files in a random fashion using the "shuffling actions" you mentioned - then that would save my day here.

pisti
  • 71
  • 10
  • You are overcomplicating matters. If you want a random picture to be shown that can be re-used in a subsequent page then you should do the [shuffling actions](https://stackoverflow.com/questions/67758150/get-a-dynamic-input-to-populate-an-array-and-display-randomly/67758525#67758525) solely in the browser (JavaScript). Leave out the cron job on the server. This way you will always have reliable image references in the browser you can use for further actions. – Carsten Massmann Jun 10 '23 at 06:49
  • thank you for your comment, Carsten, vielen Dank. now, i had read up about such javascript-based shuffling actions though i have no practical experience with such yet. the reason i came up with this current perhaps a bit cumbersome design was the following - please see my add-ons in the above main text. – pisti Jun 10 '23 at 15:47

1 Answers1

1

Under the following conditions

  • the server hasn't turned indexing off,
  • the directory doesn't have an index.html or equivalent to rewrite any attempt to index,
  • and the server isn't doing some url-rewriting.
    In other words, this should work in any server environment that doesn't rewrite or block indexes

you will be able to scan for files on a directory of your own webhost. The details can be found here (as can be the conditions listed above): List Files on a server via front-end javascript.

Following that advice I put together this snippet on my own server

    fetch("cm").then(r => r.text()).then(txt => {
        files = [...new DOMParser().parseFromString(txt, "text/html").querySelectorAll("tbody a")]
            .slice(5)
            .map(a => a.getAttribute("href"));
        console.log(files);
        shuffle(files);
        next5()
    });

to get the following result in the console:

[0 … 99]
0: "https://cars-ten.lima-city.de/100.txt"
1: "https://cars-ten.lima-city.de/101.txt"
2: "https://cars-ten.lima-city.de/102.txt"
3: "https://cars-ten.lima-city.de/103.txt"
4: "https://cars-ten.lima-city.de/104.txt"
5: "https://cars-ten.lima-city.de/105.txt"
6: "https://cars-ten.lima-city.de/106.txt"
7: "https://cars-ten.lima-city.de/107.txt"
8: "https://cars-ten.lima-city.de/108.txt"
9: "https://cars-ten.lima-city.de/109.txt"
10: "https://cars-ten.lima-city.de/110.txt"
11: "https://cars-ten.lima-city.de/111.txt"
12: "https://cars-ten.lima-city.de/112.txt"
...
..
.

So, once you have this array of file names you can apply the following shuffling function onto it to get a randomized sequence of the existing files:

function shuffle(a,n){ // shuffle array a in place (Fisher-Yates)
 let m=a.length;
 n=n||m-1;
 for(let i=0,j;i<n;i++){
  j=Math.floor(Math.random()*(m-i)+i);
  if (j-i) [ a[i],a[j] ] = [ a[j],a[i] ]; // swap 2 array elements
 }
}
Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
  • great - großartig ! will try out tonight once i have an hour or so time (i.e. family asleep) ! and many thanks in advance ! – pisti Jun 11 '23 at 18:11