exiftool-vendored
Advanced tools
Comparing version 4.5.0 to 4.6.0
@@ -0,1 +1,3 @@ | ||
# Changelog | ||
## Versioning | ||
@@ -15,3 +17,3 @@ | ||
* 🌱 New releases of ExifTool with no externally visible changes | ||
* 🌱 New releases of ExifTool with no externally visible changes | ||
* ✨ Backwards-compatible features | ||
@@ -24,4 +26,15 @@ | ||
## Changelog | ||
## Version history | ||
### v4.6.0 | ||
* 🌱 ExifTool upgraded to | ||
[v10.66](http://www.sno.phy.queensu.ca/~phil/exiftool/history.html#v10.66) | ||
* ✨ Pull in new `batch-cluster` with more aggressive child process management | ||
(uses `taskkill` on win32 platforms and `kill -9` on unixish platforms) | ||
* ✨ ExifTool constructor defaults were relaxed to handle slow NAS | ||
* ✨ Upgraded to Mocha 4.0. Added calls to `exiftool.end()` in test `after` | ||
blocks and the README so `--exit` isn't necessary. | ||
* 📦 `salita --update` | ||
### v4.5.0 | ||
@@ -34,3 +47,3 @@ | ||
* 📦 reverted batch-cluster reference | ||
* 📦 reverted batch-cluster reference | ||
@@ -73,3 +86,3 @@ ### v4.4.0 | ||
* 📦 Added `ExifTool.pids` (used by a couple new integration tests) | ||
* 📦 Rebuilt `Tags` with additional sample images and looser tag filtering. | ||
* 📦 Rebuilt `Tags` with additional sample images and looser tag filtering. | ||
@@ -139,4 +152,4 @@ ### v3.2.0 | ||
current exiftool process is recycled. | ||
* ✨ Rebuilt `Tags` definitions using more (6,412!) sample image files | ||
(via `npm run mktags ~/sample-images`), including many RAW image types | ||
* ✨ Rebuilt `Tags` definitions using more (6,412!) sample image files | ||
(via `npm run mktags ~/sample-images`), including many RAW image types | ||
(like `.ORF`, `.CR2`, and `.NEF`). | ||
@@ -171,3 +184,3 @@ | ||
* 📦 Upgraded to TypeScript 2.2 | ||
* 🐞 `update/io.ts` error message didn't handle null statuscodes properly | ||
* 🐞 `update/io.ts` error message didn't handle null statuscodes properly | ||
* 🐞 `update/mktags.ts` had a counting bug exposed by TS 2.2 | ||
@@ -213,3 +226,3 @@ | ||
* ✨ `extractThumbnail` and `extractPreview` implemented to pull out EXIF-embedded images | ||
* 📦 Rebuilt package.json.files section | ||
* 📦 Rebuilt package.json.files section | ||
@@ -223,5 +236,5 @@ ### v2.0.1 | ||
* 📦 Switch back to `platform-dependent-modules`. | ||
[npm warnings](http://stackoverflow.com/questions/15176082/npm-package-json-os-specific-dependency) | ||
aren't awesome. | ||
* 📦 Don't include tests or updater in the published package | ||
[npm warnings](http://stackoverflow.com/questions/15176082/npm-package-json-os-specific-dependency) | ||
aren't awesome. | ||
* 📦 Don't include tests or updater in the published package | ||
@@ -244,3 +257,3 @@ ### v1.5.0 | ||
* 🌱 ExifTool upgraded to v10.36 | ||
* ✨ `Tag.Error` exposed for unsupported file types. | ||
* ✨ `Tag.Error` exposed for unsupported file types. | ||
@@ -260,3 +273,3 @@ ### v1.2.0 | ||
* ✨ Added typings reference in the package.json | ||
* 🌱 Upgraded vendored exiftool to 10.33 | ||
* 🌱 Upgraded vendored exiftool to 10.33 | ||
@@ -263,0 +276,0 @@ ### v0.4.0 |
@@ -5,5 +5,9 @@ export declare function compact<T>(array: (T | undefined | null)[]): T[]; | ||
/** | ||
* | ||
* @param millis [0,1000) | ||
* @return the decimal fraction of the second (to maximally microsecond precision) | ||
* Given a time value in milliseconds, return a decimal in seconds units, | ||
* rounded to the given precision, without zero right or left padding. | ||
* @export | ||
* @param {number} millis [0,1000) | ||
* @param {number} [precision=6] how many decimal fraction digits to retain | ||
* @returns {string} the decimal fraction of the second (to maximally | ||
* microsecond precision) | ||
*/ | ||
@@ -10,0 +14,0 @@ export declare function millisToFractionalPart(millis: number, precision?: number): string; |
@@ -24,3 +24,3 @@ "use strict"; | ||
var s = i.toString(10); | ||
return (s.length >= 2) ? s : "0" + s; | ||
return s.length >= 2 ? s : "0" + s; | ||
}); | ||
@@ -37,6 +37,6 @@ } | ||
var s = Math.abs(i).toString(10); | ||
return "-" + ((s.length >= 2) ? s : "0" + s); | ||
return "-" + (s.length >= 2 ? s : "0" + s); | ||
} | ||
else { | ||
return ("000" + i).slice(Math.min(-3, -(Math.ceil(Math.log10(i))))); | ||
return ("000" + i).slice(Math.min(-3, -Math.ceil(Math.log10(i)))); | ||
} | ||
@@ -47,9 +47,15 @@ }); | ||
/** | ||
* | ||
* @param millis [0,1000) | ||
* @return the decimal fraction of the second (to maximally microsecond precision) | ||
* Given a time value in milliseconds, return a decimal in seconds units, | ||
* rounded to the given precision, without zero right or left padding. | ||
* @export | ||
* @param {number} millis [0,1000) | ||
* @param {number} [precision=6] how many decimal fraction digits to retain | ||
* @returns {string} the decimal fraction of the second (to maximally | ||
* microsecond precision) | ||
*/ | ||
function millisToFractionalPart(millis, precision) { | ||
if (precision === void 0) { precision = 6; } | ||
var frac = (millis / 1000).toPrecision(precision).split("").slice(1); // pop off the initial "0" | ||
var frac = (millis / 1000).toPrecision(precision).split(""); | ||
if (frac[0] === "0") | ||
frac.shift(); // pop off the initial "0" | ||
// strip off microsecond zero padding: | ||
@@ -86,6 +92,6 @@ while (frac.length > 4 && frac[frac.length - 1] === "0") { | ||
else { | ||
var sign = (tzoffsetMinutes >= 0) ? "+" : "-"; | ||
var sign = tzoffsetMinutes >= 0 ? "+" : "-"; | ||
var tzoff = Math.abs(tzoffsetMinutes); | ||
var hours = Math.floor(tzoff / 60); | ||
var mins = tzoff - (hours * 60); | ||
var mins = tzoff - hours * 60; | ||
return "" + sign + pad2(hours) + ":" + pad2(mins); | ||
@@ -113,3 +119,3 @@ } | ||
this.tzoffsetMinutes = tzoffsetMinutes; | ||
this.millis = (secondFraction != null) ? secondFraction * 1000 : 0; | ||
this.millis = secondFraction != null ? secondFraction * 1000 : 0; | ||
} | ||
@@ -123,3 +129,4 @@ ExifTime.for = function (input, tzoffsetMinutes) { | ||
ExifTime.prototype.toString = function () { | ||
return pad2(this.hour, this.minute, this.second).join(":") + millisToFractionalPart(this.millis); | ||
return (pad2(this.hour, this.minute, this.second).join(":") + | ||
millisToFractionalPart(this.millis)); | ||
}; | ||
@@ -182,3 +189,3 @@ ExifTime.regex = /^(\d{2}):(\d{2}):(\d{2})(\.\d{1,9})?$/; | ||
_this.tzoffsetMinutes = tzoffsetMinutes; | ||
_this.millis = (secondFraction != null) ? secondFraction * 1000 : 0; | ||
_this.millis = secondFraction != null ? secondFraction * 1000 : 0; | ||
return _this; | ||
@@ -242,5 +249,9 @@ } | ||
} | ||
else if (tagName.includes("UTC") || tagName.includes("GPS") || input.toString().endsWith("Z")) { | ||
else if (tagName.includes("UTC") || | ||
tagName.includes("GPS") || | ||
input.toString().endsWith("Z")) { | ||
_this.tzOffsetMinutes = 0; | ||
_this.inputWithoutTimezone = input.endsWith("Z") ? input.slice(0, -1) : input; | ||
_this.inputWithoutTimezone = input.endsWith("Z") | ||
? input.slice(0, -1) | ||
: input; | ||
} | ||
@@ -283,8 +294,8 @@ else { | ||
var tagValue = tz.inputWithoutTimezone; | ||
return ExifDateTime.for(tagValue, tzoffset) | ||
|| ExifDate.for(tagValue, tzoffset) | ||
|| ExifTime.for(tagValue, tzoffset) | ||
|| rawTagValue; | ||
return (ExifDateTime.for(tagValue, tzoffset) || | ||
ExifDate.for(tagValue, tzoffset) || | ||
ExifTime.for(tagValue, tzoffset) || | ||
rawTagValue); | ||
} | ||
exports.parse = parse; | ||
//# sourceMappingURL=DateTime.js.map |
@@ -9,3 +9,4 @@ import { ExifToolTask } from "./ExifToolTask"; | ||
* | ||
* Instances should be shared: consider using the exported singleton instance of this class, `exiftool`. | ||
* Instances should be shared: consider using the exported singleton | ||
* instance of this class, `exiftool`. | ||
*/ | ||
@@ -22,25 +23,26 @@ export declare class ExifTool { | ||
/** | ||
* @param maxProcs The maximum number of ExifTool child processes to spawn | ||
* when load merits. Defaults to 1. | ||
* @param maxTasksPerProcess The maximum number of requests a given ExifTool | ||
* process will service before being retired. Defaults to 250, to balance | ||
* performance with memory usage. | ||
* @param spawnTimeoutMillis Spawning new ExifTool processes must not take | ||
* longer than `spawnTimeoutMillis` millis before it times out and a new | ||
* attempt is made. Be pessimistic here--windows can regularly take several | ||
* seconds to spin up a process, thanks to antivirus shenanigans. This can't | ||
* be set to a value less than 100ms. Defaults to 20 seconds, to accomodate | ||
* slow Windows machines. | ||
* @param taskTimeoutMillis If requests to ExifTool take longer than this, | ||
* presume the underlying process is dead and we should restart the task. This | ||
* can't be set to a value less than 10ms, and really should be set to at more | ||
* than a second unless `taskRetries` is sufficiently large. Defaults to 5 | ||
* @param maxProcs The maximum number of ExifTool child processes to | ||
* spawn when load merits. Defaults to 1. | ||
* @param maxTasksPerProcess The maximum number of requests a given | ||
* ExifTool process will service before being retired. Defaults to 250, | ||
* to balance performance with memory usage. | ||
* @param spawnTimeoutMillis Spawning new ExifTool processes must not | ||
* take longer than `spawnTimeoutMillis` millis before it times out and a | ||
* new attempt is made. Be pessimistic here--windows can regularly take | ||
* several seconds to spin up a process, thanks to antivirus shenanigans. | ||
* This can't be set to a value less than 100ms. Defaults to 20 seconds, | ||
* to accomodate slow Windows machines. | ||
* @param taskTimeoutMillis If requests to ExifTool take longer than | ||
* this, presume the underlying process is dead and we should restart the | ||
* task. This can't be set to a value less than 10ms, and really should | ||
* be set to at more than a second unless `taskRetries` is sufficiently | ||
* large or all writes will be to a fast local disk. Defaults to 5 | ||
* seconds. | ||
* @param onIdleIntervalMillis An interval timer is scheduled to do periodic | ||
* maintenance of underlying child processes with this periodicity. Defaults | ||
* to 2 seconds. | ||
* @param taskRetries The number of times a task can error or timeout and be | ||
* retried. Defaults to 2. | ||
* @param batchClusterOpts Allows for overriding any configuration used by | ||
* `BatchCluster` | ||
* @param onIdleIntervalMillis An interval timer is scheduled to do | ||
* periodic maintenance of underlying child processes with this | ||
* periodicity. Defaults to 2 seconds. | ||
* @param taskRetries The number of times a task can error or timeout and | ||
* be retried. Defaults to 2. | ||
* @param batchClusterOpts Allows for overriding any configuration used | ||
* by the underlying `batch-cluster` module. | ||
*/ | ||
@@ -47,0 +49,0 @@ constructor(maxProcs?: number, maxTasksPerProcess?: number, spawnTimeoutMillis?: number, taskTimeoutMillis?: number, onIdleIntervalMillis?: number, taskRetries?: number, batchClusterOpts?: Partial<BatchClusterOptions & BatchProcessOptions>); |
@@ -45,38 +45,38 @@ "use strict"; | ||
* | ||
* Instances should be shared: consider using the exported singleton instance of this class, `exiftool`. | ||
* Instances should be shared: consider using the exported singleton | ||
* instance of this class, `exiftool`. | ||
*/ | ||
var ExifTool = /** @class */ (function () { | ||
/** | ||
* @param maxProcs The maximum number of ExifTool child processes to spawn | ||
* when load merits. Defaults to 1. | ||
* @param maxTasksPerProcess The maximum number of requests a given ExifTool | ||
* process will service before being retired. Defaults to 250, to balance | ||
* performance with memory usage. | ||
* @param spawnTimeoutMillis Spawning new ExifTool processes must not take | ||
* longer than `spawnTimeoutMillis` millis before it times out and a new | ||
* attempt is made. Be pessimistic here--windows can regularly take several | ||
* seconds to spin up a process, thanks to antivirus shenanigans. This can't | ||
* be set to a value less than 100ms. Defaults to 20 seconds, to accomodate | ||
* slow Windows machines. | ||
* @param taskTimeoutMillis If requests to ExifTool take longer than this, | ||
* presume the underlying process is dead and we should restart the task. This | ||
* can't be set to a value less than 10ms, and really should be set to at more | ||
* than a second unless `taskRetries` is sufficiently large. Defaults to 5 | ||
* @param maxProcs The maximum number of ExifTool child processes to | ||
* spawn when load merits. Defaults to 1. | ||
* @param maxTasksPerProcess The maximum number of requests a given | ||
* ExifTool process will service before being retired. Defaults to 250, | ||
* to balance performance with memory usage. | ||
* @param spawnTimeoutMillis Spawning new ExifTool processes must not | ||
* take longer than `spawnTimeoutMillis` millis before it times out and a | ||
* new attempt is made. Be pessimistic here--windows can regularly take | ||
* several seconds to spin up a process, thanks to antivirus shenanigans. | ||
* This can't be set to a value less than 100ms. Defaults to 20 seconds, | ||
* to accomodate slow Windows machines. | ||
* @param taskTimeoutMillis If requests to ExifTool take longer than | ||
* this, presume the underlying process is dead and we should restart the | ||
* task. This can't be set to a value less than 10ms, and really should | ||
* be set to at more than a second unless `taskRetries` is sufficiently | ||
* large or all writes will be to a fast local disk. Defaults to 5 | ||
* seconds. | ||
* @param onIdleIntervalMillis An interval timer is scheduled to do periodic | ||
* maintenance of underlying child processes with this periodicity. Defaults | ||
* to 2 seconds. | ||
* @param taskRetries The number of times a task can error or timeout and be | ||
* retried. Defaults to 2. | ||
* @param batchClusterOpts Allows for overriding any configuration used by | ||
* `BatchCluster` | ||
* @param onIdleIntervalMillis An interval timer is scheduled to do | ||
* periodic maintenance of underlying child processes with this | ||
* periodicity. Defaults to 2 seconds. | ||
* @param taskRetries The number of times a task can error or timeout and | ||
* be retried. Defaults to 2. | ||
* @param batchClusterOpts Allows for overriding any configuration used | ||
* by the underlying `batch-cluster` module. | ||
*/ | ||
function ExifTool(maxProcs, maxTasksPerProcess, spawnTimeoutMillis, // it shouldn't take longer than 5 seconds to spin up. 4x that should be quite conservative. | ||
taskTimeoutMillis, // tasks should complete in under 250 ms. 20x that should handle swapped procs. | ||
onIdleIntervalMillis, taskRetries, batchClusterOpts) { | ||
if (maxProcs === void 0) { maxProcs = 1; } | ||
function ExifTool(maxProcs, maxTasksPerProcess, spawnTimeoutMillis, taskTimeoutMillis, onIdleIntervalMillis, taskRetries, batchClusterOpts) { | ||
if (maxProcs === void 0) { maxProcs = _os.cpus().length; } | ||
if (maxTasksPerProcess === void 0) { maxTasksPerProcess = 500; } | ||
if (spawnTimeoutMillis === void 0) { spawnTimeoutMillis = 20000; } | ||
if (taskTimeoutMillis === void 0) { taskTimeoutMillis = 1000; } | ||
if (onIdleIntervalMillis === void 0) { onIdleIntervalMillis = 1000; } | ||
if (taskTimeoutMillis === void 0) { taskTimeoutMillis = 5000; } | ||
if (onIdleIntervalMillis === void 0) { onIdleIntervalMillis = 2000; } | ||
if (taskRetries === void 0) { taskRetries = 2; } | ||
@@ -96,3 +96,3 @@ if (batchClusterOpts === void 0) { batchClusterOpts = {}; } | ||
maxTasksPerProcess: maxTasksPerProcess, | ||
taskRetries: taskRetries, retryTasksAfterTimeout: true, maxProcAgeMillis: 10 * 60 * 1000 }, batchClusterOpts, { pass: batchClusterOpts.pass || "{ready}", fail: batchClusterOpts.fail || "{ready}", exitCommand: "-stay_open\nFalse\n", versionCommand: batchClusterOpts.versionCommand || new VersionTask_1.VersionTask().command }); | ||
taskRetries: taskRetries, retryTasksAfterTimeout: true, maxProcAgeMillis: 10 * 60 * 1000 }, batchClusterOpts, { pass: batchClusterOpts.pass || "{ready.*}", fail: batchClusterOpts.fail || "{ready.*}", exitCommand: "-stay_open\nFalse\n", versionCommand: batchClusterOpts.versionCommand || new VersionTask_1.VersionTask().command }); | ||
this.batchCluster = new batch_cluster_1.BatchCluster(opts); | ||
@@ -99,0 +99,0 @@ } |
{ | ||
"name": "exiftool-vendored", | ||
"version": "4.5.0", | ||
"version": "4.6.0", | ||
"description": "Efficient, cross-platform access to ExifTool", | ||
@@ -52,5 +52,5 @@ "main": "./dist/ExifTool.js", | ||
"@types/chai-as-promised": "^7.1.0", | ||
"@types/mocha": "^2.2.43", | ||
"@types/node": "^8.0.28", | ||
"@types/pify": "^0.0.28", | ||
"@types/mocha": "^2.2.44", | ||
"@types/node": "^8.0.52", | ||
"@types/pify": "^3.0.0", | ||
"@types/rimraf": "^2.0.2", | ||
@@ -64,16 +64,16 @@ "@types/semver": "^5.4.0", | ||
"globule": "^1.2.0", | ||
"mocha": "^3.5.2", | ||
"np": "^2.16.0", | ||
"npm-run-all": "^4.1.1", | ||
"mocha": "^4.0.1", | ||
"np": "^2.16.1", | ||
"npm-run-all": "^4.1.2", | ||
"pify": "^3.0.0", | ||
"progress": "^2.0.0", | ||
"rimraf": "^2.6.1", | ||
"rimraf": "^2.6.2", | ||
"semver": "^5.4.1", | ||
"source-map-support": "^0.4.18", | ||
"tar-fs": "^1.15.3", | ||
"source-map-support": "^0.5.0", | ||
"tar-fs": "^1.16.0", | ||
"tmp": "^0.0.33", | ||
"tslint": "^5.7.0", | ||
"tslint-config-standard": "^6.0.1", | ||
"tslint": "^5.8.0", | ||
"tslint-config-standard": "^7.0.0", | ||
"tslint-eslint-rules": "^4.1.1", | ||
"typescript": "~2.5.2", | ||
"typescript": "^2.6.1", | ||
"xmldom": "^0.1.27", | ||
@@ -83,8 +83,8 @@ "xpath": "^0.0.24" | ||
"dependencies": { | ||
"batch-cluster": "^1.4.1" | ||
"batch-cluster": "^1.6.1" | ||
}, | ||
"optionalDependencies": { | ||
"exiftool-vendored.exe": "10.64.0", | ||
"exiftool-vendored.pl": "10.64.0" | ||
"exiftool-vendored.exe": "10.66.0", | ||
"exiftool-vendored.pl": "10.66.0" | ||
} | ||
} |
@@ -11,7 +11,7 @@ # exiftool-vendored | ||
1. **Best-of-class cross-platform performance**. | ||
1. **Best-of-class cross-platform performance and reliability**. | ||
*Expect [an order of magnitude faster performance](#performance) than other packages.* | ||
1. Proper extraction of | ||
1. Proper extraction of | ||
- **dates** with [correct timezone offset encoding, when available](#dates)) | ||
@@ -30,3 +30,3 @@ - **latitudes & longitudes** as floats (where negative values indicate west or south of the meridian) | ||
1. **Robust test suite**, performed with Node v4, v6, v7, and v8 on [Linux, | ||
1. **Robust test suite**, performed with Node v4, v6, and v8 on [Linux, | ||
Mac](https://travis-ci.org/mceachen/exiftool-vendored.js), & | ||
@@ -50,5 +50,11 @@ [Windows](https://ci.appveyor.com/project/mceachen/exiftool-vendored/branch/master). | ||
```js | ||
import { exiftool } from "exiftool-vendored"; | ||
import { ExifTool } from "exiftool-vendored"; | ||
// Read all metadata tags in `path/to/image.jpg`. | ||
// Note that there are many configuration options to ExifTool. | ||
// Based on your hardware performance and expected performance | ||
// characteristics, the defaults may not be relevant for you. | ||
// See src/ExifTool.ts#L70 for jsdocs. | ||
const exiftool = new ExifTool(); | ||
// Read all metadata tags in `path/to/image.jpg`. | ||
// Returns a `Promise<Tags>`. | ||
@@ -72,13 +78,31 @@ exiftool | ||
// Extract the binary value from "tagname" tag in `path/to/image.jpg` | ||
// and write it to `dest.bin` (which cannot exist already | ||
// and write it to `dest.bin` (which cannot exist already | ||
// and whose parent directory must already exist): | ||
exiftool.extractBinaryTag("tagname", "path/to/file.exf", "path/to/dest.bin"); | ||
// Make sure you end ExifTool when you're done with it. | ||
// Note that `.end` returns a Promise that you can `await`. | ||
exiftool.end() | ||
``` | ||
## Resource hygene | ||
**Remember to call `.end()`.** | ||
If you use [mocha](https://mochajs.org/) v4 or later, and you don't call | ||
`exiftool.end()`, you will find that your tests hang after completion. [The relevant change is described | ||
here](https://github.com/mochajs/mocha/issues/3044), and can be solved by | ||
adding an `after` block that shuts down the instance of ExifTool that your | ||
tests are using: | ||
```js | ||
after(() => exiftool.end()) // assuming your singleton is called `exiftool` | ||
``` | ||
## Dates | ||
Generally, EXIF tags encode dates and times with **no timezone offset.** | ||
Presumably the time is captured in local time, but this means parsing the same | ||
file in different parts of the world results in a different *absolute* timestamp | ||
for the same file. | ||
Presumably the time is captured in local time, but this means parsing the | ||
same file in different parts of the world results in a different *absolute* | ||
timestamp for the same file. | ||
@@ -162,8 +186,2 @@ Rather than returning a | ||
## Logging | ||
[debuglog](https://nodejs.org/api/util.html#util_util_debuglog_section) is used | ||
with the `exiftool` prefix. To enable logging, set the environment flag | ||
`NODE_DEBUG=exiftool`. | ||
## Changelog | ||
@@ -175,6 +193,6 @@ | ||
* [Matthew McEachen](https://github.com/mceachen) | ||
- [Matthew McEachen](https://github.com/mceachen) | ||
## Contributors 🎉 | ||
* [Anton Mokrushin](https://github.com/amokrushin) | ||
- [Anton Mokrushin](https://github.com/amokrushin) |
Sorry, the diff of this file is not supported yet
285506
5885
193
+ Addedexiftool-vendored.exe@10.66.0(transitive)
+ Addedexiftool-vendored.pl@10.66.0(transitive)
- Removedexiftool-vendored.exe@10.64.0(transitive)
- Removedexiftool-vendored.pl@10.64.0(transitive)
Updatedbatch-cluster@^1.6.1