GGn request presets

Create request presets, set defaults and easily duplicate requests in the alternate currency

  1. // ==UserScript==
  2. // @name GGn request presets
  3. // @namespace none
  4. // @version 3
  5. // @description Create request presets, set defaults and easily duplicate requests in the alternate currency
  6. // @author ingts
  7. // @match https://gazellegames.net/requests.php
  8. // @match https://gazellegames.net/requests.php?action=new*
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @grant GM_deleteValue
  12. // ==/UserScript==
  13.  
  14. if (typeof GM_getValue('api_key') === 'undefined')
  15. GM_setValue('api_key', '')
  16.  
  17. const category = document.getElementById('categories')
  18. const hasid = location.href.includes('groupid')
  19. const ulrequest = location.href.includes('upload')
  20. let elements = {}
  21. let checkboxGroups = []
  22.  
  23. function getElements(type = category.value) {
  24. if (hasid) {
  25. elements = {
  26. title: document.querySelector('input[name=title]'),
  27. description: document.querySelector('textarea[name=description]'),
  28. bounty: document.getElementById('amount_box')
  29. }
  30. if (type === 'Games') {
  31. Object.assign(elements, {
  32. releasetypes: document.querySelectorAll('#releasetypes_tr input[type=checkbox]'),
  33. languages: document.querySelectorAll('#languages_tr input[type=checkbox]'),
  34. regions: document.querySelectorAll('#regions_tr input[type=checkbox]')
  35. })
  36. checkboxGroups = ['releasetypes', 'languages', 'regions']
  37. } else if (type === 'OST') {
  38. Object.assign(elements, {
  39. formats: document.querySelectorAll('#formats_tr input[type=checkbox]'),
  40. bitrates: document.querySelectorAll('#bitrates_tr input[type=checkbox]')
  41. })
  42. checkboxGroups = ['formats', 'bitrates']
  43. }
  44. } else {
  45. elements = {
  46. type: category,
  47. tags: document.querySelector('input[name=tags]'),
  48. title: document.querySelector('input[name=title]'),
  49. image: document.querySelector('input[name=image]'),
  50. description: document.querySelector('textarea[name=description]'),
  51. bounty: document.getElementById('amount_box')
  52. }
  53. if (type === 'Games') {
  54. Object.assign(elements, {
  55. platform: document.getElementById('platform'),
  56. year: document.querySelector('input[name=year]'),
  57. releasetypes: document.querySelectorAll('#releasetypes_tr input[type=checkbox]'),
  58. languages: document.querySelectorAll('#languages_tr input[type=checkbox]'),
  59. regions: document.querySelectorAll('#regions_tr input[type=checkbox]')
  60. })
  61. checkboxGroups = ['releasetypes', 'languages', 'regions']
  62. } else if (type === 'OST') {
  63. Object.assign(elements, {
  64. year: document.querySelector('input[name=year]'),
  65. formats: document.querySelectorAll('#formats_tr input[type=checkbox]'),
  66. bitrates: document.querySelectorAll('#bitrates_tr input[type=checkbox]')
  67. })
  68. checkboxGroups = ['formats', 'bitrates']
  69. }
  70. if (ulrequest) Object.assign(elements, {unit: document.getElementById('current_unit')})
  71. }
  72. }
  73.  
  74.  
  75. function save() {
  76. let saved = {}
  77. getElements()
  78. Object.keys(elements).forEach(key => {
  79. const element = elements[key]
  80. if (checkboxGroups.includes(key)) {
  81. saved[key] = Array.from(element).filter(c => c.checked).map(c => c.value)
  82. } else {
  83. saved[key] = element.value
  84. }
  85. })
  86. return saved
  87. }
  88.  
  89. function load(obj) {
  90. getElements(obj.type)
  91. for (const [key, val] of Object.entries(elements)) {
  92. if (hasid && key === 'title') {
  93. val.value = val.value + obj[key]
  94. continue
  95. }
  96. if (checkboxGroups.includes(key)) {
  97. val.forEach(c => {
  98. c.checked = c.value !== 'on' && obj[key].includes(c.value)
  99. })
  100. } else val.value = obj[key]
  101. }
  102. category.dispatchEvent(new Event('change'))
  103. }
  104.  
  105. const currency = location.href.includes('gold') || hasid ? 'GB' : 'Gold'
  106.  
  107. if (GM_getValue('d')) {
  108. const duplicate = GM_getValue('duplicate')
  109. const groupid = GM_getValue('groupid')
  110. load(duplicate)
  111. elements.description.value += `\n\n${currency} request: https://gazellegames.net/requests.php?action=view&id=${GM_getValue('currentID') + 1}\n${groupid ? 'Group: https://gazellegames.net/torrents.php?id=' + groupid : ''}`
  112. if (location.href.includes('gold')) /* converting from gb */ {
  113. if (duplicate.unit === 'mb') elements.bounty.value = Math.ceil(duplicate.bounty / 2.048)
  114. if (duplicate.unit === 'gb') elements.bounty.value = Math.ceil(duplicate.bounty * 500)
  115. } else {
  116. elements.bounty.value = Math.ceil(duplicate.bounty * 2.048)
  117. elements.unit.value = 'mb'
  118. }
  119. GM_deleteValue('d')
  120. GM_deleteValue('duplicate')
  121. GM_deleteValue('currentID')
  122. if (groupid) GM_deleteValue('groupid')
  123. } else {
  124. let presets = GM_getValue('presets', {})
  125. let deflt = GM_getValue('default')
  126. if (deflt) load(deflt)
  127. const end = document.querySelector("#request_form > table > tbody > tr:nth-child(16) > td > p")
  128. document.querySelector("#request_form > table > tbody > tr:nth-child(1)").insertAdjacentHTML('afterend', `
  129. <tr>
  130. <td class="label">Presets</td>
  131. <td>
  132. <select id="presets" style="border: #44ff8d 1px dotted;">
  133. <option></option>
  134. </select>
  135. <button type="button" id="deletepreset" class="hidden" style="background-color: red;;">Delete preset</button>
  136. </td>
  137. </tr>`)
  138. end.insertAdjacentHTML('afterend', `
  139. <button type="button" id="duplicate">Make ${currency} request</button>`)
  140. const duplicatebtn = document.getElementById('duplicate')
  141. const presetselect = document.getElementById('presets')
  142. const deletepreset = document.getElementById('deletepreset')
  143. duplicatebtn.addEventListener('click', () => {
  144. GM_setValue('duplicate', save())
  145. if (GM_getValue('api_key')) {
  146. let currentID
  147. fetch('https://gazellegames.net/api.php?request=search&search_type=requests', {headers: {'X-API-Key': GM_getValue('api_key')}})
  148. .then(r => r.json()).then(reqs => {
  149. const keys = Object.keys(reqs.response)
  150. currentID = parseInt(keys[24])
  151. GM_setValue('currentID', currentID)
  152. elements.description.value += `\n\n${currency} request: https://gazellegames.net/requests.php?action=view&id=${currentID + 2}`
  153. })
  154. }
  155. GM_setValue('d', 1)
  156. if (hasid) GM_setValue('groupid', new URL(location.href).searchParams.get('groupid'))
  157. hasid ? window.open(`https://gazellegames.net/requests.php?action=new&request_currency=upload`, '_blank')
  158. : window.open(`https://gazellegames.net/requests.php?action=new&request_currency=${location.href.includes('gold') ? 'upload' : 'gold'}`, '_blank')
  159. })
  160. Object.keys(presets).forEach(name => {
  161. let option = document.createElement('option')
  162. option.textContent = name
  163. option.value = name
  164. presetselect.append(option)
  165. })
  166. presetselect.addEventListener('change', ev => {
  167. if (presetselect.value) {
  168. deletepreset.classList.remove('hidden')
  169. load(presets[presetselect.value])
  170. } else {
  171. deletepreset.classList.add('hidden')
  172. document.getElementById('request_form').reset()
  173. }
  174. })
  175. deletepreset.addEventListener('click', () => {
  176. delete presets[presetselect.value]
  177. presetselect.querySelector(`option[value="${presetselect.value}"]`).remove()
  178. presetselect.selectedIndex = 0
  179. presetselect.dispatchEvent(new Event('change'))
  180. GM_setValue('presets', presets)
  181. })
  182. if (!hasid) {
  183. duplicatebtn.insertAdjacentHTML('afterend', `
  184. <button type="button" id="setdefault">${deflt ? 'Remove default' : 'Set as default'}</button>
  185. <button type="button" id="savepreset">Save preset</button>
  186. <input type="text" id="nameinput" style="margin-left: 10px;" class="hidden" placeholder="Name (required)">
  187. `)
  188. const nameinput = document.getElementById('nameinput')
  189. const setdefault = document.getElementById('setdefault')
  190. document.getElementById('savepreset').addEventListener("click", () => {
  191. nameinput.classList.toggle('hidden')
  192. nameinput.focus()
  193. })
  194. nameinput.addEventListener('keydown', ev => {
  195. if (ev.key === 'Enter') {
  196. ev.preventDefault()
  197. if (nameinput.value) {
  198. presets[nameinput.value] = save()
  199. GM_setValue('presets', presets)
  200. nameinput.value = 'Saved'
  201. nameinput.style.color = 'lightgreen'
  202. nameinput.disabled = true
  203. setTimeout(() => {
  204. nameinput.classList.toggle('hidden')
  205. nameinput.disabled = false
  206. nameinput.value = ''
  207. nameinput.style.removeProperty('color')
  208. }, 1500)
  209. }
  210. }
  211. })
  212. setdefault.addEventListener("click", () => {
  213. if (GM_getValue('default')) {
  214. GM_deleteValue('default')
  215. setdefault.disabled = true
  216. setdefault.textContent = 'Default removed'
  217. setdefault.style.color = 'lightgreen'
  218. setTimeout(() => {
  219. setdefault.disabled = false
  220. setdefault.textContent = 'Set as default'
  221. setdefault.style.removeProperty('color')
  222. }, 1500)
  223. } else {
  224. GM_setValue('default', save())
  225. setdefault.disabled = true
  226. setdefault.textContent = 'Default saved'
  227. setdefault.style.color = 'lightgreen'
  228. setTimeout(() => {
  229. setdefault.disabled = false
  230. setdefault.textContent = 'Remove default'
  231. setdefault.style.removeProperty('color')
  232. }, 1500)
  233. }
  234. })
  235. }
  236. }