您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Get information from Greasy Fork镜像 and do actions in it.
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/445697/1237548/Greasy%20Fork%20API.js
- // ==UserScript==
- // @name Greasy Fork镜像 API
- // @namespace -
- // @version 2.0.0
- // @description Get information from Greasy Fork镜像 and do actions in it.
- // @author NotYou
- // @license LGPL-3.0
- // @connect gf.qytechs.cn
- // @grant GM_xmlhttpRequest
- // @grant GM_openInTab
- // ==/UserScript==
- class GreasyFork {
- constructor() {
- if(location.host === 'gf.qytechs.cn' || location.host === 'sleazyfork.org') {
- this.host = location.host
- return
- }
- throw new Error('Invalid instance initialization location, host is not valid.')
- }
- static get INVALID_ARGUMENT_ERROR() {
- return 'Argument "{0}" is not valid'
- }
- static get PARSING_ERROR() {
- return 'Unexpected parsing error, "{0}"'
- }
- static get INVALID_PAGE_ERROR() {
- return 'Current page is not valid'
- }
- static __format(str, ...args) {
- let result = str
- for (let i = 0; i < args.length; i++) {
- const arg = args[i]
- result = result.replace(new RegExp(`\\{${i}\\}`, 'g'), arg)
- }
- return result
- }
- static __isId(id) {
- return typeof id === 'string' && /^\d+$/.test(id)
- }
- static get languages() {
- return [
- 'ar', 'bg', 'cs', 'da', 'de', 'el', 'en', 'eo', 'es', 'fi', 'fr', 'fr-CA', 'he', 'hu', 'id', 'it', 'ja', 'ka', 'ko', 'nb', 'nl', 'pl', 'pt-BR', 'ro', 'ru', 'sk', 'sr', 'sv', 'th', 'tr', 'uk', 'ug', 'vi', 'zh-CN', 'zh-TW'
- ]
- }
- static get version() {
- return '2.0.0'
- }
- static parseScriptNode(node) {
- if (!(node instanceof HTMLElement) || !node.dataset.scriptId) {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'node'))
- }
- const {
- scriptId,
- scriptName,
- scriptAuthors,
- scriptDailyInstalls,
- scriptTotalInstalls,
- scriptRatingScore,
- scriptCreatedDate,
- scriptUpdatedDate,
- scriptType,
- scriptVersion,
- sensitive,
- scriptLanguage,
- cssAvailableAsJs
- } = node.dataset
- const ratingsNode = node.querySelector('dd.script-list-ratings')
- let ratings = {}
- if(ratingsNode) {
- const ratingsGood = Number(ratingsNode.querySelector('.good-rating-count').textContent)
- const ratingsOk = Number(ratingsNode.querySelector('.ok-rating-count').textContent)
- const ratingsBad = Number(ratingsNode.querySelector('.bad-rating-count').textContent)
- ratings = {
- ratingsGood,
- ratingsOk,
- ratingsBad
- }
- }
- return Object.assign({
- scriptId,
- scriptName,
- scriptAuthors: JSON.parse(scriptAuthors),
- scriptDailyInstalls: Number(scriptDailyInstalls),
- scriptTotalInstalls: Number(scriptTotalInstalls),
- scriptRatingScore: Number(scriptRatingScore),
- scriptCreatedDate,
- scriptUpdatedDate,
- scriptType,
- scriptVersion,
- sensitive: sensitive === 'true',
- scriptLanguage,
- cssAvailableAsJs: cssAvailableAsJs === 'true',
- node
- }, ratings)
- }
- static parseScriptMetadata(code) {
- if (typeof code !== 'string') {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'code'))
- }
- const reScriptMetadata = /\/\/ ==UserScript==\n(.*?[\s\S]+)\n\/\/ ==\/UserScript==/
- const matched = code.match(reScriptMetadata)
- if (!Boolean(matched)) {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'code'))
- }
- const metadataResponse = {}
- const metadata = matched[1]
- const metadataChunks = metadata.split('\n')
- for (let i = 0; i < metadataChunks.length; i++) {
- const metadataChunk = metadataChunks[i]
- try {
- const { metaKey, metaValue } = metadataChunk.match(/\/\/ @(?<metaKey>[a-zA-Z\-\d\:]+)\s+(?<metaValue>.+)/).groups
- metadataResponse[metaKey] = metaValue
- } catch(error) {
- throw new Error(GreasyFork.__format(GreasyFork.PARSING_ERROR, error))
- }
- }
- return metadataResponse
- }
- static getScriptData(id) {
- if (!GreasyFork.__isId(id)) {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'id'))
- }
- return new Promise((res, rej) => {
- GM_xmlhttpRequest({
- url: `https://gf.qytechs.cn/scripts/${id}.json`,
- onload: response => {
- const data = JSON.parse(response.responseText)
- return res(data)
- },
- onerror: err => {
- return rej(err)
- }
- })
- })
- }
- static getScriptCode(id) {
- if (!GreasyFork.__isId(id)) {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'id'))
- }
- return new Promise((res, rej) => {
- GM_xmlhttpRequest({
- url: `https://gf.qytechs.cn/scripts/${id}/code/userscript.user.js`,
- onload: response => {
- const code = response.responseText
- return res(code)
- },
- onerror: err => {
- return rej(err)
- }
- })
- })
- }
- static getScriptHistory(id) {
- if (!GreasyFork.__isId(id)) {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'id'))
- }
- return new Promise((res, rej) => {
- GM_xmlhttpRequest({
- url: `https://gf.qytechs.cn/scripts/${id}/versions.json`,
- onload: response => {
- const data = JSON.parse(response.responseText)
- return res(data)
- },
- onerror: err => {
- return rej(err)
- }
- })
- })
- }
- static getScriptStats(id) {
- if (!GreasyFork.__isId(id)) {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'id'))
- }
- return new Promise((res, rej) => {
- GM_xmlhttpRequest({
- url: `https://gf.qytechs.cn/scripts/${id}/stats.json`,
- onload: response => {
- const data = JSON.parse(response.responseText)
- return res(data)
- },
- onerror: err => {
- return rej(err)
- }
- })
- })
- }
- static getScriptSet(id, page = 1) {
- if (!GreasyFork.__isId(id)) {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'id'))
- }
- if (typeof page !== 'number') {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'page'))
- }
- return new Promise((res, rej) => {
- GM_xmlhttpRequest({
- url: `https://gf.qytechs.cn/scripts.json?set=${id}&page=${page}&filter_locale=0`,
- onload: response => {
- const data = JSON.parse(response.responseText)
- return res(data)
- },
- onerror: err => {
- return rej(err)
- }
- })
- })
- }
- static getUserData(id) {
- if (!GreasyFork.__isId(id)) {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'id'))
- }
- return new Promise((res, rej) => {
- GM_xmlhttpRequest({
- url: `https://gf.qytechs.cn/users/${id}.json`,
- onload: response => {
- const data = JSON.parse(response.responseText)
- return res(data)
- },
- onerror: err => {
- return rej(err)
- }
- })
- })
- }
- static searchScripts(query, page = 1) {
- if (typeof query !== 'string') {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'query'))
- }
- if (typeof page !== 'number') {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'page'))
- }
- return new Promise((res, rej) => {
- GM_xmlhttpRequest({
- url: `https://gf.qytechs.cn/scripts.json?q=${query}&page=${page}`,
- onload: response => {
- const data = JSON.parse(response.responseText)
- return res(data)
- },
- onerror: err => {
- console.error(err)
- return rej([])
- }
- })
- })
- }
- static searchUsers(query, page = 1) {
- if (typeof query !== 'string') {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'query'))
- }
- if (typeof page !== 'number') {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'page'))
- }
- return new Promise((res, rej) => {
- GM_xmlhttpRequest({
- url: `https://gf.qytechs.cn/users.json?q=${query}&page=${page}`,
- onload: response => {
- const data = JSON.parse(response.responseText)
- return res(data)
- },
- onerror: err => {
- console.error(err)
- return rej([])
- }
- })
- })
- }
- static installScript(id, type = 'js') {
- if (!GreasyFork.__isId(id)) {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'id'))
- }
- if (type !== 'js' && type !== 'css') {
- throw new Error(GreasyFork.__format(GreasyFork.INVALID_ARGUMENT_ERROR, 'type'))
- }
- const URL = `https://gf.qytechs.cn/scripts/${id}/code/userscript.user.${type}`
- GM_openInTab(URL)
- }
- listScripts() {
- const scriptList = document.querySelector('.script-list')
- if (scriptList === null) {
- throw new Error(GreasyFork.INVALID_PAGE_ERROR)
- }
- const userScripts = scriptList.querySelectorAll('[data-script-id]')
- const result = []
- const typeMap = {
- 'browse-script-list': 'browse',
- 'user-script-list': 'user'
- }
- const type = typeMap[scriptList.id] || 'unknown'
- for (let i = 0; i < userScripts.length; i++) {
- const userScript = userScripts[i]
- result.push(
- GreasyFork.parseScriptNode(userScript)
- )
- }
- return {
- type,
- list: result
- }
- }
- signOut() {
- GM_xmlhttpRequest({
- url: `https://${this.host}/users/sign_out`
- })
- }
- }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址