SearchPage.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. const BasePage = require('./BasePage');
  2. const utils = require('../utils');
  3. const iconv = require('iconv-lite');
  4. class SearchPage extends BasePage {
  5. constructor(config) {
  6. super(config);
  7. this.id = 'search';
  8. this.title = 'Поиск';
  9. }
  10. async body(req) {
  11. const result = {};
  12. const query = {
  13. type: req.query.type || '',
  14. term: req.query.term || '',
  15. genre: req.query.genre || '',
  16. page: parseInt(req.query.page, 10) || 1,
  17. };
  18. let entry = [];
  19. if (query.type) {
  20. if (['author', 'series', 'title'].includes(query.type)) {
  21. try {
  22. const from = query.type;
  23. const page = query.page;
  24. const limit = 100;
  25. const offset = (page - 1)*limit;
  26. const searchQuery = {[from]: query.term, genre: query.genre, del: '0', offset, limit};
  27. let queryRes = await this.webWorker.search(from, searchQuery);
  28. if (queryRes.totalFound === 0) { // не нашли ничего, проверим, может term в кодировке ISO-8859-1 (баг koreader)
  29. searchQuery[from] = iconv.encode(query.term, 'ISO-8859-1').toString();
  30. queryRes = await this.webWorker.search(from, searchQuery);
  31. }
  32. const found = queryRes.found;
  33. for (let i = 0; i < found.length; i++) {
  34. const row = found[i];
  35. if (!row.bookCount)
  36. continue;
  37. entry.push(
  38. this.makeEntry({
  39. id: row.id,
  40. title: `${(from === 'series' ? 'Серия: ': '')}${from === 'author' ? this.bookAuthor(row[from]) : row[from]}`,
  41. link: this.navLink({href: `/${from}?${from}==${encodeURIComponent(row[from])}`}),
  42. content: {
  43. '*ATTRS': {type: 'text'},
  44. '*TEXT': `${row.bookCount} книг${utils.wordEnding(row.bookCount, 8)}`,
  45. },
  46. }),
  47. );
  48. }
  49. if (queryRes.totalFound > offset + found.length) {
  50. entry.push(
  51. this.makeEntry({
  52. id: 'next_page',
  53. title: '[Следующая страница]',
  54. link: this.navLink({href: `/${this.id}?type=${from}&term=${encodeURIComponent(query.term)}&genre=${encodeURIComponent(query.genre)}&page=${page + 1}`}),
  55. })
  56. );
  57. }
  58. } catch(e) {
  59. entry.push(
  60. this.makeEntry({
  61. id: 'error',
  62. title: `Ошибка: ${e.message}`,
  63. link: this.navLink({href: `/fake-error-link`}),
  64. })
  65. );
  66. }
  67. }
  68. } else {
  69. //корневой раздел
  70. entry = [
  71. this.makeEntry({
  72. id: 'search_author',
  73. title: 'Поиск авторов',
  74. link: this.navLink({href: `/${this.id}?type=author&term=${encodeURIComponent(query.term)}`}),
  75. content: {
  76. '*ATTRS': {type: 'text'},
  77. '*TEXT': `Искать по именам авторов`,
  78. },
  79. }),
  80. this.makeEntry({
  81. id: 'search_series',
  82. title: 'Поиск серий',
  83. link: this.navLink({href: `/${this.id}?type=series&term=${encodeURIComponent(query.term)}`}),
  84. content: {
  85. '*ATTRS': {type: 'text'},
  86. '*TEXT': `Искать по названиям серий`,
  87. },
  88. }),
  89. this.makeEntry({
  90. id: 'search_title',
  91. title: 'Поиск книг',
  92. link: this.navLink({href: `/${this.id}?type=title&term=${encodeURIComponent(query.term)}`}),
  93. content: {
  94. '*ATTRS': {type: 'text'},
  95. '*TEXT': `Искать по названиям книг`,
  96. },
  97. }),
  98. this.makeEntry({
  99. id: 'search_genre',
  100. title: 'Поиск книг в жанре',
  101. link: this.navLink({href: `/genre?from=search&term=${encodeURIComponent(query.term)}`}),
  102. content: {
  103. '*ATTRS': {type: 'text'},
  104. '*TEXT': `Искать по названиям книг в выбранном жанре`,
  105. },
  106. }),
  107. this.makeEntry({
  108. id: 'search_help',
  109. title: '[Памятка по поиску]',
  110. link: this.acqLink({href: `/search-help`}),
  111. content: {
  112. '*ATTRS': {type: 'text'},
  113. '*TEXT': `Описание формата поискового значения`,
  114. },
  115. }),
  116. ]
  117. }
  118. result.entry = entry;
  119. return this.makeBody(result, req);
  120. }
  121. }
  122. module.exports = SearchPage;