diff --git a/ass.js b/ass.js
index 0a0567f..0b10cba 100755
--- a/ass.js
+++ b/ass.js
@@ -14,6 +14,8 @@ const fs = require('fs-extra');
const express = require('express');
const useragent = require('express-useragent');
const multer = require('multer');
+const DateTime = require('luxon').DateTime;
+const OpenGraph = require('./ogp');
const { path, saveData, log, verify, generateToken, generateId } = require('./utils');
//#endregion
@@ -82,6 +84,17 @@ function startup() {
let trueDomain = getTrueDomain(req.headers["x-ass-domain"]);
let generator = req.headers["x-ass-access"] || resourceIdType;
+ // Get the uploaded time in milliseconds
+ req.file.timestamp = DateTime.now().toMillis();
+
+ // Attach any embed overrides, if necessary
+ req.file.opengraph = {
+ title: req.headers['x-ass-og-title'],
+ description: req.headers['x-ass-og-description'],
+ author: req.headers['x-ass-og-author'],
+ color: req.headers['x-ass-og-color']
+ };
+
// Save the file information
let resourceId = generateId(generator, resourceIdSize, req.file.originalname);
data[resourceId.split('.')[0]] = req.file;
@@ -107,8 +120,8 @@ function startup() {
// If the ID is invalid, return 404
if (!resourceId || !data[resourceId]) return res.sendStatus(404);
- // If a Discord client wants to load an mp4, send the data needed for a proper inline embed
- if (req.useragent.isBot && data[resourceId].mimetype == 'video/mp4') return res.type('html').send(genHtml(resourceId));
+ // If the client is Discord, send an Open Graph embed
+ if (req.useragent.isBot) return res.type('html').send(new OpenGraph(getTrueHttp(), getTrueDomain(), resourceId, data[resourceId]).build());
// Read the file and send it to the client
fs.readFile(path(data[resourceId].path))
@@ -147,16 +160,3 @@ function getTrueHttp() {
function getTrueDomain(d = domain) {
return d.concat((port == 80 || port == 443 || isProxied) ? '' : `:${port}`);
}
-
-function genHtml(resourceId) {
- return `
-
-
- ass
-
-
-
- ass
-
-`;
-}
diff --git a/ogp.js b/ogp.js
new file mode 100644
index 0000000..29703f2
--- /dev/null
+++ b/ogp.js
@@ -0,0 +1,80 @@
+const Mustache = require('mustache');
+const DateTime = require('luxon').DateTime;
+const github = require('./package.json').homepage;
+const { formatBytes } = require('./utils');
+
+//
+class OpenGraph {
+ http;
+ domain;
+ resourceId;
+
+ filename;
+ type;
+ size;
+ timestamp;
+
+ title;
+ description;
+ author;
+ color;
+
+ constructor(http, domain, resourceId, { originalname, mimetype, size, timestamp, opengraph }) {
+ this.http = http;
+ this.domain = domain;
+ this.resourceId = resourceId;
+
+ this.type = mimetype;
+ this.filename = originalname;
+ this.size = size;
+ this.timestamp = timestamp;
+
+ this.title = opengraph.title || '';
+ this.description = opengraph.description || '';
+ this.author = opengraph.author || '';
+ this.color = opengraph.color || '';
+ }
+
+ build() {
+ return Mustache.render(html, {
+ github,
+
+ http: this.http,
+ domain: this.domain,
+ resourceId: this.resourceId,
+
+ ogtype: this.type.includes('video') ? 'video.other' : 'image',
+ type: this.type.includes('video') ? 'video' : 'image',
+ ext: this.type.includes('video') ? '.mp4' : '',
+
+ title: (this.title.length != 0) ? `` : '',
+ description: (this.description.length != 0) ? `` : '',
+ site: (this.author.length != 0) ? `` : '',
+ color: (this.color.length != 0) ? `` : '',
+ card: !this.type.includes('video') ? `` : '',
+ })
+ .replace(new RegExp('&size', 'g'), formatBytes(this.size))
+ .replace(new RegExp('&filename', 'g'), this.filename)
+ .replace(new RegExp('×tamp', 'g'), DateTime.fromMillis(this.timestamp).toLocaleString(DateTime.DATETIME_MED));
+ }
+}
+
+const html = `
+
+
+ ass
+
+
+ {{{title}}}
+ {{{description}}}
+ {{{site}}}
+ {{{color}}}
+ {{{card}}}
+
+
+ Open Graph response for ass.
+
+
+`;
+
+module.exports = OpenGraph;
diff --git a/package-lock.json b/package-lock.json
index 8d1f917..7639471 100755
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,19 +1,21 @@
{
"name": "ass",
- "version": "1.0.0",
+ "version": "0.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ass",
- "version": "1.0.0",
+ "version": "0.1.0",
"license": "ISC",
"dependencies": {
"crypto-random-string": "3.3.1",
"express": "^4.17.1",
"express-useragent": "^1.0.15",
"fs-extra": "^9.1.0",
+ "luxon": "^1.26.0",
"multer": "^1.4.2",
+ "mustache": "^4.2.0",
"prompt": "^1.1.0",
"uuid": "^8.3.2"
}
@@ -493,6 +495,14 @@
"universalify": "^2.0.0"
}
},
+ "node_modules/luxon": {
+ "version": "1.26.0",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.26.0.tgz",
+ "integrity": "sha512-+V5QIQ5f6CDXQpWNICELwjwuHdqeJM1UenlZWx5ujcRMc9venvluCjFb4t5NYLhb6IhkbMVOxzVuOqkgMxee2A==",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -594,6 +604,14 @@
"node": ">= 0.10.0"
}
},
+ "node_modules/mustache": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
+ "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
+ "bin": {
+ "mustache": "bin/mustache"
+ }
+ },
"node_modules/mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
@@ -1380,6 +1398,11 @@
"universalify": "^2.0.0"
}
},
+ "luxon": {
+ "version": "1.26.0",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.26.0.tgz",
+ "integrity": "sha512-+V5QIQ5f6CDXQpWNICELwjwuHdqeJM1UenlZWx5ujcRMc9venvluCjFb4t5NYLhb6IhkbMVOxzVuOqkgMxee2A=="
+ },
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -1454,6 +1477,11 @@
"xtend": "^4.0.0"
}
},
+ "mustache": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
+ "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="
+ },
"mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
diff --git a/package.json b/package.json
index 0fa2b4e..10f44c3 100755
--- a/package.json
+++ b/package.json
@@ -28,8 +28,10 @@
"express": "^4.17.1",
"express-useragent": "^1.0.15",
"fs-extra": "^9.1.0",
+ "luxon": "^1.26.0",
"multer": "^1.4.2",
+ "mustache": "^4.2.0",
"prompt": "^1.1.0",
"uuid": "^8.3.2"
}
-}
\ No newline at end of file
+}
diff --git a/utils.js b/utils.js
index e4d81ce..d441e72 100755
--- a/utils.js
+++ b/utils.js
@@ -20,5 +20,11 @@ module.exports = {
generateId: (mode, lenth, originalName) =>
(mode == idModes.zws) ? zwsGen(lenth)
: (mode == idModes.r) ? randomGen(lenth)
- : originalName
-}
\ No newline at end of file
+ : originalName,
+ formatBytes: (bytes, decimals = 2) => {
+ if (bytes === 0) return '0 Bytes';
+ let sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+ let i = Math.floor(Math.log(bytes) / Math.log(1024));
+ return parseFloat((bytes / Math.pow(1024, i)).toFixed(decimals < 0 ? 0 : decimals)) + ' ' + sizes[i];
+ }
+}