From f4888ec4b2862cdf890ac1b0f6670b41398266df Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Wed, 21 Aug 2019 20:01:35 -0400 Subject: can create google slides presentations --- src/server/apis/google/GoogleApiServerUtils.ts | 65 +++++++++++++++++--------- 1 file changed, 43 insertions(+), 22 deletions(-) (limited to 'src/server/apis') diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts index 817b2b696..ff027c501 100644 --- a/src/server/apis/google/GoogleApiServerUtils.ts +++ b/src/server/apis/google/GoogleApiServerUtils.ts @@ -1,7 +1,10 @@ -import { google, docs_v1 } from "googleapis"; +import { google, docs_v1, slides_v1 } from "googleapis"; import { createInterface } from "readline"; import { readFile, writeFile } from "fs"; import { OAuth2Client } from "google-auth-library"; +import { Opt } from "../../../new_fields/Doc"; +import { GlobalOptions } from "googleapis-common"; +import { GaxiosResponse } from "gaxios"; /** * Server side authentication for Google Api queries. @@ -13,38 +16,57 @@ export namespace GoogleApiServerUtils { const SCOPES = [ 'documents.readonly', 'documents', + 'presentations', + 'presentations.readonly', 'drive', 'drive.file', ]; - // The file token.json stores the user's access and refresh tokens, and is - // created automatically when the authorization flow completes for the first - // time. + export const parseBuffer = (data: Buffer) => JSON.parse(data.toString()); - export namespace Docs { + export enum Sector { + Documents = "Documents", + Slides = "Slides" + } + - export interface CredentialPaths { - credentials: string; - token: string; - } + export interface CredentialPaths { + credentials: string; + token: string; + } - export type Endpoint = docs_v1.Docs; + export type ApiResponse = Promise; + export type ApiRouter = (endpoint: Endpoint, paramters: any) => ApiResponse; + export type ApiHandler = (parameters: any) => ApiResponse; + export type Action = "create" | "retrieve" | "update"; - export const GetEndpoint = async (paths: CredentialPaths) => { - return new Promise((resolve, reject) => { - readFile(paths.credentials, (err, credentials) => { - if (err) { - reject(err); - return console.log('Error loading client secret file:', err); + export type Endpoint = { get: ApiHandler, create: ApiHandler, batchUpdate: ApiHandler }; + export type EndpointParameters = GlobalOptions & { version: "v1" }; + + export const GetEndpoint = async (sector: string, paths: CredentialPaths) => { + return new Promise>((resolve, reject) => { + readFile(paths.credentials, (err, credentials) => { + if (err) { + reject(err); + return console.log('Error loading client secret file:', err); + } + return authorize(parseBuffer(credentials), paths.token).then(auth => { + let routed: Opt; + let parameters: EndpointParameters = { auth, version: "v1" }; + switch (sector) { + case Sector.Documents: + routed = google.docs(parameters).documents; + break; + case Sector.Slides: + routed = google.slides(parameters).presentations; + break; } - return authorize(parseBuffer(credentials), paths.token).then(auth => { - resolve(google.docs({ version: "v1", auth })); - }); + resolve(routed); }); }); - }; + }); + }; - } /** * Create an OAuth2 client with the given credentials, and returns the promise resolving to the authenticated client @@ -105,5 +127,4 @@ export namespace GoogleApiServerUtils { }); }); } - } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 30d55c5b91329d32a79b7135fff3566b2cd0e822 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Wed, 21 Aug 2019 20:33:42 -0400 Subject: create is now shared between slides and docs --- .../apis/google_docs/GoogleApiClientUtils.ts | 79 +++++++++------------- src/client/views/MainView.tsx | 2 +- src/client/views/nodes/FormattedTextBox.tsx | 2 +- src/server/RouteStore.ts | 2 +- src/server/apis/google/GoogleApiServerUtils.ts | 6 +- src/server/index.ts | 4 +- 6 files changed, 40 insertions(+), 55 deletions(-) (limited to 'src/server/apis') diff --git a/src/client/apis/google_docs/GoogleApiClientUtils.ts b/src/client/apis/google_docs/GoogleApiClientUtils.ts index 52452cd95..ea020ed00 100644 --- a/src/client/apis/google_docs/GoogleApiClientUtils.ts +++ b/src/client/apis/google_docs/GoogleApiClientUtils.ts @@ -9,6 +9,11 @@ export const Pushes = "googleDocsPushCount"; export namespace GoogleApiClientUtils { + export enum Service { + Documents = "Documents", + Slides = "Slides" + } + export enum Actions { Create = "create", Retrieve = "retrieve", @@ -29,6 +34,7 @@ export namespace GoogleApiClientUtils { export type ReadResult = { title?: string, body?: string }; export interface CreateOptions { + service: Service; title?: string; // if excluded, will use a default title annotated with the current date } @@ -45,6 +51,30 @@ export namespace GoogleApiClientUtils { index?: number; // if excluded, will compute the last index of the document and append the content there } + /** + * After following the authentication routine, which connects this API call to the current signed in account + * and grants the appropriate permissions, this function programmatically creates an arbitrary Google Doc which + * should appear in the user's Google Doc library instantaneously. + * + * @param options the title to assign to the new document, and the information necessary + * to store the new documentId returned from the creation process + * @returns the documentId of the newly generated document, or undefined if the creation process fails. + */ + export const create = async (options: CreateOptions): Promise => { + const path = `${RouteStore.googleDocs}/${options.service}/${Actions.Create}`; + const parameters = { + requestBody: { + title: options.title || `Dash Export (${new Date().toDateString()})` + } + }; + try { + const schema: any = await PostToServer(path, parameters); + let key = ["document", "presentation"].find(prefix => `${prefix}Id` in schema) + "Id"; + return schema[key]; + } catch { + return undefined; + } + }; export namespace Docs { @@ -96,33 +126,8 @@ export namespace GoogleApiClientUtils { } - /** - * After following the authentication routine, which connects this API call to the current signed in account - * and grants the appropriate permissions, this function programmatically creates an arbitrary Google Doc which - * should appear in the user's Google Doc library instantaneously. - * - * @param options the title to assign to the new document, and the information necessary - * to store the new documentId returned from the creation process - * @returns the documentId of the newly generated document, or undefined if the creation process fails. - */ - export const create = async (options: CreateOptions): Promise => { - const path = RouteStore.googleDocs + "Documents/" + Actions.Create; - const parameters = { - requestBody: { - title: options.title || `Dash Export (${new Date().toDateString()})` - } - }; - try { - const schema: docs_v1.Schema$Document = await PostToServer(path, parameters); - const generatedId = schema.documentId; - return generatedId; - } catch { - return undefined; - } - }; - export const retrieve = async (options: RetrieveOptions): Promise => { - const path = RouteStore.googleDocs + "Documents/" + Actions.Retrieve; + const path = `${RouteStore.googleDocs}/${Service.Documents}/${Actions.Retrieve}`; try { const schema: RetrievalResult = await PostToServer(path, options); return schema; @@ -132,7 +137,7 @@ export namespace GoogleApiClientUtils { }; export const update = async (options: UpdateOptions): Promise => { - const path = RouteStore.googleDocs + "Documents/" + Actions.Update; + const path = `${RouteStore.googleDocs}/${Service.Documents}/${Actions.Update}`; const parameters = { documentId: options.documentId, requestBody: { @@ -218,24 +223,4 @@ export namespace GoogleApiClientUtils { } - export namespace Slides { - - export const create = async (options: CreateOptions): Promise => { - const path = RouteStore.googleDocs + "Slides/" + Actions.Create; - const parameters = { - requestBody: { - title: options.title || `Dash Export (${new Date().toDateString()})` - } - }; - try { - const schema: slides_v1.Schema$Presentation = await PostToServer(path, parameters); - const generatedId = schema.presentationId; - return generatedId; - } catch { - return undefined; - } - }; - - } - } \ No newline at end of file diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 3490a0f68..2a219fdd1 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -122,7 +122,7 @@ export class MainView extends React.Component { var tag = document.createElement('script'); let title = "THIS IS MY FIRST DASH PRESENTATION"; - GoogleApiClientUtils.Slides.create({ title }).then(id => console.log("We received this! ", id)); + GoogleApiClientUtils.create({ service: GoogleApiClientUtils.Service.Slides, title }).then(id => console.log("We received this! ", id)); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 408a6948e..bcec6f7c3 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -436,7 +436,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe let reference: Opt = Cast(this.dataDoc[GoogleRef], "string"); if (!reference) { mode = modes.Insert; - reference = { title: StrCast(this.dataDoc.title) }; + reference = { service: GoogleApiClientUtils.Service.Documents, title: StrCast(this.dataDoc.title) }; } let redo = async () => { let data = Cast(this.dataDoc.data, RichTextField); diff --git a/src/server/RouteStore.ts b/src/server/RouteStore.ts index 5d977006a..014906054 100644 --- a/src/server/RouteStore.ts +++ b/src/server/RouteStore.ts @@ -31,6 +31,6 @@ export enum RouteStore { // APIS cognitiveServices = "/cognitiveservices", - googleDocs = "/googleDocs/" + googleDocs = "/googleDocs" } \ No newline at end of file diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts index ff027c501..8785cd974 100644 --- a/src/server/apis/google/GoogleApiServerUtils.ts +++ b/src/server/apis/google/GoogleApiServerUtils.ts @@ -24,7 +24,7 @@ export namespace GoogleApiServerUtils { export const parseBuffer = (data: Buffer) => JSON.parse(data.toString()); - export enum Sector { + export enum Service { Documents = "Documents", Slides = "Slides" } @@ -54,10 +54,10 @@ export namespace GoogleApiServerUtils { let routed: Opt; let parameters: EndpointParameters = { auth, version: "v1" }; switch (sector) { - case Sector.Documents: + case Service.Documents: routed = google.docs(parameters).documents; break; - case Sector.Slides: + case Service.Slides: routed = google.slides(parameters).presentations; break; } diff --git a/src/server/index.ts b/src/server/index.ts index 6aecb875a..0476bf3df 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -806,10 +806,10 @@ const EndpointHandlerMap = new Map api.batchUpdate(params)], ]); -app.post(RouteStore.googleDocs + ":sector/:action", (req, res) => { +app.post(RouteStore.googleDocs + "/:sector/:action", (req, res) => { let sector = req.params.sector; let action = req.params.action; - GoogleApiServerUtils.GetEndpoint(GoogleApiServerUtils.Sector[sector], { credentials, token }).then(endpoint => { + GoogleApiServerUtils.GetEndpoint(GoogleApiServerUtils.Service[sector], { credentials, token }).then(endpoint => { let handler = EndpointHandlerMap.get(action); if (endpoint && handler) { let execute = handler(endpoint, req.body).then( -- cgit v1.2.3-70-g09d2