feature(client) view: add ability to detect file type when extension is missing (coderaiser/cloudcmd#287)

This commit is contained in:
coderaiser 2021-02-03 13:20:33 +02:00
parent 0d79531b69
commit 2b9705d9fc
4 changed files with 68 additions and 16 deletions

View file

@ -124,7 +124,7 @@ async function show(data, options = {}) {
Images.show.load();
const path = prefixURL + Info.path;
const type = options.raw ? '' : getType(path);
const type = options.raw ? '' : await getType(path);
switch(type) {
default:
@ -137,7 +137,7 @@ async function show(data, options = {}) {
return viewHtml(path);
case 'image':
return viewImage(prefixURL);
return viewImage(Info.path, prefixURL);
case 'media':
return await viewMedia(path);
@ -245,17 +245,18 @@ function hide() {
modal.close();
}
function viewImage(prefixURL) {
function viewImage(path, prefixURL) {
const isSupportedImage = (a) => isImage(a) || a === path;
const makeTitle = (path) => {
return {
href: prefixURL + path,
href: `${prefixURL}${path}`,
title: encode(basename(path)),
};
};
const names = Info.files
.map(DOM.getCurrentPath)
.filter(isImage);
.filter(isSupportedImage);
const titles = names
.map(makeTitle);

View file

@ -1,5 +1,6 @@
'use strict';
const {extname} = require('path');
const currify = require('currify');
const testRegExp = currify((name, reg) => reg.test(name));
const getRegExp = (ext) => RegExp(`\\.${ext}$`, 'i');
@ -8,20 +9,25 @@ const isPDF = (a) => /\.pdf$/i.test(a);
const isHTML = (a) => /\.html$/.test(a);
const isMarkdown = (a) => /.\.md$/.test(a);
module.exports.getType = (name) => {
if (isPDF(name))
module.exports.getType = async (path) => {
const ext = extname(path);
if (!ext)
path = await detectType(path);
if (isPDF(path))
return 'pdf';
if (isImage(name))
if (isImage(path))
return 'image';
if (isMedia(name))
if (isMedia(path))
return 'media';
if (isHTML(name))
if (isHTML(path))
return 'html';
if (isMarkdown(name))
if (isMarkdown(path))
return 'markdown';
};
@ -54,3 +60,16 @@ function isAudio(name) {
function isVideo(name) {
return /\.(mp4|avi|webm)$/i.test(name);
}
module.exports._detectType = detectType;
async function detectType(path) {
const {headers} = await fetch(path);
for (const [name, value] of headers) {
if (name === 'content-type')
return `.${value.split('/').pop()}`;
}
return '';
}

View file

@ -1,19 +1,51 @@
'use strict';
const test = require('supertape');
const {isAudio} = require('./types');
const {test, stub} = require('supertape');
const {isAudio, _detectType} = require('./types');
test('cloudcmd: client: view: isAudio', (t) => {
test('cloudcmd: client: view: types: isAudio', (t) => {
const result = isAudio('hello.mp3');
t.ok(result);
t.end();
});
test('cloudcmd: client: view: isAudio: no', (t) => {
test('cloudcmd: client: view: types: isAudio: no', (t) => {
const result = isAudio('hello');
t.notOk(result);
t.end();
});
test('cloudcmd: client: view: types: detectType', async (t) => {
const fetch = stub().returns({
headers: [],
});
const originalFetch = global.fetch;
global.fetch = fetch;
await _detectType('/hello');
global.fetch = originalFetch;
t.calledWith(fetch, ['/hello']);
t.end();
});
test('cloudcmd: client: view: types: detectType: found', async (t) => {
const fetch = stub().returns({
headers: [
['content-type', 'image/png'],
],
});
const originalFetch = global.fetch;
global.fetch = fetch;
const result = await _detectType('/hello');
global.fetch = originalFetch;
t.equal(result, '.png');
t.end();
});

View file

@ -122,7 +122,7 @@
"putout": "^14.0.0",
"redzip": "^1.6.4",
"rendy": "^3.0.0",
"restafary": "^9.1.0",
"restafary": "^9.5.0",
"restbox": "^3.0.0",
"shortdate": "^2.0.0",
"simport": "^1.0.1",