1 | process.on('unhandledRejection', result => console.error(result));
|
2 |
|
3 | const _ = require('lodash');
|
4 | const Promise = require('bluebird');
|
5 | const Cloudant = require('@cloudant/cloudant');
|
6 |
|
7 | const BATCH_UPDATE_CHUNK_SIZE = 100;
|
8 |
|
9 | const args = process.argv.slice(2);
|
10 |
|
11 | if (!args[1]) {
|
12 | throw Error('No db specified');
|
13 | }
|
14 |
|
15 | const docFilter = doc => doc.type && doc.type === 'entity';
|
16 |
|
17 | const updateThumbnail = (doc) => {
|
18 | if (!_.isObject(doc)) {
|
19 | return doc;
|
20 | }
|
21 |
|
22 | if (doc.thumbnail && doc.thumbnail.thumbnailUrl && /_thumb_0000/.test(doc.thumbnail.thumbnailUrl)) {
|
23 | doc.thumbnail.fileName = `${doc.thumbnail.thumbnailUrl.split('/').slice(-2)[0]}.mp4`;
|
24 | doc.thumbnail.duration = 0;
|
25 | }
|
26 |
|
27 | if (doc.thumbnail && doc.thumbnail.thumbnailUrl) {
|
28 | doc.thumbnail.thumbnailUrl = doc.thumbnail.thumbnailUrl
|
29 | .replace('https://fokusio.s3.amazonaws.com', 'https://assist.cdn.fokus.io')
|
30 | .replace('_thumb_0000.jpg', 'thumb.jpg');
|
31 | }
|
32 |
|
33 | if (doc.thumbnail && doc.thumbnail.thumbnailUrl && /vimeocdn/.test(doc.thumbnail.thumbnailUrl)) {
|
34 | doc.thumbnail.thumbnailType = 'oembed';
|
35 | }
|
36 |
|
37 | if (doc.thumbnail && doc.thumbnail.fileName) {
|
38 | doc.thumbnail.name = doc.thumbnail.fileName.split('.')[0];
|
39 | doc.thumbnail.ext = `.${doc.thumbnail.fileName.split('.')[1]}`;
|
40 | }
|
41 |
|
42 | if (doc.thumbnail) {
|
43 | delete doc.thumbnail.mimeType;
|
44 | delete doc.thumbnail.location;
|
45 | }
|
46 |
|
47 | return doc;
|
48 | };
|
49 |
|
50 | const docMutate = (doc) => {
|
51 | doc.fields = _.mapValues(doc.fields, (field) => {
|
52 |
|
53 | try {
|
54 | if (field.value && field.value.status === 'incomplete') {
|
55 | delete field.value;
|
56 | }
|
57 |
|
58 | if (field.value && field.value.type === 'file' && !field.value.file) {
|
59 | const _field = _.cloneDeep(field.value);
|
60 |
|
61 | field.value = {
|
62 | original: {
|
63 | fileName: _field.original && _field.original.fileName ? _field.original.fileName : _field.fileName,
|
64 | fileSize: _field.fileSize || _field.original.fileSize,
|
65 | mimeType: _field.mimeType || _field.original.mimeType,
|
66 | },
|
67 |
|
68 | metadata: {
|
69 | width: _.get(_field, 'metadata.width') || _.get(_field, 'metadata.zencoder.thumbnail.width') || undefined,
|
70 | height: _.get(_field, 'metadata.height') || _.get(_field, 'metadata.zencoder.thumbnail.height') || undefined,
|
71 | format: (_field.mimeType || _field.original.mimeType).split('/')[1],
|
72 | },
|
73 |
|
74 | crops: _field.crops || undefined,
|
75 | dzi: _field.dzi || undefined,
|
76 | };
|
77 |
|
78 | if (_field.location === 's3' && _field.metadata && _field.metadata.s3) {
|
79 | field.value.file = {
|
80 | name: _field.metadata.s3.base,
|
81 | ext: _field.metadata.s3.ext,
|
82 | size: _field.original.fileSize,
|
83 | };
|
84 | }
|
85 |
|
86 | if (_field.location === 'assist') {
|
87 | field.value.file = {
|
88 | name: _field.fileName.split('.')[0],
|
89 | ext: `.${_field.fileName.split('.')[1]}`,
|
90 | size: _field.fileSize,
|
91 | };
|
92 | }
|
93 |
|
94 | if (_field.metadata && _field.metadata.zencoder && _field.metadata.zencoder.outputs) {
|
95 | field.value.metadata.duration = _.sample(_field.metadata.zencoder.outputs).duration;
|
96 | }
|
97 | }
|
98 | } catch (error) {
|
99 | console.error('ERROR --> ');
|
100 | console.error(field);
|
101 | console.error(error);
|
102 | delete field.value;
|
103 | }
|
104 |
|
105 | if (_.isArray(field.value)) {
|
106 | field.value = field.value.map(updateThumbnail);
|
107 | }
|
108 |
|
109 | return field;
|
110 | });
|
111 |
|
112 | doc = updateThumbnail(doc);
|
113 |
|
114 | return doc;
|
115 | };
|
116 |
|
117 | const batchUpdateDocs = (db, docs) => Promise.all(_.chunk(docs, BATCH_UPDATE_CHUNK_SIZE).map(chunk => db.bulk({ docs: chunk })));
|
118 |
|
119 | const dbUrl = args[0];
|
120 | const dbNames = args.slice(1);
|
121 |
|
122 | dbNames.forEach(async (dbName) => {
|
123 | const db = new Cloudant({
|
124 | url: dbUrl,
|
125 | plugins: ['promises', 'retry'],
|
126 | }).db.use(dbName);
|
127 |
|
128 | let docs = (await db.list({ include_docs: true })).rows.map(row => row.doc);
|
129 |
|
130 | console.log(`${dbName} --> ${docs.length} docs fetched`);
|
131 |
|
132 | docs = docs.filter(docFilter);
|
133 |
|
134 | console.log(`${dbName} --> ${docs.length} entities found`);
|
135 |
|
136 | docs = docs.map(docMutate);
|
137 |
|
138 | await batchUpdateDocs(db, docs);
|
139 |
|
140 | console.log(`${dbName} --> ${docs.length} entities updated`);
|
141 | });
|