Generic MIME types (file types) such as application/octet-stream can how have sub types for handlers (archive, info extract, ...)
+ Add Amiga DMS support via xdms
This commit is contained in:
parent
95422f71ba
commit
3ecadebf91
|
@ -11,6 +11,7 @@ const resolveMimeType = require('./mime_util.js').resolveMimeType;
|
|||
const fs = require('graceful-fs');
|
||||
const _ = require('lodash');
|
||||
const pty = require('node-pty');
|
||||
const paths = require('path');
|
||||
|
||||
let archiveUtil;
|
||||
|
||||
|
@ -75,32 +76,56 @@ module.exports = class ArchiveUtil {
|
|||
}
|
||||
|
||||
if(_.isObject(Config.fileTypes)) {
|
||||
Object.keys(Config.fileTypes).forEach(mimeType => {
|
||||
const fileType = Config.fileTypes[mimeType];
|
||||
if(fileType.sig) {
|
||||
fileType.sig = Buffer.from(fileType.sig, 'hex');
|
||||
fileType.offset = fileType.offset || 0;
|
||||
const updateSig = (ft) => {
|
||||
ft.sig = Buffer.from(ft.sig, 'hex');
|
||||
ft.offset = ft.offset || 0;
|
||||
|
||||
// :TODO: this is broken: sig is NOT this long, it's sig.length long; offset needs to allow for -negative values as well
|
||||
const sigLen = fileType.offset + fileType.sig.length;
|
||||
const sigLen = ft.offset + ft.sig.length;
|
||||
if(sigLen > this.longestSignature) {
|
||||
this.longestSignature = sigLen;
|
||||
}
|
||||
};
|
||||
|
||||
Object.keys(Config.fileTypes).forEach(mimeType => {
|
||||
const fileType = Config.fileTypes[mimeType];
|
||||
if(Array.isArray(fileType)) {
|
||||
fileType.forEach(ft => {
|
||||
if(ft.sig) {
|
||||
updateSig(ft);
|
||||
}
|
||||
});
|
||||
} else if(fileType.sig) {
|
||||
updateSig(fileType);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getArchiver(mimeTypeOrExtension) {
|
||||
mimeTypeOrExtension = resolveMimeType(mimeTypeOrExtension);
|
||||
getArchiver(mimeTypeOrExtension, justExtention) {
|
||||
const mimeType = resolveMimeType(mimeTypeOrExtension);
|
||||
|
||||
if(!mimeTypeOrExtension) { // lookup returns false on failure
|
||||
if(!mimeType) { // lookup returns false on failure
|
||||
return;
|
||||
}
|
||||
|
||||
const archiveHandler = _.get( Config, [ 'fileTypes', mimeTypeOrExtension, 'archiveHandler'] );
|
||||
if(archiveHandler) {
|
||||
return _.get( Config, [ 'archives', 'archivers', archiveHandler ] );
|
||||
let fileType = _.get(Config, [ 'fileTypes', mimeType ] );
|
||||
|
||||
if(Array.isArray(fileType)) {
|
||||
if(!justExtention) {
|
||||
// need extention for lookup; ambiguous as-is :(
|
||||
return;
|
||||
}
|
||||
// further refine by extention
|
||||
fileType = fileType.find(ft => justExtention === ft.ext);
|
||||
}
|
||||
|
||||
if(!_.isObject(fileType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(fileType.archiveHandler) {
|
||||
return _.get( Config, [ 'archives', 'archivers', fileType.archiveHandler ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,18 +152,21 @@ module.exports = class ArchiveUtil {
|
|||
}
|
||||
|
||||
const archFormat = _.findKey(Config.fileTypes, fileTypeInfo => {
|
||||
if(!fileTypeInfo.sig) {
|
||||
const fileTypeInfos = Array.isArray(fileTypeInfo) ? fileTypeInfo : [ fileTypeInfo ];
|
||||
return fileTypeInfos.find(fti => {
|
||||
if(!fti.sig || !fti.archiveHandler) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const lenNeeded = fileTypeInfo.offset + fileTypeInfo.sig.length;
|
||||
const lenNeeded = fti.offset + fti.sig.length;
|
||||
|
||||
if(bytesRead < lenNeeded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const comp = buf.slice(fileTypeInfo.offset, fileTypeInfo.offset + fileTypeInfo.sig.length);
|
||||
return (fileTypeInfo.sig.equals(comp));
|
||||
const comp = buf.slice(fti.offset, fti.offset + fti.sig.length);
|
||||
return (fti.sig.equals(comp));
|
||||
});
|
||||
});
|
||||
|
||||
return cb(archFormat ? null : Errors.General('Unknown type'), archFormat);
|
||||
|
@ -162,7 +190,7 @@ module.exports = class ArchiveUtil {
|
|||
}
|
||||
|
||||
compressTo(archType, archivePath, files, cb) {
|
||||
const archiver = this.getArchiver(archType);
|
||||
const archiver = this.getArchiver(archType, paths.extname(archivePath));
|
||||
|
||||
if(!archiver) {
|
||||
return cb(Errors.Invalid(`Unknown archive type: ${archType}`));
|
||||
|
@ -196,7 +224,7 @@ module.exports = class ArchiveUtil {
|
|||
haveFileList = true;
|
||||
}
|
||||
|
||||
const archiver = this.getArchiver(archType);
|
||||
const archiver = this.getArchiver(archType, paths.extname(archivePath));
|
||||
|
||||
if(!archiver) {
|
||||
return cb(Errors.Invalid(`Unknown archive type: ${archType}`));
|
||||
|
@ -236,7 +264,7 @@ module.exports = class ArchiveUtil {
|
|||
}
|
||||
|
||||
listEntries(archivePath, archType, cb) {
|
||||
const archiver = this.getArchiver(archType);
|
||||
const archiver = this.getArchiver(archType, paths.extname(archivePath));
|
||||
|
||||
if(!archiver) {
|
||||
return cb(Errors.Invalid(`Unknown archive type: ${archType}`));
|
||||
|
|
|
@ -297,6 +297,16 @@ function getDefaultConfig() {
|
|||
'--filemodifydate', '--fileaccessdate', '--fileinodechangedate', '--createdate', '--modifydate',
|
||||
'--metadatadate', '--xmptoolkit'
|
||||
]
|
||||
},
|
||||
XDMS2Desc : {
|
||||
// http://manpages.ubuntu.com/manpages/trusty/man1/xdms.1.html
|
||||
cmd : 'xdms',
|
||||
args : [ 'd', '{filePath}' ]
|
||||
},
|
||||
XDMS2LongDesc : {
|
||||
// http://manpages.ubuntu.com/manpages/trusty/man1/xdms.1.html
|
||||
cmd : 'xdms',
|
||||
args : [ 'f', '{filePath}' ]
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -426,13 +436,20 @@ function getDefaultConfig() {
|
|||
sig : '377abcaf271c',
|
||||
offset : 0,
|
||||
archiveHandler : '7Zip',
|
||||
}
|
||||
},
|
||||
|
||||
// :TODO: update archives::formats to fall here
|
||||
// * archive handler -> archiveHandler (consider archive if archiveHandler present)
|
||||
// * sig, offset, ...
|
||||
// * mime-db -> exts lookup
|
||||
// *
|
||||
//
|
||||
// Generics that need further mapping
|
||||
//
|
||||
'application/octet-stream' : [
|
||||
{
|
||||
desc : 'Amiga DISKMASHER',
|
||||
sig : '444d5321', // DMS!
|
||||
ext : '.dms',
|
||||
shortDescUtil : 'XDMS2Desc',
|
||||
longDescUtil : 'XDMS2LongDesc',
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
archives : {
|
||||
|
|
|
@ -24,6 +24,7 @@ const controlCodesToAnsi = require('./color_codes.js').controlCodesToAnsi;
|
|||
const async = require('async');
|
||||
const _ = require('lodash');
|
||||
const moment = require('moment');
|
||||
const paths = require('path');
|
||||
|
||||
exports.moduleInfo = {
|
||||
name : 'File Area List',
|
||||
|
@ -252,7 +253,18 @@ exports.getModule = class FileAreaList extends MenuModule {
|
|||
|
||||
if(entryInfo.archiveType) {
|
||||
const mimeType = resolveMimeType(entryInfo.archiveType);
|
||||
entryInfo.archiveTypeDesc = mimeType ? _.get(Config, [ 'fileTypes', mimeType, 'desc' ] ) || mimeType : entryInfo.archiveType;
|
||||
let desc;
|
||||
if(mimeType) {
|
||||
let fileType = _.get(Config, [ 'fileTypes', mimeType ] );
|
||||
|
||||
if(Array.isArray(fileType)) {
|
||||
// further refine by extention
|
||||
fileType = fileType.find(ft => paths.extname(currEntry.fileName) === ft.ext);
|
||||
}
|
||||
desc = fileType && fileType.desc;
|
||||
}
|
||||
entryInfo.archiveTypeDesc = desc || mimeType || entryInfo.archiveType;
|
||||
//entryInfo.archiveTypeDesc = mimeType ? _.get(Config, [ 'fileTypes', mimeType, 'desc' ] ) || mimeType : entryInfo.archiveType;
|
||||
} else {
|
||||
entryInfo.archiveTypeDesc = 'N/A';
|
||||
}
|
||||
|
|
|
@ -487,8 +487,19 @@ function populateFileEntryWithArchive(fileEntry, filePath, stepInfo, iterator, c
|
|||
);
|
||||
}
|
||||
|
||||
function getInfoExtractUtilForDesc(mimeType, descType) {
|
||||
let util = _.get(Config, [ 'fileTypes', mimeType, `${descType}DescUtil` ]);
|
||||
function getInfoExtractUtilForDesc(mimeType, filePath, descType) {
|
||||
let fileType = _.get(Config, [ 'fileTypes', mimeType ] );
|
||||
|
||||
if(Array.isArray(fileType)) {
|
||||
// further refine by extention
|
||||
fileType = fileType.find(ft => paths.extname(filePath) === ft.ext);
|
||||
}
|
||||
|
||||
if(!_.isObject(fileType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let util = _.get(fileType, `${descType}DescUtil`);
|
||||
if(!_.isString(util)) {
|
||||
return;
|
||||
}
|
||||
|
@ -508,7 +519,7 @@ function populateFileEntryInfoFromFile(fileEntry, filePath, cb) {
|
|||
}
|
||||
|
||||
async.eachSeries( [ 'short', 'long' ], (descType, nextDesc) => {
|
||||
const util = getInfoExtractUtilForDesc(mimeType, descType);
|
||||
const util = getInfoExtractUtilForDesc(mimeType, filePath, descType);
|
||||
if(!util) {
|
||||
return nextDesc(null);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ ENiGMA BBS makes use of a few packages for unarchiving and modem support. They'r
|
|||
running ENiGMA, but without them you'll miss certain functionality. Once installed, they should be made
|
||||
available on your system path.
|
||||
|
||||
| Package | Description | Ubuntu Package | CentOS Package Name | Windows Package |
|
||||
| Package | Description | Debian/Ubuntu Package (APT/DEP) | Red Hat Package (YUM/RPM) | Windows Package |
|
||||
|------------|-----------------------------------|--------------------------------------------|---------------------------------------------------|------------------------------------------------------------------|
|
||||
| arj | Unpacking arj archives | `arj` | n/a, binaries [here](http://arj.sourceforge.net/) | [ARJ](http://arj.sourceforge.net/) |
|
||||
| 7zip | Unpacking zip, rar, archives | `p7zip-full` | `p7zip-full` | [7-zip](http://www.7-zip.org/) |
|
||||
|
@ -58,8 +58,8 @@ available on your system path.
|
|||
| Rar | Unpacking rar archives | `unrar` | n/a, binaries [here](https://www.rarlab.com/download.htm) | Unknown |
|
||||
| lrzsz | sz/rz: X/Y/Z modem support | `lrzsz` | `lrzsz` | Unknown |
|
||||
| sexyz | SexyZ modem support | [sexyz](https://l33t.codes/outgoing/sexyz) | [sexyz](https://l33t.codes/outgoing/sexyz) | Available with [Synchronet](http://wiki.synchro.net/install:win) |
|
||||
|
||||
- exiftool & other external tools
|
||||
| exiftool | [ExifTool](https://www.sno.phy.queensu.ca/~phil/exiftool/) | libimage-exiftool-perl | perl-Image-ExifTool | Unknown
|
||||
| xdms | Unpack/view Amiga DMS | [xdms](http://manpages.ubuntu.com/manpages/trusty/man1/xdms.1.html) | xdms | Unknown
|
||||
|
||||
## Config Files
|
||||
|
||||
|
|
Loading…
Reference in New Issue