mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-08-06 20:08:41 +02:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b46d68027 | ||
|
|
d511612f21 | ||
|
|
6caa1aa2da | ||
|
|
32fae4a7c6 | ||
|
|
96d4021a3c | ||
|
|
49826f5163 | ||
|
|
76e33a2a4e | ||
|
|
1a440811c5 | ||
|
|
529a16b718 | ||
|
|
032f0b6b51 | ||
|
|
f5bfa1edd6 | ||
|
|
4dfad46722 |
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.35.1",
|
"version": "2.36.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.35.1",
|
"version": "2.36.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxtjs/axios": "^5.13.6",
|
"@nuxtjs/axios": "^5.13.6",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.35.1",
|
"version": "2.36.0",
|
||||||
"buildNumber": 1,
|
"buildNumber": 1,
|
||||||
"description": "Self-hosted audiobook and podcast client",
|
"description": "Self-hosted audiobook and podcast client",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
|||||||
@@ -195,6 +195,7 @@
|
|||||||
"HeaderScheduleEpisodeDownloads": "设置自动下载剧集",
|
"HeaderScheduleEpisodeDownloads": "设置自动下载剧集",
|
||||||
"HeaderScheduleLibraryScans": "自动扫描媒体库",
|
"HeaderScheduleLibraryScans": "自动扫描媒体库",
|
||||||
"HeaderSession": "会话",
|
"HeaderSession": "会话",
|
||||||
|
"HeaderSessions": "会话",
|
||||||
"HeaderSetBackupSchedule": "设置备份计划任务",
|
"HeaderSetBackupSchedule": "设置备份计划任务",
|
||||||
"HeaderSettings": "设置",
|
"HeaderSettings": "设置",
|
||||||
"HeaderSettingsDisplay": "显示",
|
"HeaderSettingsDisplay": "显示",
|
||||||
@@ -416,6 +417,7 @@
|
|||||||
"LabelIntervalEveryHour": "每小时",
|
"LabelIntervalEveryHour": "每小时",
|
||||||
"LabelIntervalEveryMinute": "每分钟",
|
"LabelIntervalEveryMinute": "每分钟",
|
||||||
"LabelInvert": "倒转",
|
"LabelInvert": "倒转",
|
||||||
|
"LabelIpAddress": "IP 地址",
|
||||||
"LabelItem": "项目",
|
"LabelItem": "项目",
|
||||||
"LabelJumpBackwardAmount": "向后跳转时长",
|
"LabelJumpBackwardAmount": "向后跳转时长",
|
||||||
"LabelJumpForwardAmount": "向前跳转时长",
|
"LabelJumpForwardAmount": "向前跳转时长",
|
||||||
@@ -775,6 +777,7 @@
|
|||||||
"MessageConfirmDeleteSession": "你确定要删除此会话吗?",
|
"MessageConfirmDeleteSession": "你确定要删除此会话吗?",
|
||||||
"MessageConfirmEmbedMetadataInAudioFiles": "你确定要将元数据嵌入到 {0} 个音频文件中吗?",
|
"MessageConfirmEmbedMetadataInAudioFiles": "你确定要将元数据嵌入到 {0} 个音频文件中吗?",
|
||||||
"MessageConfirmForceReScan": "你确定要强制重新扫描吗?",
|
"MessageConfirmForceReScan": "你确定要强制重新扫描吗?",
|
||||||
|
"MessageConfirmLogoutDevice": "确定要注销 \"{0}\" 吗?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "你确定要将所有剧集都标记为已完成吗?",
|
"MessageConfirmMarkAllEpisodesFinished": "你确定要将所有剧集都标记为已完成吗?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "你确定要将所有剧集都标记为未完成吗?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "你确定要将所有剧集都标记为未完成吗?",
|
||||||
"MessageConfirmMarkItemFinished": "你确定要将 “{0}” 标记为已完成吗?",
|
"MessageConfirmMarkItemFinished": "你确定要将 “{0}” 标记为已完成吗?",
|
||||||
|
|||||||
Generated
+17
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf",
|
"name": "audiobookshelf",
|
||||||
"version": "2.35.1",
|
"version": "2.36.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "audiobookshelf",
|
"name": "audiobookshelf",
|
||||||
"version": "2.35.1",
|
"version": "2.36.0",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
@@ -2113,6 +2113,21 @@
|
|||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||||
"devOptional": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/fsevents": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
|
|||||||
+4
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf",
|
"name": "audiobookshelf",
|
||||||
"version": "2.35.1",
|
"version": "2.36.0",
|
||||||
"buildNumber": 1,
|
"buildNumber": 1,
|
||||||
"description": "Self-hosted audiobook and podcast server",
|
"description": "Self-hosted audiobook and podcast server",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
@@ -65,5 +65,8 @@
|
|||||||
"nodemon": "^2.0.20",
|
"nodemon": "^2.0.20",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"sinon": "^17.0.1"
|
"sinon": "^17.0.1"
|
||||||
|
},
|
||||||
|
"allowScripts": {
|
||||||
|
"sqlite3@5.1.7": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
## ⚠️ Frontend pull requests are not being reviewed or merged for the existing Vue frontend. The frontend is currently being rewritten and migrated to React and should be available soon.
|
||||||
|
|
||||||
# About
|
# About
|
||||||
|
|
||||||
Audiobookshelf is a self-hosted audiobook and podcast server.
|
Audiobookshelf is a self-hosted audiobook and podcast server.
|
||||||
@@ -73,7 +75,7 @@ See [library docs](https://audiobookshelf.org/docs/category/libraries) for suppo
|
|||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
See [install docs](https://www.audiobookshelf.org/docs)
|
See [install docs](https://audiobookshelf.org/docs/category/installation)
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@@ -93,8 +95,7 @@ See [contributing docs](https://audiobookshelf.org/docs/contributing/general/)
|
|||||||
|
|
||||||
### Localization
|
### Localization
|
||||||
|
|
||||||
Thank you to [Weblate](https://hosted.weblate.org/engage/audiobookshelf/) for hosting our localization infrastructure pro-bono. If you want to see Audiobookshelf in your language, please help us localize. Additional information on helping with the translations [here](https://www.audiobookshelf.org/faq#how-do-i-help-with-translations).
|
Thank you to [Weblate](https://hosted.weblate.org/engage/audiobookshelf/) for hosting our localization infrastructure pro-bono. If you want to see Audiobookshelf in your language, please help us localize. Additional information on helping with the translations [here](https://www.audiobookshelf.org/faq#how-do-i-help-with-translations). <a href="https://hosted.weblate.org/engage/audiobookshelf/"> <img src="https://hosted.weblate.org/widget/audiobookshelf/abs-web-client/multi-auto.svg" alt="Translation status" /> </a>
|
||||||
<a href="https://hosted.weblate.org/engage/audiobookshelf/"> <img src="https://hosted.weblate.org/widget/audiobookshelf/abs-web-client/multi-auto.svg" alt="Translation status" /> </a>
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@@ -191,4 +192,3 @@ If you are using VSCode, this project includes a couple of pre-defined targets t
|
|||||||
- `Debug server`—Run the server.
|
- `Debug server`—Run the server.
|
||||||
- `Debug client (nuxt)`—Run the client with live reload.
|
- `Debug client (nuxt)`—Run the client with live reload.
|
||||||
- `Debug server and client (nuxt)`—Runs both the preceding two debug targets.
|
- `Debug server and client (nuxt)`—Runs both the preceding two debug targets.
|
||||||
|
|
||||||
|
|||||||
@@ -58,8 +58,12 @@ class PodcastScanner {
|
|||||||
/** @type {AudioFile[]} */
|
/** @type {AudioFile[]} */
|
||||||
let newAudioFiles = []
|
let newAudioFiles = []
|
||||||
|
|
||||||
|
// Track episode add/remove/update so item_updated includes the current episode list
|
||||||
|
let hasEpisodeChanges = false
|
||||||
|
|
||||||
if (libraryItemData.hasAudioFileChanges || libraryItemData.audioLibraryFiles.length !== existingPodcastEpisodes.length) {
|
if (libraryItemData.hasAudioFileChanges || libraryItemData.audioLibraryFiles.length !== existingPodcastEpisodes.length) {
|
||||||
// Filter out and destroy episodes that were removed
|
// Filter out and destroy episodes that were removed.
|
||||||
|
// filter() returns a new array — reassign to media.podcastEpisodes before emit.
|
||||||
const episodesToRemove = []
|
const episodesToRemove = []
|
||||||
existingPodcastEpisodes = existingPodcastEpisodes.filter((ep) => {
|
existingPodcastEpisodes = existingPodcastEpisodes.filter((ep) => {
|
||||||
if (libraryItemData.checkAudioFileRemoved(ep.audioFile)) {
|
if (libraryItemData.checkAudioFileRemoved(ep.audioFile)) {
|
||||||
@@ -70,6 +74,7 @@ class PodcastScanner {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (episodesToRemove.length) {
|
if (episodesToRemove.length) {
|
||||||
|
hasEpisodeChanges = true
|
||||||
// Remove episodes from playlists and media progress
|
// Remove episodes from playlists and media progress
|
||||||
const episodeIds = episodesToRemove.map((ep) => ep.id)
|
const episodeIds = episodesToRemove.map((ep) => ep.id)
|
||||||
await Database.playlistModel.removeMediaItemsFromPlaylists(episodeIds)
|
await Database.playlistModel.removeMediaItemsFromPlaylists(episodeIds)
|
||||||
@@ -116,6 +121,7 @@ class PodcastScanner {
|
|||||||
AudioFileScanner.setPodcastEpisodeMetadataFromAudioMetaTags(podcastEpisode, libraryScan)
|
AudioFileScanner.setPodcastEpisodeMetadataFromAudioMetaTags(podcastEpisode, libraryScan)
|
||||||
libraryScan.addLog(LogLevel.INFO, `Podcast episode "${podcastEpisode.title}" keys changed [${podcastEpisode.changed()?.join(', ')}]`)
|
libraryScan.addLog(LogLevel.INFO, `Podcast episode "${podcastEpisode.title}" keys changed [${podcastEpisode.changed()?.join(', ')}]`)
|
||||||
await podcastEpisode.save()
|
await podcastEpisode.save()
|
||||||
|
hasEpisodeChanges = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,9 +161,13 @@ class PodcastScanner {
|
|||||||
libraryScan.addLog(LogLevel.INFO, `New Podcast episode "${newPodcastEpisode.title}" added`)
|
libraryScan.addLog(LogLevel.INFO, `New Podcast episode "${newPodcastEpisode.title}" added`)
|
||||||
await newPodcastEpisode.save()
|
await newPodcastEpisode.save()
|
||||||
existingPodcastEpisodes.push(newPodcastEpisode)
|
existingPodcastEpisodes.push(newPodcastEpisode)
|
||||||
|
hasEpisodeChanges = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep association in sync for toOldJSONExpanded() / item_updated socket payload
|
||||||
|
media.podcastEpisodes = existingPodcastEpisodes
|
||||||
|
|
||||||
let hasMediaChanges = false
|
let hasMediaChanges = false
|
||||||
if (existingPodcastEpisodes.length !== media.numEpisodes) {
|
if (existingPodcastEpisodes.length !== media.numEpisodes) {
|
||||||
media.numEpisodes = existingPodcastEpisodes.length
|
media.numEpisodes = existingPodcastEpisodes.length
|
||||||
@@ -250,7 +260,7 @@ class PodcastScanner {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
libraryItem: existingLibraryItem,
|
libraryItem: existingLibraryItem,
|
||||||
wasUpdated: hasMediaChanges || libraryItemUpdated
|
wasUpdated: hasMediaChanges || libraryItemUpdated || hasEpisodeChanges
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user