-- {"id":6118,"ver":"2.0.9","libVer":"1.0.0","author":"TechnoJo4","dep":["url>=1.0.0"]} local baseURL = "https://www.readlightnovel.me" local qs = Require("url").querystring local function shrinkURL(url) return url:gsub(".-readlightnovel%.me", "") end local function expandURL(url) return baseURL .. url end local text = function(v) return v:text() end local function parseTop(doc) return map(doc:select("div.top-novel-block"), function(v) local e = v:selectFirst("a") return Novel { title = text(e), link = shrinkURL(e:attr("href")), imageURL = v:selectFirst("img"):attr("src") } end) end -- utils to make the code more linearly -- TODO: move these to kotlin-lib luaFuncs local function identity(...) return ... end local function pipeline(obj) return function(f, ...) if not f then return obj else return pipeline(f(obj, ...)) end end end return { id = 6118, name = "ReadLightNovel", baseURL = baseURL, imageURL = "https://github.com/shosetsuorg/extensions/raw/dev/icons/ReadLightNovel.png", chapterType = ChapterType.HTML, shrinkURL = shrinkURL, expandURL = expandURL, listings = { Listing("Top Novels", true, function(data) return parseTop(GETDocument(expandURL("/top-novels/top-rated/" .. data[PAGE]))) end) }, getPassage = function(chapterURL) local htmlElement = GETDocument(expandURL(chapterURL)):selectFirst("div.content2") local title = htmlElement:selectFirst("div.block-title"):text() htmlElement = htmlElement:selectFirst("div#chapterhidden") -- Remove/modify unwanted HTML elements to get a clean webpage. htmlElement:select("br"):remove() -- Between each

is a
. -- Chapter title inserted before chapter text. htmlElement:child(0):before("

" .. title .. "

"); return pageOfElem(htmlElement) end, parseNovel = function(novelURL, loadChapters) local doc = GETDocument(expandURL(novelURL)) local novel = doc:selectFirst("div.novel") local left = novel:selectFirst(".novel-left") local details = novel:selectFirst(".novel-right .novel-details") local leftdetails = left:selectFirst(".novel-details"):children() local info = NovelInfo { title = doc:selectFirst(".block-title h1"):text(), imageURL = left:selectFirst(".novel-cover img"):attr("src"), description = table.concat(map(details:selectFirst(".novel-detail-body"):select("p"), text), "\n"), status = ({ Ongoing = NovelStatus.PUBLISHING, Completed = NovelStatus.COMPLETED, })[leftdetails:get(leftdetails:size()-1):selectFirst("li"):text()], genres = map(leftdetails:get(1):select("a"), text), language = leftdetails:get(3):selectFirst("li"):text(), authors = map(leftdetails:get(4):select("a"), text), artists = map(leftdetails:get(5):select("a"), text) } if details:selectFirst(".novel-detail-item.color-gray") ~= nil then info:setAlternativeTitles(map(details:selectFirst(".novel-detail-item.color-gray"):select("li a"), text)) end if loadChapters then local i = 0 local dedup = {} -- table for deduplication, dedup[url] will be true if chapter already exists -- mapping with identity function is a workaround, -- TODO: flatten should support java arrays to avoid this info:setChapters( pipeline(doc:select("#accordion .panel-body .tab-content")) (map, function(v) return map(v:select(".tab-pane ul"), identity) end)(flatten) (map, function(v) return map(v:select("li a"), identity) end)(flatten) (map, function(v) i = i + 1 return NovelChapter { order = i, title = v:text(), link = shrinkURL(v:attr("href")), } end) (filter, function(chap) local duplicate = dedup[chap:getLink()] dedup[chap:getLink()] = true return not duplicate end)(AsList)()) end return info end, search = function(data) return parseTop(RequestDocument( POST(expandURL("/detailed-search-210922"), nil, RequestBody(qs({ keyword=data[QUERY], search=1 }), MediaType("application/x-www-form-urlencoded"))) )) end, }