diff options
author | geireann <geireann.lindfield@gmail.com> | 2023-08-24 10:30:02 -0400 |
---|---|---|
committer | geireann <geireann.lindfield@gmail.com> | 2023-08-24 10:30:02 -0400 |
commit | ee95ae232a251d311d7055cecc9d3cfaded2d7d9 (patch) | |
tree | 5871e42f44db939b497ddb869897d9eb023bc0f4 | |
parent | f8c2d9d029f129eb595677b1e8a09ff1ebd5880c (diff) | |
parent | d7aeb3aa85e7b66f503b61d72d459d69fb7788ea (diff) |
Merge branch 'master' into sophie-ai-images
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/client/views/DashboardView.tsx | 10 | ||||
-rw-r--r-- | src/client/views/collections/CollectionDockingView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSubView.tsx | 6 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 5 | ||||
-rw-r--r-- | src/client/views/nodes/WebBoxRenderer.js | 6 | ||||
-rw-r--r-- | src/server/ApiManagers/AzureManager.ts | 19 | ||||
-rw-r--r-- | src/server/DashUploadUtils.ts | 17 |
8 files changed, 48 insertions, 19 deletions
diff --git a/package.json b/package.json index 72f29ecf3..a1e7f858a 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "start-release-debug": "cross-env RELEASE=true USE_AZURE=true NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --inspect -- src/server/index.ts", "start": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug --transpile-only -- src/server/index.ts", "oldstart": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug -- src/server/index.ts", - "debug": "cross-env USE_AZURE=false NODE_OPTIONS=--max_old_space_size=8192 ts-node-dev --transpile-only --inspect -- src/server/index.ts", + "debug": "cross-env USE_AZURE=true NODE_OPTIONS=--max_old_space_size=8192 ts-node-dev --transpile-only --inspect -- src/server/index.ts", "monitor": "cross-env MONITORED=true NODE_OPTIONS=--max_old_space_size=4096 ts-node src/server/index.ts", "build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 webpack --env production", "test": "mocha -r ts-node/register test/**/*.ts", diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 3e4827c83..231a2d5fb 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -47,12 +47,12 @@ export class DashboardView extends React.Component { @action abortCreateNewDashboard = () => { this.newDashboardName = undefined; }; - @action setNewDashboardName(name: string) { + @action setNewDashboardName = (name: string) => { this.newDashboardName = name; - } - @action setNewDashboardColor(color: string) { + }; + @action setNewDashboardColor = (color: string) => { this.newDashboardColor = color; - } + }; @action selectDashboardGroup = (group: DashboardGroup) => { @@ -176,7 +176,7 @@ export class DashboardView extends React.Component { </div> <div className="all-dashboards"> {this.getDashboards(this.selectedDashboardGroup).map(dashboard => { - const href = ImageCast(dashboard.thumb)?.url.href; + const href = ImageCast(dashboard.thumb)?.url?.href; const shared = Object.keys(dashboard[DocAcl]) .filter(key => key !== `acl-${Doc.CurrentUserEmailNormalized}` && !['acl-Me', 'acl-Guest'].includes(key)) .some(key => dashboard[DocAcl][key] !== AclPrivate); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 95f88f14e..e15d57306 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -551,7 +551,7 @@ export class CollectionDockingView extends CollectionSubView() { }; render() { - const href = ImageCast(this.rootDoc.thumb)?.url.href; + const href = ImageCast(this.rootDoc.thumb)?.url?.href; return this.props.renderDepth > -1 ? ( <div> {href ? ( diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index c189ef126..eb4685834 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -298,7 +298,11 @@ export function CollectionSubView<X>(moreProps?: X) { let source = split; if (split.startsWith('data:image') && split.includes('base64')) { const [{ accessPaths }] = await Networking.PostToServer('/uploadRemoteImage', { sources: [split] }); - source = Utils.prepend(accessPaths.agnostic.client); + if (accessPaths.agnostic.client.indexOf("dashblobstore") === -1) { + source = Utils.prepend(accessPaths.agnostic.client); + } else { + source = accessPaths.agnostic.client; + } } if (source.startsWith('http')) { const doc = Docs.Create.ImageDocument(source, { ...options, _width: 300 }); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index d62bbc3dc..c4b3f79a7 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -298,10 +298,11 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp @computed private get url() { const data = Cast(this.dataDoc[this.fieldKey], ImageField); - return data ? data.url.href : undefined; + return data ? data.url?.href : undefined; } choosePath(url: URL) { + if (!url?.href) return ""; const lower = url.href.toLowerCase(); if (url.protocol === 'data') return url.href; if (url.href.indexOf(window.location.origin) === -1 && url.href.indexOf('dashblobstore') === -1) return Utils.CorsProxy(url.href); @@ -329,7 +330,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp if (!(data instanceof ImageField)) { return null; } - const primary = data.url.href; + const primary = data.url?.href; if (primary.includes(window.location.origin)) { return null; } diff --git a/src/client/views/nodes/WebBoxRenderer.js b/src/client/views/nodes/WebBoxRenderer.js index eb8064780..425ef3e54 100644 --- a/src/client/views/nodes/WebBoxRenderer.js +++ b/src/client/views/nodes/WebBoxRenderer.js @@ -42,21 +42,21 @@ var ForeignHtmlRenderer = function (styleSheets) { url = CorsProxy(new URL(webUrl).origin + inurl); } else if (!inurl.startsWith('http') && !inurl.startsWith('//')) { url = CorsProxy(webUrl + '/' + inurl); - } else if (inurl.startsWith('https')) { + } else if (inurl.startsWith('https') && !inurl.startsWith(window.location.origin)) { url = CorsProxy(inurl); } xhr.open('GET', url); xhr.responseType = 'blob'; xhr.onreadystatechange = async function () { - if (xhr.readyState === 4 && xhr.status === 200) { + if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { const resBase64 = await binaryStringToBase64(xhr.response); resolve({ resourceUrl: inurl, resourceBase64: resBase64, }); - } else if (xhr.readyState === 4) { + } else if (xhr.readyState === XMLHttpRequest.DONE) { console.log("COULDN'T FIND: " + (inurl.startsWith('/') ? webUrl + inurl : inurl)); resolve({ resourceUrl: '', diff --git a/src/server/ApiManagers/AzureManager.ts b/src/server/ApiManagers/AzureManager.ts index 12bb98ad0..2d0ab3aa6 100644 --- a/src/server/ApiManagers/AzureManager.ts +++ b/src/server/ApiManagers/AzureManager.ts @@ -1,8 +1,18 @@ import { ContainerClient, BlobServiceClient } from "@azure/storage-blob"; import * as fs from "fs"; import { Readable, Stream } from "stream"; +import * as path from "path"; const AZURE_STORAGE_CONNECTION_STRING = process.env.AZURE_STORAGE_CONNECTION_STRING; +const extToType: { [suffix: string]: string } = { + ".jpeg" : "image/jpeg", + ".jpg" : "image/jpeg", + ".png" : "image/png", + ".svg" : "image/svg+xml", + ".webp" : "image/webp", + ".gif" : "image/gif" +} + export class AzureManager { private _containerClient: ContainerClient; private _blobServiceClient: BlobServiceClient; @@ -10,6 +20,7 @@ export class AzureManager { public static CONTAINER_NAME = "dashmedia"; public static STORAGE_ACCOUNT_NAME = "dashblobstore"; + public static BASE_STRING = `https://${AzureManager.STORAGE_ACCOUNT_NAME}.blob.core.windows.net/${AzureManager.CONTAINER_NAME}`; constructor() { if (!AZURE_STORAGE_CONNECTION_STRING) { @@ -38,6 +49,14 @@ export class AzureManager { return blockBlobClient.uploadStream(stream, undefined, undefined, blobOptions); } + public static UploadBase64ImageBlob(filename: string, data: string, filetype?: string) { + const confirmedFiletype = filetype ? filetype : extToType[path.extname(filename)]; + const buffer = Buffer.from(data, "base64"); + const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename); + const blobOptions = { blobHTTPHeaders: { blobContentType: confirmedFiletype } }; + return blockBlobClient.upload(buffer, buffer.length, blobOptions); + } + public static UploadBlobStream(stream: Readable, filename: string, filetype: string) { const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename); const blobOptions = { blobHTTPHeaders: { blobContentType: filetype }}; diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts index 117981a7c..e5e15ce99 100644 --- a/src/server/DashUploadUtils.ts +++ b/src/server/DashUploadUtils.ts @@ -383,13 +383,18 @@ export namespace DashUploadUtils { if ((rawMatches = /^data:image\/([a-z]+);base64,(.*)/.exec(source)) !== null) { const [ext, data] = rawMatches.slice(1, 3); const resolved = (filename = `upload_${Utils.GenerateGuid()}.${ext}`); - const error = await new Promise<Error | null>(resolve => { - writeFile(serverPathToFile(Directory.images, resolved), data, 'base64', resolve); - }); - if (error !== null) { - return error; + if (usingAzure()) { + const response = await AzureManager.UploadBase64ImageBlob(resolved, data); + source = `${AzureManager.BASE_STRING}/${resolved}`; + } else { + const error = await new Promise<Error | null>(resolve => { + writeFile(serverPathToFile(Directory.images, resolved), data, 'base64', resolve); + }); + if (error !== null) { + return error; + } + source = `${resolvedServerUrl}${clientPathToFile(Directory.images, resolved)}`; } - source = `${resolvedServerUrl}${clientPathToFile(Directory.images, resolved)}`; } let resolvedUrl: string; /** |