您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Parse information on gf.qytechs.cn
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/445697/1055427/Greasy%20Fork%20API.js
- // ==UserScript==
- // @name Greasy Fork镜像 API
- // @namespace -
- // @version 1.0.0
- // @description Parse information on gf.qytechs.cn
- // @author NotYou
- // @license LGPL-3.0
- // @grant none
- // ==/UserScript==
- /*
- "Program" is a set of instructions that a computer uses to perform a specific function.
- "Library" is a program that is embedded in other programs.
- "This library" refers to "Greasy Fork镜像 API" library.
- "Account" is an arrangement in which a person uses the Internet or email services of a particular company, organization or individual person's web resource.
- "I" refers to individual person that owns internet account "NotYou" at web resource "gf.qytechs.cn".
- I does not responsible for any
- damage caused by this library
- */
- /*
- TODO:
- - [x] Feedback
- - [ ] Convesations
- - [ ] Versions
- */
- class GreasyFork {
- error(errorable, message) {
- if(!errorable) throw new Error(message)
- }
- languages() {
- return [
- 'ar', 'bg', 'cs', 'da', 'de', 'el', 'en', 'eo', 'es', 'fi', 'fr', 'fr-CA', 'he', 'hu', 'id', 'it', 'ja', 'ko', 'nb', 'nl', 'pl', 'pt-BR', 'ro', 'ru', 'sk', 'sr', 'sv', 'th', 'tr', 'uk', 'ug', 'vi', 'zh-CN', 'zh-TW'
- ]
- }
- parseScriptElement(i) {
- if(!i||!i.dataset.scriptAuthors) return null
- let _ = null,
- data = i.dataset,
- rating = i.children[0].children[1].children[7] ? i.children[0].children[1].children[7].children[0].innerText.split('\n').join(' ').split(' ') : _,
- scriptLink = i.children[0].children[0].children[0] ? i.children[0].children[0].children[0].href : _,
- source = !scriptLink ? _ : data.scriptType == 'library' ? scriptLink.slice(0, scriptLink.indexOf('-'))+'/code/index.js' : scriptLink.slice(0, scriptLink.indexOf('-'))+'/code/script.user.js'
- return {
- name: data.scriptName,
- id: +(data.scriptId),
- version: data.scriptVersion,
- lang: data.scriptLanguage,
- installs: +(data.scriptTotalInstalls),
- dailyInstalls: +(data.scriptDailyInstalls),
- rating: +(data.scriptRatingScore),
- ratingGood: rating ? rating[0] == '0' ? 0 : +(rating[0]) : _,
- ratingOk: rating ? rating[1] == '0' ? 0 : +(rating[1]) : _,
- ratingBad: rating ? rating[2] == '0' ? 0 : +(rating[2]) : _,
- authors: JSON.parse(data.scriptAuthors) || data.scriptAuthors.replaceAll('"', '"'),
- createDate: data.scriptCreatedDate,
- updateDate: data.scriptUpdatedDate,
- type: data.scriptType,
- cssAsJs: data.cssAvailableAsJs == 'true' ? true : false,
- sensitive: data.sensitive == 'true' ? true : false,
- element: i,
- url: scriptLink,
- source: source
- }
- }
- parseScriptCodeMeta(code) {
- if(typeof code != 'string'||!code.match(/\/\/ ==UserScript==/)) return null
- var arr = code.replaceAll('\n', '').match(/\/\/ ==UserScript==.*\/\/ ==\/UserScript==/)[0].split('// ')
- for (let i = 0; i < 2; i++) arr.shift()
- arr.pop()
- let result = []
- for (let i of arr) {
- let data = i.replace(/ . +/, ' ').split(' ')
- let name = data[0]
- data.shift()
- let value = data.join(' ')
- result.push({
- meta: name,
- value: value
- })
- }
- return result
- }
- ls() {
- function ls(id) {
- if(document.querySelector(`#${id}`)) {
- let result = []
- for (let i of document.querySelector(`#${id}`).children) {
- result.push(new GreasyFork().parseScriptElement(i))
- }
- return result
- } return null
- }
- return {
- scripts: ls('user-script-list'),
- browsed: ls('browse-script-list'),
- libraries: ls('user-library-script-list')
- }
- }
- get(q) {
- let parser = new DOMParser(),
- error = new GreasyFork().error,
- langs = new GreasyFork().languages(),
- str = str => str.replaceAll('\n', '').replaceAll(' ', ''),
- _ = null
- return {
- script(query = q) {
- let errMsg = 'Argument 1 is not defined'
- return {
- async asJSON(id = query || q) {
- error(id, errMsg)
- return fetch(`https://gf.qytechs.cn/scripts/${id}.json`).then((r) =>
- r.json()
- ).then((c) => {
- return c
- })
- },
- async code(id = query || q) {
- error(id, errMsg)
- return fetch(`https://gf.qytechs.cn/scripts/${id}/code`).then((r) =>
- r.text()
- ).then((c) => {
- return parser.parseFromString(c, 'text/html').querySelector('pre').innerText
- })
- },
- async history(id = query || q) {
- error(id, errMsg)
- return fetch(`https://gf.qytechs.cn/scripts/${id}/versions`).then((r) =>
- r.text()
- ).then((c) => {
- let list = parser.parseFromString(c, 'text/html').querySelectorAll('.history_versions li'), result = []
- for (let i of list) {
- let ver = i.children[1].children[0],
- time = i.children[2],
- log = i.children[3]
- result.push({
- version: {
- id: +(ver.href.match(/\?version=\d.+/)[0].replace('?version=', '')),
- text: ver.innerText,
- url: ver.href
- },
- time: {
- text: time.innerText,
- iso: time.attributes.datetime.value
- },
- changelog: log ? {
- html: log.innerHTML,
- text: log.innerText
- } : _
- })
- }
- return result
- })
- },
- async feedback(id = query || q) {
- error(id, errMsg)
- return fetch(`https://gf.qytechs.cn/scripts/${id}/feedback`).then((r) =>
- r.text()
- ).then((c) => {
- let list = parser.parseFromString(c, 'text/html').querySelectorAll('.discussion-list-container'), result = []
- for (let i of list) {
- let di = i.children[0],
- ti = di.children[1],
- mt = di.children[0],
- mt0 = mt.children[0],
- mt1 = mt.children[1],
- a0 = mt0.children[0],
- a1 = mt1.children[0].children[0],
- url = ti.href,
- last = mt1.children[0].children
- result.push({
- id: +(url.match(/ns\/\d.+/)[0].replace('ns/', '')),
- url: url,
- rating: ti.children[0].classList.contains('rating-icon') ? ti.children[0].innerText : _,
- text: ti.children[1] ? ti.children[1].innerText.replace('\n ', '').replace('\n ', '') : ti.children[0].innerText.replace('\n ', '').replace('\n ', ''),
- meta: {
- first: {
- id: +(a0.href.match(/\d.+-/)[0].replace(/-.+/, '').replace('-', '')),
- url: a0.href,
- nickname: a0.innerText
- },
- last: {
- id: +(a1.href.match(/\d.+-/)[0].replace(/-.+/, '').replace('-', '')),
- url: a1.href,
- nickname: a1.innerText
- },
- time: {
- first: {
- iso: mt0.children[1].attributes.datetime.value,
- text: mt0.children[1].innerText
- },
- last: last[last.length-1].attributes.datetime ? {
- iso: last[last.length-1].attributes.datetime.value,
- text: last[last.length-1].innerText
- } : _
- }
- }
- })
- }
- return result.length > 1 ? result : _
- })
- },
- async stats(id = query || q) {
- error(id, errMsg)
- return fetch(`https://gf.qytechs.cn/scripts/${id}/stats.json`).then((r) =>
- r.json()
- ).then((c) => {
- return c
- })
- },
- async info(id = query || q, options = {}) {
- error(id, errMsg)
- return fetch(str(`https://gf.qytechs.cn/
- ${options.locale && langs.includes(options.locale) ? options.locale : 'en'}
- /scripts/${id}${options.locale ? `&locale_override=1` : ''}`)).then((r) =>
- r.text()
- ).then((c) => {
- let doc = parser.parseFromString(c, 'text/html'),
- screenshots = _,
- addInfo = _,
- appliesTo = [],
- comp = _,
- support = doc.querySelector('#script-feedback-suggestion').children.length == 3 ? support = doc.querySelector('#script-feedback-suggestion').children[0].href : _,
- getInfo = value => doc.querySelector(`dd.script-${value}`),
- license = getInfo('show-license'),
- d_installs = getInfo('show-daily-installs') ? +(getInfo('show-daily-installs').innerText.replaceAll(',', '')) : _,
- installs = getInfo('show-total-installs') ? +(getInfo('show-total-installs').innerText.replaceAll(',', '')) : _,
- r_g = doc.querySelector('.good-rating-count') ? +(doc.querySelector('.good-rating-count').innerText) : _,
- r_o = doc.querySelector('.ok-rating-count') ? +(doc.querySelector('.ok-rating-count').innerText) : _,
- r_b = doc.querySelector('.bad-rating-count') ? +(doc.querySelector('.bad-rating-count').innerText) : _,
- c_date_text = getInfo('show-created-date').innerText,
- c_date_iso = doc.querySelector('dd.script-show-created-date').children[0].children[0].attributes.datetime.value,
- u_date_text = getInfo('show-updated-date').innerText,
- u_date_iso = doc.querySelector('dd.script-show-updated-date').children[0].children[0].attributes.datetime.value,
- global = doc.querySelector('#script-info header'),
- install = doc.querySelector('#install-area') ? doc.querySelectorAll('#install-area *:not(.install-help-link)') : _,
- data = install ? install[0].dataset : _,
- yours = doc.querySelector('#script-links').children,
- require = doc.querySelector('#script-content p code') ? doc.querySelector('#script-content p code').innerText.replace('// @require ', '') : _
- if(doc.querySelector('.user-screenshots')) {
- screenshots = []
- doc.querySelectorAll('.user-screenshots a').forEach((e) => {
- screenshots.push({
- source: e.href,
- thumbnail: e.children[0].src
- })
- })
- }
- doc.querySelectorAll('dd.script-show-applies-to li').forEach((e) => {
- appliesTo.push(e.innerText)
- })
- if(doc.querySelector('.script-show-compatibility')) {
- comp = []
- doc.querySelectorAll('.script-show-compatibility img').forEach((e) => {
- comp.push({
- browser: e.alt.replace('Compatible with ', ''),
- value: e.title.replaceAll('\n', ' '),
- })
- })
- }
- if(doc.querySelector('#additional-info')) addInfo = doc.querySelector('#additional-info')
- return {
- id: +(id),
- name: global.children[0].innerText,
- desc: global.children[1].innerText,
- version: getInfo('show-version').innerText,
- isYour: yours[yours.length-1].children[0].href.match(/\/admin/) ? true : false,
- isPrevVersion: data ? data.isPreviousVersion == 'true' ? true : false : _,
- installs: {
- daily: d_installs,
- total: installs,
- },
- rating: {
- good: r_g,
- ok: r_o,
- bad: r_b,
- },
- date: {
- created: {
- text: c_date_text,
- iso: c_date_iso,
- },
- updated: {
- text: u_date_text,
- iso: u_date_iso,
- }
- },
- license: {
- name: license.innerText,
- url: license.children[0].children[0] ? license.children[0].children[0].href : _
- },
- screenshots: screenshots,
- additionalInfo: addInfo ? [
- {
- html: addInfo.innerHTML,
- text: addInfo.innerText
- }
- ] : _,
- appliesTo: appliesTo,
- compatibility: comp,
- supportUrl: support,
- requireUrl: require
- }
- })
- },
- async set(id = query || q, options = {}) {
- error(id, errMsg)
- return id && fetch(str(`https://gf.qytechs.cn/
- ${options.locale && langs.includes(options.locale) ? options.locale : 'en'}
- /scripts?set=${id}
- ${options.sort ? `&sort=${options.sort}` : ''}
- ${options.page ? `&page=${options.page}` : ''}
- ${options.localeFilter ? `&filter_locale=${options.localeFilter}` : ''}
- ${options.locale ? `&locale_override=1` : ''}`)).then(r =>
- r.text()
- ).then((c) => {
- let result = [], list = parser.parseFromString(c, 'text/html').querySelectorAll('#browse-script-list li')
- for (let i of list) {
- result.push(new GreasyFork().parseScriptElement(i))
- }
- return result
- })
- },
- }
- },
- async user(id = q) {
- error(id, 'Argument 1 is not defined')
- return fetch(`https://gf.qytechs.cn/users/${id}`).then((r) =>
- r.text()
- ).then((c) => {
- let doc = parser.parseFromString(c, 'text/html'), url = new URL(doc.baseURI)
- return {
- nickname: doc.querySelector('#about-user h2').firstChild.data,
- id: +(id),
- isMod: doc.querySelector('#about-user > h2 .badge-moderator') ? true : false,
- scripts: (() => {
- if(doc.querySelector('#user-script-list')) {
- let result = []
- for (let i of doc.querySelector('#user-script-list').children) {
- result.push(new GreasyFork().parseScriptElement(i))
- }
- return result
- } return _
- })(),
- libraries: (() => {
- if(doc.querySelector('#user-library-script-list')) {
- let result = []
- for (let i of doc.querySelector('#user-library-script-list').children) {
- result.push(new GreasyFork().parseScriptElement(i))
- }
- return result
- } return _
- })(),
- scriptSets: (() => {
- if(doc.querySelector('#user-script-sets')) {
- let result = []
- for (let i of doc.querySelector('#user-script-sets').children) {
- if(i.firstChild.data === 'Favorites ') return _
- let data = i.firstChild.data.split(':')
- result.push({
- name: data[0],
- desc: data[1].replace(' ', '').split('').reverse().join('').replace(' ', '').split('').reverse().join(''),
- id: i.children[0].href.replace(/.*?\/scripts\?set=/, '')
- })
- }
- return result
- } return _
- })(),
- recentComments: (() => {
- if(doc.querySelectorAll('#user-discussions section ul li a')) {
- let result = []
- for (let i of doc.querySelectorAll('#user-discussions section ul li a')) {
- result.push({
- title: i.lastChild.innerText,
- id: !i.href.match(/ns\/\d+/) ? +(i.href.match(/\d+/)[0]) : +(i.href.match(/ns\/\d+/)[0].replace('ns/', '')),
- action: i.firstChild.data.replace(': ', ''),
- URL: i.href
- })
- }
- return result.length > 1 ? result : _
- } return _
- })()
- }
- })
- },
- async search(query = q, type, options = {}) {
- if(typeof query != 'string') throw new Error('Argument 1 is not string')
- function searchURL(path) {
- return str(`https://gf.qytechs.cn/
- ${options.locale && langs.includes(options.locale) ? options.locale : 'en'}/
- ${path}${options.asJSON == true ? '.json' : ''}?q=${query ? query : ''}
- ${options.sort ? `&sort=${options.sort}` : ''}
- ${options.page ? `&page=${options.page}` : ''}
- ${options.locale ? `&locale_override=1` : ''}`)
- }
- if(type === 'script') {
- return fetch(searchURL('scripts')).then((r) =>
- options.asJSON == true ? r.json() : r.text()
- ).then((c) => {
- if(options.asJSON == true) return c
- let result = [], list = parser.parseFromString(c, 'text/html').querySelectorAll('#browse-script-list li:not(.ad-entry)')
- for (let i of list) {
- result.push(new GreasyFork().parseScriptElement(i))
- }
- return result
- })
- }
- if(type === 'library') {
- return fetch(searchURL('scripts/libraries')).then((r) =>
- options.asJSON == true ? r.json() : r.text()
- ).then((c) => {
- if(options.asJSON == true) return c
- let result = [], list = parser.parseFromString(c, 'text/html').querySelectorAll('#browse-script-list li')
- for (let i of list) {
- result.push(new GreasyFork().parseScriptElement(i))
- }
- return result
- })
- } if(type === 'user') {
- return fetch(searchURL('users')).then((r) =>
- options.asJSON == true ? r.json() : r.text()
- ).then((c) => {
- if(options.asJSON == true) return c
- let result = [], list = parser.parseFromString(c, 'text/html').querySelectorAll('#browse-user-list li')
- for (let i of list) {
- result.push({
- nickname: i.children[0].innerText,
- id: +(i.children[0].href.replace(/.*?\/users\//, '').split('-')[0]),
- badge: (i.children[1] ? i.children[1].innerText.toLowerCase() : 'none'),
- url: i.children[0].href,
- scripts: +(i.innerHTML.match(/- .+/, '')[0].match(/\d/)[0])
- })
- }
- return result
- })
- } if(type === 'list') {
- return [
- 'script',
- 'library',
- 'user',
- 'list'
- ]
- } else throw new Error(`Argument 1 ${type} is not defined`)
- },
- async modlog(options = {}) {
- return fetch(str(`https://gf.qytechs.cn/
- ${options.locale && langs.includes(options.locale) ? options.locale : 'en'}
- /moderator_actions
- ${options.page ? `?page=${options.page}` : '?page=1'}
- ${options.locale ? `&locale_override=1` : ''}`)).then(r =>
- r.text()
- ).then(c => {
- let trs = parser.parseFromString(c, 'text/html').querySelectorAll('.log-table > tbody > tr'), result = []
- for (let i of trs) {
- let time = i.children[0].children[0],
- userUrl = i.children[1].children[0].href,
- item = i.children[2].children[0],
- res = i.children[4]
- result.push({
- time: {
- text: time.innerText,
- iso: time.attributes.datetime.value
- },
- mod: {
- id: userUrl.match(/\d.+-/) ? +(userUrl.match(/\d.+-/)[0].replace('-', '')) : userUrl.match(/\d-/) ? +(userUrl.match(/\d-/)[0].replace('-', '')) : _,
- url: userUrl,
- nickname: i.children[1].children[0].innerText
- },
- item: i.children[2] ? {
- name: item ? item.innerText : _,
- url: item ? item.href : _,
- type: item ? str(item.previousSibling.data.replace(': ', '')) : _
- } : _,
- action: i.children[3].innerText,
- reason: {
- name: res.innerText.replaceAll(' ', '').replaceAll('\n', ''),
- url: res.children[0].children[0] ? res.children[0].children[0].href : _
- }
- })
- }
- return result
- })
- },
- }
- }
- async action(action, options = {}) {
- let error = new GreasyFork().error,
- parser = new DOMParser()
- if(action === 'install') {
- error(options.id, 'Argument 2 { id } is not defined')
- setTimeout(() => {
- window.open(`https://gf.qytechs.cn/scripts/${options.id}/code/source.user.${options.lang === 'css' ? 'css' : 'js'}`, '_top')
- }, options.timeout * 1e3 || 0)
- }
- if(action === 'signout') {
- setTimeout(() => {
- fetch('https://gf.qytechs.cn/users/sign_out')
- }, options.timeout * 1e3 || 0)
- } if(action === 'list') {
- return [
- 'install',
- 'signout',
- 'list'
- ]
- }
- else throw new Error(`Argument 1 ${action} is not defined`)
- }
- version() {
- return '1.0.0'
- }
- }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址