mirror of
https://github.com/gotson/komga.git
synced 2026-01-03 22:36:07 +01:00
add FileSystemController API endpoint
This commit is contained in:
parent
2af4bdbcf1
commit
ee57007aa8
2 changed files with 116 additions and 0 deletions
|
|
@ -0,0 +1,67 @@
|
|||
package org.gotson.komga.interfaces.web.rest
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.web.server.ResponseStatusException
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.streams.toList
|
||||
|
||||
@RestController
|
||||
@RequestMapping("api/v1/filesystem", produces = [MediaType.APPLICATION_JSON_VALUE])
|
||||
class FileSystemController {
|
||||
|
||||
private val fs = FileSystems.getDefault()
|
||||
|
||||
@GetMapping
|
||||
fun getDirectoryListing(
|
||||
@RequestParam(name = "path", required = false) path: String?
|
||||
): DirectoryListingDto =
|
||||
if (path.isNullOrEmpty()) {
|
||||
DirectoryListingDto(
|
||||
directories = fs.rootDirectories.map { it.toDto() }
|
||||
)
|
||||
} else {
|
||||
val p = fs.getPath(path)
|
||||
if (!p.isAbsolute) throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Path must be absolute")
|
||||
try {
|
||||
DirectoryListingDto(
|
||||
parent = (p.parent ?: "").toString(),
|
||||
directories = Files.list(p).use { dirStream ->
|
||||
dirStream
|
||||
.filter { Files.isDirectory(it) }
|
||||
.sorted()
|
||||
.map { it.toDto() }
|
||||
.toList()
|
||||
}
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Path does not exist")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
data class DirectoryListingDto(
|
||||
val parent: String? = null,
|
||||
val directories: List<PathDto>
|
||||
)
|
||||
|
||||
data class PathDto(
|
||||
val type: String,
|
||||
val name: String,
|
||||
val path: String
|
||||
)
|
||||
|
||||
fun Path.toDto(): PathDto =
|
||||
PathDto(
|
||||
type = if (Files.isDirectory(this)) "directory" else "file",
|
||||
name = (fileName ?: this).toString(),
|
||||
path = toString()
|
||||
)
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package org.gotson.komga.interfaces.web.rest
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.security.test.context.support.WithAnonymousUser
|
||||
import org.springframework.security.test.context.support.WithMockUser
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension
|
||||
import org.springframework.test.web.servlet.MockMvc
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
|
||||
import java.nio.file.Files
|
||||
|
||||
@ExtendWith(SpringExtension::class)
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc(printOnlyOnFailure = false)
|
||||
class FileSystemControllerTest(
|
||||
@Autowired private val mockMvc: MockMvc
|
||||
) {
|
||||
private val route = "/api/v1/filesystem"
|
||||
|
||||
@Test
|
||||
@WithAnonymousUser
|
||||
fun `given anonymous user when getDirectoryListing then return unauthorized`() {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(route))
|
||||
.andExpect(MockMvcResultMatchers.status().isUnauthorized)
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = ["USER"])
|
||||
fun `given relative path param when getDirectoryListing then return bad request`() {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(route)
|
||||
.param("path", "."))
|
||||
.andExpect(MockMvcResultMatchers.status().isBadRequest)
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = ["USER"])
|
||||
fun `given non-existent path param when getDirectoryListing then return bad request`() {
|
||||
val parent = Files.createTempDirectory(null)
|
||||
Files.delete(parent)
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(route)
|
||||
.param("path", parent.toString()))
|
||||
.andExpect(MockMvcResultMatchers.status().isBadRequest)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue