aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/apis/google_docs/GooglePhotosClientUtils.ts22
-rw-r--r--src/client/views/MainView.tsx6
-rw-r--r--src/server/RouteStore.ts3
-rw-r--r--src/server/apis/google/GoogleApiServerUtils.ts13
-rw-r--r--src/server/apis/google/GooglePhotosUploadUtils.ts20
-rw-r--r--src/server/credentials/google_docs_token.json2
-rw-r--r--src/server/index.ts50
7 files changed, 73 insertions, 43 deletions
diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index 67a282f48..0864ebdb1 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -1,6 +1,7 @@
import { Album } from "../../../server/apis/google/typings/albums";
import { PostToServer } from "../../../Utils";
import { RouteStore } from "../../../server/RouteStore";
+import { ImageField } from "../../../new_fields/URLField";
export namespace GooglePhotosClientUtils {
@@ -9,7 +10,7 @@ export namespace GooglePhotosClientUtils {
action: Album.Action.Create,
body: { album: { title } }
} as Album.Create;
- return PostToServer(RouteStore.googlePhotos, parameters);
+ return PostToServer(RouteStore.googlePhotosQuery, parameters);
};
export const List = async (options?: Partial<Album.ListOptions>) => {
@@ -21,7 +22,7 @@ export namespace GooglePhotosClientUtils {
excludeNonAppCreatedData: (options ? options.excludeNonAppCreatedData : false) || false,
} as Album.ListOptions
} as Album.List;
- return PostToServer(RouteStore.googlePhotos, parameters);
+ return PostToServer(RouteStore.googlePhotosQuery, parameters);
};
export const Get = async (albumId: string) => {
@@ -29,7 +30,22 @@ export namespace GooglePhotosClientUtils {
action: Album.Action.Get,
albumId
} as Album.Get;
- return PostToServer(RouteStore.googlePhotos, parameters);
+ return PostToServer(RouteStore.googlePhotosQuery, parameters);
+ };
+
+ export const toDataURL = (field: ImageField | undefined) => {
+ if (!field) {
+ return undefined;
+ }
+ const image = document.createElement("img");
+ image.src = field.url.href;
+ const canvas = document.createElement("canvas");
+ canvas.width = image.width;
+ canvas.height = image.height;
+ const ctx = canvas.getContext("2d")!;
+ ctx.drawImage(image, 0, 0);
+ const dataUrl = canvas.toDataURL("image/png");
+ return dataUrl.replace(/^data:image\/(png|jpg);base64,/, "");
};
} \ No newline at end of file
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 3ee62ae86..590addaa3 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -44,6 +44,7 @@ import { GoogleApiClientUtils } from '../apis/google_docs/GoogleApiClientUtils';
import { docs_v1 } from 'googleapis';
import { Album } from '../../server/apis/google/typings/albums';
import { GooglePhotosClientUtils } from '../apis/google_docs/GooglePhotosClientUtils';
+import { ImageField } from '../../new_fields/URLField';
@observer
export class MainView extends React.Component {
@@ -130,6 +131,11 @@ export class MainView extends React.Component {
window.removeEventListener("keydown", KeyManager.Instance.handle);
window.addEventListener("keydown", KeyManager.Instance.handle);
+ let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg";
+ let image = Docs.Create.ImageDocument(imgurl, { width: 200, title: "an image of a cat" });
+ let parameters = { title: StrCast(image.title), MEDIA_BINARY_DATA: GooglePhotosClientUtils.toDataURL(Cast(image.data, ImageField)) };
+ PostToServer(RouteStore.googlePhotosMediaUpload, parameters).then(console.log);
+
reaction(() => {
let workspaces = CurrentUserUtils.UserDocument.workspaces;
let recent = CurrentUserUtils.UserDocument.recentlyClosed;
diff --git a/src/server/RouteStore.ts b/src/server/RouteStore.ts
index fc5511f98..3b3fd9b4a 100644
--- a/src/server/RouteStore.ts
+++ b/src/server/RouteStore.ts
@@ -32,6 +32,7 @@ export enum RouteStore {
// APIS
cognitiveServices = "/cognitiveservices",
googleDocs = "/googleDocs",
- googlePhotos = "/googlePhotos"
+ googlePhotosQuery = "/googlePhotosQuery",
+ googlePhotosMediaUpload = "/googlePhotosMediaUpload"
} \ No newline at end of file
diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts
index edfd89de4..2c9085ebb 100644
--- a/src/server/apis/google/GoogleApiServerUtils.ts
+++ b/src/server/apis/google/GoogleApiServerUtils.ts
@@ -48,7 +48,7 @@ export namespace GoogleApiServerUtils {
export const GetEndpoint = async (sector: string, paths: CredentialPaths) => {
return new Promise<Opt<Endpoint>>(resolve => {
- RetrieveAuthenticationInformation(paths).then(authentication => {
+ RetrieveCredentials(paths).then(authentication => {
let routed: Opt<Endpoint>;
let parameters: EndpointParameters = { auth: authentication.client, version: "v1" };
switch (sector) {
@@ -64,7 +64,7 @@ export namespace GoogleApiServerUtils {
});
};
- export const RetrieveAuthenticationInformation = async (paths: CredentialPaths) => {
+ export const RetrieveCredentials = async (paths: CredentialPaths) => {
return new Promise<TokenResult>((resolve, reject) => {
readFile(paths.credentials, async (err, credentials) => {
if (err) {
@@ -76,6 +76,15 @@ export namespace GoogleApiServerUtils {
});
};
+ export const RetrieveAccessToken = async (paths: CredentialPaths) => {
+ return new Promise<string>((resolve, reject) => {
+ RetrieveCredentials(paths).then(
+ credentials => resolve(credentials.token.access_token!),
+ error => reject(`Error: unable to authenticate Google Photos API request.\n${error}`)
+ );
+ });
+ };
+
type TokenResult = { token: Credentials, client: OAuth2Client };
/**
* Create an OAuth2 client with the given credentials, and returns the promise resolving to the authenticated client
diff --git a/src/server/apis/google/GooglePhotosUploadUtils.ts b/src/server/apis/google/GooglePhotosUploadUtils.ts
index 2e1599aaf..b358f9698 100644
--- a/src/server/apis/google/GooglePhotosUploadUtils.ts
+++ b/src/server/apis/google/GooglePhotosUploadUtils.ts
@@ -5,38 +5,24 @@ export namespace GooglePhotosUploadUtils {
interface UploadInformation {
title: string;
- url: URL;
+ MEDIA_BINARY_DATA: string;
}
const apiEndpoint = "https://photoslibrary.googleapis.com/v1/uploads";
export const SubmitUpload = async (parameters: Authorization & UploadInformation) => {
- let MEDIA_BINARY_DATA = binary(parameters.url.href);
-
let options = {
headers: {
'Content-Type': 'application/octet-stream',
- Authorization: { 'bearer': parameters.token },
+ auth: { 'bearer': parameters.token },
'X-Goog-Upload-File-Name': parameters.title,
'X-Goog-Upload-Protocol': 'raw'
},
- body: { MEDIA_BINARY_DATA },
+ body: { MEDIA_BINARY_DATA: parameters.MEDIA_BINARY_DATA },
json: true
};
const result = await request.post(apiEndpoint, options);
return result;
};
- const binary = (source: string) => {
- const image = document.createElement("img");
- image.src = source;
- const canvas = document.createElement("canvas");
- canvas.width = image.width;
- canvas.height = image.height;
- const ctx = canvas.getContext("2d")!;
- ctx.drawImage(image, 0, 0);
- const dataUrl = canvas.toDataURL("image/png");
- return dataUrl.replace(/^data:image\/(png|jpg);base64,/, "");
- };
-
} \ No newline at end of file
diff --git a/src/server/credentials/google_docs_token.json b/src/server/credentials/google_docs_token.json
index c83d82607..e4be9ff60 100644
--- a/src/server/credentials/google_docs_token.json
+++ b/src/server/credentials/google_docs_token.json
@@ -1 +1 @@
-{"access_token":"ya29.Glx4B4EQ5Q7WNw1hPrcqbZHssp0l1BtzszwNgmKGd783VBP9G3hLMe1AkbQw_Dl0amzgFeO29R4WP0ca-5U_Rf1tjsdtio6XjBGpJrY-S5wK7t71raKkwRPZFITw2Q","refresh_token":"1/kk_pPY7WBwT34JNPzx_HrSVoZlvfzys4EEVNjp7nqzg6aIbRrEKNMRTb0u0wr9GM","scope":"https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/documents.readonly https://www.googleapis.com/auth/documents https://www.googleapis.com/auth/photoslibrary.sharing https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/presentations https://www.googleapis.com/auth/presentations.readonly https://www.googleapis.com/auth/photoslibrary","token_type":"Bearer","expiry_date":1567531020435} \ No newline at end of file
+{"access_token":"ya29.Glx4B9gmH9fKJex9Je-k1KBNWEsJBPgQqoEWHhwk0TtTemCxONoyVMO38idAE7Vy9vdjcosjl0H4swnnH1s2QjTwZaspzKPeQr8Oh4sHkCJ-MbNd6naMZBdy1pccjQ","refresh_token":"1/kk_pPY7WBwT34JNPzx_HrSVoZlvfzys4EEVNjp7nqzg6aIbRrEKNMRTb0u0wr9GM","scope":"https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/documents.readonly https://www.googleapis.com/auth/documents https://www.googleapis.com/auth/photoslibrary.sharing https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/presentations https://www.googleapis.com/auth/presentations.readonly https://www.googleapis.com/auth/photoslibrary","token_type":"Bearer","expiry_date":1567545365417} \ No newline at end of file
diff --git a/src/server/index.ts b/src/server/index.ts
index 54b954cfb..3e85b1ce0 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -43,6 +43,7 @@ import * as YoutubeApi from "./apis/youtube/youtubeApiSample";
import { Response } from 'express-serve-static-core';
import { GoogleApiServerUtils } from "./apis/google/GoogleApiServerUtils";
import { GooglePhotos } from './apis/google/GooglePhotosServerUtils';
+import { GooglePhotosUploadUtils } from './apis/google/GooglePhotosUploadUtils';
const MongoStore = require('connect-mongo')(session);
const mongoose = require('mongoose');
const probe = require("probe-image-size");
@@ -824,25 +825,36 @@ app.post(RouteStore.googleDocs + "/:sector/:action", (req, res) => {
});
});
-app.post(RouteStore.googlePhotos, (req, res) => {
- GoogleApiServerUtils.RetrieveAuthenticationInformation({ credentials, token }).then(authentication => {
- let validated = authentication.token.access_token;
- if (!validated) {
- res.send("Error: unable to authenticate Google Photos API request.");
- return;
- }
- GooglePhotos.ExecuteQuery({ token: validated, query: req.body })
- .then(response => {
- if (response === undefined) {
- res.send("Error: unable to build suffix for Google Photos API request");
- return;
- }
- res.send(response);
- })
- .catch(error => {
- res.send(`Error: an exception occurred in the execution of this Google Photos API request\n${error}`);
- });
- });
+app.post(RouteStore.googlePhotosQuery, (req, res) => {
+ GoogleApiServerUtils.RetrieveAccessToken({ credentials, token }).then(
+ token => {
+ GooglePhotos.ExecuteQuery({ token, query: req.body })
+ .then(response => {
+ if (response === undefined) {
+ res.send("Error: unable to build suffix for Google Photos API request");
+ return;
+ }
+ res.send(response);
+ })
+ .catch(error => {
+ res.send(`Error: an exception occurred in the execution of this Google Photos API request\n${error}`);
+ });
+ },
+ error => res.send(error)
+ );
+});
+
+app.post(RouteStore.googlePhotosMediaUpload, (req, res) => {
+ GoogleApiServerUtils.RetrieveAccessToken({ credentials, token }).then(
+ token => {
+ GooglePhotosUploadUtils.SubmitUpload({ token, ...req.body })
+ .then(response => {
+ res.send(response);
+ }).catch(error => {
+ res.send(`Error: an exception occurred in uploading the given media\n${error}`);
+ });
+ },
+ error => res.send(error));
});
const suffixMap: { [type: string]: (string | [string, string | ((json: any) => any)]) } = {