Coriolis - Save export to file

Add a button on coriolis backup / detailed-export, to save the output as file.

  1. // ==UserScript==
  2. // @name Coriolis - Save export to file
  3. // @name:de Coriolis - Export in Datei speichern
  4. // @namespace https://gf.qytechs.cn/users/928242
  5. // @version 1.0.2
  6. // @description Add a button on coriolis backup / detailed-export, to save the output as file.
  7. // @description:de Füge einen Button zu "Coriolis Backup / Detailed-Export" hinzu, um die Ausgabe als Datei zu speichern.
  8. // @author Kamikaze (https://github.com/Kamiikaze)
  9. // @supportURL https://github.com/Kamiikaze/Tampermonkey/issues
  10. // @match https://coriolis.io/*
  11. // @icon https://www.google.com/s2/favicons?sz=64&domain=coriolis.io
  12. // @grant none
  13. // @license MIT
  14. // ==/UserScript==
  15.  
  16.  
  17. const settingsElSelector = "#coriolis .r.menu .menu-header";
  18. const menuElSelector = "#coriolis .menu-list ul";
  19. const menuEntryBackupElSelector = "li:nth-child(1) > a";
  20. const menuEntryExportElSelector = "li:nth-child(2) > a";
  21. const modalElSelector = ".modal";
  22.  
  23.  
  24. (async () => {
  25.  
  26. const settingsElement = await waitForElm(settingsElSelector)
  27. settingsElement.addEventListener('click', async () => {
  28.  
  29. const menuElement = await waitForElm(menuElSelector)
  30.  
  31. const menuEntryBackup = await waitForElm(menuEntryBackupElSelector, menuElement)
  32. menuEntryBackup.addEventListener('click', () => {
  33. createDLBtn('backup')
  34. })
  35.  
  36. const menuEntryExport = await waitForElm(menuEntryExportElSelector, menuElement)
  37. menuEntryExport.addEventListener('click', () => {
  38. createDLBtn('detailed-export')
  39. })
  40. })
  41.  
  42. })();
  43.  
  44.  
  45. async function createDLBtn(type) {
  46. const modal = await waitForElm(modalElSelector)
  47.  
  48. const btn = document.createElement("button")
  49. btn.className = "r cap"
  50. btn.innerText = "download"
  51. btn.addEventListener('click', async () => {
  52. const data = await getJsonData()
  53. download(data, type)
  54. })
  55.  
  56. modal.append(btn)
  57. }
  58.  
  59. async function getJsonData() {
  60. const modal = await waitForElm(modalElSelector)
  61. const textfield = await waitForElm("textarea", modal)
  62.  
  63. return JSON.parse(textfield.value)
  64. }
  65.  
  66. function download(content, type) {
  67. const a = document.createElement("a");
  68. const file = new Blob([JSON.stringify(content, null, 2)], {type: 'text/plain'})
  69.  
  70. const timestamp = new Date().toISOString()
  71.  
  72. a.href = URL.createObjectURL(file)
  73. a.download = `${timestamp}_coriolis_${type}.json`
  74. a.click()
  75. }
  76.  
  77. function waitForElm(selector, parent = document) {
  78. return new Promise((resolve) => {
  79. if (parent.querySelector(selector)) {
  80. console.debug("Element found", selector)
  81. return resolve(parent.querySelector(selector));
  82. }
  83.  
  84. const observer = new MutationObserver(() => {
  85. if (parent.querySelector(selector)) {
  86. console.debug("Element found", selector)
  87. resolve(parent.querySelector(selector))
  88. observer.disconnect()
  89. }
  90. });
  91.  
  92. observer.observe(document.body, {
  93. childList: true,
  94. subtree: true
  95. });
  96. });
  97. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址