cleanups
This commit is contained in:
parent
70ed4185fd
commit
aecc8c5973
4 changed files with 32 additions and 62 deletions
|
@ -32,48 +32,31 @@ class UpnpController(
|
|||
@PathVariable("uid") uid: String,
|
||||
request: HttpServletRequest
|
||||
): Resource {
|
||||
logger.info { "GET ICON request from ${request.remoteAddr}: ${request.requestURI}" }
|
||||
logger.info { "GET icon request from ${request.remoteAddr}: ${request.requestURI}" }
|
||||
return InputStreamResource(MediaServer.iconResource());
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
method = [GET, HEAD], value = [
|
||||
method = [GET, HEAD, POST], value = [
|
||||
"/dev/{uid}/desc",
|
||||
"/dev/{uid}/svc/upnp-org/ContentDirectory/desc",
|
||||
"/dev/{uid}/svc/upnp-org/ConnectionManager/desc"
|
||||
],
|
||||
produces = ["application/xml;charset=utf8", "text/xml;charset=utf8"]
|
||||
)
|
||||
fun handleGet(
|
||||
@PathVariable("uid") uid: String,
|
||||
request: HttpServletRequest
|
||||
): ResponseEntity<Any> {
|
||||
logger.info { "GET request from ${request.remoteAddr}: ${request.requestURI}" }
|
||||
val r = upnpStreamProcessor.processMessage(streamRequestMapper.map(request))
|
||||
return ResponseEntity(
|
||||
r.body,
|
||||
HttpHeaders().also { h -> r.headers.entries.forEach { h.add(it.key, it.value.joinToString { it }) } },
|
||||
HttpStatusCode.valueOf(r.operation.statusCode)
|
||||
)
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
method = [POST], value = [
|
||||
"/dev/{uid}/svc/upnp-org/ConnectionManager/desc",
|
||||
"/dev/{uid}/svc/upnp-org/ContentDirectory/action"
|
||||
],
|
||||
produces = ["application/xml;charset=utf8", "text/xml;charset=utf8"]
|
||||
)
|
||||
fun handlePost(
|
||||
fun handleUpnp(
|
||||
@PathVariable("uid") uid: String,
|
||||
request: HttpServletRequest
|
||||
): ResponseEntity<Any> {
|
||||
logger.info { "POST request from ${request.remoteAddr}: ${request.requestURI}" }
|
||||
val r = upnpStreamProcessor.processMessage(streamRequestMapper.map(request))
|
||||
return ResponseEntity(
|
||||
r.body,
|
||||
HttpHeaders().also { h -> r.headers.entries.forEach { h.add(it.key, it.value.joinToString { it }) } },
|
||||
HttpStatusCode.valueOf(r.operation.statusCode)
|
||||
)
|
||||
logger.info { "Upnp ${request.method} request from ${request.remoteAddr}: ${request.requestURI}" }
|
||||
return with(upnpStreamProcessor.processMessage(streamRequestMapper.map(request))) {
|
||||
ResponseEntity(
|
||||
body,
|
||||
HttpHeaders().also { h -> headers.entries.forEach { e -> h.add(e.key, e.value.joinToString { it }) } },
|
||||
HttpStatusCode.valueOf(operation.statusCode)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object : KLogging()
|
||||
|
|
|
@ -14,7 +14,7 @@ import java.util.function.Consumer
|
|||
|
||||
|
||||
@Component
|
||||
class MediaDB(
|
||||
class NextcloudDB(
|
||||
private val nextcloudConfig: NextcloudConfigDiscovery,
|
||||
private val mimetypeRepository: MimetypeRepository,
|
||||
private val filecacheRepository: FilecacheRepository,
|
|
@ -1,25 +1,26 @@
|
|||
package net.schowek.nextclouddlna.nextcloud.content
|
||||
|
||||
import jakarta.annotation.PostConstruct
|
||||
import mu.KLogging
|
||||
import net.schowek.nextclouddlna.nextcloud.MediaDB
|
||||
import net.schowek.nextclouddlna.nextcloud.NextcloudDB
|
||||
import org.springframework.scheduling.annotation.Scheduled
|
||||
import org.springframework.stereotype.Component
|
||||
import java.time.Instant
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.regex.Pattern
|
||||
|
||||
|
||||
@Component
|
||||
class ContentTreeProvider(
|
||||
private val mediaDB: MediaDB
|
||||
private val nextcloudDB: NextcloudDB
|
||||
) {
|
||||
private var tree = buildContentTree()
|
||||
private var lastMTime = 0L
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 60, initialDelay = 1000 * 60)
|
||||
@Scheduled(fixedDelay = REBUILD_TREE_DELAY_IN_MS, initialDelay = REBUILD_TREE_INIT_DELAY_IN_MS)
|
||||
final fun rebuildTree() {
|
||||
val maxMtime: Long = mediaDB.maxMtime()
|
||||
if (lastMTime < maxMtime) {
|
||||
val maxMtime: Long = nextcloudDB.maxMtime()
|
||||
val now = Instant.now().epochSecond
|
||||
if (lastMTime < maxMtime || lastMTime + MAX_REBUILD_OFFSET_IN_S > now) {
|
||||
logger.info("ContentTree seems to be outdated - Loading...")
|
||||
this.tree = buildContentTree()
|
||||
lastMTime = maxMtime
|
||||
|
@ -30,12 +31,12 @@ class ContentTreeProvider(
|
|||
val tree = ContentTree()
|
||||
val root = ContentNode(0, -1, "ROOT")
|
||||
tree.addNode(root)
|
||||
mediaDB.mainNodes().forEach { n ->
|
||||
nextcloudDB.mainNodes().forEach { n ->
|
||||
root.addNode(n)
|
||||
fillNode(n, tree)
|
||||
}
|
||||
logger.info("Getting content from group folders...")
|
||||
mediaDB.groupFolders().forEach { n ->
|
||||
nextcloudDB.groupFolders().forEach { n ->
|
||||
logger.info(" Group folder found: {}", n.name)
|
||||
root.addNode(n)
|
||||
fillNode(n, tree)
|
||||
|
@ -48,7 +49,7 @@ class ContentTreeProvider(
|
|||
private fun loadThumbnails(tree: ContentTree) {
|
||||
logger.info("Loading thumbnails...")
|
||||
val thumbsCount = AtomicInteger()
|
||||
mediaDB.processThumbnails { thumb ->
|
||||
nextcloudDB.processThumbnails { thumb ->
|
||||
val id = getItemIdForThumbnail(thumb)
|
||||
if (id != null) {
|
||||
val item = tree.getItem(id)
|
||||
|
@ -72,7 +73,7 @@ class ContentTreeProvider(
|
|||
}
|
||||
|
||||
private fun fillNode(node: ContentNode, tree: ContentTree) {
|
||||
mediaDB.appendChildren(node)
|
||||
nextcloudDB.appendChildren(node)
|
||||
tree.addNode(node)
|
||||
node.getItems().forEach { item ->
|
||||
logger.debug("Adding item[{}]: " + item.path, item.id)
|
||||
|
@ -87,7 +88,11 @@ class ContentTreeProvider(
|
|||
fun getItem(id: String): ContentItem? = tree.getItem(id)
|
||||
fun getNode(id: String): ContentNode? = tree.getNode(id)
|
||||
|
||||
companion object : KLogging()
|
||||
companion object : KLogging() {
|
||||
const val REBUILD_TREE_DELAY_IN_MS = 1000 * 60L // 1m
|
||||
const val REBUILD_TREE_INIT_DELAY_IN_MS = 1000 * 60L // 1m
|
||||
const val MAX_REBUILD_OFFSET_IN_S = 60 * 60 * 12L // 12h
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,8 +12,9 @@ class StreamRequestMapper {
|
|||
fun map(request: HttpServletRequest): StreamRequestMessage {
|
||||
val requestMessage = StreamRequestMessage(
|
||||
UpnpRequest.Method.getByHttpName(request.method),
|
||||
URI(request.requestURI)
|
||||
// TODO put request.inputStream.readBytes() here
|
||||
URI(request.requestURI),
|
||||
// TODO check if request is binary and create body as unwrapped byteArray
|
||||
String(request.inputStream.readBytes())
|
||||
)
|
||||
if (requestMessage.operation.method == UpnpRequest.Method.UNKNOWN) {
|
||||
logger.warn("Method not supported by UPnP stack: {}", request.method)
|
||||
|
@ -22,28 +23,9 @@ class StreamRequestMapper {
|
|||
|
||||
requestMessage.connection = MyHttpServerConnection(request)
|
||||
requestMessage.headers = createHeaders(request)
|
||||
setBody(request, requestMessage)
|
||||
return requestMessage
|
||||
}
|
||||
|
||||
private fun setBody(
|
||||
request: HttpServletRequest,
|
||||
requestMessage: StreamRequestMessage
|
||||
) {
|
||||
val bodyBytes = request.inputStream.readBytes()
|
||||
|
||||
logger.debug(" Reading request body bytes: " + bodyBytes.size)
|
||||
if (bodyBytes.isNotEmpty() && requestMessage.isContentTypeMissingOrText) {
|
||||
logger.debug("Request contains textual entity body, converting then setting string on message")
|
||||
requestMessage.setBodyCharacters(bodyBytes)
|
||||
} else if (bodyBytes.isNotEmpty()) {
|
||||
logger.debug("Request contains binary entity body, setting bytes on message")
|
||||
requestMessage.setBody(UpnpMessage.BodyType.BYTES, bodyBytes)
|
||||
} else {
|
||||
logger.debug("Request did not contain entity body")
|
||||
}
|
||||
}
|
||||
|
||||
private fun createHeaders(request: HttpServletRequest): UpnpHeaders {
|
||||
val headers = mutableMapOf<String, List<String>>()
|
||||
with(request.headerNames) {
|
||||
|
|
Loading…
Reference in a new issue