diff --git a/server/core/opds/AuthorPage.js b/server/core/opds/AuthorPage.js index f2d81e5..00c6986 100644 --- a/server/core/opds/AuthorPage.js +++ b/server/core/opds/AuthorPage.js @@ -68,10 +68,12 @@ class AuthorPage extends BasePage { const query = { author: req.query.author || '', series: req.query.series || '', + genre: req.query.genre || '', + del: 0, + limit: 100, + all: req.query.all || '', depth: 0, - del: 0, - limit: 100 }; query.depth = query.author.length + 1; @@ -91,6 +93,18 @@ class AuthorPage extends BasePage { const filtered = (query.all ? books : this.filterBooks(books, query)); const sorted = this.sortSeriesBooks(filtered); + if (books.length > filtered.length) { + entry.push( + this.makeEntry({ + id: 'all_series_books', + title: '[Все книги серии]', + link: this.navLink({ + href: `/${this.id}?author=${encodeURIComponent(query.author)}` + + `&series=${encodeURIComponent(query.series)}&all=1`}), + }) + ); + } + for (const book of sorted) { let title = `${book.serno ? `${book.serno}. `: ''}${book.title || 'Без названия'}`; if (query.all) { @@ -106,18 +120,6 @@ class AuthorPage extends BasePage { }) ); } - - if (books.length > filtered.length) { - entry.push( - this.makeEntry({ - id: 'all_series_books', - title: 'Все книги серии', - link: this.navLink({ - href: `/${this.id}?author=${encodeURIComponent(query.author)}` + - `&series=${encodeURIComponent(query.series)}&all=1`}), - }) - ); - } } } else if (query.author && query.author[0] == '=') { //книги по автору @@ -135,7 +137,7 @@ class AuthorPage extends BasePage { title: `Серия: ${b.book.series}`, link: this.navLink({ href: `/${this.id}?author=${encodeURIComponent(query.author)}` + - `&series=${encodeURIComponent(b.book.series)}`}), + `&series=${encodeURIComponent(b.book.series)}&genre=${encodeURIComponent(query.genre)}`}), }) ); } else { @@ -151,15 +153,25 @@ class AuthorPage extends BasePage { } } } else { - //поиск по каталогу - const queryRes = await this.opdsQuery('author', query, 'Остальные авторы'); + 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('author', query, '[Остальные авторы]'); for (const rec of queryRes) { entry.push( this.makeEntry({ id: rec.id, title: this.bookAuthor(rec.title),//${(query.depth > 1 && rec.count ? ` (${rec.count})` : '')} - link: this.navLink({href: `/${this.id}?author=${rec.q}`}), + 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 ceb9b5a..6dcec84 100644 --- a/server/core/opds/BasePage.js +++ b/server/core/opds/BasePage.js @@ -138,7 +138,7 @@ class BasePage { return result; } - async opdsQuery(from, query, otherTitle = 'Другие') { + async opdsQuery(from, query, otherTitle = '[Другие]') { const queryRes = await this.webWorker.opdsQuery(from, query); let count = 0; for (const row of queryRes.found) @@ -302,9 +302,12 @@ class BasePage { result = { genreTree: res.genreTree, genreMap: new Map(), + genreSection: new Map(), }; for (const section of result.genreTree) { + result.genreSection.set(section.name, section.value); + for (const g of section.value) result.genreMap.set(g.value, g.name); } diff --git a/server/core/opds/GenrePage.js b/server/core/opds/GenrePage.js new file mode 100644 index 0000000..f9df2b9 --- /dev/null +++ b/server/core/opds/GenrePage.js @@ -0,0 +1,72 @@ +const BasePage = require('./BasePage'); + +class GenrePage extends BasePage { + constructor(config) { + super(config); + + this.id = 'genre'; + this.title = 'Жанры'; + + } + + async body(req) { + const result = {}; + + const query = { + from: req.query.from || '', + section: req.query.section || '', + }; + + const entry = []; + if (query.from) { + + if (query.section) { + //выбираем подразделы + const {genreSection} = await this.getGenres(); + const section = genreSection.get(query.section); + + if (section) { + let id = 0; + const all = []; + for (const g of section) { + all.push(g.value); + entry.push( + this.makeEntry({ + id: ++id, + title: g.name, + link: this.navLink({href: `/${encodeURIComponent(query.from)}?genre=${encodeURIComponent(g.value)}`}), + }) + ); + } + + entry.unshift( + this.makeEntry({ + id: 'whole_section', + title: '[Весь раздел]', + link: this.navLink({href: `/${encodeURIComponent(query.from)}?genre=${encodeURIComponent(all.join(','))}`}), + }) + ); + } + } else { + //выбираем разделы + const {genreTree} = await this.getGenres(); + let id = 0; + for (const section of genreTree) { + entry.push( + this.makeEntry({ + id: ++id, + title: section.name, + link: this.navLink({href: `/genre?from=${encodeURIComponent(query.from)}§ion=${encodeURIComponent(section.name)}`}), + }) + ); + } + } + } + + result.entry = entry; + + return this.makeBody(result, req); + } +} + +module.exports = GenrePage; \ No newline at end of file diff --git a/server/core/opds/index.js b/server/core/opds/index.js index 95c1ede..136196f 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 GenrePage = require('./GenrePage'); const BookPage = require('./BookPage'); module.exports = function(app, config) { @@ -8,12 +9,14 @@ module.exports = function(app, config) { const root = new RootPage(config); const author = new AuthorPage(config); + const genre = new GenrePage(config); const book = new BookPage(config); const routes = [ ['', root], ['/root', root], ['/author', author], + ['/genre', genre], ['/book', book], ];