const cheerio = require('cheerio'); const fetchApi = require('@libs/fetchApi'); const fetchFile = require('@libs/fetchFile'); const languages = require('@libs/languages'); const Status = require('@libs/novelStatus'); const FilterInputs = require('@libs/filterInputs'); const pluginId = 'jaomix.ru'; const sourceName = 'Jaomix'; const baseUrl = 'https://jaomix.ru'; async function popularNovels (page, { showLatestNovels, filters }) { let url = baseUrl + '/?searchrn&sortby='; url += filters?.sort ? filters?.sort : (showLatestNovels ? 'upd' : 'count'); if (filters?.type?.length) { url += filters.type.map(i => `&lang[]=${i}`).join(''); } if (filters?.genres?.length) { url += filters.genres.map(i => `&genre[]=${i}`).join(''); } url += `&page=${page}`; const result = await fetchApi(url); let body = await result.text(); const loadedCheerio = cheerio.load(body); let novels = []; loadedCheerio('div[class="block-home"] > div[class="one"]').each(function () { const novelName = loadedCheerio(this) .find('div[class="img-home"] > a') .attr('title'); const novelCover = loadedCheerio(this) .find('div[class="img-home"] > a > img') .attr('src') .replace('-150x150', ''); const novelUrl = loadedCheerio(this) .find('div[class="img-home"] > a') .attr('href'); const novel = { name: novelName, cover: novelCover, url: novelUrl }; novels.push(novel); }); return novels; }; async function parseNovelAndChapters (novelUrl) { const result = await fetchApi(novelUrl); const body = await result.text(); const loadedCheerio = cheerio.load(body); let novel = { url: novelUrl, }; novel.name = loadedCheerio('div[class="desc-book"] > h1').text().trim(); novel.cover = loadedCheerio('div[class="img-book"] > img').attr('src'); novel.summary = loadedCheerio('div[id="desc-tab"]').text().trim(); loadedCheerio('#info-book > p').each(function () { let text = loadedCheerio(this).text().replace(/,/g, '').split(' '); if (text[0] === 'Автор:') { novel.author = text.splice(1).join(' '); } else if (text[0] === 'Жанры:') { novel.genres = text.splice(1).join(','); } else if (text[0] === 'Статус:') { novel.status = text.includes('продолжается') ? Status.Ongoing : Status.Completed; } }); const chapters = []; loadedCheerio('.download-chapter div.title').each(function () { chapters.push({ name: loadedCheerio(this).find('a').attr('title'), releaseTime: loadedCheerio(this).find('time').text(), url: loadedCheerio(this).find('a').attr('href'), }); }); novel.chapters = chapters.reverse(); return novel; }; async function parseChapter (chapterUrl) { const result = await fetchApi(chapterUrl); const body = await result.text(); const loadedCheerio = cheerio.load(body); loadedCheerio('div[class="adblock-service"]').remove(); const chapterText = loadedCheerio('div[class="entry-content"]').html(); return chapterText; }; async function searchNovels (searchTerm) { const url = `${baseUrl}/?searchrn=${searchTerm}&but=Поиск по названию&sortby=upd`; const result = await fetchApi(url); let body = await result.text(); const loadedCheerio = cheerio.load(body); let novels = []; loadedCheerio('div[class="block-home"] > div[class="one"]').each(function () { const novelName = loadedCheerio(this) .find('div[class="img-home"] > a') .attr('title'); const novelCover = loadedCheerio(this) .find('div[class="img-home"] > a > img') .attr('src') .replace('-150x150', ''); const novelUrl = loadedCheerio(this) .find('div[class="img-home"] > a') .attr('href'); const novel = {name: novelName, cover: novelCover, url: novelUrl }; novels.push(novel); }); return novels; }; const filters = [ { key: 'sort', label: 'Сортировка', values: [ { label: 'Имя', value: 'alphabet' }, { label: 'Просмотры', value: 'count' }, { label: 'Дате добавления', value: 'new' }, { label: 'Дате обновления', value: 'upd' }, ], inputType: FilterInputs.Picker, }, { key: 'type', label: 'Тип', values: [ { label: 'Английский', value: 'Английский' }, { label: 'Китайский', value: 'Китайский' }, { label: 'Корейский', value: 'Корейский' }, { label: 'Японский', value: 'Японский' }, ], inputType: FilterInputs.Checkbox, }, { key: 'genres', label: 'Жанры', values: [ { label: 'Adult', value: 'Adult' }, { label: 'Ecchi', value: 'Ecchi' }, { label: 'Josei', value: 'Josei' }, { label: 'Lolicon', value: 'Lolicon' }, { label: 'Mature', value: 'Mature' }, { label: 'Sci-fi', value: 'Sci-fi' }, { label: 'Shoujo', value: 'Shoujo' }, { label: 'Wuxia', value: 'Wuxia' }, { label: 'Xianxia', value: 'Xianxia' }, { label: 'Xuanhuan', value: 'Xuanhuan' }, { label: 'Yaoi', value: 'Yaoi' }, { label: 'Боевые Искусства', value: 'Боевые Искусства' }, { label: 'Виртуальный Мир', value: 'Виртуальный Мир' }, { label: 'Гарем', value: 'Гарем' }, { label: 'Детектив', value: 'Детектив' }, { label: 'Драма', value: 'Драма' }, { label: 'Игра', value: 'Игра' }, { label: 'Истории из жизни', value: 'Истории из жизни' }, { label: 'Исторический', value: 'Исторический' }, { label: 'История', value: 'История' }, { label: 'Комедия', value: 'Комедия' }, { label: 'Меха', value: 'Меха' }, { label: 'Мистика', value: 'Мистика' }, { label: 'Научная Фантастика', value: 'Научная Фантастика' }, { label: 'Повседневность', value: 'Повседневность' }, { label: 'Постапокалипсис', value: 'Постапокалипсис' }, { label: 'Приключения', value: 'Приключения' }, { label: 'Психология', value: 'Психология' }, { label: 'Романтика', value: 'Романтика' }, { label: 'Сёнэн', value: 'Сёнэн' }, { label: 'Сёнэн-ай', value: 'Сёнэн-ай' }, { label: 'Сверхъестественное', value: 'Сверхъестественное' }, { label: 'Спорт', value: 'Спорт' }, { label: 'Сэйнэн', value: 'Сэйнэн' }, { label: 'Сюаньхуа', value: 'Сюаньхуа' }, { label: 'Трагедия', value: 'Трагедия' }, { label: 'Триллер', value: 'Триллер' }, { label: 'Фантастика', value: 'Фантастика' }, { label: 'Фэнтези', value: 'Фэнтези' }, { label: 'Хоррор', value: 'Хоррор' }, { label: 'Школьная жизнь', value: 'Школьная жизнь' }, { label: 'Шоунен', value: 'Шоунен' }, { label: 'Экшн', value: 'Экшн' }, { label: 'Этти', value: 'Этти' }, ], inputType: FilterInputs.Checkbox, }, ]; module.exports = { id: pluginId, name: sourceName, site: baseUrl, version: '1.0.0', lang: languages.Russian, icon: 'src/ru/jaomix/icon.png', filters, popularNovels, parseNovelAndChapters, parseChapter, searchNovels, fetchImage: fetchFile, };