pst-extractor 1.6.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ColumnDescriptor.class.js +9 -4
- package/dist/DescriptorIndexNode.class.d.ts +3 -3
- package/dist/DescriptorIndexNode.class.js +1 -0
- package/dist/LZFu.class.js +2 -0
- package/dist/NodeInfo.class.d.ts +2 -2
- package/dist/NodeInfo.class.js +2 -0
- package/dist/NodeMap.class.d.ts +2 -2
- package/dist/NodeMap.class.js +7 -2
- package/dist/OffsetIndexItem.class.d.ts +3 -3
- package/dist/OffsetIndexItem.class.js +1 -0
- package/dist/OutlookProperties.d.ts +2 -0
- package/dist/OutlookProperties.js +3 -0
- package/dist/PSTActivity.class.js +1 -0
- package/dist/PSTAppointment.class.js +1 -0
- package/dist/PSTAttachment.class.js +7 -2
- package/dist/PSTContact.class.js +1 -0
- package/dist/PSTDescriptorItem.class.js +9 -4
- package/dist/PSTFile.class.d.ts +8 -8
- package/dist/PSTFile.class.js +43 -20
- package/dist/PSTFolder.class.js +10 -5
- package/dist/PSTMessage.class.d.ts +2 -2
- package/dist/PSTMessage.class.js +9 -4
- package/dist/PSTMessageStore.class.js +1 -0
- package/dist/PSTNodeInputStream.class.d.ts +5 -5
- package/dist/PSTNodeInputStream.class.js +52 -25
- package/dist/PSTObject.class.d.ts +3 -3
- package/dist/PSTObject.class.js +11 -6
- package/dist/PSTRecipient.class.js +2 -0
- package/dist/PSTTable.class.d.ts +2 -2
- package/dist/PSTTable.class.js +16 -11
- package/dist/PSTTable7C.class.js +24 -19
- package/dist/PSTTableBC.class.js +9 -4
- package/dist/PSTTableItem.class.d.ts +4 -4
- package/dist/PSTTableItem.class.js +7 -2
- package/dist/PSTTask.class.d.ts +13 -0
- package/dist/PSTTask.class.js +19 -0
- package/dist/PSTUtil.class.d.ts +5 -5
- package/dist/PSTUtil.class.js +16 -7
- package/dist/RecurrencePattern.class.d.ts +50 -0
- package/dist/RecurrencePattern.class.js +120 -0
- package/dist/index.js +7 -6
- package/example/package.json +8 -8
- package/example/test-min.ts +32 -7
- package/example/{test-mem.ts → test.ts} +43 -32
- package/example/testdata/attachments/Clinometer Usage.pdf +0 -0
- package/example/testdata/attachments/primoz-roglic-of-slovenia-and-team-jumbo-visma-red-leader-news-photo-1628610563.jpg +0 -0
- package/example/testdata/attachments/text.txt +1 -0
- package/example/testdata/output.txt +278 -0
- package/example/testdata/outputBody.txt +3404 -0
- package/example/testdata/pstextractortest@outlook.com.ost +0 -0
- package/example/testdata/pstextractortestpdf@outlook.com.ost +0 -0
- package/example/yarn.lock +85 -45
- package/junit.xml +37 -31
- package/package.json +28 -27
- package/readme.md +13 -6
- package/example/test-max.ts +0 -247
package/dist/PSTUtil.class.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import
|
|
2
|
+
import Long from 'long';
|
|
3
3
|
import { DescriptorIndexNode } from './DescriptorIndexNode.class';
|
|
4
4
|
import { PSTDescriptorItem } from './PSTDescriptorItem.class';
|
|
5
5
|
import { PSTFile } from './PSTFile.class';
|
|
@@ -43,7 +43,7 @@ export declare class PSTUtil {
|
|
|
43
43
|
* @returns {long}
|
|
44
44
|
* @memberof PSTUtil
|
|
45
45
|
*/
|
|
46
|
-
static convertLittleEndianBytesToLong(data: Buffer, start?: number, end?: number):
|
|
46
|
+
static convertLittleEndianBytesToLong(data: Buffer, start?: number, end?: number): Long;
|
|
47
47
|
/**
|
|
48
48
|
* Convert big endian bytes to long
|
|
49
49
|
* @static
|
|
@@ -53,7 +53,7 @@ export declare class PSTUtil {
|
|
|
53
53
|
* @returns {long}
|
|
54
54
|
* @memberof PSTUtil
|
|
55
55
|
*/
|
|
56
|
-
static convertBigEndianBytesToLong(data: Buffer, start?: number, end?: number):
|
|
56
|
+
static convertBigEndianBytesToLong(data: Buffer, start?: number, end?: number): Long;
|
|
57
57
|
/**
|
|
58
58
|
* Handle strings using codepages.
|
|
59
59
|
* @static
|
|
@@ -106,7 +106,7 @@ export declare class PSTUtil {
|
|
|
106
106
|
* @returns {*}
|
|
107
107
|
* @memberof PSTUtil
|
|
108
108
|
*/
|
|
109
|
-
static detectAndLoadPSTObject(theFile: PSTFile, descriptorIndex:
|
|
109
|
+
static detectAndLoadPSTObject(theFile: PSTFile, descriptorIndex: Long): any;
|
|
110
110
|
static detectAndLoadPSTObject(theFile: PSTFile, folderIndexNode: DescriptorIndexNode): any;
|
|
111
111
|
/**
|
|
112
112
|
* Creates object based on message class
|
|
@@ -131,5 +131,5 @@ export declare class PSTUtil {
|
|
|
131
131
|
* @returns {Date}
|
|
132
132
|
* @memberof PSTUtil
|
|
133
133
|
*/
|
|
134
|
-
static filetimeToDate(hi:
|
|
134
|
+
static filetimeToDate(hi: Long, low: Long): Date;
|
|
135
135
|
}
|
package/dist/PSTUtil.class.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
6
|
+
exports.PSTUtil = void 0;
|
|
7
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
8
|
+
const long_1 = __importDefault(require("long"));
|
|
4
9
|
const PSTAppointment_class_1 = require("./PSTAppointment.class");
|
|
5
10
|
const PSTContact_class_1 = require("./PSTContact.class");
|
|
6
11
|
const PSTFolder_class_1 = require("./PSTFolder.class");
|
|
@@ -9,6 +14,7 @@ const PSTNodeInputStream_class_1 = require("./PSTNodeInputStream.class");
|
|
|
9
14
|
const PSTTableBC_class_1 = require("./PSTTableBC.class");
|
|
10
15
|
const PSTTask_class_1 = require("./PSTTask.class");
|
|
11
16
|
const PSTActivity_class_1 = require("./PSTActivity.class");
|
|
17
|
+
const iconv_lite_1 = __importDefault(require("iconv-lite"));
|
|
12
18
|
/**
|
|
13
19
|
* Utility functions for PST components
|
|
14
20
|
* @export
|
|
@@ -31,11 +37,11 @@ class PSTUtil {
|
|
|
31
37
|
if (!end) {
|
|
32
38
|
end = data.length;
|
|
33
39
|
}
|
|
34
|
-
let offset =
|
|
40
|
+
let offset = long_1.default.fromNumber(data[end - 1] & 0xff);
|
|
35
41
|
let tmpLongValue;
|
|
36
42
|
for (let x = end - 2; x >= start; x--) {
|
|
37
43
|
offset = offset.shiftLeft(8);
|
|
38
|
-
tmpLongValue =
|
|
44
|
+
tmpLongValue = long_1.default.fromNumber(data[x] & 0xff);
|
|
39
45
|
offset = offset.xor(tmpLongValue);
|
|
40
46
|
}
|
|
41
47
|
return offset;
|
|
@@ -56,10 +62,10 @@ class PSTUtil {
|
|
|
56
62
|
if (!end) {
|
|
57
63
|
end = data.length;
|
|
58
64
|
}
|
|
59
|
-
let offset =
|
|
65
|
+
let offset = long_1.default.ZERO;
|
|
60
66
|
for (let x = start; x < end; ++x) {
|
|
61
67
|
offset = offset.shiftLeft(8);
|
|
62
|
-
const tmpLongValue =
|
|
68
|
+
const tmpLongValue = long_1.default.fromNumber(data[x] & 0xff);
|
|
63
69
|
offset = offset.xor(tmpLongValue);
|
|
64
70
|
}
|
|
65
71
|
return offset;
|
|
@@ -83,13 +89,16 @@ class PSTUtil {
|
|
|
83
89
|
* @returns
|
|
84
90
|
* @memberof PSTUtil
|
|
85
91
|
*/
|
|
86
|
-
static createJavascriptString(data, stringType, codepage) {
|
|
92
|
+
static createJavascriptString(data, stringType, codepage = 'utf8') {
|
|
87
93
|
// TODO - codepage is not used...
|
|
88
94
|
try {
|
|
89
95
|
if (stringType == 0x1f) {
|
|
90
96
|
// convert and trim any nulls
|
|
91
97
|
return data.toString('utf16le').replace(/\0/g, '');
|
|
92
98
|
}
|
|
99
|
+
else {
|
|
100
|
+
return iconv_lite_1.default.decode(data, codepage).toString();
|
|
101
|
+
}
|
|
93
102
|
}
|
|
94
103
|
catch (err) {
|
|
95
104
|
console.error('PSTUtil::createJavascriptString Unable to decode string\n' + err);
|
|
@@ -286,7 +295,7 @@ class PSTUtil {
|
|
|
286
295
|
const l = low.and(0xffffffff);
|
|
287
296
|
const filetime = h.or(l);
|
|
288
297
|
const msSince16010101 = filetime.divide(1000 * 10);
|
|
289
|
-
const epochDiff =
|
|
298
|
+
const epochDiff = long_1.default.fromValue('11644473600000');
|
|
290
299
|
const msSince19700101 = msSince16010101.subtract(epochDiff);
|
|
291
300
|
return new Date(msSince19700101.toNumber());
|
|
292
301
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export declare enum RecurFrequency {
|
|
3
|
+
Daily = 8202,
|
|
4
|
+
Weekly = 8203,
|
|
5
|
+
Monthly = 8204,
|
|
6
|
+
Yearly = 8205
|
|
7
|
+
}
|
|
8
|
+
export declare enum PatternType {
|
|
9
|
+
Day = 0,
|
|
10
|
+
Week = 1,
|
|
11
|
+
Month = 2,
|
|
12
|
+
MonthEnd = 4,
|
|
13
|
+
MonthNth = 3
|
|
14
|
+
}
|
|
15
|
+
export declare enum EndType {
|
|
16
|
+
AfterDate = 8225,
|
|
17
|
+
AfterNOccurrences = 8226,
|
|
18
|
+
NeverEnd = 8227
|
|
19
|
+
}
|
|
20
|
+
export declare enum NthOccurrence {
|
|
21
|
+
First = 1,
|
|
22
|
+
Second = 2,
|
|
23
|
+
Third = 3,
|
|
24
|
+
Fourth = 4,
|
|
25
|
+
Last = 5
|
|
26
|
+
}
|
|
27
|
+
export declare type WeekSpecific = boolean[] & {
|
|
28
|
+
length: 7;
|
|
29
|
+
};
|
|
30
|
+
export declare type MonthNthSpecific = {
|
|
31
|
+
weekdays: WeekSpecific;
|
|
32
|
+
nth: NthOccurrence;
|
|
33
|
+
};
|
|
34
|
+
export declare class RecurrencePattern {
|
|
35
|
+
private buffer;
|
|
36
|
+
recurFrequency: RecurFrequency;
|
|
37
|
+
patternType: PatternType;
|
|
38
|
+
firstDateTime: Date;
|
|
39
|
+
period: number;
|
|
40
|
+
patternTypeSpecific: number | WeekSpecific | MonthNthSpecific | null;
|
|
41
|
+
endType: EndType;
|
|
42
|
+
occurrenceCount: number;
|
|
43
|
+
firstDOW: number;
|
|
44
|
+
startDate: Date;
|
|
45
|
+
endDate: Date;
|
|
46
|
+
constructor(buffer: Buffer);
|
|
47
|
+
toJSON(): any;
|
|
48
|
+
private readInt;
|
|
49
|
+
private readPatternTypeSpecific;
|
|
50
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RecurrencePattern = exports.NthOccurrence = exports.EndType = exports.PatternType = exports.RecurFrequency = void 0;
|
|
4
|
+
const OFFSETS = {
|
|
5
|
+
RecurFrequency: 4,
|
|
6
|
+
PatternType: 6,
|
|
7
|
+
FirstDateTime: 10,
|
|
8
|
+
Period: 14,
|
|
9
|
+
PatternTypeSpecific: 22,
|
|
10
|
+
EndType: 22,
|
|
11
|
+
OccurrenceCount: 26,
|
|
12
|
+
FirstDOW: 30,
|
|
13
|
+
StartDate: -8,
|
|
14
|
+
EndDate: -4,
|
|
15
|
+
};
|
|
16
|
+
var RecurFrequency;
|
|
17
|
+
(function (RecurFrequency) {
|
|
18
|
+
RecurFrequency[RecurFrequency["Daily"] = 8202] = "Daily";
|
|
19
|
+
RecurFrequency[RecurFrequency["Weekly"] = 8203] = "Weekly";
|
|
20
|
+
RecurFrequency[RecurFrequency["Monthly"] = 8204] = "Monthly";
|
|
21
|
+
RecurFrequency[RecurFrequency["Yearly"] = 8205] = "Yearly";
|
|
22
|
+
})(RecurFrequency = exports.RecurFrequency || (exports.RecurFrequency = {}));
|
|
23
|
+
var PatternType;
|
|
24
|
+
(function (PatternType) {
|
|
25
|
+
PatternType[PatternType["Day"] = 0] = "Day";
|
|
26
|
+
PatternType[PatternType["Week"] = 1] = "Week";
|
|
27
|
+
PatternType[PatternType["Month"] = 2] = "Month";
|
|
28
|
+
PatternType[PatternType["MonthEnd"] = 4] = "MonthEnd";
|
|
29
|
+
PatternType[PatternType["MonthNth"] = 3] = "MonthNth";
|
|
30
|
+
})(PatternType = exports.PatternType || (exports.PatternType = {}));
|
|
31
|
+
var EndType;
|
|
32
|
+
(function (EndType) {
|
|
33
|
+
EndType[EndType["AfterDate"] = 8225] = "AfterDate";
|
|
34
|
+
EndType[EndType["AfterNOccurrences"] = 8226] = "AfterNOccurrences";
|
|
35
|
+
EndType[EndType["NeverEnd"] = 8227] = "NeverEnd";
|
|
36
|
+
})(EndType = exports.EndType || (exports.EndType = {}));
|
|
37
|
+
var NthOccurrence;
|
|
38
|
+
(function (NthOccurrence) {
|
|
39
|
+
NthOccurrence[NthOccurrence["First"] = 1] = "First";
|
|
40
|
+
NthOccurrence[NthOccurrence["Second"] = 2] = "Second";
|
|
41
|
+
NthOccurrence[NthOccurrence["Third"] = 3] = "Third";
|
|
42
|
+
NthOccurrence[NthOccurrence["Fourth"] = 4] = "Fourth";
|
|
43
|
+
NthOccurrence[NthOccurrence["Last"] = 5] = "Last";
|
|
44
|
+
})(NthOccurrence = exports.NthOccurrence || (exports.NthOccurrence = {}));
|
|
45
|
+
class RecurrencePattern {
|
|
46
|
+
constructor(buffer) {
|
|
47
|
+
this.buffer = buffer;
|
|
48
|
+
const bufferEnd = buffer.length;
|
|
49
|
+
let patternTypeOffset = 0;
|
|
50
|
+
this.recurFrequency = this.readInt(OFFSETS.RecurFrequency, 1);
|
|
51
|
+
this.patternType = this.readInt(OFFSETS.PatternType, 1);
|
|
52
|
+
this.firstDateTime = winToJsDate(this.readInt(OFFSETS.FirstDateTime, 2));
|
|
53
|
+
this.period = this.readInt(OFFSETS.Period, 2);
|
|
54
|
+
this.patternTypeSpecific = this.readPatternTypeSpecific(this.patternType);
|
|
55
|
+
switch (this.patternType) {
|
|
56
|
+
case PatternType.Week:
|
|
57
|
+
case PatternType.Month:
|
|
58
|
+
case PatternType.MonthEnd:
|
|
59
|
+
patternTypeOffset = 4;
|
|
60
|
+
break;
|
|
61
|
+
case PatternType.MonthNth:
|
|
62
|
+
patternTypeOffset = 8;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
this.endType = this.readInt(OFFSETS.EndType + patternTypeOffset, 2);
|
|
66
|
+
this.occurrenceCount = this.readInt(OFFSETS.OccurrenceCount + patternTypeOffset, 2);
|
|
67
|
+
this.firstDOW = this.readInt(OFFSETS.FirstDOW + patternTypeOffset, 2);
|
|
68
|
+
this.startDate = winToJsDate(this.readInt(bufferEnd + OFFSETS.StartDate, 2));
|
|
69
|
+
this.endDate = winToJsDate(this.readInt(bufferEnd + OFFSETS.EndDate, 2));
|
|
70
|
+
}
|
|
71
|
+
toJSON() {
|
|
72
|
+
return {
|
|
73
|
+
recurFrequency: RecurFrequency[this.recurFrequency],
|
|
74
|
+
patternType: PatternType[this.patternType],
|
|
75
|
+
firstDateTime: this.firstDateTime,
|
|
76
|
+
period: this.period,
|
|
77
|
+
patternTypeSpecific: this.patternTypeSpecific,
|
|
78
|
+
endType: EndType[this.endType],
|
|
79
|
+
occurrenceCount: this.occurrenceCount,
|
|
80
|
+
firstDOW: this.firstDOW,
|
|
81
|
+
startDate: this.startDate,
|
|
82
|
+
endDate: this.endDate,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
readInt(offset, size) {
|
|
86
|
+
switch (size) {
|
|
87
|
+
case 1:
|
|
88
|
+
return this.buffer.readInt16LE(offset);
|
|
89
|
+
case 2:
|
|
90
|
+
return this.buffer.readInt32LE(offset);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
readPatternTypeSpecific(type) {
|
|
94
|
+
switch (type) {
|
|
95
|
+
case PatternType.Day:
|
|
96
|
+
return null;
|
|
97
|
+
case PatternType.Week:
|
|
98
|
+
return readWeekByte(this.buffer.readInt8(OFFSETS.PatternTypeSpecific));
|
|
99
|
+
case PatternType.Month:
|
|
100
|
+
case PatternType.MonthEnd:
|
|
101
|
+
return this.readInt(OFFSETS.PatternTypeSpecific, 2);
|
|
102
|
+
case PatternType.MonthNth:
|
|
103
|
+
return {
|
|
104
|
+
weekdays: readWeekByte(this.buffer.readInt8(OFFSETS.PatternTypeSpecific)),
|
|
105
|
+
nth: this.readInt(OFFSETS.PatternTypeSpecific + 4, 2),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.RecurrencePattern = RecurrencePattern;
|
|
111
|
+
function winToJsDate(dateInt) {
|
|
112
|
+
return new Date(dateInt * 60 * 1000 - 1.16444736e13); // subtract milliseconds between 1601-01-01 and 1970-01-01
|
|
113
|
+
}
|
|
114
|
+
function readWeekByte(byte) {
|
|
115
|
+
const weekArr = [];
|
|
116
|
+
for (let i = 0; i < 7; ++i) {
|
|
117
|
+
weekArr.push(Boolean(byte & (1 << i)));
|
|
118
|
+
}
|
|
119
|
+
return weekArr;
|
|
120
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PSTFolder = exports.PSTMessage = exports.PSTAttachment = exports.PSTRecipient = exports.PSTTask = exports.PSTFile = void 0;
|
|
3
4
|
var PSTFile_class_1 = require("./PSTFile.class");
|
|
4
|
-
exports
|
|
5
|
+
Object.defineProperty(exports, "PSTFile", { enumerable: true, get: function () { return PSTFile_class_1.PSTFile; } });
|
|
5
6
|
var PSTTask_class_1 = require("./PSTTask.class");
|
|
6
|
-
exports
|
|
7
|
+
Object.defineProperty(exports, "PSTTask", { enumerable: true, get: function () { return PSTTask_class_1.PSTTask; } });
|
|
7
8
|
var PSTRecipient_class_1 = require("./PSTRecipient.class");
|
|
8
|
-
exports
|
|
9
|
+
Object.defineProperty(exports, "PSTRecipient", { enumerable: true, get: function () { return PSTRecipient_class_1.PSTRecipient; } });
|
|
9
10
|
var PSTAttachment_class_1 = require("./PSTAttachment.class");
|
|
10
|
-
exports
|
|
11
|
+
Object.defineProperty(exports, "PSTAttachment", { enumerable: true, get: function () { return PSTAttachment_class_1.PSTAttachment; } });
|
|
11
12
|
var PSTMessage_class_1 = require("./PSTMessage.class");
|
|
12
|
-
exports
|
|
13
|
+
Object.defineProperty(exports, "PSTMessage", { enumerable: true, get: function () { return PSTMessage_class_1.PSTMessage; } });
|
|
13
14
|
var PSTFolder_class_1 = require("./PSTFolder.class");
|
|
14
|
-
exports
|
|
15
|
+
Object.defineProperty(exports, "PSTFolder", { enumerable: true, get: function () { return PSTFolder_class_1.PSTFolder; } });
|
package/example/package.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pst-extractor-example",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"pst-extractor": "link:.."
|
|
7
7
|
},
|
|
8
8
|
"devDependencies": {
|
|
9
|
-
"
|
|
10
|
-
"eslint-
|
|
11
|
-
"prettier": "^
|
|
12
|
-
"
|
|
13
|
-
"
|
|
9
|
+
"@types/node": "^17.0.23",
|
|
10
|
+
"eslint-config-prettier": "^8.5.0",
|
|
11
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
12
|
+
"prettier": "^2.6.2",
|
|
13
|
+
"ts-node": "^10.7.0",
|
|
14
|
+
"typescript": "^4.6.3"
|
|
14
15
|
},
|
|
15
16
|
"scripts": {
|
|
16
17
|
"start": "ts-node test-min.ts",
|
|
17
18
|
"test-min": "ts-node test-min.ts",
|
|
18
|
-
"test
|
|
19
|
-
"test-max": "ts-node test-max.ts"
|
|
19
|
+
"test": "ts-node test.ts"
|
|
20
20
|
},
|
|
21
21
|
"eslintConfig": {
|
|
22
22
|
"extends": [
|
package/example/test-min.ts
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
|
+
import * as fs from 'fs'
|
|
1
2
|
import { PSTMessage } from '../src/PSTMessage.class'
|
|
2
3
|
import { PSTFile } from '../src/PSTFile.class'
|
|
3
4
|
import { PSTFolder } from '../src/PSTFolder.class'
|
|
4
5
|
const resolve = require('path').resolve
|
|
5
6
|
|
|
7
|
+
const pstFolder = './testdata/'
|
|
8
|
+
const topOutputFolder = './testdataoutput/'
|
|
6
9
|
let depth = -1
|
|
7
10
|
let col = 0
|
|
8
11
|
|
|
12
|
+
// console log highlight with https://en.wikipedia.org/wiki/ANSI_escape_code
|
|
13
|
+
const ANSI_RED = 31
|
|
14
|
+
const ANSI_YELLOW = 93
|
|
15
|
+
const ANSI_GREEN = 32
|
|
16
|
+
const ANSI_BLUE = 34
|
|
17
|
+
const highlight = (str: string, code: number = ANSI_RED) => '\u001b[' + code + 'm' + str + '\u001b[0m'
|
|
18
|
+
|
|
9
19
|
/**
|
|
10
20
|
* Returns a string with visual indication of depth in tree.
|
|
11
21
|
* @param {number} depth
|
|
@@ -51,10 +61,10 @@ function processFolder(folder: PSTFolder): void {
|
|
|
51
61
|
while (email != null) {
|
|
52
62
|
console.log(
|
|
53
63
|
getDepth(depth) +
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
'Sender: ' +
|
|
65
|
+
email.senderName +
|
|
66
|
+
', Subject: ' +
|
|
67
|
+
email.subject
|
|
58
68
|
)
|
|
59
69
|
email = folder.getNextChild()
|
|
60
70
|
}
|
|
@@ -63,6 +73,21 @@ function processFolder(folder: PSTFolder): void {
|
|
|
63
73
|
depth--
|
|
64
74
|
}
|
|
65
75
|
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
76
|
+
const directoryListing = fs.readdirSync(pstFolder)
|
|
77
|
+
directoryListing.forEach((filename) => {
|
|
78
|
+
if (filename.endsWith('.pst') || filename.endsWith('.ost')) {
|
|
79
|
+
console.log(highlight(pstFolder + filename, ANSI_GREEN))
|
|
80
|
+
|
|
81
|
+
// time for performance comparison to Java and improvement
|
|
82
|
+
const start = Date.now()
|
|
83
|
+
|
|
84
|
+
// load file into memory buffer, then open as PSTFile
|
|
85
|
+
const pstFile = new PSTFile(fs.readFileSync(pstFolder + filename))
|
|
86
|
+
|
|
87
|
+
console.log(pstFile.getMessageStore().displayName)
|
|
88
|
+
processFolder(pstFile.getRootFolder())
|
|
89
|
+
|
|
90
|
+
const end = Date.now()
|
|
91
|
+
console.log(highlight(pstFolder + filename + ' processed in ' + (end - start) + ' ms', ANSI_GREEN))
|
|
92
|
+
}
|
|
93
|
+
})
|
|
@@ -4,18 +4,26 @@ import { PSTFile } from '../src/PSTFile.class'
|
|
|
4
4
|
import { PSTFolder } from '../src/PSTFolder.class'
|
|
5
5
|
import { PSTMessage } from '../src/PSTMessage.class'
|
|
6
6
|
|
|
7
|
-
const pstFolder = '/
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const displaySender = true
|
|
12
|
-
const displayBody = false
|
|
7
|
+
const pstFolder = './testdata/'
|
|
8
|
+
const saveToFS = true
|
|
9
|
+
const topOutputFolder = './testdataoutput/'
|
|
10
|
+
|
|
13
11
|
const verbose = true
|
|
12
|
+
const displaySender = true
|
|
13
|
+
const displayBody = true
|
|
14
|
+
let outputFolder = ''
|
|
14
15
|
let depth = -1
|
|
15
16
|
let col = 0
|
|
16
17
|
|
|
18
|
+
// console log highlight with https://en.wikipedia.org/wiki/ANSI_escape_code
|
|
19
|
+
const ANSI_RED = 31
|
|
20
|
+
const ANSI_YELLOW = 93
|
|
21
|
+
const ANSI_GREEN = 32
|
|
22
|
+
const ANSI_BLUE = 34
|
|
23
|
+
const highlight = (str: string, code: number = ANSI_RED) => '\u001b[' + code + 'm' + str + '\u001b[0m'
|
|
24
|
+
|
|
17
25
|
/**
|
|
18
|
-
* Returns a string with visual
|
|
26
|
+
* Returns a string with visual indication of depth in tree.
|
|
19
27
|
* @param {number} depth
|
|
20
28
|
* @returns {string}
|
|
21
29
|
*/
|
|
@@ -49,7 +57,7 @@ function doSaveToFS(
|
|
|
49
57
|
// save the msg as a txt file
|
|
50
58
|
const filename = emailFolder + msg.descriptorNodeId + '.txt'
|
|
51
59
|
if (verbose) {
|
|
52
|
-
console.log('saving msg to ' + filename)
|
|
60
|
+
console.log(highlight('saving msg to ' + filename))
|
|
53
61
|
}
|
|
54
62
|
const fd = fs.openSync(filename, 'w')
|
|
55
63
|
fs.writeSync(fd, msg.clientSubmitTime + '\r\n')
|
|
@@ -71,7 +79,7 @@ function doSaveToFS(
|
|
|
71
79
|
const filename =
|
|
72
80
|
emailFolder + msg.descriptorNodeId + '-' + attachment.longFilename
|
|
73
81
|
if (verbose) {
|
|
74
|
-
console.log('saving attachment to ' + filename)
|
|
82
|
+
console.log(highlight('saving attachment to ' + filename, ANSI_BLUE))
|
|
75
83
|
}
|
|
76
84
|
try {
|
|
77
85
|
const fd = fs.openSync(filename, 'w')
|
|
@@ -158,10 +166,10 @@ function processFolder(folder: PSTFolder): void {
|
|
|
158
166
|
if (verbose) {
|
|
159
167
|
console.log(
|
|
160
168
|
getDepth(depth) +
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
169
|
+
'Email: ' +
|
|
170
|
+
email.descriptorNodeId +
|
|
171
|
+
' - ' +
|
|
172
|
+
email.subject
|
|
165
173
|
)
|
|
166
174
|
} else {
|
|
167
175
|
printDot()
|
|
@@ -175,8 +183,9 @@ function processFolder(folder: PSTFolder): void {
|
|
|
175
183
|
|
|
176
184
|
// display body?
|
|
177
185
|
if (verbose && displayBody) {
|
|
178
|
-
console.log(email.body)
|
|
179
|
-
console.log(email.bodyRTF)
|
|
186
|
+
console.log(highlight('email.body', ANSI_YELLOW), email.body)
|
|
187
|
+
console.log(highlight('email.bodyRTF', ANSI_YELLOW), email.bodyRTF)
|
|
188
|
+
console.log(highlight('email.bodyHTML', ANSI_YELLOW), email.bodyHTML)
|
|
180
189
|
}
|
|
181
190
|
|
|
182
191
|
// save content to fs?
|
|
@@ -223,27 +232,29 @@ try {
|
|
|
223
232
|
|
|
224
233
|
const directoryListing = fs.readdirSync(pstFolder)
|
|
225
234
|
directoryListing.forEach((filename) => {
|
|
226
|
-
|
|
235
|
+
if (filename.endsWith('.pst') || filename.endsWith('.ost')) {
|
|
236
|
+
console.log(highlight(pstFolder + filename, ANSI_GREEN))
|
|
227
237
|
|
|
228
|
-
|
|
229
|
-
|
|
238
|
+
// time for performance comparison to Java and improvement
|
|
239
|
+
const start = Date.now()
|
|
230
240
|
|
|
231
|
-
|
|
232
|
-
|
|
241
|
+
// load file into memory buffer, then open as PSTFile
|
|
242
|
+
const pstFile = new PSTFile(fs.readFileSync(pstFolder + filename))
|
|
233
243
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
244
|
+
// make a sub folder for each PST
|
|
245
|
+
try {
|
|
246
|
+
if (saveToFS) {
|
|
247
|
+
outputFolder = topOutputFolder + filename + '/'
|
|
248
|
+
fs.mkdirSync(outputFolder)
|
|
249
|
+
}
|
|
250
|
+
} catch (err) {
|
|
251
|
+
console.error(err)
|
|
239
252
|
}
|
|
240
|
-
} catch (err) {
|
|
241
|
-
console.error(err)
|
|
242
|
-
}
|
|
243
253
|
|
|
244
|
-
|
|
245
|
-
|
|
254
|
+
console.log(pstFile.getMessageStore().displayName)
|
|
255
|
+
processFolder(pstFile.getRootFolder())
|
|
246
256
|
|
|
247
|
-
|
|
248
|
-
|
|
257
|
+
const end = Date.now()
|
|
258
|
+
console.log(highlight(pstFolder + filename + ' processed in ' + (end - start) + ' ms', ANSI_GREEN))
|
|
259
|
+
}
|
|
249
260
|
})
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
this is a text doc
|