diff --git a/server/controllers/LibraryController.js b/server/controllers/LibraryController.js index f768bb93..b25e02aa 100644 --- a/server/controllers/LibraryController.js +++ b/server/controllers/LibraryController.js @@ -9,7 +9,8 @@ const libraryItemsBookFilters = require('../utils/queries/libraryItemsBookFilter const libraryItemFilters = require('../utils/queries/libraryItemFilters') const seriesFilters = require('../utils/queries/seriesFilters') const fileUtils = require('../utils/fileUtils') -const { sort, createNewSortInstance } = require('../libs/fastSort') +const { asciiOnlyToLowerCase } = require('../utils/index') +const { createNewSortInstance } = require('../libs/fastSort') const naturalSort = createNewSortInstance({ comparer: new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }).compare }) @@ -555,7 +556,7 @@ class LibraryController { return res.status(400).send('No query string') } const limit = req.query.limit && !isNaN(req.query.limit) ? Number(req.query.limit) : 12 - const query = req.query.q.trim().toLowerCase() + const query = asciiOnlyToLowerCase(req.query.q.trim()) const matches = await libraryItemFilters.search(req.user, req.library, query, limit) res.json(matches) diff --git a/server/utils/index.js b/server/utils/index.js index 5797b0b5..abcc626c 100644 --- a/server/utils/index.js +++ b/server/utils/index.js @@ -166,4 +166,27 @@ module.exports.getTitleIgnorePrefix = (title) => { module.exports.getTitlePrefixAtEnd = (title) => { let [sort, prefix] = getTitleParts(title) return prefix ? `${sort}, ${prefix}` : title +} + +/** + * to lower case for only ascii characters + * used to handle sqlite that doesnt support unicode lower + * @see https://github.com/advplyr/audiobookshelf/issues/2187 + * + * @param {string} str + * @returns {string} + */ +module.exports.asciiOnlyToLowerCase = (str) => { + if (!str) return '' + + let temp = '' + for (let chars of str) { + let value = chars.charCodeAt() + if (value >= 65 && value <= 90) { + temp += String.fromCharCode(value + 32) + } else { + temp += chars + } + } + return temp } \ No newline at end of file diff --git a/server/utils/queries/libraryItemsBookFilters.js b/server/utils/queries/libraryItemsBookFilters.js index 10e1101d..d23459b4 100644 --- a/server/utils/queries/libraryItemsBookFilters.js +++ b/server/utils/queries/libraryItemsBookFilters.js @@ -2,6 +2,7 @@ const Sequelize = require('sequelize') const Database = require('../../Database') const Logger = require('../../Logger') const authorFilters = require('./authorFilters') +const { asciiOnlyToLowerCase } = require('../index') module.exports = { /** @@ -1013,7 +1014,8 @@ module.exports = { let matchText = null let matchKey = null for (const key of ['title', 'subtitle', 'asin', 'isbn']) { - if (book[key]?.toLowerCase().includes(query)) { + const valueToLower = asciiOnlyToLowerCase(book[key]) + if (valueToLower.includes(query)) { matchText = book[key] matchKey = key break diff --git a/server/utils/queries/libraryItemsPodcastFilters.js b/server/utils/queries/libraryItemsPodcastFilters.js index 27ac3fcd..7665c89b 100644 --- a/server/utils/queries/libraryItemsPodcastFilters.js +++ b/server/utils/queries/libraryItemsPodcastFilters.js @@ -2,6 +2,7 @@ const Sequelize = require('sequelize') const Database = require('../../Database') const Logger = require('../../Logger') +const { asciiOnlyToLowerCase } = require('../index') module.exports = { /** @@ -364,7 +365,8 @@ module.exports = { let matchText = null let matchKey = null for (const key of ['title', 'author', 'itunesId', 'itunesArtistId']) { - if (podcast[key]?.toLowerCase().includes(query)) { + const valueToLower = asciiOnlyToLowerCase(podcast[key]) + if (valueToLower.includes(query)) { matchText = podcast[key] matchKey = key break