diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/documents/Documents.ts | 3 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 2 | ||||
-rw-r--r-- | src/fields/URLField.ts | 2 | ||||
-rw-r--r-- | src/server/ApiManagers/AzureManager.ts | 74 | ||||
-rw-r--r-- | src/server/DashUploadUtils.ts | 25 |
5 files changed, 96 insertions, 10 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ffde9fe1b..ac6c48619 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1739,7 +1739,8 @@ export namespace DocUtils { return; } const full = { ...options, _width: 400, title: name }; - const pathname = Utils.prepend(result.accessPaths.agnostic.client); + // const pathname = Utils.prepend(result.accessPaths.agnostic.client); + const pathname = result.accessPaths.azure.client; const doc = await DocUtils.DocumentFromType(type, pathname, full, overwriteDoc); if (doc) { const proto = Doc.GetProto(doc); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 9acbee1e7..de1365adc 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -295,7 +295,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp choosePath(url: URL) { const lower = url.href.toLowerCase(); if (url.protocol === 'data') return url.href; - if (url.href.indexOf(window.location.origin) === -1) return Utils.CorsProxy(url.href); + if (url.href.indexOf(window.location.origin) === -1 && url.href.indexOf("dashblobstore") === -1) return Utils.CorsProxy(url.href); if (!/\.(png|jpg|jpeg|gif|webp)$/.test(lower)) return `/assets/unknown-file-icon-hi.png`; const ext = extname(url.href); diff --git a/src/fields/URLField.ts b/src/fields/URLField.ts index 8ac20b1e5..8db4d6003 100644 --- a/src/fields/URLField.ts +++ b/src/fields/URLField.ts @@ -25,7 +25,7 @@ export abstract class URLField extends ObjectField { constructor(url: URL | string) { super(); if (typeof url === 'string') { - url = url.startsWith('http') ? new URL(url) : new URL(url, window.location.origin); + url = (url.startsWith('http') || url.startsWith('https')) ? new URL(url) : new URL(url, window.location.origin); } this.url = url; } diff --git a/src/server/ApiManagers/AzureManager.ts b/src/server/ApiManagers/AzureManager.ts new file mode 100644 index 000000000..e105f5d80 --- /dev/null +++ b/src/server/ApiManagers/AzureManager.ts @@ -0,0 +1,74 @@ +import { ContainerClient, BlobServiceClient } from "@azure/storage-blob"; +// import * as dotenv from 'dotenv'; +import * as fs from "fs"; +import { Readable, Stream } from "stream"; +// dotenv.config(); +const AZURE_STORAGE_CONNECTION_STRING = "DefaultEndpointsProtocol=https;AccountName=dashblobstore;AccountKey=3i+E5XkCz3TJ0m5QOatiEnbRACz9V1qCW72L6ldiYGH1tLdfJWa2eQoRfYmPA68lx1a6YAcfYJfWHadIxQvhGQ==;EndpointSuffix=core.windows.net"; + +export class AzureManager { + private _containerClient: ContainerClient; + private _blobServiceClient: BlobServiceClient; + private static _instance: AzureManager | undefined; + + public static CONTAINER_NAME = "dashmedia"; + public static STORAGE_ACCOUNT_NAME = "dashblobstore"; + + constructor() { + if (!AZURE_STORAGE_CONNECTION_STRING) { + throw Error("Azure Storage Connection String Not Found"); + } + // this._blobServiceClient = BlobServiceClient.fromConnectionString(process.env.AZURE_STORAGE_CONNECTION_STRING); + this._blobServiceClient = BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING); + this._containerClient = this.BlobServiceClient.getContainerClient(AzureManager.CONTAINER_NAME); + } + + public static get Instance() { + return this._instance = this._instance ?? new AzureManager(); + } + + public get BlobServiceClient() { + return this._blobServiceClient; + } + + public get ContainerClient() { + return this._containerClient; + } + + public static UploadBlob(filename: string, filepath: string, filetype: string) { + console.log("Upload Blob File"); + const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename); + const blobOptions = { blobHTTPHeaders: { blobContentType: filetype }}; + const stream = fs.createReadStream(filepath); + return blockBlobClient.uploadStream(stream, undefined, undefined, blobOptions); + } + + public static UploadBlobStream(stream: Readable, filename: string, filetype: string) { + console.log("Upload Blob Stream: %s, %s", filename, filetype); + const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename); + const blobOptions = { blobHTTPHeaders: { blobContentType: filetype }}; + return blockBlobClient.uploadStream(stream, undefined, undefined, blobOptions); + } + + public static DeleteBlob(filename: string) { + console.log("Delete Blob from filename"); + const blockBlobClient = this.Instance.ContainerClient.getBlockBlobClient(filename); + return blockBlobClient.deleteIfExists(); + } + + public static async GetBlobs() { + console.log("Get Blobs"); + const foundBlobs = []; + for await (const blob of this.Instance.ContainerClient.listBlobsFlat()) { + console.log(`${blob.name}`); + + const blobItem = { + url : `https://${AzureManager.STORAGE_ACCOUNT_NAME}.blob.core.windows.net/${AzureManager.CONTAINER_NAME}/${blob.name}`, + name : blob.name + } + + foundBlobs.push(blobItem); + } + + return foundBlobs; + } +}
\ No newline at end of file diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts index eaaac4e6d..53f2d6501 100644 --- a/src/server/DashUploadUtils.ts +++ b/src/server/DashUploadUtils.ts @@ -6,7 +6,7 @@ import { createReadStream, createWriteStream, existsSync, readFileSync, rename, import * as path from 'path'; import { basename } from 'path'; import * as sharp from 'sharp'; -import { Stream } from 'stream'; +import { Readable, Stream } from 'stream'; import { filesDirectory, publicDirectory } from '.'; import { Opt } from '../fields/Doc'; import { ParsedPDF } from '../server/PdfTypes'; @@ -17,6 +17,7 @@ import { resolvedServerUrl } from './server_Initialization'; import { AcceptableMedia, Upload } from './SharedMediaTypes'; import request = require('request-promise'); import formidable = require('formidable'); +import { AzureManager } from './ApiManagers/AzureManager'; const spawn = require('child_process').spawn; const { exec } = require('child_process'); const parse = require('pdf-parse'); @@ -193,7 +194,7 @@ export namespace DashUploadUtils { switch (category) { case 'image': if (imageFormats.includes(format)) { - const result = await UploadImage(path, basename(path)); + const result = await UploadImage(path, basename(path), name); return { source: file, result }; } fs.unlink(path, () => {}); @@ -323,12 +324,13 @@ export namespace DashUploadUtils { * 3) the size of the image, in bytes (4432130) * 4) the content type of the image, i.e. image/(jpeg | png | ...) */ - export const UploadImage = async (source: string, filename?: string, prefix: string = ''): Promise<Upload.ImageInformation | Error> => { + export const UploadImage = async (source: string, filename?: string, originalFilename?: string, prefix: string = ''): Promise<Upload.ImageInformation | Error> => { const metadata = await InspectImage(source); if (metadata instanceof Error) { return { name: metadata.name, message: metadata.message }; } - return UploadInspectedImage(metadata, filename || metadata.filename, prefix); + console.log(originalFilename); + return UploadInspectedImage(metadata, filename || metadata.filename, originalFilename, prefix); }; export async function buildFileDirectories() { @@ -478,17 +480,21 @@ export namespace DashUploadUtils { }; } - export const UploadInspectedImage = async (metadata: Upload.InspectionResults, filename?: string, prefix = '', cleanUp = true): Promise<Upload.ImageInformation> => { + export const UploadInspectedImage = async (metadata: Upload.InspectionResults, filename?: string, originalFilename?: string, prefix = '', cleanUp = true): Promise<Upload.ImageInformation> => { const { requestable, source, ...remaining } = metadata; const resolved = filename || `${prefix}upload_${Utils.GenerateGuid()}.${remaining.contentType.split('/')[1].toLowerCase()}`; const { images } = Directory; const information: Upload.ImageInformation = { accessPaths: { agnostic: getAccessPaths(images, resolved), + azure: { + client: `https://dashblobstore.blob.core.windows.net/dashmedia/${originalFilename}`, + server: `https://dashblobstore.blob.core.windows.net/dashmedia/${originalFilename}` + } }, ...metadata, }; - const writtenFiles = await outputResizedImages(() => request(requestable), resolved, pathToDirectory(Directory.images)); + const writtenFiles = await outputResizedImages(() => request(requestable), resolved, pathToDirectory(Directory.images), originalFilename, metadata.contentType); for (const suffix of Object.keys(writtenFiles)) { information.accessPaths[suffix] = getAccessPaths(images, writtenFiles[suffix]); } @@ -533,16 +539,21 @@ export namespace DashUploadUtils { force: true, }; - export async function outputResizedImages(streamProvider: () => Stream | Promise<Stream>, outputFileName: string, outputDirectory: string) { + export async function outputResizedImages(streamProvider: () => Stream | Promise<Stream>, outputFileName: string, outputDirectory: string, originalFilename?: string, contentType?: string) { + console.log("resized original filename: ", originalFilename); const writtenFiles: { [suffix: string]: string } = {}; for (const { resizer, suffix } of resizers(path.extname(outputFileName))) { const outputPath = path.resolve(outputDirectory, (writtenFiles[suffix] = InjectSize(outputFileName, suffix))); + console.log(`https://dashblobstore.blob.core.windows.net/dashmedia/${InjectSize(originalFilename!, suffix)}`); await new Promise<void>(async (resolve, reject) => { const source = streamProvider(); let readStream: Stream = source instanceof Promise ? await source : source; if (resizer) { readStream = readStream.pipe(resizer.withMetadata()); } + if(originalFilename && contentType) { + AzureManager.UploadBlobStream(readStream as Readable, InjectSize(originalFilename, suffix), contentType); + } readStream.pipe(createWriteStream(outputPath)).on('close', resolve).on('error', reject); }); } |