aboutsummaryrefslogtreecommitdiff
path: root/src/server/apis/google/GooglePhotosUploadUtils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/apis/google/GooglePhotosUploadUtils.ts')
-rw-r--r--src/server/apis/google/GooglePhotosUploadUtils.ts119
1 files changed, 86 insertions, 33 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