Merge pull request #196 from usbharu/feature/local-file-controller

Feature/local file controller
This commit is contained in:
usbharu 2023-12-06 22:28:14 +09:00 committed by GitHub
commit 66c003ce8e
5 changed files with 65 additions and 8 deletions

View File

@ -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()

View File

@ -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"))

View File

@ -42,7 +42,6 @@ data class S3StorageConfig(
val secretKey: String val secretKey: String
) )
/** /**
* メディアの保存にローカルファイルシステムを使用する際のコンフィグ * メディアの保存にローカルファイルシステムを使用する際のコンフィグ
* *

View File

@ -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)
}
}

View File

@ -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
) )
} }