极客时间离线课堂 (3)

接下来,封装简单的课程下载:
ProductLoader, 传入一个product的信息,他就会自动给你下载课程原有的元数据, 对是 元数据, 还不能在浏览器里面看。

class ProductLoader { constructor(proudct) { /** * 产品 */ this.product = proudct; /** * 专栏id */ this.cid = null; /** * 全部文章 */ this.articles = []; /** * 全部文章内容 */ this.articlesContents = []; /** * 章节信息 */ this.chapters = null; } getActiles(pid) { // 获取全部文章 return request(API_URL.articles, { cid: `${pid}`, // 产品id order: "earliest", prev: 0, sample: false, size: 200 }, { "referrer": `https://time.geekbang.org/column/article/0?cid=${pid}` }); } async getArticlesContents(articles = []) { const articlesContents = []; const len = articles.length; for (let i = 0; i < len; i++) { const p = articles[i]; try { const resArticle = await request(API_URL.article, { id: p.id, include_neighbors: false, is_freelyread: true }); await delay().run(); console.log("get acticle success:", resArticle.data.id); articlesContents.push(resArticle.data); console.log("articlesContents", articlesContents.length); // break; } catch (err) { return articlesContents; // await delay().run(); // console.log(`downdload article failed: artile id ${p.id}`); // continue; } } return articlesContents; } getChapters(cid) { return request(API_URL.chapters, { cid }); } async getJSONData() { try { const resAticles = await this.getActiles(this.product.id); if (resAticles.code !== 0) { return console.log("获取全部文章失败"); } const cid = resAticles.data.list[0].column_id; const articles = resAticles.data.list; this.cid = cid; // 全部文章 this.articles = articles; const resChapters = await this.getChapters(cid); if (resChapters.code !== 0) { return console.log("fetch chapters failed"); } // 章节信息 this.chapters = resChapters.data; // 文章内容 this.articlesContents = await this.getArticlesContents(articles); } catch (err) { console.log("download product failed, product id", this.product.id); throw err } } async zipDownload() { try { await this.getJSONData(); const zip = new JSZip(); zip.file("product.json", JSON.stringify(this.product)); zip.file("articles.json", JSON.stringify(this.articles)); zip.file("chapters.json", JSON.stringify(this.chapters)); const folder = zip.folder("articles"); this.articlesContents.forEach(a => { folder.file(`${a.id}.json`, JSON.stringify(a)); }) const blob = await zip.generateAsync({ type: "blob" }); downloadBlob(this.product.id + ".zip", blob); } catch (err) { console.log("zipDownload error,", err); } } }

最后调整一下入口代码, 运行一下,就可以 某个课程的元数据了。

; (async function init() { try { // 获取已购买的产品 const resProducts = await request(API_URL.product, { "desc": true, "expire": 1, "last_learn": 0, "learn_status": 0, "prev": 0, "size": 50, "sort": 1, "type": "", "with_learn_count": 1 }); if (resProducts.code != 0 || resProducts.data.list.length < 0) { return console.log("穷光蛋,没有购买任何产品"); } console.log("准备检查和注入JSZip"); if (!checkScript({ names: "jszip.min.js", objectName: "JSzip", })) { await injectScript("https://cdn.bootcdn.net/ajax/libs/jszip/3.5.0/jszip.min.js"); console.log("注入JSZip成功"); } injectControlPanel(resProducts.data.products); download("product.json", JSON.stringify(resProducts.data)) } catch (err) { console.log("脚本执行异常", err); } })();

到此为止, 我们回顾一下,zip包的数据接口,因为这和接下来的预览网站相关。

[productId] product.json // 课程信息 chapters.json // 章节信息 artilces.json // 文章摘要信息 artilces // 文章沐浴露 [article.id].json // 具体的文章 comments // 代码并未下载,自行添加 [article.id].json 搭建预览网站

这里分两步走搭建课程列表,文章详情。
先看一下文件接口

images // 图片目录,之后下载图片和MP4有用 [productId] [img-1] products // 产品列表 [productId] artiles [artileId].json acticles.json chapters.json product.json index.html // 列表页 article.html // 文章页 product.json // 产品列表 搭建预览网站 - 课程列表

代码非常的简单,预览

<ul> </ul> <script> function getJSONData(url) { return fetch(url).then(res => res.json()) }; const plEl = document.getElementById("product-list"); (async () => { try { const res = await getJSONData("./product.json"); res.products.forEach(p=>{ const pEl = document.createElement("div"); pEl.innerHTML = ` <li> <a href="http://www.likecs.com/article.html?id=${p.id}"> ${p.title} </a> </li> ` plEl.appendChild(pEl); }); } catch (err) { console.log("读取产品列表失败", err); } })(); </script>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjjgy.html