This repository has been archived by the owner on Jun 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 64
/
message-body-utils.es6
80 lines (70 loc) · 2.25 KB
/
message-body-utils.es6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
const fs = require('fs')
const mkdirp = require('mkdirp')
const path = require('path')
const zlib = require('zlib')
const MAX_PATH_DIRS = 5;
const FILE_EXTENSION = 'nylasmail'
function baseMessagePath() {
return path.join(process.env.NYLAS_HOME, 'messages');
}
export function tryReadBody(val) {
try {
const parsed = JSON.parse(val);
if (parsed && parsed.path && parsed.path.startsWith(baseMessagePath())) {
if (parsed.compressed) {
return zlib.gunzipSync(fs.readFileSync(parsed.path)).toString();
}
return fs.readFileSync(parsed.path, {encoding: 'utf8'});
}
} catch (err) {
// ignore. this is valid. JSON parse should fail if the body isn't
// metadata about the flat zipped file, but rather a plain text
}
return null;
}
export function pathForBodyFile(msgId) {
const pathGroups = [];
let remainingId = msgId;
if (remainingId) {
while (pathGroups.length < MAX_PATH_DIRS) {
pathGroups.push(remainingId.substring(0, 2));
remainingId = remainingId.substring(2);
}
}
const bodyPath = path.join(...pathGroups);
return path.join(baseMessagePath(), bodyPath, `${remainingId}.${FILE_EXTENSION}`);
}
// NB: The return value of this function is what gets written into the database.
export function writeBody({msgId, body} = {}) {
const bodyPath = pathForBodyFile(msgId);
const bodyDir = path.dirname(bodyPath);
const compressedBody = zlib.gzipSync(body);
const dbEntry = {
path: bodyPath,
compressed: true,
};
// It's possible that gzipping actually makes the body larger. If that's the
// case then just write the uncompressed body instead.
let bodyToWrite = compressedBody;
if (compressedBody.length >= body.length) {
dbEntry.compressed = false;
bodyToWrite = body;
}
const result = JSON.stringify(dbEntry);
// If the JSON db entry would be longer than the body itself then just write
// the body directly into the database.
if (result.length > body.length) {
return body;
}
try {
if (!fs.existsSync(bodyPath)) {
mkdirp.sync(bodyDir);
}
fs.writeFileSync(bodyPath, bodyToWrite);
return result;
} catch (err) {
// If anything bad happens while trying to write to disk just store the
// body in the database.
return body;
}
}