diff --git a/index.js b/index.js old mode 100644 new mode 100755 index 955838b..6bb63d9 --- a/index.js +++ b/index.js @@ -1,61 +1,64 @@ -const express = require("express"); -const sources = require("./sources"); - -const app = express(); - -app.use( - express.json({ - extended: false, - }) -); - -app.get("/", (req, res) => - res.json({ - Author: "@rajarsheechatterjee", - Version: "1.0.0", - Github: "https://github.com/rajarsheechatterjee/lnreader-extensions", - }) -); - -// English -app.get("/api/", (req, res) => res.json(sources)); -app.use("/api/1/", require("./src/en/boxnovel/BoxNovel")); -app.use("/api/2/", require("./src/en/readlightnovel/ReadLightNovel")); -app.use("/api/3/", require("./src/en/fastnovel/FastNovel")); -app.use("/api/4/", require("./src/en/readnovelfull/ReadNovelFull")); -app.use("/api/5/", require("./src/en/mtlnovel/MTLNovel")); -app.use("/api/6/", require("./src/en/novelhall/Novelhall")); -app.use("/api/7/", require("./src/en/wuxiaworld/WuxiaWorld")); -app.use("/api/8/", require("./src/en/novelfull/NovelFull")); -app.use("/api/9/", require("./src/en/noveltrench/NovelTrench")); -app.use("/api/10/", require("./src/en/vipnovel/VipNovel")); -app.use("/api/11/", require("./src/en/kisslightnovels/KissLightNovels")); -app.use("/api/12/", require("./src/en/wuxiaworldsite/WuxiaWorldSite")); -app.use("/api/13/", require("./src/en/freewebnovel/FreeWebNovel")); -app.use("/api/14/", require("./src/en/jpmtl/JPMTL")); -app.use("/api/15/", require("./src/en/lightnovelpub/LightNovelPub")); -app.use("/api/16/", require("./src/en/wuxiaworldco/WuxiaWorldCo")); -app.use("/api/17/", require("./src/en/tapread/TapRead")); -app.use("/api/18/", require("./src/en/novelupdatescc/NovelUpdatesCc")); -app.use("/api/19/", require("./src/en/readlightnovelcc/ReadLightNovelCc")); -app.use("/api/20/", require("./src/en/wuxiaworldcloud/WuxiaWorldCloud")); -app.use("/api/21/", require("./src/en/woopread/WoopRead")); -app.use("/api/22/", require("./src/en/foxaholic/Foxaholic")); -app.use("/api/27/", require("./src/en/comrademao/ComradeMao")); -app.use("/api/33/", require("./src/en/novelpassion/NovelPassion")); -app.use("/api/34/", require("./src/en/royalroad/RoyalRoad")); -app.use("/api/35/", require("./src/en/scribblehub/ScribbleHub")); - -// Spanish -app.use("/api/23/", require("./src/es/tunovelaligera/Tunovelaligera")); -app.use("/api/24/", require("./src/es/skynovels/Skynovels")); -app.use("/api/25/", require("./src/es/einherjarproject/EinherjarProject")); -app.use("/api/26/", require("./src/es/novelasligera/NovelasLigera")); -app.use("/api/28/", require("./src/es/yuukitls/YuukiTls")); -app.use("/api/29/", require("./src/es/hasutl/Hasutl")); -app.use("/api/30/", require("./src/es/oasistranslations/OasisTranslations")); -app.use("/api/31/", require("./src/es/novelawuxia/NovelaWuxia")); - -const PORT = process.env.PORT || 5000; - -app.listen(PORT, () => console.log(`Server started on port ${PORT}`)); +const express = require("express"); +const sources = require("./sources"); + +const app = express(); + +app.use( + express.json({ + extended: false, + }) +); + +app.get("/", (req, res) => + res.json({ + Author: "@rajarsheechatterjee", + Version: "1.0.0", + Github: "https://github.com/rajarsheechatterjee/lnreader-extensions", + }) +); + +// English +app.get("/api/", (req, res) => res.json(sources)); +app.use("/api/1/", require("./src/en/boxnovel/BoxNovel")); +app.use("/api/2/", require("./src/en/readlightnovel/ReadLightNovel")); +app.use("/api/3/", require("./src/en/fastnovel/FastNovel")); +app.use("/api/4/", require("./src/en/readnovelfull/ReadNovelFull")); +app.use("/api/5/", require("./src/en/mtlnovel/MTLNovel")); +app.use("/api/6/", require("./src/en/novelhall/Novelhall")); +app.use("/api/7/", require("./src/en/wuxiaworld/WuxiaWorld")); +app.use("/api/8/", require("./src/en/novelfull/NovelFull")); +app.use("/api/9/", require("./src/en/noveltrench/NovelTrench")); +app.use("/api/10/", require("./src/en/vipnovel/VipNovel")); +app.use("/api/11/", require("./src/en/kisslightnovels/KissLightNovels")); +app.use("/api/12/", require("./src/en/wuxiaworldsite/WuxiaWorldSite")); +app.use("/api/13/", require("./src/en/freewebnovel/FreeWebNovel")); +app.use("/api/14/", require("./src/en/jpmtl/JPMTL")); +app.use("/api/15/", require("./src/en/lightnovelpub/LightNovelPub")); +app.use("/api/16/", require("./src/en/wuxiaworldco/WuxiaWorldCo")); +app.use("/api/17/", require("./src/en/tapread/TapRead")); +app.use("/api/18/", require("./src/en/novelupdatescc/NovelUpdatesCc")); +app.use("/api/19/", require("./src/en/readlightnovelcc/ReadLightNovelCc")); +app.use("/api/20/", require("./src/en/wuxiaworldcloud/WuxiaWorldCloud")); +app.use("/api/21/", require("./src/en/woopread/WoopRead")); +app.use("/api/22/", require("./src/en/foxaholic/Foxaholic")); +app.use("/api/27/", require("./src/en/comrademao/ComradeMao")); +app.use("/api/33/", require("./src/en/novelpassion/NovelPassion")); +app.use("/api/34/", require("./src/en/royalroad/RoyalRoad")); +app.use("/api/35/", require("./src/en/scribblehub/ScribbleHub")); + +// Spanish +app.use("/api/23/", require("./src/es/tunovelaligera/Tunovelaligera")); +app.use("/api/24/", require("./src/es/skynovels/Skynovels")); +app.use("/api/25/", require("./src/es/einherjarproject/EinherjarProject")); +app.use("/api/26/", require("./src/es/novelasligera/NovelasLigera")); +app.use("/api/28/", require("./src/es/yuukitls/YuukiTls")); +app.use("/api/29/", require("./src/es/hasutl/Hasutl")); +app.use("/api/30/", require("./src/es/oasistranslations/OasisTranslations")); +app.use("/api/31/", require("./src/es/novelawuxia/NovelaWuxia")); + +// Japanese +app.use("/api/36", require("./src/jp/syosetu/Syosetu")); + +const PORT = process.env.PORT || 5000; + +app.listen(PORT, () => console.log(`Server started on port ${PORT}`)); diff --git a/sources.js b/sources.js old mode 100644 new mode 100755 index 6870d44..a307a20 --- a/sources.js +++ b/sources.js @@ -1,319 +1,331 @@ -extensions = [ - /** - * English - */ - - { - sourceId: 1, - sourceUrl: "https://boxnovel.com/", - sourceName: "BoxNovel", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/boxnovel/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 2, - sourceUrl: "https://www.readlightnovel.org/", - sourceName: "ReadLightNovel", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/readlightnovel/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 3, - sourceUrl: "https://fastnovel.net/", - sourceName: "FastNovel", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/fastnovel/icon.png?raw=true", - sourceLanguage: "English", - status: 0, - }, - { - sourceId: 4, - sourceUrl: "https://readnovelfull.com/", - sourceName: "ReadNovelFull", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/readnovelfull/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 5, - sourceUrl: "https://www.mtlnovel.com/", - sourceName: "MTLNovel", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/mtlnovel/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 6, - sourceUrl: "https://www.novelhall.com/", - sourceName: "NovelHall", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/novelhall/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 7, - sourceUrl: "https://www.wuxiaworld.com/", - sourceName: "WuxiaWorld", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/wuxiaworld/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 8, - sourceUrl: "https://novelfull.com/", - sourceName: "NovelFull", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/novelfull/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 9, - sourceUrl: "https://noveltrench.com/", - sourceName: "NovelTrench", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/noveltrench/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 10, - sourceUrl: "https://vipnovel.com/", - sourceName: "VipNovel", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/vipnovel/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 11, - sourceUrl: "https://kisslightnovels.info/", - sourceName: "KissLightNovels", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/kisslightnovels/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 12, - sourceUrl: "https://wuxiaworldsite.co/", - sourceName: "WuxiaWorldSite", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/wuxiaworldsite/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 13, - sourceUrl: "https://freewebnovel.com/", - sourceName: "FreeWebNovel", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/freewebnovel/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 14, - sourceUrl: "https://jpmtl.com/", - sourceName: "JPMTL", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/jpmtl/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 15, - sourceUrl: "https://www.lightnovelpub.com/", - sourceName: "LightNovelPub", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/lightnovelpub/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 16, - sourceUrl: "https://www.wuxiaworld.co/", - sourceName: "WuxiaWorld.co", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/wuxiaworldco/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 17, - sourceUrl: "http://www.tapread.com/", - sourceName: "TapRead", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/tapread/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 18, - sourceUrl: "https://www.novelupdates.cc/", - sourceName: "NovelUpdates.cc", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/novelupdatescc/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 19, - sourceUrl: "https://m.readlightnovel.cc/", - sourceName: "ReadLightNovel.cc", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/readlightnovelcc/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 20, - sourceUrl: "http://wuxiaworld.cloud/", - sourceName: "WuxiaWorld.cloud", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/wuxiaworldcloud/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 21, - sourceUrl: "https://woopread.com/", - sourceName: "WoopRead", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/woopread/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 22, - sourceUrl: "https://foxaholic.com/", - sourceName: "Foxaholic", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/foxaholic/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 27, - sourceUrl: "https://comrademao.com/", - sourceName: "ComradeMao", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/comrademao/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 33, - sourceUrl: "https://www.novelpassion.com/", - sourceName: "NovelPassion", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/novelpassion/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 34, - sourceUrl: "https://www.royalroad.com/", - sourceName: "Royal Road", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/royalroad/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - { - sourceId: 35, - sourceUrl: "https://www.scribblehub.com/", - sourceName: "Scribble Hub", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/scribblehub/icon.png?raw=true", - sourceLanguage: "English", - status: 1, - }, - - /** - * Spanish - */ - - { - sourceId: 23, - sourceUrl: "https://tunovelaligera.com/", - sourceName: "Tunovelaligera", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/tunovelaligera/icon.png?raw=true", - sourceLanguage: "Spanish", - status: 1, - }, - { - sourceId: 24, - sourceUrl: "https://www.skynovels.net/", - sourceName: "SkyNovels", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/skynovels/icon.png?raw=true", - sourceLanguage: "Spanish", - status: 1, - }, - { - sourceId: 25, - sourceUrl: "https://einherjarproject.net/", - sourceName: "EinherjarProject", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/einherjarproject/icon.png?raw=true", - sourceLanguage: "Spanish", - status: 1, - }, - { - sourceId: 26, - sourceUrl: "https://novelasligera.com/", - sourceName: "NovelasLigera", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/novelasligera/icon.png?raw=true", - sourceLanguage: "Spanish", - status: 1, - }, - { - sourceId: 28, - sourceUrl: "https://yuukitls.com/", - sourceName: "YuukiTls", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/yuukitls/icon.png?raw=true", - sourceLanguage: "Spanish", - status: 1, - }, - { - sourceId: 29, - sourceUrl: "https://hasutl.wordpress.com/", - sourceName: "Hasu Translations", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/hasutl/icon.png?raw=true", - sourceLanguage: "Spanish", - status: 1, - }, - { - sourceId: 30, - sourceUrl: "https://oasistranslations.wordpress.com/", - sourceName: "Oasis Translations", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/oasistranslations/icon.png?raw=true", - sourceLanguage: "Spanish", - status: 1, - }, - { - sourceId: 31, - sourceUrl: "http://www.novelawuxia.com/", - sourceName: "Novela Wuxia", - sourceCover: - "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/novelawuxia/icon.png?raw=true", - sourceLanguage: "Spanish", - status: 1, - }, -]; - -module.exports = extensions; +extensions = [ + /** + * English + */ + + { + sourceId: 1, + sourceUrl: "https://boxnovel.com/", + sourceName: "BoxNovel", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/boxnovel/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 2, + sourceUrl: "https://www.readlightnovel.org/", + sourceName: "ReadLightNovel", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/readlightnovel/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 3, + sourceUrl: "https://fastnovel.net/", + sourceName: "FastNovel", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/fastnovel/icon.png?raw=true", + sourceLanguage: "English", + status: 0, + }, + { + sourceId: 4, + sourceUrl: "https://readnovelfull.com/", + sourceName: "ReadNovelFull", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/readnovelfull/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 5, + sourceUrl: "https://www.mtlnovel.com/", + sourceName: "MTLNovel", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/mtlnovel/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 6, + sourceUrl: "https://www.novelhall.com/", + sourceName: "NovelHall", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/novelhall/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 7, + sourceUrl: "https://www.wuxiaworld.com/", + sourceName: "WuxiaWorld", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/wuxiaworld/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 8, + sourceUrl: "https://novelfull.com/", + sourceName: "NovelFull", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/novelfull/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 9, + sourceUrl: "https://noveltrench.com/", + sourceName: "NovelTrench", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/noveltrench/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 10, + sourceUrl: "https://vipnovel.com/", + sourceName: "VipNovel", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/vipnovel/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 11, + sourceUrl: "https://kisslightnovels.info/", + sourceName: "KissLightNovels", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/kisslightnovels/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 12, + sourceUrl: "https://wuxiaworldsite.co/", + sourceName: "WuxiaWorldSite", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/wuxiaworldsite/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 13, + sourceUrl: "https://freewebnovel.com/", + sourceName: "FreeWebNovel", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/freewebnovel/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 14, + sourceUrl: "https://jpmtl.com/", + sourceName: "JPMTL", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/jpmtl/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 15, + sourceUrl: "https://www.lightnovelpub.com/", + sourceName: "LightNovelPub", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/lightnovelpub/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 16, + sourceUrl: "https://www.wuxiaworld.co/", + sourceName: "WuxiaWorld.co", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/wuxiaworldco/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 17, + sourceUrl: "http://www.tapread.com/", + sourceName: "TapRead", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/tapread/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 18, + sourceUrl: "https://www.novelupdates.cc/", + sourceName: "NovelUpdates.cc", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/novelupdatescc/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 19, + sourceUrl: "https://m.readlightnovel.cc/", + sourceName: "ReadLightNovel.cc", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/readlightnovelcc/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 20, + sourceUrl: "http://wuxiaworld.cloud/", + sourceName: "WuxiaWorld.cloud", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/wuxiaworldcloud/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 21, + sourceUrl: "https://woopread.com/", + sourceName: "WoopRead", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/woopread/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 22, + sourceUrl: "https://foxaholic.com/", + sourceName: "Foxaholic", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/foxaholic/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 27, + sourceUrl: "https://comrademao.com/", + sourceName: "ComradeMao", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/comrademao/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 33, + sourceUrl: "https://www.novelpassion.com/", + sourceName: "NovelPassion", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/novelpassion/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 34, + sourceUrl: "https://www.royalroad.com/", + sourceName: "Royal Road", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/royalroad/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + { + sourceId: 35, + sourceUrl: "https://www.scribblehub.com/", + sourceName: "Scribble Hub", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/en/scribblehub/icon.png?raw=true", + sourceLanguage: "English", + status: 1, + }, + + /** + * Spanish + */ + + { + sourceId: 23, + sourceUrl: "https://tunovelaligera.com/", + sourceName: "Tunovelaligera", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/tunovelaligera/icon.png?raw=true", + sourceLanguage: "Spanish", + status: 1, + }, + { + sourceId: 24, + sourceUrl: "https://www.skynovels.net/", + sourceName: "SkyNovels", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/skynovels/icon.png?raw=true", + sourceLanguage: "Spanish", + status: 1, + }, + { + sourceId: 25, + sourceUrl: "https://einherjarproject.net/", + sourceName: "EinherjarProject", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/einherjarproject/icon.png?raw=true", + sourceLanguage: "Spanish", + status: 1, + }, + { + sourceId: 26, + sourceUrl: "https://novelasligera.com/", + sourceName: "NovelasLigera", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/novelasligera/icon.png?raw=true", + sourceLanguage: "Spanish", + status: 1, + }, + { + sourceId: 28, + sourceUrl: "https://yuukitls.com/", + sourceName: "YuukiTls", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/yuukitls/icon.png?raw=true", + sourceLanguage: "Spanish", + status: 1, + }, + { + sourceId: 29, + sourceUrl: "https://hasutl.wordpress.com/", + sourceName: "Hasu Translations", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/hasutl/icon.png?raw=true", + sourceLanguage: "Spanish", + status: 1, + }, + { + sourceId: 30, + sourceUrl: "https://oasistranslations.wordpress.com/", + sourceName: "Oasis Translations", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/oasistranslations/icon.png?raw=true", + sourceLanguage: "Spanish", + status: 1, + }, + { + sourceId: 31, + sourceUrl: "http://www.novelawuxia.com/", + sourceName: "Novela Wuxia", + sourceCover: + "https://github.com/rajarsheechatterjee/lnreader-extensions/blob/main/src/es/novelawuxia/icon.png?raw=true", + sourceLanguage: "Spanish", + status: 1, + }, + + /** + * Japanese + */ + { + sourceId: 36, + sourceUrl: "https://syosetsu.com", + sourceName: "Syosetsu", + sourceCover: "https://github.com/skillgg/lnreader-sources/blob/main/src/jp/syosetu/icon.png?raw=true", + sourceLanguage: "Japanese", + status: 0 + }, +]; + +module.exports = extensions; diff --git a/src/jp/syosetu/Syosetu.js b/src/jp/syosetu/Syosetu.js new file mode 100755 index 0000000..94ac731 --- /dev/null +++ b/src/jp/syosetu/Syosetu.js @@ -0,0 +1,11 @@ +const express = require("express"); +const syosetuNovelScrapper = require("./SyosetuScrapper"); + +const router = express.Router(); + +router.get("/novels/", syosetuNovelScrapper.novelsScraper); +router.get("/novel/:novelUrl", syosetuNovelScrapper.novelScraper); +router.get("/novel/:novelUrl/:chapterUrl", syosetuNovelScrapper.chapterScraper); +router.get("/search/", syosetuNovelScrapper.searchScraper); + +module.exports = router; diff --git a/src/jp/syosetu/SyosetuScrapper.js b/src/jp/syosetu/SyosetuScrapper.js new file mode 100755 index 0000000..061164b --- /dev/null +++ b/src/jp/syosetu/SyosetuScrapper.js @@ -0,0 +1,283 @@ +// scraper and cheerio for scrapping from site +const { scraper } = require("../../helper"); +const cheerio = require("cheerio"); + +const baseUrl = "https://syosetu.com"; // base url for syosetu.com + +// get given page of search (if pagenum is 0 or >100 (max possible on site) see first page) +const searchUrl = (pagenum, order) => { + return `https://yomou.syosetu.com/search.php?order=${order || "hyoka"}${ + !isNaN((pagenum = parseInt(pagenum))) // check if pagenum is a number + ? `&p=${pagenum <= 1 || pagenum > 100 ? "1" : pagenum}` // check if pagenum is between 1 and 100 + : "" // if isn't don't set ?p + }`; +}; + +// get the Syosetu ID of the chapter +const getLastPartOfUrl = (url) => + (ex = /.*(?=\/)(.{2,})$/.exec(url)) ? ex[1].replace(/\//g, "") : null; + +// get novelUrl from Syosetu ID +const getNovelUrl = (id) => `https://ncode.syosetu.com/${id}`; + +// get chapterUrl from Syosetu ID and chapter ID +const getChapterUrl = (id, chn) => + `https://ncode.syosetu.com/${id}${chn === "oneshot" ? "" : `/${chn}`}`; + +// Because syosetu does not have any covers, I did a replacement for them +const novelCover = "https://raw.githubusercontent.com/skillgg/lnreader-sources/main/src/jp/syosetu/not_found.png"; + +// ID of this extension +const extensionId = 36; + +// Name of this extension +const sourceName = "Syosetu"; + +// there are 20 mangas per page +// this is number of pages loaded in the first "batch" of loads +// TOOD: in-app dynamic loading on scroll +const maxPageLoad = 3; + +const novelsScraper = async (req, res) => { + // array of all the novels + let novels = []; + // returns list of novels from given page + let getNovelsFromPage = async (pagenumber) => { + // load page + console.log(searchUrl(pagenumber)); + const body = await scraper(searchUrl(pagenumber || null)); + console.log("Loaded"); + // Cheerio it! + const cheerioQuery = cheerio.load(body, { decodeEntities: false }); + + console.log("Parsed"); + + let pageNovels = []; + // find class=searchkekka_box + cheerioQuery(".searchkekka_box").each(function (i, e) { + // get div with link and name + const novelDIV = cheerioQuery(this).find(".novel_h"); + // get link element + const novelA = novelDIV.children()[0]; + // add new novel to array + pageNovels.push({ + novelName: novelDIV.text(), // get the name + novelUrl: getLastPartOfUrl(novelA.attribs.href), // get last part of the link + extensionId, + novelCover, // TODO: IDK what to do about covers... On Syo they don't have them + }); + }); + console.log("Read"); + // return all novels from this page + return pageNovels; + }; + + // counter of loaded pages + let pagesLoaded = 0; + do { + // always load first one + novels.push(...(await getNovelsFromPage(pagesLoaded + 1))); + pagesLoaded++; + console.log("Added"); + } while (pagesLoaded < maxPageLoad); // check if we should load more + + /** Use + * novels.push(...(await getNovelsFromPage(pageNumber))) + * if you want to load more + */ + + // respond with novels! + res.json(novels); + console.log("Finished!"); +}; + +const novelScraper = async (req, res) => { + const novelUrl = getNovelUrl(req.params.novelUrl); + + let chapters = []; + + const body = await scraper(novelUrl); + const cheerioQuery = cheerio.load(body, { decodeEntities: false }); + + // create novel object + let novel = { + extensionId, + sourceName, + sourceUrl: novelUrl, + novelUrl: req.params.novelUrl, + novelName: cheerioQuery(".novel_title").text(), + novelCover, + }; + + // Get all the chapters + const cqGetChapters = cheerioQuery(".novel_sublist2"); + console.log(novelUrl, cqGetChapters.length); + if (cqGetChapters.length !== 0) { + // has more than 1 chapter + novel.novelSummary = cheerioQuery("#novel_ex") + .text() + .replace(/<\s*br.*?>/g, "\n"); + cqGetChapters.each(function (i, e) { + const chapterA = cheerioQuery(this).find("a"); + const [chapterName, releaseDate, chapterUrl] = [ + // set the variables + chapterA.text(), + cheerioQuery(this) + .find("dt") // get title + .text() // get text + .replace(/(.)/g, "") // remove "(edited)" mark + .trim(), // trim spaces + getLastPartOfUrl(chapterA.attr("href")), + ]; + chapters.push({ chapterName, releaseDate, chapterUrl }); + }); + } else { + /** + * Because there are oneshots on the site, they have to be treated with special care + * that's what pisses me off in Shosetsu app. They have this extension, + * but every oneshot is set as "there are no chapters" and all contents are thrown into the description!! + */ + // get summary for oneshot chapter + novel.novelSummary = cheerio // because there is no summary anywhere on the novel page, we have to take it from search page for a one-shot manga + .load(await scraper(searchUrl() + `&word=${novel.novelName}`), { + decodeEntities: false, + })(".searchkekka_box") // find the manga in search.php + .first() + .find(".ex") + .text() + .replace(/\s{2,}/g, "\n"); // get the description as text + // add single chapter + chapters.push({ + chapterName: novel.novelName, + releaseDate: cheerioQuery("head") + .find("meta[name='WWWC']") + .attr("content"), // get date from metadata + chapterUrl: "oneshot", // set chapterUrl to oneshot so that chapterScraper knows it's a one-shot + }); + } + + novel.novelChapters = chapters; + + res.json(novel); + console.log("Finished!"); +}; + +let chapterScraper = async (req, res) => { + const novelUrl = req.params.novelUrl; + const chapterUrl = req.params.chapterUrl; + + const url = getChapterUrl(novelUrl, chapterUrl); // get Url + + // create cheerioQuery + const cheerioQuery = cheerio.load(await scraper(url), { + decodeEntities: false, + }); + + // create chapter data structure + let chapter = { + extensionId: 1, + novelUrl, + chapterUrl, + chapterName: "", + chapterText: cheerioQuery("#novel_honbun") // get chapter text + .text() + .replace(/<\s*br.*?>/g, "") + .replace(/\n{2,}/g, "\n"), // remove double breaklines + nextChapter: null, + prevChapter: null, + }; + + if (chapterUrl === "oneshot") + // oneshot get name + chapter.chapterName = cheerioQuery("#novel_title").text(); + else { + // single chapter + + // get name + chapter.chapterName = cheerioQuery(".novel_subtitle").first().text(); + + // get next/prev buttons + const chapterButtons = cheerioQuery( + "#novel_contents .novel_bn" + ).first(); + if (chapterButtons.length === 1) { + const button = chapterButtons.find("a"); + if (button.text().match(/次/)) + chapter.nextChapter = getLastPartOfUrl(button.attr("href")); + else chapter.prevChapter = getLastPartOfUrl(button.attr("href")); + } else { + const firstButton = chapterButtons.find("a").first(); + const lastButton = chapterButtons.find("a").last(); + chapter.prevChapter = getLastPartOfUrl(firstButton.attribs.href); + chapter.nextChapter = getLastPartOfUrl(lastButton.attribs.href); + } + } + + res.json(chapter); + console.log("Finished!"); +}; + +let searchScraper = async (req, res) => { + const searchTerm = req.query.s; + const orderBy = req.query.o; + + // array of all the novels + let novels = []; + + let isNext = true; + + // returns list of novels from given page + let getNovelsFromPage = async (pagenumber) => { + // load page + const body = await scraper( + searchUrl(pagenumber || null, req.query.o || null) + + `&word=${searchTerm}` + ); + // Cheerio it! + const cheerioQuery = cheerio.load(body, { decodeEntities: false }); + + if (cheerioQuery(".nextlink").length === 0) isNext = false; + + let pageNovels = []; + // find class=searchkekka_box + cheerioQuery(".searchkekka_box").each(function (i, e) { + // get div with link and name + const novelDIV = cheerioQuery(this).find(".novel_h"); + // get link element + const novelA = novelDIV.children()[0]; + // add new novel to array + pageNovels.push({ + novelName: novelDIV.text(), // get the name + novelUrl: getLastPartOfUrl(novelA.attribs.href), // get last part of the link + extensionId, + novelCover, // TODO: IDK what to do about covers... On Syo they don't have them + }); + }); + // return all novels from this page + return pageNovels; + }; + + // counter of loaded pages + let pagesLoaded = 0; + do { + // always load first one + novels.push(...(await getNovelsFromPage(pagesLoaded + 1))); + pagesLoaded++; + } while (pagesLoaded < maxPageLoad && isNext); // check if we should load more + + /** Use + * novels.push(...(await getNovelsFromPage(pageNumber))) + * if you want to load more + */ + + // respond with novels! + res.json(novels); + console.log("Finished!"); +}; + +module.exports = mtlNovelScraper = { + novelsScraper, + novelScraper, + chapterScraper, + searchScraper, +}; diff --git a/src/jp/syosetu/icon.png b/src/jp/syosetu/icon.png new file mode 100644 index 0000000..a516abf Binary files /dev/null and b/src/jp/syosetu/icon.png differ diff --git a/src/jp/syosetu/not_found.png b/src/jp/syosetu/not_found.png new file mode 100644 index 0000000..fd89a4a Binary files /dev/null and b/src/jp/syosetu/not_found.png differ