BZOJ exports

Export problem data from BZOJ

  1. // ==UserScript==
  2. // @name BZOJ exports
  3. // @namespace https://zhangzisu.cn/
  4. // @version 0.2
  5. // @description Export problem data from BZOJ
  6. // @author ZhangZisu
  7. // @match https://www.lydsy.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. function deselectCurrent() {
  12. var selection = document.getSelection()
  13. if (!selection.rangeCount) {
  14. return function () { }
  15. }
  16. var active = document.activeElement
  17.  
  18. var ranges = []
  19. for (var i = 0; i < selection.rangeCount; i++) {
  20. ranges.push(selection.getRangeAt(i))
  21. }
  22.  
  23. switch (active.tagName.toUpperCase()) {
  24. case 'INPUT':
  25. case 'TEXTAREA':
  26. active.blur()
  27. break
  28.  
  29. default:
  30. active = null
  31. break
  32. }
  33.  
  34. selection.removeAllRanges()
  35. return function () {
  36. selection.type === 'Caret' &&
  37. selection.removeAllRanges()
  38.  
  39. if (!selection.rangeCount) {
  40. ranges.forEach(function (range) {
  41. selection.addRange(range)
  42. })
  43. }
  44.  
  45. active &&
  46. active.focus()
  47. }
  48. }
  49.  
  50. function format(message) {
  51. var copyKey = (/mac os x/i.test(navigator.userAgent) ? '⌘' : 'Ctrl') + '+C'
  52. return message.replace(/#{\s*key\s*}/g, copyKey)
  53. }
  54.  
  55. function copy(text) {
  56. var debug, message, reselectPrevious, range, selection, mark, success = false
  57. try {
  58. reselectPrevious = deselectCurrent()
  59.  
  60. range = document.createRange()
  61. selection = document.getSelection()
  62.  
  63. mark = document.createElement('span')
  64. mark.textContent = text
  65. // reset user styles for span element
  66. mark.style.all = 'unset'
  67. // prevents scrolling to the end of the page
  68. mark.style.position = 'fixed'
  69. mark.style.top = 0
  70. mark.style.clip = 'rect(0, 0, 0, 0)'
  71. // used to preserve spaces and line breaks
  72. mark.style.whiteSpace = 'pre'
  73. // do not inherit user-select (it may be `none`)
  74. mark.style.webkitUserSelect = 'text'
  75. mark.style.MozUserSelect = 'text'
  76. mark.style.msUserSelect = 'text'
  77. mark.style.userSelect = 'text'
  78.  
  79. document.body.appendChild(mark)
  80.  
  81. range.selectNode(mark)
  82. selection.addRange(range)
  83.  
  84. var successful = document.execCommand('copy')
  85. if (!successful) {
  86. throw new Error('copy command was unsuccessful')
  87. }
  88. success = true
  89. } catch (err) {
  90. try {
  91. window.clipboardData.setData('text', text)
  92. success = true
  93. } catch (err) {
  94. message = format('Copy to clipboard: #{key}, Enter')
  95. window.prompt(message, text)
  96. }
  97. } finally {
  98. if (selection) {
  99. if (typeof selection.removeRange == 'function') {
  100. selection.removeRange(range)
  101. } else {
  102. selection.removeAllRanges()
  103. }
  104. }
  105.  
  106. if (mark) {
  107. document.body.removeChild(mark)
  108. }
  109. reselectPrevious()
  110. }
  111.  
  112. return success
  113. }
  114.  
  115. (function() {
  116. 'use strict'
  117.  
  118. console.log(setInterval(() => {
  119. fetch('/')
  120. }, 60000))
  121.  
  122. document.querySelector('body > center:nth-child(1) > div').remove()
  123.  
  124. if(location.pathname === '/JudgeOnline/problem.php'){
  125. let id = /id=([0-9]+)/.exec(location.search)[1]
  126. if((id = parseInt(id))){
  127. let header = document.querySelector('body > center:nth-child(4)')
  128. if(id >= 1000 && id < 5000){
  129. let download = document.createElement("a")
  130. download.href = `https://lydsy.download/archive/${id}.zip`
  131. download.text = "Download"
  132. header.append("[")
  133. header.append(download)
  134. header.append("]")
  135. }
  136.  
  137. let exp = document.createElement("a")
  138. exp.href = '#'
  139. exp.onclick = function (){
  140. let desc = document.querySelector('body > div:nth-child(6)').textContent.split('\n').map(x => x.trim()).filter(x => x.length).join('\n\n')
  141. let input = document.querySelector('body > div:nth-child(8)').textContent.split('\n').map(x => x.trim()).filter(x => x.length).join('\n\n')
  142. let output = document.querySelector('body > div:nth-child(10)').textContent.split('\n').map(x => x.trim()).filter(x => x.length).join('\n\n')
  143. let samplein = document.querySelector('body > div:nth-child(12)').textContent.split('\n').map(x => x.trim()).filter(x => x.length).join('\n')
  144. let sampleout = document.querySelector('body > div:nth-child(14)').textContent.split('\n').map(x => x.trim()).filter(x => x.length).join('\n')
  145. let hint = document.querySelector('body > div:nth-child(16)').textContent.split('\n').map(x => x.trim()).filter(x => x.length).join('\n\n')
  146. let source = document.querySelector('body > div:nth-child(18)').textContent.split('\n').map(x => x.trim()).filter(x => x.length).join('\n\n')
  147. let content =
  148. `## Description
  149. ${desc}
  150.  
  151. ## Input
  152. ${input}
  153.  
  154. ## Output
  155. ${output}
  156.  
  157. ## Sample Input
  158. \`\`\`
  159. ${samplein}
  160. \`\`\`
  161.  
  162. ## Sample Output
  163. \`\`\`
  164. ${sampleout}
  165. \`\`\`
  166.  
  167. ## Hint
  168. ${hint}
  169.  
  170. ## Source
  171. ${source}
  172. `
  173.  
  174. let tags = ['BZOJ']
  175. let title = /[0-9]+: (.*)/.exec(document.querySelector('body > center:nth-child(4) > h2').textContent)[1]
  176. let exported = {content, tags, title}
  177. console.log(exported)
  178. let text = JSON.stringify(exported)
  179. console.log(text)
  180. copy(text)
  181. if(id >= 1000 && id < 5000 && confirm("Problem data is exported to your clipboard. Download testdata?")){
  182. window.open(`https://lydsy.download/archive/${id}.zip`)
  183. }
  184. }
  185. exp.text = "Export"
  186. header.append("[")
  187. header.append(exp)
  188. header.append("]")
  189. }
  190. }
  191. })();

QingJ © 2025

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