aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/ApiManagers/UploadManager.ts14
-rw-r--r--src/server/DashUploadUtils.ts61
-rw-r--r--src/server/DataVizUtils.ts13
3 files changed, 84 insertions, 4 deletions
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index e7b7056a1..332ba3d35 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -24,6 +24,7 @@ export enum Directory {
text = "text",
pdf_thumbnails = "pdf_thumbnails",
audio = "audio",
+ csv = "csv",
}
export function serverPathToFile(directory: Directory, filename: string) {
@@ -40,7 +41,16 @@ export function clientPathToFile(directory: Directory, filename: string) {
export default class UploadManager extends ApiManager {
- protected initialize(register: Registration): void {
+ protected initialize(register: Registration): void {
+
+ register({
+ method: Method.POST,
+ subscription: "/concatVideos",
+ secureHandler: async ({ req, res }) => {
+ // req.body contains the array of server paths to the videos
+ _success(res, await DashUploadUtils.concatVideos(req.body));
+ }
+ });
register({
method: Method.POST,
@@ -50,7 +60,7 @@ export default class UploadManager extends ApiManager {
form.keepExtensions = true;
form.uploadDir = pathToDirectory(Directory.parsed_files);
return new Promise<void>(resolve => {
- form.parse(req, async (_err, _fields, files) => {
+ form.parse(req, async (_err, _fields, files) => {
const results: Upload.FileResponse[] = [];
for (const key in files) {
const f = files[key];
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 552ab57a5..cae35da60 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -1,9 +1,9 @@
import { green, red } from 'colors';
import { ExifImage } from 'exif';
+import * as exifr from 'exifr';
import { File } from 'formidable';
import { createWriteStream, existsSync, readFileSync, rename, unlinkSync, writeFile } from 'fs';
import * as path from 'path';
-import * as exifr from 'exifr';
import { basename } from "path";
import * as sharp from 'sharp';
import { Stream } from 'stream';
@@ -17,9 +17,12 @@ import { resolvedServerUrl } from "./server_Initialization";
import { AcceptableMedia, Upload } from './SharedMediaTypes';
import request = require('request-promise');
import formidable = require('formidable');
+import { file } from 'jszip';
+import { csvParser } from './DataVizUtils';
const { exec } = require("child_process");
const parse = require('pdf-parse');
const ffmpeg = require("fluent-ffmpeg");
+const fs = require("fs");
const requestImageSize = require("../client/util/request-image-size");
export enum SizeSuffix {
@@ -60,6 +63,43 @@ export namespace DashUploadUtils {
const type = "content-type";
const { imageFormats, videoFormats, applicationFormats, audioFormats } = AcceptableMedia; //TODO:glr
+
+ export async function concatVideos(filePaths: string[]): Promise<Upload.AccessPathInfo> {
+ // make a list of paths to create the ordered text file for ffmpeg
+ const inputListName = 'concat.txt';
+ const textFilePath = path.join(filesDirectory, inputListName);
+ // make a list of paths to create the ordered text file for ffmpeg
+ const filePathsText = filePaths.map(filePath => `file '${filePath}'`).join('\n');
+ // write the text file to the file system
+ writeFile(textFilePath, filePathsText, (err) => console.log(err));
+
+ // make output file name based on timestamp
+ const outputFileName = `output-${Utils.GenerateGuid()}.mp4`;
+ // create the output file path in the videos directory
+ const outputFilePath = path.join(pathToDirectory(Directory.videos), outputFileName);
+
+ // concatenate the videos
+ await new Promise((resolve, reject) => {
+ var merge = ffmpeg();
+ merge.input(textFilePath)
+ .inputOptions(['-f concat', '-safe 0'])
+ .outputOptions('-c copy')
+ //.videoCodec("copy")
+ .save(outputFilePath)
+ .on("error", reject)
+ .on("end", resolve);
+ })
+
+ // delete concat.txt from the file system
+ unlinkSync(textFilePath);
+ // delete the old segment videos from the server
+ filePaths.forEach(filePath => unlinkSync(filePath));
+
+ // return the path(s) to the output file
+ return {
+ accessPaths: getAccessPaths(Directory.videos, outputFileName)
+ }
+ }
export function uploadYoutube(videoId: string): Promise<Upload.FileResponse> {
console.log("UPLOAD " + videoId);
@@ -85,7 +125,7 @@ export namespace DashUploadUtils {
const category = types[0];
let format = `.${types[1]}`;
console.log(green(`Processing upload of file (${name}) and format (${format}) with upload type (${type}) in category (${category}).`));
-
+
switch (category) {
case "image":
if (imageFormats.includes(format)) {
@@ -94,6 +134,7 @@ export namespace DashUploadUtils {
}
case "video":
if (format.includes("x-matroska")) {
+ console.log("case video");
await new Promise(res => ffmpeg(file.path)
.videoCodec("copy") // this will copy the data instead of reencode it
.save(file.path.replace(".mkv", ".mp4"))
@@ -116,6 +157,11 @@ export namespace DashUploadUtils {
if (audioFormats.includes(format)) {
return UploadAudio(file, format);
}
+ case "text":
+ if (types[1] == "csv") {
+ return UploadCsv(file);
+ }
+
}
console.log(red(`Ignoring unsupported file (${name}) with upload type (${type}).`));
@@ -135,6 +181,16 @@ export namespace DashUploadUtils {
return MoveParsedFile(file, Directory.pdfs, undefined, result.text);
}
+ async function UploadCsv(file: File) {
+ const { path: sourcePath } = file;
+ // read the file as a string
+ const data = readFileSync(sourcePath, 'utf8');
+ // split the string into an array of lines
+ return MoveParsedFile(file, Directory.csv, undefined, data);
+ // console.log(csvParser(data));
+
+ }
+
const manualSuffixes = [".webm"];
async function UploadAudio(file: File, format: string) {
@@ -220,6 +276,7 @@ export namespace DashUploadUtils {
}
let resolvedUrl: string;
/**
+ *
* At this point, we want to take whatever url we have and make sure it's requestable.
* Anything that's hosted by some other website already is, but if the url is a local file url
* (locates the file on this server machine), we have to resolve the client side url by cutting out the
diff --git a/src/server/DataVizUtils.ts b/src/server/DataVizUtils.ts
new file mode 100644
index 000000000..4fd0ca6ff
--- /dev/null
+++ b/src/server/DataVizUtils.ts
@@ -0,0 +1,13 @@
+export function csvParser(csv: string) {
+ const lines = csv.split("\n");
+ const headers = lines[0].split(",");
+ const data = lines.slice(1).map(line => {
+ const values = line.split(",");
+ const obj: any = {};
+ for (let i = 0; i < headers.length; i++) {
+ obj[headers[i]] = values[i];
+ }
+ return obj;
+ });
+ return data;
+} \ No newline at end of file