mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-08-14 13:47:16 +02:00
Merge branch 'advplyr:master' into master
This commit is contained in:
commit
ed4af72515
@ -276,6 +276,11 @@ export default {
|
|||||||
text: this.$strings.ButtonIssues,
|
text: this.$strings.ButtonIssues,
|
||||||
value: 'issues',
|
value: 'issues',
|
||||||
sublist: false
|
sublist: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: this.$strings.LabelRSSFeedOpen,
|
||||||
|
value: 'feed-open',
|
||||||
|
sublist: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -162,7 +162,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
// Find closest bitrate rounding up
|
// Find closest bitrate rounding up
|
||||||
const bitratesToMatch = [32, 64, 128, 192]
|
const bitratesToMatch = [32, 64, 128, 192]
|
||||||
const closestBitrate = bitratesToMatch.find((bitrate) => bitrate >= this.currentBitrate)
|
const closestBitrate = bitratesToMatch.find((bitrate) => bitrate >= this.currentBitrate) || 192
|
||||||
this.selectedBitrate = closestBitrate + 'k'
|
this.selectedBitrate = closestBitrate + 'k'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,15 +359,14 @@ export default {
|
|||||||
// Check if path already exists before starting upload
|
// Check if path already exists before starting upload
|
||||||
// uploading fails if path already exists
|
// uploading fails if path already exists
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const filepath = Path.join(this.selectedFolder.fullPath, item.directory)
|
|
||||||
const exists = await this.$axios
|
const exists = await this.$axios
|
||||||
.$post(`/api/filesystem/pathexists`, { filepath, directory: item.directory, folderPath: this.selectedFolder.fullPath })
|
.$post(`/api/filesystem/pathexists`, { directory: item.directory, folderPath: this.selectedFolder.fullPath })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.exists) {
|
if (data.exists) {
|
||||||
if (data.libraryItemTitle) {
|
if (data.libraryItemTitle) {
|
||||||
this.$toast.error(this.$getString('ToastUploaderItemExistsInSubdirectoryError', [data.libraryItemTitle]))
|
this.$toast.error(this.$getString('ToastUploaderItemExistsInSubdirectoryError', [data.libraryItemTitle]))
|
||||||
} else {
|
} else {
|
||||||
this.$toast.error(this.$getString('ToastUploaderFilepathExistsError', [filepath]))
|
this.$toast.error(this.$getString('ToastUploaderFilepathExistsError', [Path.join(this.selectedFolder.fullPath, item.directory)]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data.exists
|
return data.exists
|
||||||
|
@ -84,49 +84,67 @@ class FileSystemController {
|
|||||||
*/
|
*/
|
||||||
async checkPathExists(req, res) {
|
async checkPathExists(req, res) {
|
||||||
if (!req.user.canUpload) {
|
if (!req.user.canUpload) {
|
||||||
Logger.error(`[FileSystemController] Non-admin user "${req.user.username}" attempting to check path exists`)
|
Logger.error(`[FileSystemController] User "${req.user.username}" without upload permissions attempting to check path exists`)
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { filepath, directory, folderPath } = req.body
|
const { directory, folderPath } = req.body
|
||||||
|
|
||||||
if (!filepath?.length || typeof filepath !== 'string') {
|
if (!directory?.length || typeof directory !== 'string' || !folderPath?.length || typeof folderPath !== 'string') {
|
||||||
|
Logger.error(`[FileSystemController] Invalid request body: ${JSON.stringify(req.body)}`)
|
||||||
|
return res.status(400).json({
|
||||||
|
error: 'Invalid request body'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that library folder exists
|
||||||
|
const libraryFolder = await Database.libraryFolderModel.findOne({
|
||||||
|
where: {
|
||||||
|
path: folderPath
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!libraryFolder) {
|
||||||
|
Logger.error(`[FileSystemController] Library folder not found: ${folderPath}`)
|
||||||
|
return res.sendStatus(404)
|
||||||
|
}
|
||||||
|
|
||||||
|
const filepath = Path.posix.join(libraryFolder.path, directory)
|
||||||
|
// Ensure filepath is inside library folder (prevents directory traversal)
|
||||||
|
if (!filepath.startsWith(libraryFolder.path)) {
|
||||||
|
Logger.error(`[FileSystemController] Filepath is not inside library folder: ${filepath}`)
|
||||||
return res.sendStatus(400)
|
return res.sendStatus(400)
|
||||||
}
|
}
|
||||||
|
|
||||||
const exists = await fs.pathExists(filepath)
|
if (await fs.pathExists(filepath)) {
|
||||||
|
|
||||||
if (exists) {
|
|
||||||
return res.json({
|
return res.json({
|
||||||
exists: true
|
exists: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// If directory and folderPath are passed in, check if a library item exists in a subdirectory
|
// Check if a library item exists in a subdirectory
|
||||||
// See: https://github.com/advplyr/audiobookshelf/issues/4146
|
// See: https://github.com/advplyr/audiobookshelf/issues/4146
|
||||||
if (typeof directory === 'string' && typeof folderPath === 'string' && directory.length > 0 && folderPath.length > 0) {
|
const cleanedDirectory = directory.split('/').filter(Boolean).join('/')
|
||||||
const cleanedDirectory = directory.split('/').filter(Boolean).join('/')
|
if (cleanedDirectory.includes('/')) {
|
||||||
if (cleanedDirectory.includes('/')) {
|
// Can only be 2 levels deep
|
||||||
// Can only be 2 levels deep
|
const possiblePaths = []
|
||||||
const possiblePaths = []
|
const subdir = Path.dirname(directory)
|
||||||
const subdir = Path.dirname(directory)
|
possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, subdir)))
|
||||||
possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, subdir)))
|
if (subdir.includes('/')) {
|
||||||
if (subdir.includes('/')) {
|
possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, Path.dirname(subdir))))
|
||||||
possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, Path.dirname(subdir))))
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const libraryItem = await Database.libraryItemModel.findOne({
|
const libraryItem = await Database.libraryItemModel.findOne({
|
||||||
where: {
|
where: {
|
||||||
path: possiblePaths
|
path: possiblePaths
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (libraryItem) {
|
||||||
|
return res.json({
|
||||||
|
exists: true,
|
||||||
|
libraryItemTitle: libraryItem.title
|
||||||
})
|
})
|
||||||
|
|
||||||
if (libraryItem) {
|
|
||||||
return res.json({
|
|
||||||
exists: true,
|
|
||||||
libraryItemTitle: libraryItem.title
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,9 +246,10 @@ class MediaProgress extends Model {
|
|||||||
// For local sync
|
// For local sync
|
||||||
if (progressPayload.lastUpdate) {
|
if (progressPayload.lastUpdate) {
|
||||||
this.updatedAt = progressPayload.lastUpdate
|
this.updatedAt = progressPayload.lastUpdate
|
||||||
|
this.changed('updatedAt', true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.save()
|
return this.save({ silent: !!progressPayload.lastUpdate })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ function extractEpisodeData(item) {
|
|||||||
} else if (typeof guidItem?._ === 'string') {
|
} else if (typeof guidItem?._ === 'string') {
|
||||||
episode.guid = guidItem._
|
episode.guid = guidItem._
|
||||||
} else {
|
} else {
|
||||||
Logger.error(`[podcastUtils] Invalid guid ${item['guid']} for ${episode.enclosure.url}`)
|
Logger.error(`[podcastUtils] Invalid guid for ${episode.enclosure.url}`, item['guid'])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,11 +149,12 @@ module.exports = {
|
|||||||
libraryId
|
libraryId
|
||||||
}
|
}
|
||||||
const libraryItemIncludes = []
|
const libraryItemIncludes = []
|
||||||
if (includeRSSFeed) {
|
if (filterGroup === 'feed-open' || includeRSSFeed) {
|
||||||
|
const rssFeedRequired = filterGroup === 'feed-open'
|
||||||
libraryItemIncludes.push({
|
libraryItemIncludes.push({
|
||||||
model: Database.feedModel,
|
model: Database.feedModel,
|
||||||
required: filterGroup === 'feed-open',
|
required: rssFeedRequired,
|
||||||
separate: true
|
separate: !rssFeedRequired
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (filterGroup === 'issues') {
|
if (filterGroup === 'issues') {
|
||||||
|
Loading…
Reference in New Issue
Block a user