Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6527e68e52 |
@ -50,7 +50,6 @@ class WebConfig: WebMvcConfigurer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun configurePathMatch(configurer: PathMatchConfigurer) {
|
override fun configurePathMatch(configurer: PathMatchConfigurer) {
|
||||||
|
|||||||
@ -0,0 +1,15 @@
|
|||||||
|
package no.iktdev.mediaprocessing.ui.dto
|
||||||
|
|
||||||
|
import no.iktdev.mediaprocessing.shared.common.contract.data.Event
|
||||||
|
|
||||||
|
data class DatabaseEntriesDelete(
|
||||||
|
val referenceId: String,
|
||||||
|
val eventId: String
|
||||||
|
)
|
||||||
|
|
||||||
|
data class DatabaseEventEntries(
|
||||||
|
val referenceId: String,
|
||||||
|
val events: List<Event>,
|
||||||
|
val created: Long,
|
||||||
|
val lastEventCreated: Long,
|
||||||
|
)
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
package no.iktdev.mediaprocessing.ui.socket
|
||||||
|
|
||||||
|
import no.iktdev.eventi.data.referenceId
|
||||||
|
import no.iktdev.eventi.database.executeWithStatus
|
||||||
|
import no.iktdev.eventi.database.toEpochSeconds
|
||||||
|
import no.iktdev.eventi.database.withDirtyRead
|
||||||
|
import no.iktdev.eventi.database.withTransaction
|
||||||
|
import no.iktdev.mediaprocessing.shared.common.database.cal.toEvent
|
||||||
|
import no.iktdev.mediaprocessing.shared.common.database.tables.events
|
||||||
|
import no.iktdev.mediaprocessing.ui.dto.DatabaseEntriesDelete
|
||||||
|
import no.iktdev.mediaprocessing.ui.dto.DatabaseEventEntries
|
||||||
|
import no.iktdev.mediaprocessing.ui.eventDatabase
|
||||||
|
import no.iktdev.mediaprocessing.ui.eventsManager
|
||||||
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
|
import org.jetbrains.exposed.sql.and
|
||||||
|
import org.jetbrains.exposed.sql.deleteWhere
|
||||||
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.messaging.handler.annotation.MessageMapping
|
||||||
|
import org.springframework.messaging.handler.annotation.Payload
|
||||||
|
import org.springframework.messaging.simp.SimpMessagingTemplate
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
class DatabaseEntriesTopic(
|
||||||
|
@Autowired private val template: SimpMessagingTemplate?
|
||||||
|
) {
|
||||||
|
|
||||||
|
private fun push(destination: String, payload: Any) = template?.convertAndSend(destination, payload)
|
||||||
|
private fun push(payload: Any) = template?.convertAndSend(payload)
|
||||||
|
|
||||||
|
@MessageMapping("/database/events/pull")
|
||||||
|
fun pullAllDatabaseEvents() {
|
||||||
|
val result = withDirtyRead(eventDatabase.database) {
|
||||||
|
events.selectAll().toEvent()
|
||||||
|
.groupBy { it.referenceId() }.onEach { (t, u) ->
|
||||||
|
u.sortedBy { x -> x.metadata.created }
|
||||||
|
}
|
||||||
|
} ?: emptyMap()
|
||||||
|
result.map { it -> DatabaseEventEntries(
|
||||||
|
referenceId = it.key,
|
||||||
|
events = it.value,
|
||||||
|
created = it.value.first().metadata.created.toEpochSeconds() * 1000L,
|
||||||
|
lastEventCreated = it.value.last().metadata.created.toEpochSeconds() * 1000L
|
||||||
|
) }.also {
|
||||||
|
push(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MessageMapping("/database/events/delete")
|
||||||
|
fun deleteEvent(@Payload payload: DatabaseEntriesDelete) {
|
||||||
|
val status = executeWithStatus (eventDatabase.database) {
|
||||||
|
events.deleteWhere {
|
||||||
|
(referenceId eq payload.referenceId) and
|
||||||
|
(eventId eq payload.eventId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
pullAllDatabaseEvents()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MessageMapping("/database/tasks")
|
||||||
|
fun pullAllDatabaseTasks() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,7 +5,6 @@ import no.iktdev.eventi.data.referenceId
|
|||||||
import no.iktdev.eventi.database.toEpochSeconds
|
import no.iktdev.eventi.database.toEpochSeconds
|
||||||
import no.iktdev.eventi.database.withDirtyRead
|
import no.iktdev.eventi.database.withDirtyRead
|
||||||
import no.iktdev.eventi.database.withTransaction
|
import no.iktdev.eventi.database.withTransaction
|
||||||
import no.iktdev.mediaprocessing.shared.common.contract.Events
|
|
||||||
import no.iktdev.mediaprocessing.shared.common.contract.ProcessType
|
import no.iktdev.mediaprocessing.shared.common.contract.ProcessType
|
||||||
import no.iktdev.mediaprocessing.shared.common.contract.data.*
|
import no.iktdev.mediaprocessing.shared.common.contract.data.*
|
||||||
import no.iktdev.mediaprocessing.shared.common.contract.dto.OperationEvents
|
import no.iktdev.mediaprocessing.shared.common.contract.dto.OperationEvents
|
||||||
@ -19,6 +18,7 @@ import no.iktdev.mediaprocessing.shared.common.task.TaskType
|
|||||||
import no.iktdev.mediaprocessing.ui.WebSocketMonitoringService
|
import no.iktdev.mediaprocessing.ui.WebSocketMonitoringService
|
||||||
import no.iktdev.mediaprocessing.ui.eventDatabase
|
import no.iktdev.mediaprocessing.ui.eventDatabase
|
||||||
import no.iktdev.mediaprocessing.ui.socket.a2a.ProcesserListenerService
|
import no.iktdev.mediaprocessing.ui.socket.a2a.ProcesserListenerService
|
||||||
|
import no.iktdev.mediaprocessing.ui.socket.impl.SocketListener
|
||||||
import org.jetbrains.exposed.sql.selectAll
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.messaging.handler.annotation.MessageMapping
|
import org.springframework.messaging.handler.annotation.MessageMapping
|
||||||
@ -85,6 +85,7 @@ class ProcesserTasksTopic(
|
|||||||
val encode: Status = Status.Skipped,
|
val encode: Status = Status.Skipped,
|
||||||
val extract: Status = Status.Skipped,
|
val extract: Status = Status.Skipped,
|
||||||
val convert: Status = Status.Skipped,
|
val convert: Status = Status.Skipped,
|
||||||
|
val completed: Status = Status.Awaiting,
|
||||||
val created: Long
|
val created: Long
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,35 @@
|
|||||||
|
package no.iktdev.mediaprocessing.ui.socket
|
||||||
|
|
||||||
|
import no.iktdev.eventi.database.withTransaction
|
||||||
|
import no.iktdev.mediaprocessing.shared.common.database.cal.toTask
|
||||||
|
import no.iktdev.mediaprocessing.shared.common.database.tables.tasks
|
||||||
|
import no.iktdev.mediaprocessing.shared.common.task.Task
|
||||||
|
import no.iktdev.mediaprocessing.ui.eventDatabase
|
||||||
|
import no.iktdev.mediaprocessing.ui.socket.impl.SocketListener
|
||||||
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.messaging.handler.annotation.MessageMapping
|
||||||
|
import org.springframework.messaging.simp.SimpMessagingTemplate
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class TaskTableTopic(
|
||||||
|
@Autowired private val message: SimpMessagingTemplate?,
|
||||||
|
) : SocketListener(message) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
data class TaskGroup(
|
||||||
|
val referenceId: String,
|
||||||
|
val tasks: List<Task>
|
||||||
|
)
|
||||||
|
|
||||||
|
@MessageMapping("/taskTable/all")
|
||||||
|
fun pullAllTasks() {
|
||||||
|
val result = withTransaction(eventDatabase.database) {
|
||||||
|
tasks.selectAll().toTask()
|
||||||
|
.groupBy { it.referenceId }.map { g -> TaskGroup(g.key, g.value) }
|
||||||
|
} ?: emptyList()
|
||||||
|
template?.convertAndSend("/topic/taskTable/all", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,10 +7,9 @@ import no.iktdev.mediaprocessing.shared.common.task.Task
|
|||||||
import no.iktdev.mediaprocessing.ui.UIEnv
|
import no.iktdev.mediaprocessing.ui.UIEnv
|
||||||
import no.iktdev.mediaprocessing.ui.WebSocketMonitoringService
|
import no.iktdev.mediaprocessing.ui.WebSocketMonitoringService
|
||||||
import no.iktdev.mediaprocessing.ui.log
|
import no.iktdev.mediaprocessing.ui.log
|
||||||
import no.iktdev.mediaprocessing.ui.socket.SocketClient
|
import no.iktdev.mediaprocessing.ui.socket.impl.SocketClient
|
||||||
import no.iktdev.mediaprocessing.ui.socket.SocketMessageHandler
|
import no.iktdev.mediaprocessing.ui.socket.impl.SocketMessageHandler
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.messaging.simp.SimpMessagingTemplate
|
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package no.iktdev.mediaprocessing.ui.socket
|
package no.iktdev.mediaprocessing.ui.socket.impl
|
||||||
|
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import org.springframework.messaging.simp.stomp.StompCommand
|
import org.springframework.messaging.simp.stomp.StompCommand
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package no.iktdev.mediaprocessing.ui.socket
|
package no.iktdev.mediaprocessing.ui.socket.impl
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.messaging.simp.SimpMessagingTemplate
|
import org.springframework.messaging.simp.SimpMessagingTemplate
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package no.iktdev.mediaprocessing.ui.socket
|
package no.iktdev.mediaprocessing.ui.socket.impl
|
||||||
|
|
||||||
import org.springframework.messaging.simp.stomp.StompHeaders
|
import org.springframework.messaging.simp.stomp.StompHeaders
|
||||||
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter
|
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter
|
||||||
@ -28,6 +28,7 @@ import InputIcon from '@mui/icons-material/Input';
|
|||||||
import NotStartedIcon from '@mui/icons-material/NotStarted';
|
import NotStartedIcon from '@mui/icons-material/NotStarted';
|
||||||
import EventsPage from './app/page/EventsPage';
|
import EventsPage from './app/page/EventsPage';
|
||||||
import TableChartIcon from '@mui/icons-material/TableChart';
|
import TableChartIcon from '@mui/icons-material/TableChart';
|
||||||
|
import SubscriptionsIcon from '@mui/icons-material/Subscriptions';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const client = useStompClient();
|
const client = useStompClient();
|
||||||
@ -94,21 +95,22 @@ function App() {
|
|||||||
}}>
|
}}>
|
||||||
<QueueIcon />
|
<QueueIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton onClick={() => window.location.href = "/tasks"} sx={{
|
<IconButton onClick={() => window.location.href = "/events"} sx={{
|
||||||
...iconHeight
|
...iconHeight
|
||||||
}}>
|
}}>
|
||||||
<TableChartIcon />
|
<SubscriptionsIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
display: "block",
|
display: "block",
|
||||||
maxHeight: window.screen.height - 70,
|
maxHeight: window.innerHeight - 70,
|
||||||
height: window.screen.height - 70,
|
height: window.innerHeight - 70,
|
||||||
width: "100vw",
|
width: "100vw",
|
||||||
maxWidth: "100vw"
|
maxWidth: "100vw"
|
||||||
}}>
|
}}>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
|
<Route path='/events' element={<EventsPage />} />
|
||||||
<Route path='/processer' element={<EventsPage />} />
|
<Route path='/processer' element={<EventsPage />} />
|
||||||
<Route path='/unprocessed' element={<UnprocessedFilesPage />} />
|
<Route path='/unprocessed' element={<UnprocessedFilesPage />} />
|
||||||
<Route path='/files' element={<ExplorePage />} />
|
<Route path='/files' element={<ExplorePage />} />
|
||||||
|
|||||||
@ -4,3 +4,18 @@ export interface CoordinatorOperationRequest {
|
|||||||
source: string;
|
source: string;
|
||||||
mode: "FLOW" | "MANUAL";
|
mode: "FLOW" | "MANUAL";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Event {
|
||||||
|
referenceId: string;
|
||||||
|
eventId: string;
|
||||||
|
event: string;
|
||||||
|
data: any;
|
||||||
|
created: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DatabaseEventEntry {
|
||||||
|
referenceId: string;
|
||||||
|
events: Array<Event>
|
||||||
|
created: number;
|
||||||
|
lastEventCreated: number;
|
||||||
|
}
|
||||||
@ -25,7 +25,7 @@ import SimpleTable from "../features/table/sortableTable";
|
|||||||
import { UnixTimestamp } from "../features/UxTc";
|
import { UnixTimestamp } from "../features/UxTc";
|
||||||
import ProgressbarWithLabel from "../features/components/ProgressbarWithLabel";
|
import ProgressbarWithLabel from "../features/components/ProgressbarWithLabel";
|
||||||
import { LinearProgress, Typography } from "@mui/material";
|
import { LinearProgress, Typography } from "@mui/material";
|
||||||
import { stat } from "fs";
|
import SaveIcon from '@mui/icons-material/Save';
|
||||||
|
|
||||||
interface RawNodeDatum {
|
interface RawNodeDatum {
|
||||||
name: string;
|
name: string;
|
||||||
@ -107,6 +107,10 @@ function renderCustomNodeElement(nodeData: CustomNodeElementProps): JSX.Element
|
|||||||
workIcon = <AutoAwesomeMotionIcon />
|
workIcon = <AutoAwesomeMotionIcon />
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "completed": {
|
||||||
|
workIcon = <SaveIcon />
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -163,6 +167,16 @@ const transformToSteps = (state: ContentEventState): RawNodeDatum => ({
|
|||||||
type: "convert",
|
type: "convert",
|
||||||
status: state.extract
|
status: state.extract
|
||||||
},
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: state.referenceId,
|
||||||
|
attributes: {
|
||||||
|
type: "completed",
|
||||||
|
status: state.completed
|
||||||
|
},
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -181,7 +195,7 @@ export default function EventsPage() {
|
|||||||
const items = events.items.map((event: ContentEventState) => {
|
const items = events.items.map((event: ContentEventState) => {
|
||||||
return {
|
return {
|
||||||
rowId: event.referenceId,
|
rowId: event.referenceId,
|
||||||
title: event.referenceId,
|
title: event.title ?? event.referenceId,
|
||||||
item: event
|
item: event
|
||||||
} as ExpandableItemRow
|
} as ExpandableItemRow
|
||||||
});
|
});
|
||||||
@ -210,7 +224,7 @@ export default function EventsPage() {
|
|||||||
return (<>
|
return (<>
|
||||||
<div id="treeWrapper" style={{
|
<div id="treeWrapper" style={{
|
||||||
...linkThicc,
|
...linkThicc,
|
||||||
width: '150px', height: '90px'
|
width: '200px', height: '90px'
|
||||||
}} ref={containerRef}>
|
}} ref={containerRef}>
|
||||||
<Tree
|
<Tree
|
||||||
dimensions={dimensions}
|
dimensions={dimensions}
|
||||||
|
|||||||
@ -43,6 +43,7 @@ export interface ContentEventState {
|
|||||||
encode: Status
|
encode: Status
|
||||||
extract: Status
|
extract: Status
|
||||||
convert: Status
|
convert: Status
|
||||||
|
completed: Status
|
||||||
created: number
|
created: number
|
||||||
encodeWork: ProcesserEventInfo
|
encodeWork: ProcesserEventInfo
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user