From fd9bc45fb12fd0da508f8b8a247e274fff7efe8d Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Thu, 24 Nov 2022 17:20:11 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B4=20opds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/core/opds/AuthorPage.js | 11 +--- server/core/opds/BasePage.js | 9 +++ server/core/opds/RootPage.js | 3 + server/core/opds/SeriesPage.js | 114 +++++++++++++++++++++++++++++++++ server/core/opds/index.js | 3 + 5 files changed, 130 insertions(+), 10 deletions(-) create mode 100644 server/core/opds/SeriesPage.js diff --git a/server/core/opds/AuthorPage.js b/server/core/opds/AuthorPage.js index e8c3309..f8cb8f1 100644 --- a/server/core/opds/AuthorPage.js +++ b/server/core/opds/AuthorPage.js @@ -8,15 +8,6 @@ class AuthorPage extends BasePage { this.title = 'Авторы'; } - bookAuthor(author) { - if (author) { - let a = author.split(','); - return a.slice(0, 3).join(', ') + (a.length > 3 ? ' и др.' : ''); - } - - return ''; - } - sortBooks(bookList) { //схлопывание серий const books = []; @@ -175,7 +166,7 @@ class AuthorPage extends BasePage { entry.push( this.makeEntry({ id: rec.id, - title: this.bookAuthor(rec.title),//${(query.depth > 1 && rec.count ? ` (${rec.count})` : '')} + title: this.bookAuthor(rec.title), link: this.navLink({href: `/${this.id}?author=${rec.q}&genre=${encodeURIComponent(query.genre)}`}), }) ); diff --git a/server/core/opds/BasePage.js b/server/core/opds/BasePage.js index 300b066..461abc5 100644 --- a/server/core/opds/BasePage.js +++ b/server/core/opds/BasePage.js @@ -298,6 +298,15 @@ class BasePage { }); } + bookAuthor(author) { + if (author) { + let a = author.split(','); + return a.slice(0, 3).join(', ') + (a.length > 3 ? ' и др.' : ''); + } + + return ''; + } + async getGenres() { let result; if (!this.genres) { diff --git a/server/core/opds/RootPage.js b/server/core/opds/RootPage.js index 3edb10a..481884e 100644 --- a/server/core/opds/RootPage.js +++ b/server/core/opds/RootPage.js @@ -1,5 +1,6 @@ const BasePage = require('./BasePage'); const AuthorPage = require('./AuthorPage'); +const SeriesPage = require('./SeriesPage'); class RootPage extends BasePage { constructor(config) { @@ -9,6 +10,7 @@ class RootPage extends BasePage { this.title = ''; this.authorPage = new AuthorPage(config); + this.seriesPage = new SeriesPage(config); } async body(req) { @@ -24,6 +26,7 @@ class RootPage extends BasePage { result.entry = [ this.authorPage.myEntry(), + this.seriesPage.myEntry(), ]; return this.makeBody(result, req); diff --git a/server/core/opds/SeriesPage.js b/server/core/opds/SeriesPage.js new file mode 100644 index 0000000..260592a --- /dev/null +++ b/server/core/opds/SeriesPage.js @@ -0,0 +1,114 @@ +const BasePage = require('./BasePage'); + +class SeriesPage extends BasePage { + constructor(config) { + super(config); + + this.id = 'series'; + this.title = 'Серии'; + } + + sortSeriesBooks(seriesBooks) { + seriesBooks.sort((a, b) => { + const dserno = (a.serno || Number.MAX_VALUE) - (b.serno || Number.MAX_VALUE); + const dtitle = a.title.localeCompare(b.title); + const dext = a.ext.localeCompare(b.ext); + return (dserno ? dserno : (dtitle ? dtitle : dext)); + }); + + return seriesBooks; + } + + async body(req) { + const result = {}; + + const query = { + series: req.query.series || '', + genre: req.query.genre || '', + del: 0, + + all: req.query.all || '', + depth: 0, + }; + query.depth = query.series.length + 1; + + if (query.series == '___others') { + query.series = ''; + query.depth = 1; + query.others = true; + } + + const entry = []; + if (query.series && query.series[0] == '=') { + //книги по серии + const bookList = await this.webWorker.getSeriesBookList(query.series.substring(1)); + + if (bookList.books) { + let books = JSON.parse(bookList.books); + const booksAll = this.filterBooks(books, {del: 0}); + const filtered = (query.all ? booksAll : this.filterBooks(books, query)); + const sorted = this.sortSeriesBooks(filtered); + + if (booksAll.length > filtered.length) { + entry.push( + this.makeEntry({ + id: 'all_series_books', + title: '[Все книги серии]', + link: this.navLink({ + href: `/${this.id}?series=${encodeURIComponent(query.series)}&all=1`}), + }) + ); + } + + for (const book of sorted) { + const title = `${book.serno ? `${book.serno}. `: ''}${book.title || 'Без названия'} (${book.ext})`; + + const e = { + id: book._uid, + title, + link: this.acqLink({href: `/book?uid=${encodeURIComponent(book._uid)}`}), + }; + + if (query.all) { + e.content = { + '*ATTRS': {type: 'text'}, + '*TEXT': this.bookAuthor(book.author), + } + } + + entry.push( + this.makeEntry(e) + ); + } + } + } else { + if (query.depth == 1 && !query.genre && !query.others) { + entry.push( + this.makeEntry({ + id: 'select_genre', + title: '[Выбрать жанр]', + link: this.navLink({href: `/genre?from=${this.id}`}), + }) + ); + } + + //навигация по каталогу + const queryRes = await this.opdsQuery('series', query, '[Остальные серии]'); + + for (const rec of queryRes) { + entry.push( + this.makeEntry({ + id: rec.id, + title: rec.title, + link: this.navLink({href: `/${this.id}?series=${rec.q}&genre=${encodeURIComponent(query.genre)}`}), + }) + ); + } + } + + result.entry = entry; + return this.makeBody(result, req); + } +} + +module.exports = SeriesPage; \ No newline at end of file diff --git a/server/core/opds/index.js b/server/core/opds/index.js index 136196f..60501b2 100644 --- a/server/core/opds/index.js +++ b/server/core/opds/index.js @@ -1,5 +1,6 @@ const RootPage = require('./RootPage'); const AuthorPage = require('./AuthorPage'); +const SeriesPage = require('./SeriesPage'); const GenrePage = require('./GenrePage'); const BookPage = require('./BookPage'); @@ -9,6 +10,7 @@ module.exports = function(app, config) { const root = new RootPage(config); const author = new AuthorPage(config); + const series = new SeriesPage(config); const genre = new GenrePage(config); const book = new BookPage(config); @@ -16,6 +18,7 @@ module.exports = function(app, config) { ['', root], ['/root', root], ['/author', author], + ['/series', series], ['/genre', genre], ['/book', book], ];