Skip to content

Commit

Permalink
Merge pull request #208 from LordTocs/dev
Browse files Browse the repository at this point in the history
Beta Build
  • Loading branch information
LordTocs authored Sep 4, 2024
2 parents 82db7e5 + 0f6ce0d commit f2e56ac
Show file tree
Hide file tree
Showing 39 changed files with 799 additions and 198 deletions.
27 changes: 17 additions & 10 deletions libs/castmate-core/src/info/info-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { defineIPCFunc } from "../util/electron"

import electronUpdater, { autoUpdater, UpdateInfo, CancellationToken } from "electron-updater"
import { UpdateData } from "castmate-schema"
import { globalLogger } from "../logging/logging"
import { globalLogger, usePluginLogger } from "../logging/logging"
import path from "path"

import semver from "semver"
Expand All @@ -15,6 +15,8 @@ interface StartInfo {
lastVer: string
}

const logger = usePluginLogger("info-manager")

export const InfoService = Service(
class {
startInfo: StartInfo | undefined
Expand Down Expand Up @@ -81,18 +83,23 @@ export const InfoService = Service(
}

async checkUpdate() {
const result = await autoUpdater.checkForUpdates()
if (result != null) {
if (semver.gt(result.updateInfo.version, app.getVersion())) {
globalLogger.log("Update!", result.updateInfo.releaseName, result.updateInfo.version)
this.updateInfo = result.updateInfo
return true
try {
const result = await autoUpdater.checkForUpdates()
if (result != null) {
if (semver.gt(result.updateInfo.version, app.getVersion())) {
globalLogger.log("Update!", result.updateInfo.releaseName, result.updateInfo.version)
this.updateInfo = result.updateInfo
return true
}
return false
} else {
globalLogger.log("No Update :(")
}
return false
} else {
globalLogger.log("No Update :(")
} catch (err) {
logger.error("Error Checking Update", err)
return false
}
return false
}

async checkInfo() {
Expand Down
114 changes: 113 additions & 1 deletion libs/castmate-core/src/media/media-manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Service } from "../util/service"
import { ImageFormats, MediaMetadata, stillImageFormats } from "castmate-schema"
import * as fs from "fs/promises"
import * as fsSync from "fs"
import path, * as pathTools from "path"
import * as rra from "recursive-readdir-async"
import * as ffmpeg from "fluent-ffmpeg"
Expand All @@ -10,11 +11,15 @@ import { ensureDirectory, resolveProjectPath } from "../io/file-system"
import { shell, app } from "electron"
import { globalLogger, usePluginLogger } from "../logging/logging"
import { WebService } from "../webserver/internal-webserver"
import express, { Application, Router } from "express"
import express, { Application, response, Router } from "express"
import { coreAxios } from "../util/request-utils"
//require("@ffmpeg-installer/win32-x64")
//require("@ffprobe-installer/win32-x64")
//Thumbnails?
//Durations?

import http from "http"

const logger = usePluginLogger("media")

function probeMedia(file: string) {
Expand All @@ -37,6 +42,69 @@ export interface MediaFolder {
path: string
watcher: chokidar.FSWatcher
}
/*
function downloadFile(url: string, dest: string) {
return new Promise<void>((resolve, reject) => {
const writeStream = fsSync.createWriteStream(dest)
const request = http.get(url, (resp) => {
if (resp.statusCode !== 200) {
reject(`Failed to download ${url} with ${resp.statusCode}`)
}
resp.pipe(writeStream)
})
writeStream.on("finish", () => {
writeStream.close((err) => {
if (err) return reject(err)
resolve()
})
})
request.on("error", (err) => {
fsSync.unlink(dest, (unlinkErr) => {
if (unlinkErr) return reject(unlinkErr)
reject(err)
})
})
writeStream.on("error", (err) => {
fsSync.unlink(dest, (unlinkErr) => {
if (unlinkErr) return reject(unlinkErr)
reject(err)
})
})
})
}*/

async function downloadFile(url: string, dest: string) {
const writeStream = fsSync.createWriteStream(dest)
//https://stackoverflow.com/questions/55374755/node-js-axios-download-file-stream-and-writefile
await coreAxios
.get(url, {
responseType: "stream",
})
.then((response) => {
return new Promise<boolean>((resolve, reject) => {
response.data.pipe(writeStream)

let error: any = undefined
writeStream.on("error", (err) => {
error = err
writeStream.close()
reject(err)
})
writeStream.on("close", () => {
if (!error) {
resolve(true)
}
//no need to call the reject here, as it will have been called in the
//'error' stream;
})
})
})
}

export const MediaManager = Service(
class {
Expand All @@ -62,11 +130,55 @@ export const MediaManager = Service(
shell.showItemInFolder(mediaItem.file)
})

defineIPCFunc("media", "downloadMedia", async (url: string, mediaPath: string) => {
await this.downloadMedia(url, mediaPath)
})

defineIPCFunc("media", "copyMedia", async (localPath: string, mediaPath: string) => {
await this.copyMedia(localPath, mediaPath)
})

const router = express.Router()
router.use(express.static(mediaPath))
WebService.getInstance().addRootRouter("/media/default", router)
}

getLocalPath(mediaPath: string) {
const baseMediaPath = resolveProjectPath("./media")

if (!mediaPath.startsWith("/default")) throw new Error("not a media path")

const defaultPath = path.relative("/default", mediaPath)

const localPath = path.join(baseMediaPath, defaultPath)

return localPath
}

async downloadMedia(url: string, mediaPath: string) {
try {
const localPath = this.getLocalPath(mediaPath)

logger.log("Downloading Media", url, "to", localPath)

await downloadFile(url, localPath)
} catch (err) {
logger.error("ERROR DOWNLOADING MEDIA", err)
}
}

async copyMedia(localPath: string, mediaPath: string) {
try {
const destPath = this.getLocalPath(mediaPath)

logger.log("Copying Media", localPath, "to", destPath)

await fs.copyFile(localPath, destPath)
} catch (err) {
logger.error("ERROR COPYING MEDIA", err)
}
}

getMedia(path: string) {
return this.mediaFiles.get(path)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="action-preview-container">
<div class="cropper">
<data-view v-if="actionInfo" :model-value="modelValue" :schema="actionInfo.config" />
<data-view v-if="actionInfo" :model-value="modelValue" :schema="actionInfo.config" :context="modelValue" />
</div>
</div>
</template>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<template>
<span class="data-label" v-if="schema.name">{{ schema.name }}: </span>{{ dataView }}
</template>

<script setup lang="ts">
import { SchemaBase, Enumable, EnumItem } from "castmate-schema"
import { SharedDataViewProps } from "../../../main"
import { computed, ref, watch, onMounted } from "vue"
import _isFunction from "lodash/isFunction"
const props = defineProps<
{
modelValue: any
schema: SchemaBase & Enumable<any>
} & SharedDataViewProps
>()
const fetching = ref(false)
const dynamicItem = ref<EnumItem<any>>()
function findItem(arr: Array<EnumItem<any>>) {
return arr.find((v) => {
if (typeof v == "object" && "value" in v) return v.value == props.modelValue
return v == props.modelValue
})
}
onMounted(() => {
watch(
() => props.modelValue,
() => {
fetchItem()
},
{ immediate: true }
)
})
//TODO: Is there a better way to
async function fetchItem() {
const enumable = props.schema as Enumable<any>
if (!enumable.enum) return
if (!_isFunction(enumable.enum)) {
const item = findItem(enumable.enum)
dynamicItem.value = item
return
}
console.log("Do Fetch ITEM!")
fetching.value = true
try {
const items = await enumable.enum(props.context)
console.log("ITEMS", items, props.context)
const item = findItem(items)
dynamicItem.value = item
return
} catch (err) {
console.error("FETCH ERROR", err)
}
fetching.value = false
}
const dataView = computed(() => {
if (props.schema.enum == null) return props.modelValue
return dynamicItem.value?.name ?? dynamicItem.value ?? props.modelValue
})
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
v-if="documentComponent && document"
v-model="documentData"
v-model:view="documentView"
@keydown="onKeyDown"
tabindex="-1"
/>
</template>
Expand Down Expand Up @@ -57,12 +56,6 @@ const documentView = computed({
document.value.viewData = data
},
})
function onKeyDown(ev: KeyboardEvent) {
if (ev.ctrlKey && ev.code == "KeyS") {
documentStore.saveDocument(props.documentId)
}
}
</script>

<style scoped></style>
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
<template>
<div ref="container" class="dialog-container">
<component :is="resource?.editDialog" :resourceType="resourceType" :resourceId="resourceId" v-model="config" />
<component
v-if="resource?.editDialog"
:is="resource.editDialog"
:resourceType="resourceType"
:resourceId="resourceId"
v-model="config"
/>
<div class="p-inputgroup mt-5" v-else>
<span class="p-float-label">
<p-input-text id="l" v-model="config" ref="nameInput" autofocus />
<label for="l"> Name </label>
</span>
</div>
<div class="flex justify-content-end mt-1">
<p-button :label="isCreate ? 'Create' : 'Save'" @click="submit"></p-button>
</div>
Expand All @@ -11,6 +23,7 @@
import { computed, onMounted, ref } from "vue"
import { provideScrollAttachable, useDialogRef, useResourceData } from "../../main"
import PButton from "primevue/button"
import PInputText from "primevue/inputtext"
import { constructDefault } from "castmate-schema"
const props = defineProps<{}>()
Expand Down
Loading

0 comments on commit f2e56ac

Please sign in to comment.