├── .gitignore ├── .prettierrc.js ├── .eslintrc ├── README.md ├── package.json ├── LICENSE └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | package-lock.json -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 160, 3 | tabWidth: 4, 4 | singleQuote: true 5 | }; 6 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "indent": 0, 4 | "no-await-in-loop": 0 5 | }, 6 | "extends": ["nodemailer", "prettier"], 7 | "parserOptions": { 8 | "ecmaVersion": 2017 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # getattachments 2 | 3 | ## Install 4 | 5 | ```bash 6 | $ npm install -g getattachments 7 | ``` 8 | 9 | ## Usage 10 | 11 | Pipe an email message to `getattachments` command. All files are dumped to current folder. If a file exists, it gets overwritten. 12 | 13 | ``` 14 | cat message.eml | getattachments 15 | ``` 16 | 17 | ## License 18 | 19 | **MIT** 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getattachments", 3 | "version": "1.1.0", 4 | "description": "Extarct mime parts from emails", 5 | "main": "index.js", 6 | "author": "", 7 | "license": "MIT", 8 | "dependencies": { 9 | "libmime": "4.1.1", 10 | "mailsplit": "4.4.1" 11 | }, 12 | "bin": { 13 | "getattachments": "./index.js" 14 | }, 15 | "devDependencies": { 16 | "eslint-config-nodemailer": "1.2.0", 17 | "eslint-config-prettier": "4.2.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Andris Reinman 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 11 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 12 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 13 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 14 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 15 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 16 | SOFTWARE. 17 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* eslint no-unused-expressions: 0, global-require: 0, no-console: 0 */ 4 | 'use strict'; 5 | 6 | const mailsplit = require('mailsplit'); 7 | const Splitter = mailsplit.Splitter; 8 | const Joiner = mailsplit.Joiner; 9 | const Streamer = mailsplit.Streamer; 10 | const libmime = require('libmime'); 11 | const path = require('path'); 12 | const fs = require('fs'); 13 | 14 | let streamer = new Streamer(node => !node.multipart); 15 | 16 | let filenames = new Set(); 17 | 18 | streamer.on('node', data => { 19 | let extension = libmime.detectExtension(data.node.contentType || 'application/octet-stream'); 20 | let filename = path.parse(data.node.filename || (data.node.contentType || 'attachment').split('/').shift() + '.' + extension); 21 | 22 | let base = (filename.name || 'attachment') 23 | .replace(/[\/\\]/g, '_') 24 | .replace(/\.+/g, '.') 25 | .replace(/[\x00-\x1F]/g, '_'); // eslint-disable-line no-control-regex 26 | let fname; 27 | let i = 0; 28 | while (1) { 29 | // eslint-disable-line no-constant-condition 30 | fname = base + (i ? '-' + i : '') + filename.ext; 31 | i++; 32 | if (filenames.has(fname)) { 33 | continue; 34 | } 35 | filenames.add(fname); 36 | break; 37 | } 38 | 39 | data.decoder.pipe(fs.createWriteStream(path.join(process.cwd(), fname))); 40 | data.done(); 41 | }); 42 | 43 | process.stdin 44 | .pipe(new Splitter()) 45 | .pipe(streamer) 46 | .pipe(new Joiner()) 47 | .pipe(process.stdout); 48 | --------------------------------------------------------------------------------