Plex Random Movie Picker

Picks a random movie from the Plex library on localhost and displays additional information

  1. // ==UserScript==
  2. // @name Plex Random Movie Picker
  3. // @namespace https://greasyfork.org/en/users/247131
  4. // @author ALi3naTEd0
  5. // @version 1.5
  6. // @license MIT
  7. // @description Picks a random movie from the Plex library on localhost and displays additional information
  8. // @match http://localhost/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. // Create the main button for random movie selection
  16. const button = document.createElement("button");
  17. button.innerText = "Pick Random Movie";
  18. button.style.position = "fixed";
  19. button.style.top = "20px"; // Space from the top
  20. button.style.left = "50%";
  21. button.style.transform = "translateX(-50%)";
  22. button.style.padding = "10px 20px";
  23. button.style.fontSize = "16px";
  24. button.style.zIndex = 1000;
  25. button.onclick = fetchRandomMovie;
  26. document.body.appendChild(button);
  27.  
  28. // Function to fetch a random movie from the Plex library
  29. async function fetchRandomMovie() {
  30. try {
  31. // Replace with your Plex token and server details
  32. const token = "Kbx3LfZzfsM9XkRzPqk9";
  33. const url = "http://localhost:32400/library/sections/1/all?X-Plex-Token=" + token;
  34.  
  35. const response = await fetch(url);
  36. const data = await response.text();
  37. const parser = new DOMParser();
  38. const xmlDoc = parser.parseFromString(data, "text/xml");
  39.  
  40. // Get all movies in the library
  41. const movies = xmlDoc.getElementsByTagName("Video");
  42. if (movies.length === 0) {
  43. alert("No movies found.");
  44. return;
  45. }
  46.  
  47. // Select a random movie
  48. const randomIndex = Math.floor(Math.random() * movies.length);
  49. const randomMovie = movies[randomIndex];
  50.  
  51. // Retrieve movie details
  52. const title = randomMovie.getAttribute("title");
  53. const year = randomMovie.getAttribute("year");
  54. const durationMs = randomMovie.getAttribute("duration");
  55. const duration = durationMs ? Math.round(durationMs / 60000) + " mins" : "Unknown";
  56. const movieKey = randomMovie.getAttribute("ratingKey");
  57. const thumbPath = randomMovie.getAttribute("thumb");
  58.  
  59. // Construct Plex movie URL on localhost
  60. const plexUrl = `http://localhost:32400/web/index.html#!/server/0f12cd3b912ff67f98de19cb45b4459d8e55222a/details?key=%2Flibrary%2Fmetadata%2F${movieKey}`;
  61.  
  62. // Construct IMDb search URL
  63. const imdbSearchUrl = `https://www.imdb.com/find?q=${encodeURIComponent(title + " " + year)}&s=tt`;
  64.  
  65. // If dialog exists, remove it to refresh content
  66. const existingDialog = document.getElementById("movieDialog");
  67. if (existingDialog) existingDialog.remove();
  68.  
  69. // Create custom dialog to display movie details
  70. const dialog = document.createElement("div");
  71. dialog.id = "movieDialog";
  72. dialog.style.position = "fixed";
  73. dialog.style.top = "50%";
  74. dialog.style.left = "50%";
  75. dialog.style.transform = "translate(-50%, -50%)";
  76. dialog.style.backgroundColor = "#fff";
  77. dialog.style.border = "2px solid #ccc";
  78. dialog.style.padding = "20px";
  79. dialog.style.zIndex = 1001;
  80. dialog.style.boxShadow = "0 4px 8px rgba(0,0,0,0.2)";
  81. dialog.style.width = "300px";
  82. dialog.style.textAlign = "center";
  83.  
  84. // Add movie thumbnail if available
  85. if (thumbPath) {
  86. const thumbnail = document.createElement("img");
  87. thumbnail.src = `http://localhost:32400${thumbPath}?X-Plex-Token=${token}`;
  88. thumbnail.style.width = "100%";
  89. thumbnail.style.borderRadius = "5px";
  90. thumbnail.style.marginBottom = "10px";
  91. dialog.appendChild(thumbnail);
  92. }
  93.  
  94. // Add movie details
  95. const message = document.createElement("p");
  96. message.innerText = `Title: ${title}\nYear: ${year}\nDuration: ${duration}`;
  97. dialog.appendChild(message);
  98.  
  99. // Add link to open movie in current tab
  100. const goButton = document.createElement("a");
  101. goButton.href = plexUrl; // URL of the movie in localhost
  102. goButton.innerText = "Go to Movie";
  103. goButton.style.display = "block";
  104. goButton.style.marginTop = "15px";
  105. goButton.style.textDecoration = "none";
  106. goButton.style.color = "#007bff";
  107. goButton.onclick = () => {
  108. window.location.href = plexUrl; // Opens the URL in the same tab
  109. };
  110. dialog.appendChild(goButton);
  111.  
  112. // Add IMDb link in yellow Plex color
  113. const imdbLink = document.createElement("a");
  114. imdbLink.href = imdbSearchUrl;
  115. imdbLink.innerText = "View on IMDb";
  116. imdbLink.target = "_blank"; // Open IMDb in a new tab
  117. imdbLink.style.display = "block";
  118. imdbLink.style.marginTop = "10px";
  119. imdbLink.style.marginBottom = "15px"; // Add space before the buttons
  120. imdbLink.style.textDecoration = "none";
  121. imdbLink.style.color = "#e5a00d"; // Yellow color for IMDb link
  122. dialog.appendChild(imdbLink);
  123.  
  124. // Add 'Next' button for another random selection
  125. const nextButton = document.createElement("button");
  126. nextButton.innerText = "Next";
  127. nextButton.onclick = fetchRandomMovie; // Calls the function again for a new random movie
  128. nextButton.style.marginTop = "10px";
  129. nextButton.style.marginRight = "10px";
  130. dialog.appendChild(nextButton);
  131.  
  132. // Add 'Close' button to close the dialog
  133. const closeButton = document.createElement("button");
  134. closeButton.innerText = "Close";
  135. closeButton.onclick = () => {
  136. document.body.removeChild(dialog);
  137. };
  138. closeButton.style.marginTop = "10px";
  139. closeButton.style.marginLeft = "10px";
  140. dialog.appendChild(closeButton);
  141.  
  142. // Add the dialog to the document
  143. document.body.appendChild(dialog);
  144.  
  145. } catch (error) {
  146. console.error("Error fetching movie:", error);
  147. alert("Error fetching movie.");
  148. }
  149. }
  150. })();