mirror of https://github.com/usbharu/Hideout.git
Merge pull request #196 from usbharu/feature/local-file-controller
Feature/local file controller
This commit is contained in:
commit
66c003ce8e
|
@ -20,6 +20,7 @@ constructor(
|
||||||
var following: String?
|
var following: String?
|
||||||
) : Object(add(type, "Person")), HasId, HasName {
|
) : Object(add(type, "Person")), HasId, HasName {
|
||||||
|
|
||||||
|
@Suppress("CyclomaticComplexMethod", "CognitiveComplexMethod")
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (javaClass != other?.javaClass) return false
|
if (javaClass != other?.javaClass) return false
|
||||||
|
@ -43,6 +44,7 @@ constructor(
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("CyclomaticComplexMethod")
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
var result = super.hashCode()
|
var result = super.hashCode()
|
||||||
result = 31 * result + name.hashCode()
|
result = 31 * result + name.hashCode()
|
||||||
|
|
|
@ -186,6 +186,9 @@ class SecurityConfig {
|
||||||
authorize(POST, "/api/v1/accounts", permitAll)
|
authorize(POST, "/api/v1/accounts", permitAll)
|
||||||
|
|
||||||
authorize("/auth/sign_up", hasRole("ANONYMOUS"))
|
authorize("/auth/sign_up", hasRole("ANONYMOUS"))
|
||||||
|
authorize(GET, "/files", permitAll)
|
||||||
|
authorize(GET, "/users/*/icon.jpg", permitAll)
|
||||||
|
authorize(GET, "/users/*/header.jpg", permitAll)
|
||||||
|
|
||||||
authorize(GET, "/api/v1/accounts/verify_credentials", hasAnyScope("read", "read:accounts"))
|
authorize(GET, "/api/v1/accounts/verify_credentials", hasAnyScope("read", "read:accounts"))
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@ data class S3StorageConfig(
|
||||||
val secretKey: String
|
val secretKey: String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* メディアの保存にローカルファイルシステムを使用する際のコンフィグ
|
* メディアの保存にローカルファイルシステムを使用する際のコンフィグ
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package dev.usbharu.hideout.core.interfaces.api.media
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.application.config.LocalStorageConfig
|
||||||
|
import dev.usbharu.hideout.core.service.media.FileTypeDeterminationService
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
|
||||||
|
import org.springframework.core.io.ClassPathResource
|
||||||
|
import org.springframework.core.io.PathResource
|
||||||
|
import org.springframework.core.io.Resource
|
||||||
|
import org.springframework.http.MediaType
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.name
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@ConditionalOnProperty("hideout.storage.type", havingValue = "local", matchIfMissing = true)
|
||||||
|
class LocalFileController(
|
||||||
|
localStorageConfig: LocalStorageConfig,
|
||||||
|
private val fileTypeDeterminationService: FileTypeDeterminationService
|
||||||
|
) {
|
||||||
|
|
||||||
|
private val savePath = Path.of(localStorageConfig.path).toAbsolutePath()
|
||||||
|
|
||||||
|
@GetMapping("/files/{id}")
|
||||||
|
fun files(@PathVariable("id") id: String): ResponseEntity<Resource> {
|
||||||
|
val name = Path.of(id).name
|
||||||
|
val path = savePath.resolve(name)
|
||||||
|
|
||||||
|
val mimeType = fileTypeDeterminationService.fileType(path, name)
|
||||||
|
val pathResource = PathResource(path)
|
||||||
|
|
||||||
|
return ResponseEntity
|
||||||
|
.ok()
|
||||||
|
.contentType(MediaType(mimeType.type, mimeType.subtype))
|
||||||
|
.contentLength(pathResource.contentLength())
|
||||||
|
.body(pathResource)
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/users/{user}/icon.jpg", "/users/{user}/header.jpg")
|
||||||
|
fun icons(): ResponseEntity<Resource> {
|
||||||
|
val pathResource = ClassPathResource("icon.png")
|
||||||
|
return ResponseEntity
|
||||||
|
.ok()
|
||||||
|
.contentType(MediaType.IMAGE_PNG)
|
||||||
|
.contentLength(pathResource.contentLength())
|
||||||
|
.body(pathResource)
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,8 +12,6 @@ import kotlin.io.path.createDirectories
|
||||||
import kotlin.io.path.deleteIfExists
|
import kotlin.io.path.deleteIfExists
|
||||||
import kotlin.io.path.outputStream
|
import kotlin.io.path.outputStream
|
||||||
|
|
||||||
@Service
|
|
||||||
@ConditionalOnProperty("hideout.storage.type", havingValue = "local", matchIfMissing = true)
|
|
||||||
/**
|
/**
|
||||||
* ローカルファイルシステムにメディアを保存します
|
* ローカルファイルシステムにメディアを保存します
|
||||||
*
|
*
|
||||||
|
@ -23,8 +21,11 @@ import kotlin.io.path.outputStream
|
||||||
* @param applicationConfig ApplicationConfig
|
* @param applicationConfig ApplicationConfig
|
||||||
* @param localStorageConfig LocalStorageConfig
|
* @param localStorageConfig LocalStorageConfig
|
||||||
*/
|
*/
|
||||||
|
@Service
|
||||||
|
@ConditionalOnProperty("hideout.storage.type", havingValue = "local", matchIfMissing = true)
|
||||||
class LocalFileSystemMediaDataStore(
|
class LocalFileSystemMediaDataStore(
|
||||||
applicationConfig: ApplicationConfig, localStorageConfig: LocalStorageConfig
|
applicationConfig: ApplicationConfig,
|
||||||
|
localStorageConfig: LocalStorageConfig
|
||||||
) : MediaDataStore {
|
) : MediaDataStore {
|
||||||
|
|
||||||
private val savePath: Path = Path.of(localStorageConfig.path).toAbsolutePath()
|
private val savePath: Path = Path.of(localStorageConfig.path).toAbsolutePath()
|
||||||
|
@ -39,7 +40,6 @@ class LocalFileSystemMediaDataStore(
|
||||||
val fileSavePath = buildSavePath(savePath, dataMediaSave.name)
|
val fileSavePath = buildSavePath(savePath, dataMediaSave.name)
|
||||||
val thumbnailSavePath = buildSavePath(savePath, "thumbnail-" + dataMediaSave.name)
|
val thumbnailSavePath = buildSavePath(savePath, "thumbnail-" + dataMediaSave.name)
|
||||||
|
|
||||||
|
|
||||||
dataMediaSave.thumbnailInputStream?.inputStream()?.use {
|
dataMediaSave.thumbnailInputStream?.inputStream()?.use {
|
||||||
it.buffered().use { bufferedInputStream ->
|
it.buffered().use { bufferedInputStream ->
|
||||||
thumbnailSavePath.outputStream(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
|
thumbnailSavePath.outputStream(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
|
||||||
|
@ -51,7 +51,6 @@ class LocalFileSystemMediaDataStore(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dataMediaSave.fileInputStream.inputStream().use {
|
dataMediaSave.fileInputStream.inputStream().use {
|
||||||
it.buffered().use { bufferedInputStream ->
|
it.buffered().use { bufferedInputStream ->
|
||||||
fileSavePath.outputStream(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
|
fileSavePath.outputStream(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
|
||||||
|
@ -60,7 +59,9 @@ class LocalFileSystemMediaDataStore(
|
||||||
}
|
}
|
||||||
|
|
||||||
return SuccessSavedMedia(
|
return SuccessSavedMedia(
|
||||||
dataMediaSave.name, publicUrl + dataMediaSave.name, publicUrl + "thumbnail-" + dataMediaSave.name
|
dataMediaSave.name,
|
||||||
|
publicUrl + dataMediaSave.name,
|
||||||
|
publicUrl + "thumbnail-" + dataMediaSave.name
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +83,9 @@ class LocalFileSystemMediaDataStore(
|
||||||
|
|
||||||
logger.info("SUCCESS Media upload. {}", dataSaveRequest.name)
|
logger.info("SUCCESS Media upload. {}", dataSaveRequest.name)
|
||||||
return SuccessSavedMedia(
|
return SuccessSavedMedia(
|
||||||
dataSaveRequest.name, publicUrl + dataSaveRequest.name, publicUrl + "thumbnail-" + dataSaveRequest.name
|
dataSaveRequest.name,
|
||||||
|
publicUrl + dataSaveRequest.name,
|
||||||
|
publicUrl + "thumbnail-" + dataSaveRequest.name
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue