Skip to content

Commit

Permalink
feat: rescan library
Browse files Browse the repository at this point in the history
also moved the actions into a menu

closes #38
  • Loading branch information
gotson committed Jan 6, 2020
1 parent b599b72 commit 30208a2
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 47 deletions.
39 changes: 14 additions & 25 deletions komga-webui/src/components/BrowseLibraries.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
class="sticky-bar"
:style="barStyle"
>
<!-- Action menu -->
<library-actions-menu v-if="library"
:library="library"/>

<v-toolbar-title>
<span>{{ libraryName }}</span>
<span>{{ library ? library.name : 'All libraries' }}</span>
<span class="ml-4 badge-count"
v-if="totalElements"
>
Expand All @@ -16,6 +20,7 @@

<v-spacer/>

<!-- Sort menu -->
<v-menu offset-y>
<template v-slot:activator="{on}">
<v-btn icon v-on="on">
Expand All @@ -41,19 +46,6 @@
</v-list-item>
</v-list>
</v-menu>

<v-menu offset-y v-if="libraryId !== 0">
<template v-slot:activator="{ on }">
<v-btn icon v-on="on">
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item @click="analyze()">
<v-list-item-title>Analyze</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-toolbar>

<v-container fluid class="px-6">
Expand All @@ -80,15 +72,16 @@

<script lang="ts">
import CardSeries from '@/components/CardSeries.vue'
import LibraryActionsMenu from '@/components/LibraryActionsMenu.vue'
import { LoadState } from '@/types/common'
import Vue from 'vue'
export default Vue.extend({
name: 'BrowseLibraries',
components: { CardSeries },
components: { LibraryActionsMenu, CardSeries },
data: () => {
return {
libraryName: '',
library: undefined as LibraryDto | undefined,
series: [] as SeriesDto[],
pagesState: [] as LoadState[],
pageSize: 20,
Expand Down Expand Up @@ -122,7 +115,7 @@ export default Vue.extend({
}
},
async created () {
this.libraryName = await this.getLibraryNameLazy(this.libraryId)
this.library = await this.getLibraryLazy(this.libraryId)
},
mounted () {
// fill series skeletons if an index is provided, so scroll position can be restored
Expand All @@ -137,7 +130,7 @@ export default Vue.extend({
},
beforeRouteUpdate (to, from, next) {
if (to.params.libraryId !== from.params.libraryId) {
this.libraryName = this.getLibraryNameLazy(Number(to.params.libraryId))
this.library = this.getLibraryLazy(Number(to.params.libraryId))
this.sortActive = this.parseQuerySortOrDefault(to.query.sort)
this.reloadData(Number(to.params.libraryId))
}
Expand Down Expand Up @@ -249,20 +242,16 @@ export default Vue.extend({
this.series.splice(page.number * page.size, page.size, ...page.content)
this.pagesState[page.number] = LoadState.Loaded
},
getLibraryNameLazy (libraryId: any): string {
getLibraryLazy (libraryId: any): LibraryDto | undefined {
if (libraryId !== 0) {
return (this.$store.getters.getLibraryById(libraryId)).name
return this.$store.getters.getLibraryById(libraryId)
} else {
return 'All libraries'
return undefined
}
},
analyze () {
this.$komgaLibraries.analyzeLibrary(this.libraryId)
}
}
})
</script>

<style scoped>
@import "../assets/css/badge.css";
@import "../assets/css/sticky-bar.css";
Expand Down
76 changes: 76 additions & 0 deletions komga-webui/src/components/LibraryActionsMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<template>
<div>
<v-menu offset-y v-if="isAdmin">
<template v-slot:activator="{ on }">
<v-btn icon v-on="on" @click.prevent="">
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item @click="scan">
<v-list-item-title>Scan library files</v-list-item-title>
</v-list-item>
<v-list-item @click="analyze">
<v-list-item-title>Analyze</v-list-item-title>
</v-list-item>
<v-list-item @click="promptDeleteLibrary"
class="list-warning">
<v-list-item-title>Delete</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>

<library-delete-dialog v-model="modalDeleteLibrary"
:library="library"
@deleted="navigateHome"
/>
</div>
</template>
<script lang="ts">
import LibraryDeleteDialog from '@/components/LibraryDeleteDialog.vue'
import Vue from 'vue'
export default Vue.extend({
name: 'library-actions-menu',
components: { LibraryDeleteDialog },
data: function () {
return {
modalDeleteLibrary: false
}
},
props: {
library: {
type: Object,
required: true
}
},
computed: {
isAdmin (): boolean {
return this.$store.getters.meAdmin
}
},
methods: {
scan () {
this.$komgaLibraries.scanLibrary(this.library)
},
analyze () {
this.$komgaLibraries.analyzeLibrary(this.library)
},
promptDeleteLibrary () {
this.modalDeleteLibrary = true
},
navigateHome () {
this.$router.push({ name: 'home' })
}
}
})
</script>
<style scoped>
.list-warning:hover {
background: #F44336;
}
.list-warning:hover .v-list-item__title {
color: white;
}
</style>
1 change: 1 addition & 0 deletions komga-webui/src/components/LibraryDeleteDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export default Vue.extend({
async deleteLibrary () {
try {
await this.$store.dispatch('deleteLibrary', this.library)
this.$emit('deleted', true)
} catch (e) {
this.showSnack(e.message)
}
Expand Down
18 changes: 15 additions & 3 deletions komga-webui/src/services/komga-libraries.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,23 @@ export default class KomgaLibrariesService {
}
}

async analyzeLibrary (libraryId: number) {
async scanLibrary (library: LibraryDto) {
try {
await this.http.post(`${API_LIBRARIES}/${libraryId}/analyze`)
await this.http.post(`${API_LIBRARIES}/${library.id}/scan`)
} catch (e) {
let msg = `An error occurred while trying to analyze library`
let msg = `An error occurred while trying to scan library '${library.name}'`
if (e.response.data.message) {
msg += `: ${e.response.data.message}`
}
throw new Error(msg)
}
}

async analyzeLibrary (library: LibraryDto) {
try {
await this.http.post(`${API_LIBRARIES}/${library.id}/analyze`)
} catch (e) {
let msg = `An error occurred while trying to analyze library '${library.name}'`
if (e.response.data.message) {
msg += `: ${e.response.data.message}`
}
Expand Down
20 changes: 4 additions & 16 deletions komga-webui/src/views/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@
</v-tooltip>
</v-list-item-content>
<v-list-item-action v-if="isAdmin">
<v-btn icon @click.prevent="promptDeleteLibrary(l)">
<v-icon>mdi-delete</v-icon>
</v-btn>
<library-actions-menu :library="l"/>
</v-list-item-action>
</v-list-item>

Expand Down Expand Up @@ -103,27 +101,21 @@
<v-content>
<router-view/>
</v-content>

<library-delete-dialog v-model="modalDeleteLibrary"
:library="libraryToDelete">
</library-delete-dialog>
</div>
</template>

<script lang="ts">
import LibraryDeleteDialog from '@/components/LibraryDeleteDialog.vue'
import LibraryActionsMenu from '@/components/LibraryActionsMenu.vue'
import SearchBox from '@/components/SearchBox.vue'
import Vue from 'vue'
export default Vue.extend({
name: 'home',
components: { LibraryDeleteDialog, SearchBox },
components: { LibraryActionsMenu, SearchBox },
data: function () {
return {
drawerVisible: this.$vuetify.breakpoint.lgAndUp,
modalAddLibrary: false,
modalDeleteLibrary: false,
libraryToDelete: {} as LibraryDto
modalAddLibrary: false
}
},
computed: {
Expand All @@ -138,10 +130,6 @@ export default Vue.extend({
toggleDrawer () {
this.drawerVisible = !this.drawerVisible
},
promptDeleteLibrary (library: LibraryDto) {
this.libraryToDelete = library
this.modalDeleteLibrary = true
},
logout () {
this.$store.dispatch('logout')
this.$router.push({ name: 'login' })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.gotson.komga.domain.service
import mu.KotlinLogging
import org.apache.commons.lang3.time.DurationFormatUtils
import org.gotson.komga.domain.model.Book
import org.gotson.komga.domain.model.Library
import org.gotson.komga.domain.persistence.BookRepository
import org.gotson.komga.domain.persistence.LibraryRepository
import org.springframework.scheduling.annotation.Async
Expand All @@ -21,7 +22,7 @@ class AsyncOrchestrator(
) {

@Async("periodicScanTaskExecutor")
fun scanAndAnalyze() {
fun scanAndAnalyzeAllLibraries() {
logger.info { "Starting periodic libraries scan" }
val libraries = libraryRepository.findAll()

Expand All @@ -37,6 +38,12 @@ class AsyncOrchestrator(
}
}

@Async("periodicScanTaskExecutor")
fun scanAndAnalyzeOneLibrary(library: Library) {
libraryScanner.scanRootFolder(library)
libraryScanner.analyzeUnknownBooks()
}

@Async("regenerateThumbnailsTaskExecutor")
fun regenerateAllThumbnails() {
logger.info { "Regenerate thumbnail for all books" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class LibraryLifecycle(

logger.info { "Trying to launch a scan for the newly added library: ${library.name}" }
try {
asyncOrchestrator.scanAndAnalyze()
asyncOrchestrator.scanAndAnalyzeAllLibraries()
} catch (e: RejectedExecutionException) {
logger.warn { "Another scan is already running, skipping" }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class PeriodicScannerController(
@Scheduled(cron = "#{@komgaProperties.librariesScanCron ?: '-'}")
fun scanRootFolder() {
try {
asyncOrchestrator.scanAndAnalyze()
asyncOrchestrator.scanAndAnalyzeAllLibraries()
} catch (e: RejectedExecutionException) {
logger.warn { "Another scan is already running, skipping" }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ class LibraryController(
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
}

@PostMapping("{libraryId}/scan")
@PreAuthorize("hasRole('ROLE_ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun scan(@PathVariable libraryId: Long) {
libraryRepository.findByIdOrNull(libraryId)?.let { library ->
try {
asyncOrchestrator.scanAndAnalyzeOneLibrary(library)
} catch (e: RejectedExecutionException) {
throw ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "Another scan task is already running")
}
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
}

@PostMapping("{libraryId}/analyze")
@PreAuthorize("hasRole('ROLE_ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
Expand Down

0 comments on commit 30208a2

Please sign in to comment.