diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/apis/google_docs/GooglePhotosClientUtils.ts | 4 | ||||
-rw-r--r-- | src/client/northstar/utils/Extensions.ts | 83 | ||||
-rw-r--r-- | src/client/views/Main.tsx | 13 | ||||
-rw-r--r-- | src/extensions/ArrayExtensions.ts (renamed from src/client/util/UtilExtensions.ts) | 238 | ||||
-rw-r--r-- | src/extensions/StringExtensions.ts | 20 | ||||
-rw-r--r-- | src/server/apis/google/GooglePhotosUploadUtils.ts | 1 | ||||
-rw-r--r-- | src/server/credentials/google_docs_token.json | 2 | ||||
-rw-r--r-- | src/server/index.ts | 21 |
8 files changed, 195 insertions, 187 deletions
diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts index a13d9dcd6..671d05421 100644 --- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts +++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts @@ -89,7 +89,7 @@ export namespace GooglePhotos { return undefined; } const resolved = title ? title : (StrCast(collection.title) || `Dash Collection (${collection[Id]}`); - const { id } = await Create.Album(resolved); + const { id, productUrl } = await Create.Album(resolved); const newMediaItemResults = await Transactions.UploadImages(images, { id }, descriptionKey); if (newMediaItemResults) { const mediaItems = newMediaItemResults.map(item => item.mediaItem); @@ -101,9 +101,11 @@ export namespace GooglePhotos { const image = Doc.GetProto(images[i]); const mediaItem = mediaItems[i]; image.googlePhotosId = mediaItem.id; + image.googlePhotosAlbumUrl = productUrl; image.googlePhotosUrl = mediaItem.productUrl || mediaItem.baseUrl; idMapping[mediaItem.id] = image; } + collection.googlePhotosAlbumUrl = productUrl; collection.googlePhotosIdMapping = idMapping; if (tag) { await Query.TagChildImages(collection); diff --git a/src/client/northstar/utils/Extensions.ts b/src/client/northstar/utils/Extensions.ts index 8254c775c..df14d4da0 100644 --- a/src/client/northstar/utils/Extensions.ts +++ b/src/client/northstar/utils/Extensions.ts @@ -1,12 +1,8 @@ interface String { ReplaceAll(toReplace: string, replacement: string): string; Truncate(length: number, replacement: string): String; - removeTrailingNewlines(): string; - hasNewline(): boolean; } -const extensions = require(".././/.//../util/UtilExtensions"); - String.prototype.ReplaceAll = function (toReplace: string, replacement: string): string { var target = this; return target.split(toReplace).join(replacement); @@ -20,85 +16,6 @@ String.prototype.Truncate = function (length: number, replacement: string): Stri return target; }; -interface BatchContext { - completedBatches: number; - remainingBatches: number; -} -type BatchConverterSync<I, O> = (batch: I[], context: BatchContext) => O[]; -type BatchHandlerSync<I> = (batch: I[], context: BatchContext) => void; -type BatchConverterAsync<I, O> = (batch: I[], context: BatchContext) => Promise<O[]>; -type BatchHandlerAsync<I> = (batch: I[], context: BatchContext) => Promise<void>; -type BatchConverter<I, O> = BatchConverterSync<I, O> | BatchConverterAsync<I, O>; -type BatchHandler<I> = BatchHandlerSync<I> | BatchHandlerAsync<I>; -type FixedBatcher = { batchSize: number } | { batchCount: number, mode?: Mode }; -interface ExecutorResult<A> { - updated: A; - makeNextBatch: boolean; -} -interface PredicateBatcher<I, A> { - executor: (element: I, accumulator: A) => ExecutorResult<A>; - initial: A; - persistAccumulator?: boolean; -} -interface PredicateBatcherAsync<I, A> { - executor: (element: I, accumulator: A) => Promise<ExecutorResult<A>>; - initial: A; - persistAccumulator?: boolean; -} -type Batcher<I, A> = FixedBatcher | PredicateBatcher<I, A>; -type BatcherAsync<I, A> = Batcher<I, A> | PredicateBatcherAsync<I, A>; - -enum TimeUnit { - Milliseconds, - Seconds, - Minutes -} - -interface Interval { - magnitude: number; - unit: TimeUnit; -} - -interface Array<T> { - fixedBatch<T>(batcher: FixedBatcher): T[][]; - predicateBatch<T, A = undefined>(batcher: PredicateBatcher<T, A>): T[][]; - predicateBatchAsync<T, A = undefined>(batcher: PredicateBatcherAsync<T, A>): Promise<T[][]>; - batch<A = undefined>(batcher: Batcher<T, A>): T[][]; - batchAsync<A = undefined>(batcher: BatcherAsync<T, A>): Promise<T[][]>; - - batchedForEach<A = undefined>(batcher: Batcher<T, A>, handler: BatchHandlerSync<T>): void; - batchedMap<O, A = undefined>(batcher: Batcher<T, A>, handler: BatchConverterSync<T, O>): O[]; - - batchedForEachAsync<A = undefined>(batcher: Batcher<T, A>, handler: BatchHandler<T>): Promise<void>; - batchedMapAsync<O, A = undefined>(batcher: Batcher<T, A>, handler: BatchConverter<T, O>): Promise<O[]>; - - batchedForEachInterval<A = undefined>(batcher: Batcher<T, A>, handler: BatchHandler<T>, interval: Interval): Promise<void>; - batchedMapInterval<O, A = undefined>(batcher: Batcher<T, A>, handler: BatchConverter<T, O>, interval: Interval): Promise<O[]>; - - lastElement(): T; -} - -Array.prototype.fixedBatch = extensions.FixedBatch; -Array.prototype.predicateBatch = extensions.PredicateBatch; -Array.prototype.predicateBatchAsync = extensions.PredicateBatchAsync; -Array.prototype.batch = extensions.Batch; -Array.prototype.batchAsync = extensions.BatchAsync; - -Array.prototype.batchedForEach = extensions.ExecuteInBatches; -Array.prototype.batchedMap = extensions.ConvertInBatches; -Array.prototype.batchedForEachAsync = extensions.ExecuteInBatchesAsync; -Array.prototype.batchedMapAsync = extensions.ConvertInBatchesAsync; -Array.prototype.batchedForEachInterval = extensions.ExecuteInBatchesAtInterval; -Array.prototype.batchedMapInterval = extensions.ConvertInBatchesAtInterval; - -Array.prototype.lastElement = function <T>() { - if (!this.length) { - return undefined; - } - const last: T = this[this.length - 1]; - return last; -}; - interface Math { log10(val: number): number; } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index aa002cee9..55fa138c8 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -7,18 +7,9 @@ import { Cast } from "../../new_fields/Types"; import { Doc, DocListCastAsync } from "../../new_fields/Doc"; import { List } from "../../new_fields/List"; import { DocServer } from "../DocServer"; +const ArrayExtensions = require("../../extensions/ArrayExtensions"); -String.prototype.removeTrailingNewlines = function () { - let sliced = this; - while (sliced.endsWith("\n")) { - sliced = sliced.substring(0, this.length - 1); - } - return sliced as string; -}; - -String.prototype.hasNewline = function () { - return this.endsWith("\n"); -}; +ArrayExtensions.AssignArrayExtensions(); let swapDocs = async () => { let oldDoc = await Cast(CurrentUserUtils.UserDocument.linkManagerDoc, Doc); diff --git a/src/client/util/UtilExtensions.ts b/src/extensions/ArrayExtensions.ts index 1447e37cb..1190aa48c 100644 --- a/src/client/util/UtilExtensions.ts +++ b/src/extensions/ArrayExtensions.ts @@ -1,69 +1,96 @@ -module.exports.Batch = function <T, A>(batcher: Batcher<T, A>): T[][] { - if ("executor" in batcher) { - return this.predicateBatch(batcher); - } else { - return this.fixedBatch(batcher); - } -}; - -module.exports.BatchAsync = async function <T, A>(batcher: BatcherAsync<T, A>): Promise<T[][]> { - if ("executor" in batcher) { - return this.predicateBatchAsync(batcher); - } else { - return this.fixedBatch(batcher); - } -}; +interface BatchContext { + completedBatches: number; + remainingBatches: number; +} +type BatchConverterSync<I, O> = (batch: I[], context: BatchContext) => O[]; +type BatchHandlerSync<I> = (batch: I[], context: BatchContext) => void; +type BatchConverterAsync<I, O> = (batch: I[], context: BatchContext) => Promise<O[]>; +type BatchHandlerAsync<I> = (batch: I[], context: BatchContext) => Promise<void>; +type BatchConverter<I, O> = BatchConverterSync<I, O> | BatchConverterAsync<I, O>; +type BatchHandler<I> = BatchHandlerSync<I> | BatchHandlerAsync<I>; +type FixedBatcher = { batchSize: number } | { batchCount: number, mode?: Mode }; +interface ExecutorResult<A> { + updated: A; + makeNextBatch: boolean; +} +interface PredicateBatcher<I, A> { + executor: (element: I, accumulator: A) => ExecutorResult<A>; + initial: A; + persistAccumulator?: boolean; +} +interface PredicateBatcherAsyncInterface<I, A> { + executor: (element: I, accumulator: A) => Promise<ExecutorResult<A>>; + initial: A; + persistAccumulator?: boolean; +} +type PredicateBatcherAsync<I, A> = PredicateBatcher<I, A> | PredicateBatcherAsyncInterface<I, A>; +type Batcher<I, A> = FixedBatcher | PredicateBatcher<I, A>; +type BatcherAsync<I, A> = Batcher<I, A> | PredicateBatcherAsync<I, A>; -module.exports.PredicateBatch = function <T, A>(batcher: PredicateBatcher<T, A>): T[][] { - const batches: T[][] = []; - let batch: T[] = []; - const { executor, initial, persistAccumulator } = batcher; - let accumulator = initial; - for (let element of this) { - const { updated, makeNextBatch } = executor(element, accumulator); - accumulator = updated; - if (!makeNextBatch) { - batch.push(element); - } else { - batches.push(batch); - batch = [element]; - if (!persistAccumulator) { - accumulator = initial; - } - } - } - batches.push(batch); - return batches; -}; +enum TimeUnit { + Milliseconds, + Seconds, + Minutes +} -module.exports.PredicateBatchAsync = async function <T, A>(batcher: PredicateBatcherAsync<T, A>): Promise<T[][]> { - const batches: T[][] = []; - let batch: T[] = []; - const { executor, initial, persistAccumulator } = batcher; - let accumulator: A = initial; - for (let element of this) { - const { updated, makeNextBatch } = await executor(element, accumulator); - accumulator = updated; - if (!makeNextBatch) { - batch.push(element); - } else { - batches.push(batch); - batch = [element]; - if (!persistAccumulator) { - accumulator = initial; - } - } - } - batches.push(batch); - return batches; -}; +interface Interval { + magnitude: number; + unit: TimeUnit; +} enum Mode { Balanced, Even } -module.exports.FixedBatch = function <T>(batcher: FixedBatcher): T[][] { +const convert = (interval: Interval) => { + const { magnitude, unit } = interval; + switch (unit) { + default: + case TimeUnit.Milliseconds: + return magnitude; + case TimeUnit.Seconds: + return magnitude * 1000; + case TimeUnit.Minutes: + return magnitude * 1000 * 60; + } +}; + +interface Array<T> { + fixedBatch<T>(batcher: FixedBatcher): T[][]; + predicateBatch<T, A = undefined>(batcher: PredicateBatcher<T, A>): T[][]; + predicateBatchAsync<T, A = undefined>(batcher: PredicateBatcherAsync<T, A>): Promise<T[][]>; + batch<A = undefined>(batcher: Batcher<T, A>): T[][]; + batchAsync<A = undefined>(batcher: BatcherAsync<T, A>): Promise<T[][]>; + + batchedForEach<A = undefined>(batcher: Batcher<T, A>, handler: BatchHandlerSync<T>): void; + batchedMap<O, A = undefined>(batcher: Batcher<T, A>, handler: BatchConverterSync<T, O>): O[]; + + batchedForEachAsync<A = undefined>(batcher: Batcher<T, A>, handler: BatchHandler<T>): Promise<void>; + batchedMapAsync<O, A = undefined>(batcher: Batcher<T, A>, handler: BatchConverter<T, O>): Promise<O[]>; + + batchedForEachInterval<A = undefined>(batcher: Batcher<T, A>, handler: BatchHandler<T>, interval: Interval): Promise<void>; + batchedMapInterval<O, A = undefined>(batcher: Batcher<T, A>, handler: BatchConverter<T, O>, interval: Interval): Promise<O[]>; + + lastElement(): T; +} + +module.exports.AssignArrayExtensions = function () { + Array.prototype.fixedBatch = module.exports.fixedBatch; + Array.prototype.predicateBatch = module.exports.predicateBatch; + Array.prototype.predicateBatchAsync = module.exports.predicateBatchAsync; + Array.prototype.batch = module.exports.batch; + Array.prototype.batchAsync = module.exports.batchAsync; + Array.prototype.batchedForEach = module.exports.batchedForEach; + Array.prototype.batchedMap = module.exports.batchedMap; + Array.prototype.batchedForEachAsync = module.exports.batchedForEachAsync; + Array.prototype.batchedMapAsync = module.exports.batchedMapAsync; + Array.prototype.batchedForEachInterval = module.exports.batchedForEachInterval; + Array.prototype.batchedMapInterval = module.exports.batchedMapInterval; + Array.prototype.lastElement = module.exports.lastElement; +}; + +module.exports.fixedBatch = function <T>(batcher: FixedBatcher): T[][] { const batches: T[][] = []; const length = this.length; let i = 0; @@ -114,7 +141,67 @@ module.exports.FixedBatch = function <T>(batcher: FixedBatcher): T[][] { return batches; }; -module.exports.ExecuteBatches = function <I, A>(batcher: Batcher<I, A>, handler: BatchHandlerSync<I>): void { +module.exports.predicateBatch = function <T, A>(batcher: PredicateBatcher<T, A>): T[][] { + const batches: T[][] = []; + let batch: T[] = []; + const { executor, initial, persistAccumulator } = batcher; + let accumulator = initial; + for (let element of this) { + const { updated, makeNextBatch } = executor(element, accumulator); + accumulator = updated; + if (!makeNextBatch) { + batch.push(element); + } else { + batches.push(batch); + batch = [element]; + if (!persistAccumulator) { + accumulator = initial; + } + } + } + batches.push(batch); + return batches; +}; + +module.exports.predicateBatchAsync = async function <T, A>(batcher: PredicateBatcherAsync<T, A>): Promise<T[][]> { + const batches: T[][] = []; + let batch: T[] = []; + const { executor, initial, persistAccumulator } = batcher; + let accumulator: A = initial; + for (let element of this) { + const { updated, makeNextBatch } = await executor(element, accumulator); + accumulator = updated; + if (!makeNextBatch) { + batch.push(element); + } else { + batches.push(batch); + batch = [element]; + if (!persistAccumulator) { + accumulator = initial; + } + } + } + batches.push(batch); + return batches; +}; + +module.exports.batch = function <T, A>(batcher: Batcher<T, A>): T[][] { + if ("executor" in batcher) { + return this.predicateBatch(batcher); + } else { + return this.fixedBatch(batcher); + } +}; + +module.exports.batchAsync = async function <T, A>(batcher: BatcherAsync<T, A>): Promise<T[][]> { + if ("executor" in batcher) { + return this.predicateBatchAsync(batcher); + } else { + return this.fixedBatch(batcher); + } +}; + +module.exports.batchedForEach = function <I, A>(batcher: Batcher<I, A>, handler: BatchHandlerSync<I>): void { if (this.length) { let completed = 0; const batches = this.batch(batcher); @@ -130,7 +217,7 @@ module.exports.ExecuteBatches = function <I, A>(batcher: Batcher<I, A>, handler: } }; -module.exports.ConvertInBatches = function <I, O, A>(batcher: Batcher<I, A>, handler: BatchConverterSync<I, O>): O[] { +module.exports.batchedMap = function <I, O, A>(batcher: Batcher<I, A>, handler: BatchConverterSync<I, O>): O[] { if (!this.length) { return []; } @@ -149,7 +236,7 @@ module.exports.ConvertInBatches = function <I, O, A>(batcher: Batcher<I, A>, han return collector; }; -module.exports.ExecuteInBatchesAsync = async function <I, A>(batcher: BatcherAsync<I, A>, handler: BatchHandler<I>): Promise<void> { +module.exports.batchedForEachAsync = async function <I, A>(batcher: BatcherAsync<I, A>, handler: BatchHandler<I>): Promise<void> { if (this.length) { let completed = 0; const batches = await this.batchAsync(batcher); @@ -165,7 +252,7 @@ module.exports.ExecuteInBatchesAsync = async function <I, A>(batcher: BatcherAsy } }; -module.exports.ConvertInBatchesAsync = async function <I, O, A>(batcher: BatcherAsync<I, A>, handler: BatchConverter<I, O>): Promise<O[]> { +module.exports.batchedMapAsync = async function <I, O, A>(batcher: BatcherAsync<I, A>, handler: BatchConverter<I, O>): Promise<O[]> { if (!this.length) { return []; } @@ -184,20 +271,7 @@ module.exports.ConvertInBatchesAsync = async function <I, O, A>(batcher: Batcher return collector; }; -const convert = (interval: Interval) => { - const { magnitude, unit } = interval; - switch (unit) { - default: - case TimeUnit.Milliseconds: - return magnitude; - case TimeUnit.Seconds: - return magnitude * 1000; - case TimeUnit.Minutes: - return magnitude * 1000 * 60; - } -}; - -module.exports.ExecuteInBatchesAtInterval = async function <I, A>(batcher: BatcherAsync<I, A>, handler: BatchHandler<I>, interval: Interval): Promise<void> { +module.exports.batchedForEachInterval = async function <I, A>(batcher: BatcherAsync<I, A>, handler: BatchHandler<I>, interval: Interval): Promise<void> { if (!this.length) { return; } @@ -227,7 +301,7 @@ module.exports.ExecuteInBatchesAtInterval = async function <I, A>(batcher: Batch }); }; -module.exports.ConvertInBatchesAtInterval = async function <I, O, A>(batcher: BatcherAsync<I, A>, handler: BatchConverter<I, O>, interval: Interval): Promise<O[]> { +module.exports.batchedMapInterval = async function <I, O, A>(batcher: BatcherAsync<I, A>, handler: BatchConverter<I, O>, interval: Interval): Promise<O[]> { if (!this.length) { return []; } @@ -256,4 +330,12 @@ module.exports.ConvertInBatchesAtInterval = async function <I, O, A>(batcher: Ba } } }); -};
\ No newline at end of file +}; + +module.exports.lastElement = function <T>() { + if (!this.length) { + return undefined; + } + const last: T = this[this.length - 1]; + return last; +}; diff --git a/src/extensions/StringExtensions.ts b/src/extensions/StringExtensions.ts new file mode 100644 index 000000000..1168fdda8 --- /dev/null +++ b/src/extensions/StringExtensions.ts @@ -0,0 +1,20 @@ +interface String { + removeTrailingNewlines(): string; + hasNewline(): boolean; +} + +function AssignStringExtensions() { + + String.prototype.removeTrailingNewlines = function () { + let sliced = this; + while (sliced.endsWith("\n")) { + sliced = sliced.substring(0, this.length - 1); + } + return sliced as string; + }; + + String.prototype.hasNewline = function () { + return this.endsWith("\n"); + }; + +}
\ No newline at end of file diff --git a/src/server/apis/google/GooglePhotosUploadUtils.ts b/src/server/apis/google/GooglePhotosUploadUtils.ts index 9275bf125..7eaf8a8b7 100644 --- a/src/server/apis/google/GooglePhotosUploadUtils.ts +++ b/src/server/apis/google/GooglePhotosUploadUtils.ts @@ -7,6 +7,7 @@ import { Opt } from '../../../new_fields/Doc'; import * as sharp from 'sharp'; import { MediaItemCreationResult, NewMediaItemResult } from './SharedTypes'; import { NewMediaItem } from '../..'; +import { TimeUnit } from "../../index"; const uploadDirectory = path.join(__dirname, "../../public/files/"); diff --git a/src/server/credentials/google_docs_token.json b/src/server/credentials/google_docs_token.json index be50f4dd2..a476498a8 100644 --- a/src/server/credentials/google_docs_token.json +++ b/src/server/credentials/google_docs_token.json @@ -1 +1 @@ -{"access_token":"ya29.ImCHB-QNh-blUK7Ajw1Dk1yNBZ7w5JAKcrgzW4xYE3sfNTLdq_gXEQOK0ZZeJBPL1_WcJbbX7EKuMxWN-fwWMuhAG6-IHk1TpkOG1KZpSGo3myT7xiZDnONxLfVuodT0Nlc","refresh_token":"1/HTv_xFHszu2Nf3iiFrUTaeKzC_Vp2-6bpIB06xW_WHI","scope":"https://www.googleapis.com/auth/presentations.readonly https://www.googleapis.com/auth/documents.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/documents https://www.googleapis.com/auth/photoslibrary https://www.googleapis.com/auth/photoslibrary.appendonly https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/presentations https://www.googleapis.com/auth/photoslibrary.sharing","token_type":"Bearer","expiry_date":1568797587975}
\ No newline at end of file +{"access_token":"ya29.ImCIBw01ZtZwR2NI608a-TfejTTGAzAWICqX9QdfNcLHo4upydH3tvpR7l5YmEbyuH2CHjHSQW2QKAPU_zXSpGAo_ZjQE5iRqsP_VdlSDVCS_NyabpHNL5m-0tmdyZJ8Qoc","refresh_token":"1/HTv_xFHszu2Nf3iiFrUTaeKzC_Vp2-6bpIB06xW_WHI","scope":"https://www.googleapis.com/auth/presentations.readonly https://www.googleapis.com/auth/documents.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/documents https://www.googleapis.com/auth/photoslibrary https://www.googleapis.com/auth/photoslibrary.appendonly https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/presentations https://www.googleapis.com/auth/photoslibrary.sharing","token_type":"Bearer","expiry_date":1568919703546}
\ No newline at end of file diff --git a/src/server/index.ts b/src/server/index.ts index 83bbe734b..6a06454ec 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -47,7 +47,7 @@ const mongoose = require('mongoose'); const probe = require("probe-image-size"); import * as qs from 'query-string'; import { Opt } from '../new_fields/Doc'; -const extensions = require("../client/util/UtilExtensions"); +const ArrayExtensions = require("../extensions/ArrayExtensions"); const download = (url: string, dest: fs.PathLike) => request.get(url).pipe(fs.createWriteStream(dest)); let youtubeApiKey: string; @@ -99,6 +99,8 @@ enum Method { POST } +ArrayExtensions.AssignArrayExtensions(); + /** * Please invoke this function when adding a new route to Dash's server. * It ensures that any requests leading to or containing user-sensitive information @@ -835,18 +837,11 @@ export interface NewMediaItem { }; } -Array.prototype.fixedBatch = extensions.FixedBatch; -Array.prototype.predicateBatch = extensions.PredicateBatch; -Array.prototype.predicateBatchAsync = extensions.PredicateBatchAsync; -Array.prototype.batch = extensions.Batch; -Array.prototype.batchAsync = extensions.BatchAsync; - -Array.prototype.batchedForEach = extensions.ExecuteInBatches; -Array.prototype.batchedMap = extensions.ConvertInBatches; -Array.prototype.batchedForEachAsync = extensions.ExecuteInBatchesAsync; -Array.prototype.batchedMapAsync = extensions.ConvertInBatchesAsync; -Array.prototype.batchedForEachInterval = extensions.ExecuteInBatchesAtInterval; -Array.prototype.batchedMapInterval = extensions.ConvertInBatchesAtInterval; +export enum TimeUnit { + Milliseconds, + Seconds, + Minutes +} app.post(RouteStore.googlePhotosMediaUpload, async (req, res) => { const mediaInput: GooglePhotosUploadUtils.MediaInput[] = req.body.media; |