1 | import * as fs from "fs-extra";
|
2 | import * as request from "request";
|
3 | import * as retry from "retry";
|
4 |
|
5 | import { MagnoliaSourceOptions } from "./magnolia-source-options.interface";
|
6 | import { reject } from "bluebird";
|
7 |
|
8 | export function fetchDamAssets(
|
9 | uuids: string[],
|
10 | options?: MagnoliaSourceOptions
|
11 | ): Promise<any> {
|
12 | return new Promise(resolve => {
|
13 | const operation = retry.operation();
|
14 | const damUrl = options.magnolia.url + options.magnolia.damJsonEndpoint;
|
15 |
|
16 | request.get(
|
17 | damUrl,
|
18 | {
|
19 | json: true,
|
20 | headers: {
|
21 | Authorization: options.magnolia.auth.header,
|
22 | "User-Agent": "Paperboy"
|
23 | },
|
24 | timeout: 60 * 1000
|
25 | },
|
26 | async (err, res, body) => {
|
27 | if (operation.retry(err)) {
|
28 | console.error(
|
29 | "Attempt to get asset information failed, will retry in some time..."
|
30 | );
|
31 | return;
|
32 | }
|
33 |
|
34 | if (body && body.results && body.results.length > 0) {
|
35 | const sanitizedAssetJson = uuids
|
36 | .map(uuid =>
|
37 | body.results.find(
|
38 | (asset: any) =>
|
39 | asset["jcr:uuid"] === uuid || asset["@id"] === uuid
|
40 | )
|
41 | )
|
42 | .map(json => (json ? sanitizeDamJson(json) : null));
|
43 |
|
44 | const assetsNeedingUpdate = sanitizedAssetJson.filter(asset => {
|
45 | if (asset) {
|
46 | const filePath = options.output.assets + asset.path;
|
47 | const fileExists = fs.existsSync(filePath);
|
48 |
|
49 | if (fileExists) {
|
50 | return (
|
51 | new Date(fs.statSync(filePath).mtime).getTime() <
|
52 | new Date(asset.lastModified).getTime()
|
53 | );
|
54 | }
|
55 | }
|
56 |
|
57 | return true;
|
58 | });
|
59 |
|
60 | await Promise.all(
|
61 | assetsNeedingUpdate.map(asset => downloadAsset(options, asset))
|
62 | ).catch(error => {
|
63 | console.error(error);
|
64 | });
|
65 |
|
66 | resolve(sanitizedAssetJson);
|
67 | } else {
|
68 | resolve([]);
|
69 | }
|
70 | }
|
71 | );
|
72 | });
|
73 | }
|
74 |
|
75 | function sanitizeDamJson(damJson: any): any {
|
76 | const sanitized: any = {};
|
77 |
|
78 | Object.keys(damJson).forEach(async key => {
|
79 | const sanitizedKey = key
|
80 | .replace(/^@path/, "path")
|
81 | .replace(/^@/, "")
|
82 | .replace(/^mgnl:/, "")
|
83 | .replace(/^jcr:uuid/, "id")
|
84 | .replace(/^jcr:mimeType/, "mimeType");
|
85 |
|
86 | if (!sanitizedKey.match(/^jcr:/)) {
|
87 | sanitized[sanitizedKey] = damJson[key];
|
88 | }
|
89 | });
|
90 |
|
91 | return sanitized;
|
92 | }
|
93 |
|
94 | function downloadAsset(
|
95 | options: MagnoliaSourceOptions,
|
96 | asset: any
|
97 | ): Promise<void> {
|
98 | return new Promise(resolve => {
|
99 | if (asset) {
|
100 | const filePath = options.output.assets + asset.path;
|
101 | const directory = filePath
|
102 | .split("/")
|
103 | .slice(0, -1)
|
104 | .join("/");
|
105 |
|
106 | fs.mkdirpSync(directory);
|
107 |
|
108 | request
|
109 | .get(options.magnolia.url + "/dam/jcr:" + asset.id, {
|
110 | headers: {
|
111 | Authorization: options.magnolia.auth.header,
|
112 | "User-Agent": "Paperboy"
|
113 | },
|
114 | timeout: 60 * 1000
|
115 | })
|
116 | .on("response", res => {
|
117 | res.pipe(fs.createWriteStream(filePath));
|
118 |
|
119 | res.on("end", () => {
|
120 | resolve();
|
121 | });
|
122 | })
|
123 | .on("error", function(error) {
|
124 | reject(new Error(`Could not fetch asset ${asset.id}: ${error}`));
|
125 | });
|
126 | } else {
|
127 | resolve();
|
128 | }
|
129 | });
|
130 | }
|