├── logo.png ├── babel.config.js ├── dist └── index.js.LICENSE.txt ├── src ├── lib │ ├── base.js │ └── elearn.js └── index.js ├── webpack.config.js ├── README.md ├── manifest.json ├── package.json ├── LICENSE └── .gitignore /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sincerefly/gopeed-extension-liangyou/HEAD/logo.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | exclude: ['transform-async-to-generator', 'transform-regenerator'], 7 | }, 8 | ], 9 | ], 10 | }; 11 | -------------------------------------------------------------------------------- /dist/index.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * The buffer module from node.js, for the browser. 3 | * 4 | * @author Feross Aboukhadijeh 5 | * @license MIT 6 | */ 7 | 8 | /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */ 9 | -------------------------------------------------------------------------------- /src/lib/base.js: -------------------------------------------------------------------------------- 1 | // 获取 HTML 页面内容 2 | export async function FetchWebHtml(webUrl, settings) { 3 | const resp = await fetch(webUrl, { 4 | headers: { 5 | "User-Agent": settings.ua, 6 | }, 7 | }); 8 | return await resp.text(); 9 | } 10 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { fileURLToPath } from 'url'; 3 | import GopeedPolyfillPlugin from 'gopeed-polyfill-webpack-plugin'; 4 | 5 | const __dirname = fileURLToPath(import.meta.url); 6 | 7 | export default { 8 | entry: './src/index.js', 9 | output: { 10 | filename: 'index.js', 11 | path: path.resolve(__dirname, '../dist'), 12 | }, 13 | devtool: false, 14 | plugins: [new GopeedPolyfillPlugin()], 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.m?js$/, 19 | use: { 20 | loader: 'babel-loader', 21 | }, 22 | }, 23 | ], 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gopeed Extension Liangyou 2 | 3 | Download YouTube videos easily with [Gopeed](https://gopeed.com/). 4 | 5 | ## Install 6 | 7 | Open the `Gopeed` extension page, enter `https://github.com/sincerefly/gopeed-extension-liangyou`, and click install. 8 | 9 | ## Usage 10 | 11 | Create task with zanmei.ai music url, and click `Download` button, then the music will be resolved and ready to download. 12 | 13 | ## Example Url 14 | 15 | - [https://lts33.net/elearn/servlet/elearn.Awcour?coref=CO000000534](https://lts33.net/elearn/servlet/elearn.Awcour?coref=CO000000534) 16 | - [https://lts33.net/elearn/servlet/elearn.Awcour?coref=CO000000948](https://lts33.net/elearn/servlet/elearn.Awcour?coref=CO000000948) 17 | 18 | ## Useful Links 19 | 20 | - [How to develop a gopeed extension](https://docs.gopeed.com/dev-extension.html) 21 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gopeed-extention-liangyou", 3 | "author": "sincerefly", 4 | "title": "良友圣经学院课程下载", 5 | "description": "良友(https://lts33.net/) 插件", 6 | "icon": "logo.png", 7 | "version": "1.0.0", 8 | "homepage": "https://github.com/sincerefly/gopeed-extension-liangyou", 9 | "repository": { 10 | "url": "https://github.com/sincerefly/gopeed-extension-liangyou" 11 | }, 12 | "scripts": [ 13 | { 14 | "event": "onResolve", 15 | "match": { 16 | "urls": ["*://lts33.net/*"] 17 | }, 18 | "entry": "dist/index.js" 19 | } 20 | ], 21 | "settings": [ 22 | { 23 | "name": "ua", 24 | "title": "User-Agent", 25 | "description": "HTTP User-Agent header", 26 | "type": "string", 27 | "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.47" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gopeed-extention-liangyou", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "", 6 | "main": "index.js", 7 | "type": "module", 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "dev": "webpack --mode development --watch", 11 | "build": "webpack --mode production" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "devDependencies": { 17 | "@babel/core": "^7.22.20", 18 | "@babel/preset-env": "^7.22.20", 19 | "babel-loader": "^9.1.3", 20 | "eslint": "^8.51.0", 21 | "eslint-config-prettier": "^9.0.0", 22 | "eslint-plugin-prettier": "^5.0.0", 23 | "gopeed": "^1.3.7", 24 | "gopeed-polyfill-webpack-plugin": "^1.0.2", 25 | "prettier": "^3.0.3", 26 | "webpack": "^5.75.0", 27 | "webpack-cli": "^5.0.1" 28 | }, 29 | "dependencies": { 30 | "cheerio": "^1.0.0-rc.12" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | // https://lts33.net/elearn/servlet/elearn.Awcour?coref=CO000000534 2 | 3 | import * as libbase from "./lib/base.js"; 4 | import * as libelearn from "./lib/elearn.js"; 5 | 6 | gopeed.events.onResolve(async function(ctx) { 7 | 8 | let [name, files] = await handleElearn(ctx) 9 | 10 | ctx.res = { 11 | name: name, 12 | files: files, 13 | }; 14 | }); 15 | 16 | // 课程列表 17 | async function handleElearn(ctx) { 18 | const elearnWebUrl = ctx.req.url; 19 | 20 | const elearnWebHtml = await libbase.FetchWebHtml(elearnWebUrl, gopeed.settings); 21 | 22 | const [hubName, elearnList] = libelearn.ParserDownloadUrlList(elearnWebHtml); 23 | 24 | let files = []; 25 | for (var i = 0; i < elearnList.length; i++) { 26 | let item = elearnList[i]; 27 | 28 | let name = item["name"] + ".mp3"; 29 | let url = item["url"]; 30 | 31 | let file = { 32 | name: name, 33 | req: { 34 | url: url, 35 | }, 36 | }; 37 | files.push(file); 38 | } 39 | return [hubName, files]; 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Yieldone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/lib/elearn.js: -------------------------------------------------------------------------------- 1 | import * as cheerio from "cheerio"; 2 | 3 | // 从 HTML 页面中解析出歌曲列表 4 | export function ParserDownloadUrlList(webHtml) { 5 | // 使用 cheerio 加载网页内容 6 | const $ = cheerio.load(webHtml); 7 | 8 | const subject = $("a.icon.icon-left.pull-left").text().trim(); // 启航课程 9 | const title = $("title").text().trim(); // 灵修默想与应用 10 | const hubName = subject + "-" + title; // 启航课程-灵修默想与应用 11 | 12 | // throw new MessageError(hubName); 13 | 14 | // 获取
内的 下所有 元素 15 | const liElements = $("li.cour"); 16 | 17 | // 遍历并输出每个元素 18 | let list = []; 19 | liElements.each((i, element) => { 20 | 21 | /* 22 |
  • 23 | 24 |
    25 | 26 |
    27 |
  • 28 | */ 29 | let name = $(element).find("a.cour").text().trim(); 30 | let url = $(element).find("a").last().attr("href").trim(); 31 | 32 | let item = { 33 | name: name, 34 | url: url, 35 | }; 36 | list.push(item); 37 | }); 38 | return [hubName, list]; 39 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | # dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | --------------------------------------------------------------------------------