exiftool-vendored
Advanced tools
Comparing version 24.6.0 to 25.0.0
@@ -31,3 +31,3 @@ "use strict"; | ||
const DefaultMaxProcs_1 = require("./DefaultMaxProcs"); | ||
const FindExiftool_1 = require("./FindExiftool"); | ||
const ExiftoolPath_1 = require("./ExiftoolPath"); | ||
const GeoTz_1 = require("./GeoTz"); | ||
@@ -49,3 +49,3 @@ const IsWin32_1 = require("./IsWin32"); | ||
taskRetries: 1, | ||
exiftoolPath: FindExiftool_1.DefaultExifToolPath, | ||
exiftoolPath: ExiftoolPath_1.exiftoolPath, | ||
exiftoolArgs: DefaultExiftoolArgs_1.DefaultExiftoolArgs, | ||
@@ -63,2 +63,3 @@ exiftoolEnv: {}, | ||
geoTz: GeoTz_1.geoTz, | ||
geolocation: false, | ||
ignoreZeroZeroLatLon: true, | ||
@@ -65,0 +66,0 @@ imageHashType: false, |
@@ -8,2 +8,3 @@ /// <reference types="node" /> | ||
import { ExifToolTask } from "./ExifToolTask"; | ||
import { GeolocationTags } from "./GeolocationTags"; | ||
import { ICCProfileTags } from "./ICCProfileTags"; | ||
@@ -36,3 +37,3 @@ import { CollectionInfo, KeywordInfoStruct, KeywordStruct, MWGCollectionsTags, MWGKeywordTags } from "./MWGTags"; | ||
export { DefaultWriteTaskOptions } from "./WriteTask"; | ||
export type { APP12Tags, APP14Tags, APP1Tags, APP4Tags, APP5Tags, APP6Tags, AdditionalWriteTags, ApplicationRecordTags, CollectionInfo, CompositeTags, Defined, DefinedOrNullValued, EXIFTags, ErrorsAndWarnings, ExifToolOptions, ExifToolTags, ExpandedDateTags, FileTags, FlashPixTags, ICCProfileTags, IPTCTags, JFIFTags, Json, KeywordInfoStruct, KeywordStruct, Literal, MPFTags, MWGCollectionsTags, MWGKeywordTags, MakerNotesTags, Maybe, MetaTags, MutableTags, Omit, PanasonicRawTags, PhotoshopTags, PrintIMTags, QuickTimeTags, RAFTags, RIFFTags, RawTags, ReadTaskOptions, ResourceEvent, ShortcutTags, Struct, StructAppendTags, Tags, Version, WriteTags, WriteTaskOptions, WriteTaskResult, XMPTags, }; | ||
export type { APP12Tags, APP14Tags, APP1Tags, APP4Tags, APP5Tags, APP6Tags, AdditionalWriteTags, ApplicationRecordTags, CollectionInfo, CompositeTags, Defined, DefinedOrNullValued, EXIFTags, ErrorsAndWarnings, ExifToolOptions, ExifToolTags, ExpandedDateTags, FileTags, FlashPixTags, GeolocationTags, ICCProfileTags, IPTCTags, JFIFTags, Json, KeywordInfoStruct, KeywordStruct, Literal, MPFTags, MWGCollectionsTags, MWGKeywordTags, MakerNotesTags, Maybe, MetaTags, MutableTags, Omit, PanasonicRawTags, PhotoshopTags, PrintIMTags, QuickTimeTags, RAFTags, RIFFTags, RawTags, ReadTaskOptions, ResourceEvent, ShortcutTags, Struct, StructAppendTags, Tags, Version, WriteTags, WriteTaskOptions, WriteTaskResult, XMPTags, }; | ||
/** | ||
@@ -48,2 +49,3 @@ * Manages delegating calls to a cluster of ExifTool child processes. | ||
private readonly batchCluster; | ||
readonly exiftoolPath: () => Promise<string>; | ||
constructor(options?: Partial<ExifToolOptions>); | ||
@@ -50,0 +52,0 @@ /** |
@@ -48,2 +48,3 @@ "use strict"; | ||
const Lazy_1 = require("./Lazy"); | ||
const Object_1 = require("./Object"); | ||
const Pick_1 = require("./Pick"); | ||
@@ -142,5 +143,6 @@ const ReadRawTask_1 = require("./ReadRawTask"); | ||
}; | ||
this.exiftoolPath = (0, Lazy_1.lazy)(async () => (0, Object_1.isFunction)(o.exiftoolPath) ? o.exiftoolPath(o.logger()) : o.exiftoolPath); | ||
const processFactory = async () => ignoreShebang | ||
? _cp.spawn(await whichPerl(), [o.exiftoolPath, ...o.exiftoolArgs], spawnOpts) | ||
: _cp.spawn(o.exiftoolPath, o.exiftoolArgs, spawnOpts); | ||
? _cp.spawn(await whichPerl(), [await this.exiftoolPath(), ...o.exiftoolArgs], spawnOpts) | ||
: _cp.spawn(await this.exiftoolPath(), o.exiftoolArgs, spawnOpts); | ||
this.options = { | ||
@@ -150,6 +152,2 @@ ...o, | ||
processFactory, | ||
exitCommand: o.exitCommand, | ||
versionCommand: o.versionCommand, | ||
// User options win: | ||
...options, | ||
}; | ||
@@ -156,0 +154,0 @@ this.batchCluster = new bc.BatchCluster(this.options); |
@@ -60,3 +60,3 @@ /// <reference types="node" /> | ||
*/ | ||
exiftoolPath: string; | ||
exiftoolPath: string | ((logger?: bc.Logger) => string | Promise<string>); | ||
/** | ||
@@ -163,5 +163,38 @@ * Args passed to exiftool on launch. | ||
* location. | ||
* | ||
* If both this and {@link geolocation} are `true`, we will _delete_ the | ||
* Geolocation tags from the returned metadata object. | ||
* | ||
* @see https://en.wikipedia.org/wiki/Null_Island | ||
*/ | ||
ignoreZeroZeroLatLon: boolean; | ||
/** | ||
* Override the default geo-to-timezone lookup service. Note that if {@link geolocation} is enabled, we'll try to use {@ | ||
* | ||
* This defaults to `@photostructure/tz-lookup`, but if you have the | ||
* resources, consider using `geo-tz` for more accurate results. | ||
* | ||
* If your implementation throws an error, `ExifTool` will consider that given | ||
* latitude/longitude as invalid. | ||
* | ||
* Here's a snippet of how to use `geo-tz` instead of `tz-lookup`: | ||
* | ||
```js | ||
const geotz = require("geo-tz") | ||
const { ExifTool } = require("exiftool-vendored") | ||
const exiftool = new ExifTool({ geoTz: (lat, lon) => geotz.find(lat, lon)[0] }) | ||
``` | ||
* | ||
* @see https://github.com/photostructure/tz-lookup | ||
* @see https://github.com/evansiroky/node-geo-tz/ | ||
*/ | ||
geoTz: typeof geoTz; | ||
/** | ||
* When reading metadata, should we enable ExifTool's geolocation features? | ||
* Note that this requires ExifTool version 12.78 or later. | ||
* | ||
* @see https://exiftool.org/geolocation.html | ||
*/ | ||
geolocation: boolean; | ||
/** | ||
* `ExifTool` has a shebang line that assumes a valid `perl` is installed at | ||
@@ -184,21 +217,3 @@ * `/usr/bin/perl`. | ||
checkPerl: boolean; | ||
/** | ||
* Override the default geo-to-timezone lookup service. | ||
* | ||
* This defaults to `@photostructure/tz-lookup`, but if you have the | ||
* resources, consider using `geo-tz` for more accurate results. | ||
* | ||
* Here's a snippet of how to use `geo-tz` instead of `tz-lookup`: | ||
* | ||
```js | ||
const geotz = require("geo-tz") | ||
const { ExifTool } = require("exiftool-vendored") | ||
const exiftool = new ExifTool({ geoTz: (lat, lon) => geotz.find(lat, lon)[0] }) | ||
``` | ||
* | ||
* @see https://github.com/photostructure/tz-lookup | ||
* @see https://github.com/evansiroky/node-geo-tz/ | ||
*/ | ||
geoTz: typeof geoTz; | ||
} | ||
export declare function handleDeprecatedOptions<T extends Pick<ExifToolOptions, "includeImageDataMD5" | "imageHashType">>(options: T): T; |
import { Maybe } from "./Maybe"; | ||
/** | ||
* @throws if the given latitude and longitude are invalid. | ||
*/ | ||
export declare function geoTz(lat: number, lon: number): Maybe<string>; |
@@ -8,11 +8,9 @@ "use strict"; | ||
const tz_lookup_1 = __importDefault(require("@photostructure/tz-lookup")); | ||
/** | ||
* @throws if the given latitude and longitude are invalid. | ||
*/ | ||
function geoTz(lat, lon) { | ||
try { | ||
return (0, tz_lookup_1.default)(lat, lon); | ||
} | ||
catch { | ||
return; | ||
} | ||
return (0, tz_lookup_1.default)(lat, lon); | ||
} | ||
exports.geoTz = geoTz; | ||
//# sourceMappingURL=GeoTz.js.map |
import { ExifToolTask } from "./ExifToolTask"; | ||
import { Tags } from "./Tags"; | ||
export declare const ReadTaskOptionFields: readonly ["backfillTimezones", "defaultVideosToUTC", "geoTz", "ignoreZeroZeroLatLon", "imageHashType", "includeImageDataMD5", "inferTimezoneFromDatestamps", "inferTimezoneFromDatestampTags", "numericTags", "useMWG"]; | ||
export declare const ReadTaskOptionFields: ["backfillTimezones", "defaultVideosToUTC", "geoTz", "geolocation", "ignoreZeroZeroLatLon", "imageHashType", "includeImageDataMD5", "inferTimezoneFromDatestamps", "inferTimezoneFromDatestampTags", "numericTags", "useMWG"]; | ||
export declare function nullish(s: string | undefined): s is undefined; | ||
@@ -16,2 +16,3 @@ export declare const DefaultReadTaskOptions: { | ||
readonly geoTz: typeof import("./GeoTz").geoTz; | ||
readonly geolocation: boolean; | ||
readonly optionalArgs: string[]; | ||
@@ -26,10 +27,2 @@ }; | ||
private readonly degroup; | ||
private _raw; | ||
private _rawDegrouped; | ||
private readonly tags; | ||
private lat; | ||
private lon; | ||
private invalidLatLon; | ||
private tz; | ||
private tzSource?; | ||
private constructor(); | ||
@@ -36,0 +29,0 @@ static for(filename: string, options: Partial<ReadTaskOptions>): ReadTask; |
@@ -25,2 +25,8 @@ "use strict"; | ||
}; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
@@ -31,3 +37,3 @@ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
}; | ||
var _ReadTask_instances, _ReadTask_isVideo, _ReadTask_defaultToUTC, _ReadTask_tagName, _ReadTask_parseTags, _ReadTask_extractLatLon, _ReadTask_latlon, _ReadTask_geoTz, _ReadTask_extractTzOffset, _ReadTask_parseTag; | ||
var _ReadTask_instances, _ReadTask_raw, _ReadTask_rawDegrouped, _ReadTask_tags, _ReadTask_lat, _ReadTask_lon, _ReadTask_invalidLatLon, _ReadTask_tz, _ReadTask_tzSource, _ReadTask_isVideo, _ReadTask_defaultToUTC, _ReadTask_tagName, _ReadTask_parseTags, _ReadTask_extractLatLon, _ReadTask_latlon, _ReadTask_geoTz, _ReadTask_extractTzOffset, _ReadTask_parseTag; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -55,3 +61,4 @@ exports.ReadTask = exports.DefaultReadTaskOptions = exports.nullish = exports.ReadTaskOptionFields = void 0; | ||
/** | ||
* tag names we don't need to muck with: | ||
* tag names we don't need to muck with, but name conventions (like including | ||
* "date") suggest they might be date/time tags | ||
*/ | ||
@@ -69,2 +76,3 @@ const PassthroughTags = [ | ||
"geoTz", | ||
"geolocation", | ||
"ignoreZeroZeroLatLon", | ||
@@ -95,9 +103,13 @@ "imageHashType", | ||
this.options = options; | ||
this._raw = {}; | ||
this._rawDegrouped = {}; | ||
this.tags = {}; | ||
this.invalidLatLon = false; | ||
_ReadTask_raw.set(this, {}); | ||
_ReadTask_rawDegrouped.set(this, {}); | ||
_ReadTask_tags.set(this, {}); | ||
_ReadTask_lat.set(this, void 0); | ||
_ReadTask_lon.set(this, void 0); | ||
_ReadTask_invalidLatLon.set(this, false); | ||
_ReadTask_tz.set(this, void 0); | ||
_ReadTask_tzSource.set(this, void 0); | ||
_ReadTask_extractLatLon.set(this, (0, Lazy_1.lazy)(() => { | ||
var _a, _b; | ||
(_a = this.lat) !== null && _a !== void 0 ? _a : (this.lat = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_latlon).call(this, { | ||
__classPrivateFieldSet(this, _ReadTask_lat, (_a = __classPrivateFieldGet(this, _ReadTask_lat, "f")) !== null && _a !== void 0 ? _a : __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_latlon).call(this, { | ||
tagName: "GPSLatitude", | ||
@@ -107,4 +119,4 @@ positiveRef: "N", | ||
maxValid: 90, | ||
})); | ||
(_b = this.lon) !== null && _b !== void 0 ? _b : (this.lon = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_latlon).call(this, { | ||
}), "f"); | ||
__classPrivateFieldSet(this, _ReadTask_lon, (_b = __classPrivateFieldGet(this, _ReadTask_lon, "f")) !== null && _b !== void 0 ? _b : __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_latlon).call(this, { | ||
tagName: "GPSLongitude", | ||
@@ -114,8 +126,20 @@ positiveRef: "E", | ||
maxValid: 180, | ||
})); | ||
if (this.options.ignoreZeroZeroLatLon && this.lat === 0 && this.lon === 0) { | ||
this.invalidLatLon = true; | ||
}), "f"); | ||
if (this.options.ignoreZeroZeroLatLon && | ||
__classPrivateFieldGet(this, _ReadTask_lat, "f") === 0 && | ||
__classPrivateFieldGet(this, _ReadTask_lon, "f") === 0) { | ||
__classPrivateFieldSet(this, _ReadTask_invalidLatLon, true, "f"); | ||
} | ||
if (this.invalidLatLon) { | ||
this.lat = this.lon = undefined; | ||
if (__classPrivateFieldGet(this, _ReadTask_invalidLatLon, "f")) { | ||
__classPrivateFieldSet(this, _ReadTask_lat, __classPrivateFieldSet(this, _ReadTask_lon, undefined, "f"), "f"); | ||
if (this.options.geolocation) { | ||
this.warnings.push("Invalid GPSLatitude or GPSLongitude. Geolocation tags have been deleted."); | ||
for (const key of Object.keys(__classPrivateFieldGet(this, _ReadTask_raw, "f"))) { | ||
const k = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_tagName).call(this, key); | ||
if (k.startsWith("Geolocation")) { | ||
delete __classPrivateFieldGet(this, _ReadTask_raw, "f")[key]; | ||
delete __classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f")[k]; | ||
} | ||
} | ||
} | ||
} | ||
@@ -125,10 +149,10 @@ })); | ||
__classPrivateFieldGet(this, _ReadTask_extractLatLon, "f").call(this); | ||
if (this.invalidLatLon || this.lat == null || this.lon == null) | ||
if (__classPrivateFieldGet(this, _ReadTask_invalidLatLon, "f") || __classPrivateFieldGet(this, _ReadTask_lat, "f") == null || __classPrivateFieldGet(this, _ReadTask_lon, "f") == null) | ||
return; | ||
try { | ||
const geoTz = this.options.geoTz(this.lat, this.lon); | ||
const geoTz = this.options.geoTz(__classPrivateFieldGet(this, _ReadTask_lat, "f"), __classPrivateFieldGet(this, _ReadTask_lon, "f")); | ||
return (0, Timezones_1.normalizeZone)(geoTz); | ||
} | ||
catch { | ||
this.invalidLatLon = true; | ||
__classPrivateFieldSet(this, _ReadTask_invalidLatLon, true, "f"); | ||
return; | ||
@@ -139,6 +163,7 @@ } | ||
this.degroup = this.args.includes("-G"); | ||
this.tags = { SourceFile: sourceFile }; | ||
this.tags.errors = this.errors; | ||
__classPrivateFieldSet(this, _ReadTask_tags, { SourceFile: sourceFile }, "f"); | ||
__classPrivateFieldGet(this, _ReadTask_tags, "f").errors = this.errors; | ||
} | ||
static for(filename, options) { | ||
var _a; | ||
const opts = (0, ExifToolOptions_1.handleDeprecatedOptions)({ | ||
@@ -163,2 +188,5 @@ ...exports.DefaultReadTaskOptions, | ||
} | ||
if ((_a = opts.geolocation) !== null && _a !== void 0 ? _a : false) { | ||
args.push("-api", "geolocation"); | ||
} | ||
// IMPORTANT: "-all" must be after numeric tag references, as the first | ||
@@ -178,3 +206,3 @@ // reference in wins | ||
try { | ||
this._raw = JSON.parse(data)[0]; | ||
__classPrivateFieldSet(this, _ReadTask_raw, JSON.parse(data)[0], "f"); | ||
} | ||
@@ -191,18 +219,8 @@ catch (jsonError) { | ||
// ExifTool does "humorous" things to paths, like flip path separators. resolve() undoes that. | ||
const SourceFile = _path.resolve(this._raw.SourceFile); | ||
const SourceFile = _path.resolve(__classPrivateFieldGet(this, _ReadTask_raw, "f").SourceFile); | ||
// Sanity check that the result is for the file we want: | ||
if (SourceFile !== this.sourceFile) { | ||
// Throw an error rather than add an errors string because this is *really* bad: | ||
throw new Error(`Internal error: unexpected SourceFile of ${this._raw.SourceFile} for file ${this.sourceFile}`); | ||
throw new Error(`Internal error: unexpected SourceFile of ${__classPrivateFieldGet(this, _ReadTask_raw, "f").SourceFile} for file ${this.sourceFile}`); | ||
} | ||
if (this.degroup) { | ||
this._rawDegrouped = {}; | ||
for (const [key, value] of Object.entries(this._raw)) { | ||
const k = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_tagName).call(this, key); | ||
this._rawDegrouped[k] = value; | ||
} | ||
} | ||
else { | ||
this._rawDegrouped = this._raw; | ||
} | ||
return __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_parseTags).call(this); | ||
@@ -212,5 +230,5 @@ } | ||
exports.ReadTask = ReadTask; | ||
_ReadTask_extractLatLon = new WeakMap(), _ReadTask_geoTz = new WeakMap(), _ReadTask_instances = new WeakSet(), _ReadTask_isVideo = function _ReadTask_isVideo() { | ||
_ReadTask_raw = new WeakMap(), _ReadTask_rawDegrouped = new WeakMap(), _ReadTask_tags = new WeakMap(), _ReadTask_lat = new WeakMap(), _ReadTask_lon = new WeakMap(), _ReadTask_invalidLatLon = new WeakMap(), _ReadTask_tz = new WeakMap(), _ReadTask_tzSource = new WeakMap(), _ReadTask_extractLatLon = new WeakMap(), _ReadTask_geoTz = new WeakMap(), _ReadTask_instances = new WeakSet(), _ReadTask_isVideo = function _ReadTask_isVideo() { | ||
var _a; | ||
return String((_a = this._rawDegrouped) === null || _a === void 0 ? void 0 : _a.MIMEType).startsWith("video/"); | ||
return String((_a = __classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f")) === null || _a === void 0 ? void 0 : _a.MIMEType).startsWith("video/"); | ||
}, _ReadTask_defaultToUTC = function _ReadTask_defaultToUTC() { | ||
@@ -222,9 +240,19 @@ return __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_isVideo).call(this) && this.options.defaultVideosToUTC; | ||
}, _ReadTask_parseTags = function _ReadTask_parseTags() { | ||
if (this.degroup) { | ||
__classPrivateFieldSet(this, _ReadTask_rawDegrouped, {}, "f"); | ||
for (const [key, value] of Object.entries(__classPrivateFieldGet(this, _ReadTask_raw, "f"))) { | ||
const k = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_tagName).call(this, key); | ||
__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f")[k] = value; | ||
} | ||
} | ||
else { | ||
__classPrivateFieldSet(this, _ReadTask_rawDegrouped, __classPrivateFieldGet(this, _ReadTask_raw, "f"), "f"); | ||
} | ||
__classPrivateFieldGet(this, _ReadTask_extractLatLon, "f").call(this); | ||
__classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_extractTzOffset).call(this); | ||
(0, Maybe_1.map)(this.tz, (ea) => (this.tags.tz = ea)); | ||
(0, Maybe_1.map)(this.tzSource, (ea) => (this.tags.tzSource = ea)); | ||
// avoid casting `this.tags as any` everywhere: | ||
const tags = this.tags; | ||
for (const [key, value] of Object.entries(this._raw)) { | ||
(0, Maybe_1.map)(__classPrivateFieldGet(this, _ReadTask_tz, "f"), (ea) => (__classPrivateFieldGet(this, _ReadTask_tags, "f").tz = ea)); | ||
(0, Maybe_1.map)(__classPrivateFieldGet(this, _ReadTask_tzSource, "f"), (ea) => (__classPrivateFieldGet(this, _ReadTask_tags, "f").tzSource = ea)); | ||
// avoid casting `this.tags as any` for the rest of the function: | ||
const tags = __classPrivateFieldGet(this, _ReadTask_tags, "f"); | ||
for (const [key, value] of Object.entries(__classPrivateFieldGet(this, _ReadTask_raw, "f"))) { | ||
const k = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_tagName).call(this, key); | ||
@@ -235,4 +263,4 @@ const v = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_parseTag).call(this, k, value); | ||
} | ||
// we could `return {...tags, ...errorsAndWarnings(this, tags)}` but tags | ||
// is a chonky monster, and we don't want to double work for the poor | ||
// we could `return {...tags, ...errorsAndWarnings(this, tags)}` but tags is | ||
// a chonky monster, and we don't want to double the work for the poor | ||
// garbage collector. | ||
@@ -244,5 +272,5 @@ const { errors, warnings } = (0, ErrorsAndWarnings_1.errorsAndWarnings)(this, tags); | ||
}, _ReadTask_latlon = function _ReadTask_latlon({ tagName, positiveRef, negativeRef, maxValid, }) { | ||
const tagValue = this._rawDegrouped[tagName]; | ||
const tagValue = __classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f")[tagName]; | ||
const refKey = tagName + "Ref"; | ||
const ref = this._rawDegrouped[refKey]; | ||
const ref = __classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f")[refKey]; | ||
const result = (0, Number_1.toFloat)(tagValue); | ||
@@ -254,3 +282,3 @@ if (result == null) { | ||
this.warnings.push(`Invalid ${tagName}: ${JSON.stringify(tagValue)}`); | ||
this.invalidLatLon = true; | ||
__classPrivateFieldSet(this, _ReadTask_invalidLatLon, true, "f"); | ||
return; | ||
@@ -276,25 +304,28 @@ } | ||
}, _ReadTask_extractTzOffset = function _ReadTask_extractTzOffset() { | ||
(0, Maybe_1.map)((0, Maybe_1.firstDefinedThunk)([ | ||
// If there is an explicit TimeZone tag (which is rare), defer to that | ||
// before defaulting to UTC for videos: | ||
() => (0, Timezones_1.extractTzOffsetFromTags)(this._rawDegrouped), | ||
() => (0, Maybe_1.map)(__classPrivateFieldGet(this, _ReadTask_geoTz, "f").call(this), (ea) => ({ | ||
tz: ea.name, | ||
src: "GPSLatitude/GPSLongitude", | ||
})), | ||
() => (0, Timezones_1.extractTzOffsetFromDatestamps)(this._rawDegrouped, this.options), | ||
// See https://github.com/photostructure/exiftool-vendored.js/issues/113 | ||
// and https://github.com/photostructure/exiftool-vendored.js/issues/156 | ||
// Videos are frequently encoded in UTC, but don't include the | ||
// timezone offset in their datetime stamps. | ||
() => __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_defaultToUTC).call(this) | ||
? { | ||
tz: "UTC", | ||
src: "defaultVideosToUTC", | ||
} | ||
: // not applicable: | ||
undefined, | ||
// This is a last-ditch estimation heuristic: | ||
() => (0, Timezones_1.extractTzOffsetFromUTCOffset)(this._rawDegrouped), | ||
]), (ea) => ({ tz: this.tz, src: this.tzSource } = ea)); | ||
var _a, _b, _c, _d; | ||
const result = | ||
// If there is an explicit TimeZone tag (which is rare), or if defer to that | ||
// before defaulting to UTC for videos: | ||
(_d = (_c = (_b = (_a = (0, Timezones_1.extractTzOffsetFromTags)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f"))) !== null && _a !== void 0 ? _a : (0, Maybe_1.map)(__classPrivateFieldGet(this, _ReadTask_geoTz, "f").call(this), (ea) => ({ | ||
tz: ea.name, | ||
src: "GPSLatitude/GPSLongitude", | ||
}))) !== null && _b !== void 0 ? _b : (0, Timezones_1.extractTzOffsetFromDatestamps)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f"), this.options)) !== null && _c !== void 0 ? _c : | ||
// See https://github.com/photostructure/exiftool-vendored.js/issues/113 | ||
// and https://github.com/photostructure/exiftool-vendored.js/issues/156 | ||
// Videos are frequently encoded in UTC, but don't include the | ||
// timezone offset in their datetime stamps. | ||
(__classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_defaultToUTC).call(this) | ||
? { | ||
tz: "UTC", | ||
src: "defaultVideosToUTC", | ||
} | ||
: // not applicable: | ||
undefined)) !== null && _d !== void 0 ? _d : | ||
// This is a last-ditch estimation heuristic: | ||
(0, Timezones_1.extractTzOffsetFromUTCOffset)(__classPrivateFieldGet(this, _ReadTask_rawDegrouped, "f")); | ||
if (result != null) { | ||
__classPrivateFieldSet(this, _ReadTask_tz, result.tz, "f"); | ||
__classPrivateFieldSet(this, _ReadTask_tzSource, result.src, "f"); | ||
} | ||
return result; | ||
}, _ReadTask_parseTag = function _ReadTask_parseTag(tagName, value) { | ||
@@ -309,6 +340,6 @@ var _a, _b, _c; | ||
if (tagName === "GPSLatitude") { | ||
return this.lat; | ||
return __classPrivateFieldGet(this, _ReadTask_lat, "f"); | ||
} | ||
if (tagName === "GPSLongitude") { | ||
return this.lon; | ||
return __classPrivateFieldGet(this, _ReadTask_lon, "f"); | ||
} | ||
@@ -339,3 +370,3 @@ if (Array.isArray(value)) { | ||
: this.options.backfillTimezones | ||
? this.tz | ||
? __classPrivateFieldGet(this, _ReadTask_tz, "f") | ||
: undefined; | ||
@@ -355,3 +386,3 @@ // Time-only tags have "time" but not "date" in their name: | ||
result != null && | ||
this.tz != null && | ||
__classPrivateFieldGet(this, _ReadTask_tz, "f") != null && | ||
result instanceof ExifDateTime_1.ExifDateTime && | ||
@@ -361,3 +392,3 @@ __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_defaultToUTC).call(this) && | ||
true === result.inferredZone) { | ||
return result.setZone(this.tz); | ||
return result.setZone(__classPrivateFieldGet(this, _ReadTask_tz, "f")); | ||
} | ||
@@ -364,0 +395,0 @@ return result; |
@@ -5,2 +5,3 @@ import { Maybe } from "./Maybe"; | ||
export declare function notBlank(s: Maybe<string>): s is string; | ||
export declare function toNotBlank(s: Maybe<string>): Maybe<string>; | ||
export declare function compactBlanks(arr: Maybe<string>[]): string[]; | ||
@@ -7,0 +8,0 @@ export declare function toS(s: Maybe<any>): string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.splitLines = exports.stripSuffix = exports.stripPrefix = exports.pad3 = exports.pad2 = exports.leftPad = exports.toS = exports.compactBlanks = exports.notBlank = exports.blank = exports.isString = void 0; | ||
exports.splitLines = exports.stripSuffix = exports.stripPrefix = exports.pad3 = exports.pad2 = exports.leftPad = exports.toS = exports.compactBlanks = exports.toNotBlank = exports.notBlank = exports.blank = exports.isString = void 0; | ||
const Number_1 = require("./Number"); | ||
@@ -20,2 +20,9 @@ const Times_1 = require("./Times"); | ||
exports.notBlank = notBlank; | ||
function toNotBlank(s) { | ||
if (s == null) | ||
return; | ||
s = String(s).trim(); | ||
return s.length === 0 ? undefined : s; | ||
} | ||
exports.toNotBlank = toNotBlank; | ||
function compactBlanks(arr) { | ||
@@ -22,0 +29,0 @@ return arr.filter(notBlank); |
@@ -66,3 +66,3 @@ "use strict"; | ||
// This is a bit tricky... We want to keep the local time and just _say_ it | ||
// was in the zone of the image **if we don't already have a zone.** | ||
// was in the zone of the image **but only if we don't already have a zone.** | ||
// If we _do_ have a zone, assume it was already converted by ExifTool into | ||
@@ -69,0 +69,0 @@ // (probably the system) timezone, which means _don't_ `keepLocalTime`. |
@@ -309,2 +309,3 @@ "use strict"; | ||
"TimeZoneOffset", // number | number[] | string | ||
"GeolocationTimeZone", | ||
]; | ||
@@ -311,0 +312,0 @@ function extractTzOffsetFromTags(t) { |
{ | ||
"name": "exiftool-vendored", | ||
"version": "24.6.0", | ||
"version": "25.0.0", | ||
"description": "Efficient, cross-platform access to ExifTool", | ||
@@ -76,8 +76,8 @@ "main": "./dist/ExifTool.js", | ||
"@types/mocha": "^10.0.6", | ||
"@types/node": "^20.11.25", | ||
"@types/node": "^20.11.30", | ||
"@types/progress": "^2.0.7", | ||
"@types/tmp": "^0.2.6", | ||
"@types/xmldom": "^0.1.34", | ||
"@typescript-eslint/eslint-plugin": "^7.1.1", | ||
"@typescript-eslint/parser": "^7.1.1", | ||
"@typescript-eslint/eslint-plugin": "^7.4.0", | ||
"@typescript-eslint/parser": "^7.4.0", | ||
"@xmldom/xmldom": "^0.8.10", | ||
@@ -90,8 +90,8 @@ "chai": "^4.3.10", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-regexp": "^2.2.0", | ||
"eslint-plugin-regexp": "^2.4.0", | ||
"extract-zip": "^2.0.1", | ||
"geo-tz": "^8.0.1", | ||
"geo-tz": "^8.0.2", | ||
"globule": "^1.3.4", | ||
"mocha": "^10.3.0", | ||
"npm-check-updates": "^16.14.15", | ||
"mocha": "^10.4.0", | ||
"npm-check-updates": "^16.14.18", | ||
"npm-run-all": "^4.1.5", | ||
@@ -105,4 +105,4 @@ "prettier": "^3.2.5", | ||
"tmp": "^0.2.3", | ||
"typedoc": "^0.25.11", | ||
"typescript": "^5.4.2", | ||
"typedoc": "^0.25.12", | ||
"typescript": "^5.4.3", | ||
"xpath": "^0.0.34" | ||
@@ -112,3 +112,3 @@ }, | ||
"dependencies": { | ||
"@photostructure/tz-lookup": "^9.0.2", | ||
"@photostructure/tz-lookup": "^10.0.0", | ||
"@types/luxon": "^3.4.2", | ||
@@ -120,5 +120,5 @@ "batch-cluster": "^13.0.0", | ||
"optionalDependencies": { | ||
"exiftool-vendored.exe": "12.78.0", | ||
"exiftool-vendored.pl": "12.78.0" | ||
"exiftool-vendored.exe": "12.80.0", | ||
"exiftool-vendored.pl": "12.80.0" | ||
} | ||
} |
@@ -47,2 +47,21 @@ # exiftool-vendored | ||
### Electron-builder support | ||
Add the following pattern to `electron-builder.yml`'s `asarUnpack`: | ||
```yaml | ||
- "node_modules/exiftool-vendored.*/**/*" | ||
``` | ||
### Electron-forge support | ||
Version 25.0 of this library added experimental support for `electron-forge`: | ||
add the following element to your `ForgeConfig.packagerConfig.extraResource` | ||
string array, and things should "just work": | ||
```ts | ||
"./node_modules/exiftool-vendored." + | ||
(process.platform === "win32" ? "exe" : "pl") | ||
``` | ||
### Installation notes | ||
@@ -62,2 +81,4 @@ | ||
- If the platform-correct vendor module (`exiftool-vendored.exe` or `exiftool-vendored.pl`) is not found, `exiftool` is searched for on your `PATH`. Note that _very_ old versions of `exiftool` are found on currently-supported Linux distributions which this library will not work correctly with. | ||
## Upgrading | ||
@@ -64,0 +85,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
567663
186
9673
494
+ Added@photostructure/tz-lookup@10.0.0(transitive)
+ Addedexiftool-vendored.exe@12.80.0(transitive)
+ Addedexiftool-vendored.pl@12.80.0(transitive)
- Removed@photostructure/tz-lookup@9.0.2(transitive)
- Removedexiftool-vendored.exe@12.78.0(transitive)
- Removedexiftool-vendored.pl@12.78.0(transitive)