Add Suggestions to OAPEN Library

Adds suggestions to the sidebar on https://library.oapen.org when viewing a publication.

  1. // ==UserScript==
  2. // @name Add Suggestions to OAPEN Library
  3. // @namespace Violentmonkey Scripts
  4. // @match *://library.oapen.org/handle/*
  5. // @grant none
  6. // @version 1.1
  7. // @author OAPEN Suggestion Service
  8. // @grant GM_xmlhttpRequest
  9. // @description Adds suggestions to the sidebar on https://library.oapen.org when viewing a publication.
  10. // ==/UserScript==
  11. const FETCH_URL_HOST = "https://oss.ebookfoundation.org";
  12.  
  13. async function mountSuggestions() {
  14. let sidebar = document.querySelector("#aspect_artifactbrowser_ItemViewer_div_item-view > div > div.row > div.col-sm-4");
  15. let suggestionsElement = document.createElement("div");
  16. suggestionsElement.className = "item-page-field-wrapper list-group";
  17. suggestionsElement.style.width = "75%";
  18. let heading = document.createElement("h5");
  19. heading.innerText = "Suggestions"
  20.  
  21.  
  22. let handle = window.location.pathname.split('/').slice(-2).join("/");
  23. GM_xmlhttpRequest({
  24. url: FETCH_URL_HOST + "/api/" + handle,
  25. method: "GET",
  26. responseType: "json",
  27. onload: (response) => {
  28. try {
  29. let resp = JSON.parse(response.responseText);
  30.  
  31. if (!resp || resp.error) throw "No response!";
  32. if (!resp.items || !resp?.items?.suggestions) throw "No items in response!";
  33.  
  34. const { suggestions } = resp.items;
  35.  
  36. // create suggestions list element
  37. const suggestionsListElement = document.createElement("ul");
  38. suggestionsListElement.className = "suggestions-list";
  39.  
  40. // create suggestions list items
  41. const suggestionsListItems = suggestions.slice(0, 4).map((suggestion) => {
  42. const listItem = document.createElement("li");
  43. listItem.className = "list-group-item ds-option";
  44. listItem.style.textAlign = "center";
  45. // make it a link
  46. const link = document.createElement("a");
  47. link.className = "suggestions-list-item-link";
  48. link.href = "https://library.oapen.org/handle/" + suggestion.suggestion;
  49. link.target = "_blank";
  50. link.innerText = suggestion.suggestion_name;
  51. // add the thumbail
  52. const thumbnail = document.createElement("img");
  53. const thumbnailDiv = document.createElement("div");
  54. thumbnailDiv.className = "thumbnail";
  55. thumbnail.className = "img-thumbnail";
  56. thumbnail.style.margin = "0 auto";
  57. thumbnail.src = suggestion.suggestion_thumbnail;
  58. // append it all together
  59. thumbnailDiv.appendChild(thumbnail);
  60. listItem.appendChild(thumbnailDiv);
  61. listItem.appendChild(link);
  62. return listItem;
  63. });
  64.  
  65. // append suggestions list items to list
  66. suggestionsListItems.forEach((item) =>
  67. suggestionsListElement.appendChild(item)
  68. );
  69.  
  70. // append list to suggestions element
  71. suggestionsElement.appendChild(suggestionsListElement);
  72. } catch (e) {
  73. let noSuggestions = document.createElement("p");
  74. noSuggestions.innerText = "Not available for this text";
  75. suggestionsElement.innerHTML = "";
  76. suggestionsElement.append(noSuggestions);
  77. suggestionsElement.prepend(heading);
  78. console.error(e);
  79. }
  80. },
  81. onerror: (e) => {
  82. let noSuggestions = document.createElement("p");
  83. noSuggestions.innerText = "Not available for this text";
  84. suggestionsElement.innerHTML = "";
  85. suggestionsElement.append(noSuggestions);
  86. suggestionsElement.prepend(heading);
  87. sidebar.appendChild(suggestionsElement);
  88. console.error(e);
  89. }
  90. });
  91. sidebar.appendChild(suggestionsElement);
  92. }
  93.  
  94. window.onload = function () {
  95. mountSuggestions();
  96. };