fixed uploads
This commit is contained in:
parent
a0fcc376b7
commit
30ff3dbdcd
7 changed files with 86 additions and 46 deletions
|
@ -1,12 +1,15 @@
|
|||
import Controller from "./Controller";
|
||||
import type DashboardViewModel from "../models/home/DashboardViewModel";
|
||||
import UserService from "../services/UserService";
|
||||
import DomainService from "../services/DomainService";
|
||||
import ArrayUtility from "../utilities/ArrayUtility";
|
||||
|
||||
export default class HomeController extends Controller {
|
||||
public async Index_Get_AllowAnonymous() {
|
||||
if (this.session) {
|
||||
const dashboardViewModel: DashboardViewModel = {
|
||||
recentUploads: await UserService.GetRecentUploads(this.session.userId)
|
||||
recentUploads: await UserService.GetRecentUploads(this.session.userId),
|
||||
domains: ArrayUtility.ToIdKeyedDict(await DomainService.LoadDomains())
|
||||
}
|
||||
|
||||
return this.view("dashboard",dashboardViewModel);
|
||||
|
|
7
index.ts
7
index.ts
|
@ -35,7 +35,12 @@ fastify.register(FastifyView, {
|
|||
|
||||
fastify.register(FastifyFormBody);
|
||||
|
||||
fastify.register(FastifyMultipart);
|
||||
fastify.register(FastifyMultipart, {
|
||||
limits: {
|
||||
files: 1,
|
||||
fileSize: 104857600
|
||||
}
|
||||
});
|
||||
|
||||
fastify.register(FastifyCookie, {
|
||||
secret: Config.session.secret,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import type Domain from "../../entities/Domain";
|
||||
import Media from "../../entities/Media";
|
||||
|
||||
export default interface DashboardViewModel {
|
||||
recentUploads: Array<Media>
|
||||
recentUploads: Array<Media>,
|
||||
domains: { [key: string]: Domain }
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
// ! Hashed File Store (not file system!!)
|
||||
|
||||
import { join } from "path";
|
||||
import { existsSync, mkdirSync, createWriteStream, rename, stat, writeFile, rm, rmSync, } from "fs";
|
||||
import { existsSync, mkdirSync, createWriteStream, rename, stat, writeFile, rm, rmSync, createReadStream } from "fs";
|
||||
import { Console } from "hsconsole";
|
||||
import { yellow } from "dyetty";
|
||||
import { createHash, randomBytes } from "crypto";
|
||||
import FunkyArray from "funky-array";
|
||||
import HashFSFileInformation from "./HashFSFileInformation";
|
||||
import type { BusboyFileStream } from "@fastify/busboy";
|
||||
import { pipeline } from "stream/promises";
|
||||
|
||||
export default class HashFS {
|
||||
public static STARTUP_DIR: string;
|
||||
|
@ -104,49 +105,50 @@ export default class HashFS {
|
|||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
|
||||
resolve(fileInfo);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public AddFromStream(stream: BusboyFileStream) {
|
||||
return new Promise<HashFSFileInformation>(async (resolve, reject) => {
|
||||
const hasher = createHash("sha1");
|
||||
hasher.setEncoding("hex");
|
||||
|
||||
const tempFilePath = join(this.tempPath, randomBytes(16).toString("base64url"));
|
||||
const tempFile = createWriteStream(tempFilePath);
|
||||
tempFile.on("close", async () => {
|
||||
const hash: string = hasher.read();
|
||||
const fileInfo = new HashFSFileInformation();
|
||||
fileInfo.fileHash = hash;
|
||||
fileInfo.fileSize = fileSize;
|
||||
if (await this.FileExists(hash)) {
|
||||
fileInfo.fileExistsAlready = true;
|
||||
rm(tempFilePath, err => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
this.logInfo(`File with hash "${hash}" already exists.`);
|
||||
resolve(fileInfo);
|
||||
});
|
||||
} else {
|
||||
rename(tempFilePath, this.GetFilePath(hash), err => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
this.logInfo(`Stored file as ${hash}`);
|
||||
resolve(fileInfo);
|
||||
});
|
||||
}
|
||||
});
|
||||
stream.pipe(tempFile);
|
||||
stream.pipe(hasher);
|
||||
let fileSize = 0;
|
||||
stream.on("data", chunk => fileSize += chunk.length);
|
||||
const tempFilePath = join(this.tempPath, randomBytes(16).toString("base64url"));
|
||||
await pipeline(stream, createWriteStream(tempFilePath));
|
||||
const readStream = createReadStream(tempFilePath);
|
||||
for await (const chunk of readStream) {
|
||||
fileSize += chunk.length;
|
||||
hasher.write(chunk)
|
||||
}
|
||||
hasher.end();
|
||||
const hash: string = hasher.read();
|
||||
const fileInfo = new HashFSFileInformation();
|
||||
fileInfo.fileHash = hash;
|
||||
fileInfo.fileSize = fileSize;
|
||||
if (await this.FileExists(hash)) {
|
||||
fileInfo.fileExistsAlready = true;
|
||||
rm(tempFilePath, err => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
this.logInfo(`File with hash "${hash}" already exists.`);
|
||||
resolve(fileInfo);
|
||||
});
|
||||
} else {
|
||||
rename(tempFilePath, this.GetFilePath(hash), err => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
this.logInfo(`Stored file as ${hash}`);
|
||||
resolve(fileInfo);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
13
services/DomainService.ts
Normal file
13
services/DomainService.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { Console } from "hsconsole";
|
||||
import DomainRepo from "../repos/DomainRepo";
|
||||
|
||||
export default abstract class DomainService {
|
||||
public static async LoadDomains() {
|
||||
try {
|
||||
return await DomainRepo.SelectAll();
|
||||
} catch (e) {
|
||||
Console.printError(`EUS server service error:\n${e}`);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
10
utilities/ArrayUtility.ts
Normal file
10
utilities/ArrayUtility.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
export default abstract class ArrayUtility {
|
||||
public static ToIdKeyedDict(array: Array<any>) {
|
||||
const dict: { [key: string]: any } = {};
|
||||
for (const item of array) {
|
||||
dict[item.Id] = item;
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
}
|
|
@ -11,15 +11,20 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table>
|
||||
<tbody>
|
||||
<% for (const upload of recentUploads) { %>
|
||||
<tr>
|
||||
<td><%= upload.FileName %></td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="row row-cols-1">
|
||||
<% for (const upload of recentUploads) { %>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<% if (upload.MediaType.startsWith("image/")) { %>
|
||||
<img src="<%= domains[upload.DomainId].HasHttps ? "https" : "http" %>://<%= domains[upload.DomainId].Domain %>/<%= upload.MediaTag %>" height="30" width="50">
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="col"><%= upload.FileName %></div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue