aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/apis/google/GooglePhotosUploadUtils.ts119
-rw-r--r--src/server/credentials/google_docs_token.json2
-rw-r--r--src/server/index.ts27
3 files changed, 106 insertions, 42 deletions
diff --git a/src/server/apis/google/GooglePhotosUploadUtils.ts b/src/server/apis/google/GooglePhotosUploadUtils.ts
index 9b3e68761..5ac3eaef7 100644
--- a/src/server/apis/google/GooglePhotosUploadUtils.ts
+++ b/src/server/apis/google/GooglePhotosUploadUtils.ts
@@ -4,6 +4,9 @@ import * as fs from 'fs';
import { Utils } from '../../../Utils';
import * as path from 'path';
import { Opt } from '../../../new_fields/Doc';
+import * as sharp from 'sharp';
+
+const uploadDirectory = path.join(__dirname, "../../public/files/");
export namespace GooglePhotosUploadUtils {
@@ -18,13 +21,6 @@ export namespace GooglePhotosUploadUtils {
description: string;
}
- export interface DownloadInformation {
- mediaPath: string;
- fileName: string;
- contentType?: string;
- contentSize?: string;
- }
-
const prepend = (extension: string) => `https://photoslibrary.googleapis.com/v1/${extension}`;
const headers = (type: string) => ({
'Content-Type': `application/${type}`,
@@ -76,35 +72,92 @@ export namespace GooglePhotosUploadUtils {
});
};
- export namespace IOUtils {
+}
- export const Download = async (url: string, filename?: string, prefix = ""): Promise<Opt<DownloadInformation>> => {
- const resolved = filename || `${prefix}upload_${Utils.GenerateGuid()}${path.extname(url).toLowerCase()}`;
- const mediaPath = Paths.uploadDirectory + resolved;
- return new Promise<DownloadInformation>((resolve, reject) => {
- request.head(url, (error, res) => {
- if (error) {
- return reject(error);
- }
- const information: DownloadInformation = {
- fileName: resolved,
- contentSize: res.headers['content-length'],
- contentType: res.headers['content-type'],
- mediaPath
- };
- request(url).pipe(fs.createWriteStream(mediaPath)).on('close', () => resolve(information));
- });
- });
- };
+export namespace DownloadUtils {
- export const createIfNotExists = async (path: string) => {
- if (await new Promise<boolean>(resolve => fs.exists(path, resolve))) {
- return true;
- }
- return new Promise<boolean>(resolve => fs.mkdir(path, error => resolve(error === null)));
- };
+ export interface Size {
+ width: number;
+ suffix: string;
+ }
- export const Destroy = (mediaPath: string) => new Promise<boolean>(resolve => fs.unlink(mediaPath, error => resolve(error === null)));
+ export const Sizes: { [size: string]: Size } = {
+ SMALL: { width: 100, suffix: "_s" },
+ MEDIUM: { width: 400, suffix: "_m" },
+ LARGE: { width: 900, suffix: "_l" },
+ };
+
+ const png = ".png";
+ const pngs = [".png", ".PNG"];
+ const jpg = [".jpg", ".JPG", ".jpeg", ".JPEG"];
+ const size = "content-length";
+ const type = "content-type";
+
+ export interface DownloadInformation {
+ mediaPaths: string[];
+ fileNames: { [key: string]: string };
+ contentSize?: string;
+ contentType?: string;
}
+ const generate = (prefix: string, url: string) => `${prefix}upload_${Utils.GenerateGuid()}${path.extname(url).toLowerCase()}`;
+ const sanitize = (filename: string) => filename.replace(/\s+/g, "_");
+
+ export const Download = async (url: string, filename?: string, prefix = ""): Promise<Opt<DownloadInformation>> => {
+ const resolved = filename ? sanitize(filename) : generate(prefix, url);
+ const extension = path.extname(url) || path.extname(resolved) || png;
+ return new Promise<DownloadInformation>((resolve, reject) => {
+ request.head(url, async (error, res) => {
+ if (error) {
+ return reject(error);
+ }
+ const information: DownloadInformation = {
+ fileNames: { clean: resolved },
+ contentSize: res.headers[size],
+ contentType: res.headers[type],
+ mediaPaths: []
+ };
+ const resizers = [
+ { resizer: sharp().rotate(), suffix: "_o" },
+ ...Object.values(Sizes).map(size => ({
+ resizer: sharp().resize(size.width, undefined, { withoutEnlargement: true }).rotate(),
+ suffix: size.suffix
+ }))
+ ];
+ let validated = true;
+ if (pngs.includes(extension)) {
+ resizers.forEach(element => element.resizer = element.resizer.png());
+ } else if (jpg.includes(extension)) {
+ resizers.forEach(element => element.resizer = element.resizer.jpeg());
+ } else {
+ validated = false;
+ }
+ if (validated) {
+ for (let resizer of resizers) {
+ const suffix = resizer.suffix;
+ let mediaPath: string;
+ await new Promise<void>(resolve => {
+ const filename = resolved.substring(0, resolved.length - extension.length) + suffix + extension;
+ information.mediaPaths.push(mediaPath = uploadDirectory + filename);
+ information.fileNames[suffix] = filename;
+ request(url)
+ .pipe(resizer.resizer)
+ .pipe(fs.createWriteStream(mediaPath))
+ .on('close', resolve);
+ });
+ }
+ resolve(information);
+ }
+ });
+ });
+ };
+
+ export const createIfNotExists = async (path: string) => {
+ if (await new Promise<boolean>(resolve => fs.exists(path, resolve))) {
+ return true;
+ }
+ return new Promise<boolean>(resolve => fs.mkdir(path, error => resolve(error === null)));
+ };
+
+ export const Destroy = (mediaPath: string) => new Promise<boolean>(resolve => fs.unlink(mediaPath, error => resolve(error === null)));
} \ 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 a1c23ea35..4f911f7e0 100644
--- a/src/server/credentials/google_docs_token.json
+++ b/src/server/credentials/google_docs_token.json
@@ -1 +1 @@
-{"access_token":"ya29.Glx9B3Fumh3qHpgasQvHNNrwNXtmTVWJR9XckFsnUjOswDOO91ccF3FhD4ko7Z-3rvxEljpP1Qj5BgNq305pt-pgIquoLPWYiaEtinHNF7IXGPz4s4raqJWEJPJxow","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":1567913435149} \ No newline at end of file
+{"access_token":"ya29.Glx9B3_l5JbKNtvzx378Nsz917bP-OTKf6VZzc2K8QDBm-Y0j_-c8v7bL8LCEM3wF8d7JauF-5Z4Uq4v7wPwUQUlDO1uPyoHeSF6iz98xkgJr9OW4KzJo2Ij722gpQ","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":1567931641928} \ No newline at end of file
diff --git a/src/server/index.ts b/src/server/index.ts
index 49010e7e2..013345a76 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -42,7 +42,7 @@ var AdmZip = require('adm-zip');
import * as YoutubeApi from "./apis/youtube/youtubeApiSample";
import { Response } from 'express-serve-static-core';
import { GoogleApiServerUtils } from "./apis/google/GoogleApiServerUtils";
-import { GooglePhotosUploadUtils } from './apis/google/GooglePhotosUploadUtils';
+import { GooglePhotosUploadUtils, DownloadUtils } from './apis/google/GooglePhotosUploadUtils';
const MongoStore = require('connect-mongo')(session);
const mongoose = require('mongoose');
const probe = require("probe-image-size");
@@ -154,6 +154,11 @@ app.get("/buxton", (req, res) => {
command_line('python scraper.py', cwd).then(onResolved, tryPython3);
});
+const STATUS = {
+ OK: 200,
+ BAD_REQUEST: 400
+};
+
const command_line = (command: string, fromDirectory?: string) => {
return new Promise<string>((resolve, reject) => {
let options: ExecOptions = {};
@@ -848,16 +853,22 @@ app.post(RouteStore.googlePhotosMediaUpload, async (req, res) => {
);
});
+interface MediaItem {
+ baseUrl: string;
+ filename: string;
+}
const prefix = "google_photos_";
+
app.post(RouteStore.googlePhotosMediaDownload, async (req, res) => {
- const contents = req.body;
- if (!contents) {
- return res.send(undefined);
+ const contents: { mediaItems: MediaItem[] } = req.body;
+ if (contents) {
+ const downloads = contents.mediaItems.map(item =>
+ DownloadUtils.Download(item.baseUrl, item.filename, prefix)
+ );
+ res.status(STATUS.OK).send(await Promise.all(downloads));
+ return;
}
- await GooglePhotosUploadUtils.initialize({ uploadDirectory, credentialsPath, tokenPath });
- res.send(await Promise.all(contents.mediaItems.map((item: any) =>
- GooglePhotosUploadUtils.IOUtils.Download(item.baseUrl, undefined, prefix)))
- );
+ res.status(STATUS.BAD_REQUEST).send();
});
const suffixMap: { [type: string]: (string | [string, string | ((json: any) => any)]) } = {