vtb-appit 0.1.6 → 0.1.8
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/appit.js +226 -829
- package/package.json +1 -1
package/appit.js
CHANGED
|
@@ -27,7 +27,7 @@ class Appit {
|
|
|
27
27
|
|
|
28
28
|
history()
|
|
29
29
|
{
|
|
30
|
-
|
|
30
|
+
this.history = {
|
|
31
31
|
excursionId: null,
|
|
32
32
|
members: {},
|
|
33
33
|
ships: {},
|
|
@@ -42,112 +42,64 @@ class Appit {
|
|
|
42
42
|
destinations: {},
|
|
43
43
|
flights: {},
|
|
44
44
|
flightImages: {},
|
|
45
|
-
notifications: {}
|
|
46
|
-
status: 'pending',
|
|
47
|
-
errors: [],
|
|
48
|
-
lastSaved: null
|
|
45
|
+
notifications: {}
|
|
49
46
|
};
|
|
50
47
|
|
|
51
48
|
try {
|
|
52
49
|
const historyFile = fs.readFileSync(this.historyPath, {encoding: 'utf8'});
|
|
53
|
-
this.history =
|
|
54
|
-
this.log('info', 'History loaded from file');
|
|
50
|
+
this.history = JSON.parse(historyFile);
|
|
55
51
|
} catch(e) {
|
|
56
|
-
|
|
57
|
-
this.log('info', 'Starting with fresh history');
|
|
52
|
+
|
|
58
53
|
}
|
|
59
54
|
}
|
|
60
55
|
|
|
61
56
|
async exec()
|
|
62
57
|
{
|
|
63
|
-
this.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
this.log('info', 'Login successful');
|
|
72
|
-
|
|
73
|
-
this.transformer.profile = await this.fetchProfile();
|
|
74
|
-
this.log('info', 'Profile fetched successfully');
|
|
75
|
-
|
|
76
|
-
if(this.options && this.options.tsData) {
|
|
77
|
-
try {
|
|
78
|
-
this.transformer.tsData = await this.transformer.tsGetData();
|
|
79
|
-
this.log('info', 'TS data loaded successfully');
|
|
80
|
-
} catch(e) {
|
|
81
|
-
this.log('error', 'Failed to load TS data', e.message);
|
|
82
|
-
errors.push({ step: 'tsData', error: e.message });
|
|
83
|
-
}
|
|
84
|
-
}
|
|
58
|
+
if(!await this.login()) return false;
|
|
59
|
+
|
|
60
|
+
this.transformer.profile = await this.fetchProfile();
|
|
61
|
+
|
|
62
|
+
if(this.options && this.options.tsData) {
|
|
63
|
+
try {
|
|
64
|
+
this.transformer.tsData = await this.transformer.tsGetData();
|
|
65
|
+
} catch(e) {
|
|
85
66
|
|
|
86
|
-
if(this.options && this.options.tsDocuments) {
|
|
87
|
-
try {
|
|
88
|
-
this.transformer.tsDocuments = await this.transformer.tsGetDocuments();
|
|
89
|
-
this.log('info', 'TS documents loaded successfully');
|
|
90
|
-
} catch(e) {
|
|
91
|
-
this.log('error', 'Failed to load TS documents', e.message);
|
|
92
|
-
errors.push({ step: 'tsDocuments', error: e.message });
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const steps = [
|
|
97
|
-
{ name: 'excursion', fn: () => this.excursion() },
|
|
98
|
-
{ name: 'labels', fn: () => this.labels() },
|
|
99
|
-
{ name: 'ships', fn: () => this.ships() },
|
|
100
|
-
{ name: 'places', fn: () => this.places() },
|
|
101
|
-
{ name: 'organizations', fn: () => this.organizations() },
|
|
102
|
-
{ name: 'members', fn: () => this.members() },
|
|
103
|
-
{ name: 'travelInfo', fn: () => this.travelInfo() },
|
|
104
|
-
{ name: 'accommodations', fn: () => this.accommodations() },
|
|
105
|
-
{ name: 'destinations', fn: () => this.destinations() },
|
|
106
|
-
{ name: 'schemes', fn: () => this.schemes() },
|
|
107
|
-
{ name: 'flights', fn: () => this.flights() },
|
|
108
|
-
{ name: 'flightImages', fn: () => this.flightImages() },
|
|
109
|
-
{ name: 'contacts', fn: () => this.contacts() },
|
|
110
|
-
{ name: 'documents', fn: () => this.documents() },
|
|
111
|
-
{ name: 'homescreen', fn: () => this.homescreen() },
|
|
112
|
-
{ name: 'menu', fn: () => this.menu() },
|
|
113
|
-
{ name: 'settings', fn: () => this.settings() },
|
|
114
|
-
{ name: 'notifications', fn: () => this.notifications() }
|
|
115
|
-
];
|
|
116
|
-
|
|
117
|
-
for(const step of steps) {
|
|
118
|
-
try {
|
|
119
|
-
this.log('info', `Processing ${step.name}...`);
|
|
120
|
-
await step.fn();
|
|
121
|
-
this.log('info', `✓ ${step.name} completed successfully`);
|
|
122
|
-
} catch(error) {
|
|
123
|
-
this.log('error', `✗ ${step.name} failed`, error.message);
|
|
124
|
-
errors.push({ step: step.name, error: error.message });
|
|
125
|
-
// Continue with next step instead of failing entirely
|
|
126
|
-
}
|
|
127
67
|
}
|
|
68
|
+
}
|
|
128
69
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
70
|
+
if(this.options && this.options.tsDocuments) {
|
|
71
|
+
try {
|
|
72
|
+
this.transformer.tsDocuments = await this.transformer.tsGetDocuments();
|
|
73
|
+
} catch(e) {
|
|
132
74
|
|
|
133
|
-
fs.writeFileSync(this.historyPath, JSON.stringify(this.history, null, 2));
|
|
134
|
-
|
|
135
|
-
if(errors.length === 0) {
|
|
136
|
-
this.log('info', 'Sync completed successfully');
|
|
137
|
-
return true;
|
|
138
|
-
} else {
|
|
139
|
-
this.log('warn', `Sync completed with ${errors.length} errors`, errors);
|
|
140
|
-
return true; // Still return true as we completed what we could
|
|
141
75
|
}
|
|
142
|
-
|
|
143
|
-
} catch(error) {
|
|
144
|
-
this.log('error', 'Critical error during sync', error);
|
|
145
|
-
this.history.status = 'failed';
|
|
146
|
-
this.history.criticalError = error.message;
|
|
147
|
-
this.history.updatedAt = new Date().getTime();
|
|
148
|
-
this.saveHistoryIncremental();
|
|
149
|
-
return false;
|
|
150
76
|
}
|
|
77
|
+
|
|
78
|
+
await this.excursion();
|
|
79
|
+
await this.labels();
|
|
80
|
+
await this.explores();
|
|
81
|
+
await this.ships();
|
|
82
|
+
await this.places();
|
|
83
|
+
await this.organizations();
|
|
84
|
+
await this.members();
|
|
85
|
+
await this.travelInfo();
|
|
86
|
+
await this.accommodations();
|
|
87
|
+
await this.destinations();
|
|
88
|
+
await this.schemes();
|
|
89
|
+
await this.flights();
|
|
90
|
+
await this.flightImages();
|
|
91
|
+
await this.contacts();
|
|
92
|
+
await this.documents();
|
|
93
|
+
await this.homescreen();
|
|
94
|
+
await this.menu();
|
|
95
|
+
await this.settings();
|
|
96
|
+
await this.notifications();
|
|
97
|
+
|
|
98
|
+
this.history.updatedAt = new Date().getTime();
|
|
99
|
+
|
|
100
|
+
fs.writeFileSync(this.historyPath, JSON.stringify(this.history));
|
|
101
|
+
|
|
102
|
+
return true;
|
|
151
103
|
}
|
|
152
104
|
|
|
153
105
|
async labels()
|
|
@@ -193,6 +145,14 @@ class Appit {
|
|
|
193
145
|
}
|
|
194
146
|
}
|
|
195
147
|
|
|
148
|
+
async explores()
|
|
149
|
+
{
|
|
150
|
+
let explores = this.transformer.explores()
|
|
151
|
+
if(explores) {
|
|
152
|
+
await this.saveExplores(this.transformer.workspace_id, explores);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
196
156
|
async settings()
|
|
197
157
|
{
|
|
198
158
|
let settings = this.transformer.settings()
|
|
@@ -222,78 +182,37 @@ class Appit {
|
|
|
222
182
|
{
|
|
223
183
|
let placesHistory = {};
|
|
224
184
|
const places = this.transformer.places();
|
|
225
|
-
if(
|
|
226
|
-
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
this.log('info', `Processing ${places.length} places`);
|
|
231
|
-
|
|
232
|
-
for(let i = 0; i < places.length; i++) {
|
|
233
|
-
try {
|
|
234
|
-
this.log('debug', `Processing place ${i + 1}/${places.length}: ${places[i].object_id}`);
|
|
235
|
-
|
|
185
|
+
if(places && places.length) {
|
|
186
|
+
for(let i = 0; i < places.length; i++) {
|
|
236
187
|
let place = this.clean(JSON.parse(JSON.stringify(places[i])));
|
|
237
188
|
|
|
238
|
-
const images = (place.images
|
|
189
|
+
const images = (place.images.length) ? await this.getImages(place.images, 'original/lg') : {};
|
|
239
190
|
delete place.images;
|
|
240
191
|
|
|
241
192
|
if(place.category_id && typeof place.category_id === 'string') {
|
|
242
193
|
place.category_id = await this.findOrCreateCategory(place.category_id);
|
|
243
194
|
}
|
|
244
195
|
|
|
245
|
-
const placeData = {...place, ...images, excursion_id: this.history.excursionId};
|
|
246
196
|
let id = this.findId('places', places[i].object_id);
|
|
247
|
-
|
|
248
197
|
if(!id) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
this.history.places[places[i].object_id] = model.data.id;
|
|
253
|
-
this.saveHistoryIncremental();
|
|
254
|
-
this.log('debug', `✓ Created place: ${places[i].object_id}`);
|
|
255
|
-
}
|
|
198
|
+
let model = await this.createPlace({...place, ...images, excursion_id: this.history.excursionId});
|
|
199
|
+
console.log('place', model);
|
|
200
|
+
placesHistory[places[i].object_id] = model.data.id;
|
|
256
201
|
} else {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
placesHistory[places[i].object_id] = model.data.id;
|
|
260
|
-
this.history.places[places[i].object_id] = model.data.id;
|
|
261
|
-
this.saveHistoryIncremental();
|
|
262
|
-
this.log('debug', `✓ Updated place: ${places[i].object_id}`);
|
|
263
|
-
}
|
|
202
|
+
let model = await this.updatePlace(id, {...place, ...images, excursion_id: this.history.excursionId});
|
|
203
|
+
placesHistory[places[i].object_id] = model.data.id;
|
|
264
204
|
}
|
|
265
|
-
} catch(error) {
|
|
266
|
-
this.log('error', `Failed to process place ${places[i].object_id}`, error.message);
|
|
267
|
-
this.saveErrorToHistory('places', places[i].object_id, error.message);
|
|
268
|
-
// Continue with next place instead of failing entirely
|
|
269
205
|
}
|
|
270
206
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if(nonExisting.length > 0) {
|
|
278
|
-
this.log('info', `Deleting ${nonExisting.length} removed places`);
|
|
279
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
280
|
-
try {
|
|
281
|
-
await this.retryOperation(() => this.deletePlace(nonExisting[i]));
|
|
282
|
-
// Remove from history after successful deletion
|
|
283
|
-
for(const [key, value] of Object.entries(this.history.places || {})) {
|
|
284
|
-
if(value === nonExisting[i]) {
|
|
285
|
-
delete this.history.places[key];
|
|
286
|
-
this.saveHistoryIncremental();
|
|
287
|
-
this.log('debug', `✓ Deleted place: ${key}`);
|
|
288
|
-
break;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
} catch(error) {
|
|
292
|
-
this.log('error', `Failed to delete place ${nonExisting[i]}`, error.message);
|
|
293
|
-
this.saveErrorToHistory('places', `delete-${nonExisting[i]}`, error.message);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
207
|
+
console.log(Object.values(this.history.places));
|
|
208
|
+
console.log(Object.values(placesHistory));
|
|
209
|
+
let nonExisting = this.difference(Object.values(this.history.places), Object.values(placesHistory));
|
|
210
|
+
console.log(nonExisting);
|
|
211
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
212
|
+
await this.deletePlace(nonExisting[i]);
|
|
296
213
|
}
|
|
214
|
+
|
|
215
|
+
this.history.places = placesHistory;
|
|
297
216
|
}
|
|
298
217
|
|
|
299
218
|
|
|
@@ -323,74 +242,32 @@ class Appit {
|
|
|
323
242
|
async ships()
|
|
324
243
|
{
|
|
325
244
|
const ships = this.transformer.ships();
|
|
326
|
-
if(!ships || !ships.length) {
|
|
327
|
-
this.log('info', 'No ships to process');
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
this.log('info', `Processing ${ships.length} ships`);
|
|
332
245
|
let shipsHistory = {};
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
try {
|
|
336
|
-
this.log('debug', `Processing ship ${i + 1}/${ships.length}: ${ships[i].object_id}`);
|
|
337
|
-
|
|
246
|
+
if(ships && ships.length) {
|
|
247
|
+
for(let i = 0; i < ships.length; i++) {
|
|
338
248
|
let ship = this.clean(JSON.parse(JSON.stringify(ships[i])));
|
|
339
249
|
|
|
340
|
-
const images = (ship.images
|
|
250
|
+
const images = (ship.images.length) ? await this.getImages(ship.images, 'original/lg') : {};
|
|
341
251
|
delete ship.images;
|
|
342
252
|
|
|
343
|
-
const shipData = {...ship, ...images, excursion_id: this.history.excursionId};
|
|
344
253
|
let id = this.findId('ships', ships[i].object_id);
|
|
345
|
-
|
|
346
254
|
if(!id) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
shipsHistory[ships[i].object_id] = model.data.id;
|
|
350
|
-
this.history.ships[ships[i].object_id] = model.data.id;
|
|
351
|
-
this.saveHistoryIncremental();
|
|
352
|
-
this.log('debug', `✓ Created ship: ${ships[i].object_id}`);
|
|
353
|
-
}
|
|
255
|
+
let model = await this.createShip({...ship, ...images, excursion_id: this.history.excursionId});
|
|
256
|
+
shipsHistory[ships[i].object_id] = model.data.id;
|
|
354
257
|
} else {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
shipsHistory[ships[i].object_id] = model.data.id;
|
|
358
|
-
this.history.ships[ships[i].object_id] = model.data.id;
|
|
359
|
-
this.saveHistoryIncremental();
|
|
360
|
-
this.log('debug', `✓ Updated ship: ${ships[i].object_id}`);
|
|
361
|
-
}
|
|
258
|
+
let model = await this.updateShip(id, {...ship, ...images, excursion_id: this.history.excursionId});
|
|
259
|
+
shipsHistory[ships[i].object_id] = model.data.id;
|
|
362
260
|
}
|
|
363
|
-
} catch(error) {
|
|
364
|
-
this.log('error', `Failed to process ship ${ships[i].object_id}`, error.message);
|
|
365
|
-
this.saveErrorToHistory('ships', ships[i].object_id, error.message);
|
|
366
|
-
// Continue with next ship instead of failing entirely
|
|
367
261
|
}
|
|
368
262
|
}
|
|
369
263
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
378
|
-
try {
|
|
379
|
-
await this.retryOperation(() => this.deleteShip(nonExisting[i]));
|
|
380
|
-
// Remove from history after successful deletion
|
|
381
|
-
for(const [key, value] of Object.entries(this.history.ships || {})) {
|
|
382
|
-
if(value === nonExisting[i]) {
|
|
383
|
-
delete this.history.ships[key];
|
|
384
|
-
this.saveHistoryIncremental();
|
|
385
|
-
this.log('debug', `✓ Deleted ship: ${key}`);
|
|
386
|
-
break;
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
} catch(error) {
|
|
390
|
-
this.log('error', `Failed to delete ship ${nonExisting[i]}`, error.message);
|
|
391
|
-
this.saveErrorToHistory('ships', `delete-${nonExisting[i]}`, error.message);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
264
|
+
if(this.history.hasOwnProperty('ships')) {
|
|
265
|
+
let nonExisting = this.difference(Object.values(this.history.ships), Object.values(shipsHistory));
|
|
266
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
267
|
+
await this.deleteShips(nonExisting[i]);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
this.history.ships = shipsHistory;
|
|
394
271
|
}
|
|
395
272
|
}
|
|
396
273
|
|
|
@@ -398,71 +275,28 @@ class Appit {
|
|
|
398
275
|
async flights()
|
|
399
276
|
{
|
|
400
277
|
const flights = this.transformer.flights();
|
|
401
|
-
if(!flights || !flights.length) {
|
|
402
|
-
this.log('info', 'No flights to process');
|
|
403
|
-
return;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
this.log('info', `Processing ${flights.length} flights`);
|
|
407
278
|
let flightsHistory = {};
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
try {
|
|
411
|
-
this.log('debug', `Processing flight ${i + 1}/${flights.length}: ${flights[i].object_id}`);
|
|
412
|
-
|
|
279
|
+
if(flights && flights.length) {
|
|
280
|
+
for(let i = 0; i < flights.length; i++) {
|
|
413
281
|
let flight = this.clean(JSON.parse(JSON.stringify(flights[i])));
|
|
414
|
-
|
|
282
|
+
|
|
415
283
|
let id = this.findId('flights', flights[i].object_id);
|
|
416
|
-
|
|
417
284
|
if(!id) {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
flightsHistory[flights[i].object_id] = model.data.id;
|
|
421
|
-
this.history.flights[flights[i].object_id] = model.data.id;
|
|
422
|
-
this.saveHistoryIncremental();
|
|
423
|
-
this.log('debug', `✓ Created flight: ${flights[i].object_id}`);
|
|
424
|
-
}
|
|
285
|
+
let model = await this.createFlight({...flight, excursion_id: this.history.excursionId});
|
|
286
|
+
flightsHistory[flights[i].object_id] = model.data.id;
|
|
425
287
|
} else {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
flightsHistory[flights[i].object_id] = model.data.id;
|
|
429
|
-
this.history.flights[flights[i].object_id] = model.data.id;
|
|
430
|
-
this.saveHistoryIncremental();
|
|
431
|
-
this.log('debug', `✓ Updated flight: ${flights[i].object_id}`);
|
|
432
|
-
}
|
|
288
|
+
let model = await this.updateFlight(id, {...flight, excursion_id: this.history.excursionId});
|
|
289
|
+
flightsHistory[flights[i].object_id] = model.data.id;
|
|
433
290
|
}
|
|
434
|
-
} catch(error) {
|
|
435
|
-
this.log('error', `Failed to process flight ${flights[i].object_id}`, error.message);
|
|
436
|
-
this.saveErrorToHistory('flights', flights[i].object_id, error.message);
|
|
437
|
-
// Continue with next flight instead of failing entirely
|
|
438
291
|
}
|
|
439
292
|
}
|
|
440
293
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
const nonExisting = this.difference(currentFlightIds, newFlightIds);
|
|
445
|
-
|
|
446
|
-
if(nonExisting.length > 0) {
|
|
447
|
-
this.log('info', `Deleting ${nonExisting.length} removed flights`);
|
|
448
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
449
|
-
try {
|
|
450
|
-
await this.retryOperation(() => this.deleteFlight(nonExisting[i]));
|
|
451
|
-
// Remove from history after successful deletion
|
|
452
|
-
for(const [key, value] of Object.entries(this.history.flights || {})) {
|
|
453
|
-
if(value === nonExisting[i]) {
|
|
454
|
-
delete this.history.flights[key];
|
|
455
|
-
this.saveHistoryIncremental();
|
|
456
|
-
this.log('debug', `✓ Deleted flight: ${key}`);
|
|
457
|
-
break;
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
} catch(error) {
|
|
461
|
-
this.log('error', `Failed to delete flight ${nonExisting[i]}`, error.message);
|
|
462
|
-
this.saveErrorToHistory('flights', `delete-${nonExisting[i]}`, error.message);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
294
|
+
let nonExisting = this.difference(Object.values(this.history.flights), Object.values(flightsHistory));
|
|
295
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
296
|
+
await this.deleteFlight(nonExisting[i]);
|
|
465
297
|
}
|
|
298
|
+
|
|
299
|
+
this.history.flights = flightsHistory;
|
|
466
300
|
}
|
|
467
301
|
|
|
468
302
|
async flightImages()
|
|
@@ -484,616 +318,258 @@ class Appit {
|
|
|
484
318
|
|
|
485
319
|
async organizations()
|
|
486
320
|
{
|
|
487
|
-
const organizations = this.transformer.organizations();
|
|
488
|
-
if(!organizations || !organizations.length) {
|
|
489
|
-
this.log('info', 'No organizations to process');
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
this.log('info', `Processing ${organizations.length} organizations`);
|
|
494
321
|
let organizationsHistory = {};
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
const orgData = {...organizations[i], excursion_id: this.history.excursionId};
|
|
322
|
+
const organizations = this.transformer.organizations();
|
|
323
|
+
if(organizations) {
|
|
324
|
+
for(let i = 0; i < organizations.length; i++) {
|
|
325
|
+
organizations[i].excursion_id = this.history.excursionId;
|
|
501
326
|
let id = this.findId('organizations', organizations[i].object_id);
|
|
502
|
-
|
|
503
327
|
if(!id) {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
this.history.organizations[organizations[i].object_id] = model.data.id;
|
|
508
|
-
this.saveHistoryIncremental();
|
|
509
|
-
this.log('debug', `✓ Created organization: ${organizations[i].object_id}`);
|
|
510
|
-
}
|
|
328
|
+
let model = await this.createOrganization(organizations[i]);
|
|
329
|
+
console.log('organization', model);
|
|
330
|
+
organizationsHistory[organizations[i].object_id] = model.data.id;
|
|
511
331
|
} else {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
organizationsHistory[organizations[i].object_id] = model.data.id;
|
|
515
|
-
this.history.organizations[organizations[i].object_id] = model.data.id;
|
|
516
|
-
this.saveHistoryIncremental();
|
|
517
|
-
this.log('debug', `✓ Updated organization: ${organizations[i].object_id}`);
|
|
518
|
-
}
|
|
332
|
+
let model = await this.updateOrganization(id, organizations[i]);
|
|
333
|
+
organizationsHistory[organizations[i].object_id] = model.data.id;
|
|
519
334
|
}
|
|
520
|
-
} catch(error) {
|
|
521
|
-
this.log('error', `Failed to process organization ${organizations[i].object_id}`, error.message);
|
|
522
|
-
this.saveErrorToHistory('organizations', organizations[i].object_id, error.message);
|
|
523
|
-
// Continue with next organization instead of failing entirely
|
|
524
335
|
}
|
|
525
336
|
}
|
|
526
337
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
const nonExisting = this.difference(currentOrgIds, newOrgIds);
|
|
531
|
-
|
|
532
|
-
if(nonExisting.length > 0) {
|
|
533
|
-
this.log('info', `Deleting ${nonExisting.length} removed organizations`);
|
|
534
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
535
|
-
try {
|
|
536
|
-
await this.retryOperation(() => this.deleteOrganization(nonExisting[i]));
|
|
537
|
-
// Remove from history after successful deletion
|
|
538
|
-
for(const [key, value] of Object.entries(this.history.organizations || {})) {
|
|
539
|
-
if(value === nonExisting[i]) {
|
|
540
|
-
delete this.history.organizations[key];
|
|
541
|
-
this.saveHistoryIncremental();
|
|
542
|
-
this.log('debug', `✓ Deleted organization: ${key}`);
|
|
543
|
-
break;
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
} catch(error) {
|
|
547
|
-
this.log('error', `Failed to delete organization ${nonExisting[i]}`, error.message);
|
|
548
|
-
this.saveErrorToHistory('organizations', `delete-${nonExisting[i]}`, error.message);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
338
|
+
let nonExisting = this.difference(Object.values(this.history.organizations), Object.values(organizationsHistory));
|
|
339
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
340
|
+
await this.deleteOrganization(nonExisting[i]);
|
|
551
341
|
}
|
|
342
|
+
|
|
343
|
+
this.history.organizations = organizationsHistory;
|
|
552
344
|
}
|
|
553
345
|
|
|
554
346
|
async notifications()
|
|
555
347
|
{
|
|
556
348
|
const notifications = this.transformer.notifications();
|
|
557
|
-
if(
|
|
558
|
-
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
this.log('info', `Processing ${notifications.length} notifications`);
|
|
563
|
-
|
|
564
|
-
for(let i = 0; i < notifications.length; i++) {
|
|
565
|
-
try {
|
|
566
|
-
this.log('debug', `Processing notification ${i + 1}/${notifications.length}: ${notifications[i].object_id}`);
|
|
567
|
-
|
|
349
|
+
if(notifications) {
|
|
350
|
+
for(let i = 0; i < notifications.length; i++) {
|
|
568
351
|
let notification = this.clean(JSON.parse(JSON.stringify(notifications[i])));
|
|
569
|
-
|
|
352
|
+
notification.excursion_id = this.history.excursionId;
|
|
353
|
+
|
|
570
354
|
let id = this.findId('notifications', notifications[i].object_id);
|
|
571
|
-
|
|
572
355
|
if(!id) {
|
|
573
|
-
|
|
574
|
-
if(
|
|
575
|
-
|
|
576
|
-
this.history.notifications[notifications[i].object_id] = model.data.id;
|
|
577
|
-
this.saveHistoryIncremental();
|
|
578
|
-
this.log('debug', `✓ Created notification: ${notifications[i].object_id}`);
|
|
579
|
-
}
|
|
356
|
+
let model = await this.createNotification(notification);
|
|
357
|
+
if(!this.history.hasOwnProperty('notifications')) this.history.notifications = {};
|
|
358
|
+
this.history.notifications[notifications[i].object_id] = model.data.id;
|
|
580
359
|
} else {
|
|
581
|
-
|
|
582
|
-
if(model && model.data && model.data.id) {
|
|
583
|
-
this.history.notifications[notifications[i].object_id] = model.data.id;
|
|
584
|
-
this.saveHistoryIncremental();
|
|
585
|
-
this.log('debug', `✓ Updated notification: ${notifications[i].object_id}`);
|
|
586
|
-
}
|
|
360
|
+
await this.updateNotification(id, notification);
|
|
587
361
|
}
|
|
588
|
-
} catch(error) {
|
|
589
|
-
this.log('error', `Failed to process notification ${notifications[i].object_id}`, error.message);
|
|
590
|
-
this.saveErrorToHistory('notifications', notifications[i].object_id, error.message);
|
|
591
|
-
// Continue with next notification instead of failing entirely
|
|
592
362
|
}
|
|
593
363
|
}
|
|
594
364
|
}
|
|
595
365
|
|
|
596
366
|
async members()
|
|
597
367
|
{
|
|
598
|
-
const participants = this.transformer.participants();
|
|
599
|
-
if(!participants || !participants.length) {
|
|
600
|
-
this.log('info', 'No members to process');
|
|
601
|
-
return;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
this.log('info', `Processing ${participants.length} members`);
|
|
605
368
|
let memberHistory = {};
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
this.log('debug', `Processing member ${i + 1}/${participants.length}: ${participants[i].id}`);
|
|
610
|
-
|
|
369
|
+
const participants = this.transformer.participants();
|
|
370
|
+
if(participants && participants.length) {
|
|
371
|
+
for(let i = 0; i < participants.length; i++) {
|
|
611
372
|
let participant = this.clean(JSON.parse(JSON.stringify(participants[i])));
|
|
612
|
-
|
|
373
|
+
|
|
613
374
|
let id = this.findId('members', participants[i].id);
|
|
614
|
-
|
|
615
375
|
if(!id) {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
this.history.members[participants[i].id] = model.data.id;
|
|
620
|
-
this.saveHistoryIncremental();
|
|
621
|
-
this.log('debug', `✓ Created member: ${participants[i].id}`);
|
|
622
|
-
}
|
|
376
|
+
let model = await this.createMember({...participant, excursion_id: this.history.excursionId});
|
|
377
|
+
console.log('member', model);
|
|
378
|
+
memberHistory[participants[i].id] = model.data.id;
|
|
623
379
|
} else {
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
memberHistory[participants[i].id] = model.data.id;
|
|
627
|
-
this.history.members[participants[i].id] = model.data.id;
|
|
628
|
-
this.saveHistoryIncremental();
|
|
629
|
-
this.log('debug', `✓ Updated member: ${participants[i].id}`);
|
|
630
|
-
}
|
|
380
|
+
let model = await this.updateMember(id, {...participant, excursion_id: this.history.excursionId});
|
|
381
|
+
memberHistory[participants[i].id] = model.data.id;
|
|
631
382
|
}
|
|
632
|
-
} catch(error) {
|
|
633
|
-
this.log('error', `Failed to process member ${participants[i].id}`, error.message);
|
|
634
|
-
this.saveErrorToHistory('members', participants[i].id, error.message);
|
|
635
|
-
// Continue with next member instead of failing entirely
|
|
636
383
|
}
|
|
637
384
|
}
|
|
638
385
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
const nonExisting = this.difference(currentMemberIds, newMemberIds);
|
|
643
|
-
|
|
644
|
-
if(nonExisting.length > 0) {
|
|
645
|
-
this.log('info', `Deleting ${nonExisting.length} removed members`);
|
|
646
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
647
|
-
try {
|
|
648
|
-
await this.retryOperation(() => this.deleteMember(nonExisting[i]));
|
|
649
|
-
// Remove from history after successful deletion
|
|
650
|
-
for(const [key, value] of Object.entries(this.history.members || {})) {
|
|
651
|
-
if(value === nonExisting[i]) {
|
|
652
|
-
delete this.history.members[key];
|
|
653
|
-
this.saveHistoryIncremental();
|
|
654
|
-
this.log('debug', `✓ Deleted member: ${key}`);
|
|
655
|
-
break;
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
} catch(error) {
|
|
659
|
-
this.log('error', `Failed to delete member ${nonExisting[i]}`, error.message);
|
|
660
|
-
this.saveErrorToHistory('members', `delete-${nonExisting[i]}`, error.message);
|
|
661
|
-
}
|
|
662
|
-
}
|
|
386
|
+
let nonExisting = this.difference(Object.values(this.history.members), Object.values(memberHistory));
|
|
387
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
388
|
+
await this.deleteMember(nonExisting[i]);
|
|
663
389
|
}
|
|
390
|
+
|
|
391
|
+
this.history.members = memberHistory;
|
|
664
392
|
}
|
|
665
393
|
|
|
666
394
|
async travelInfo()
|
|
667
395
|
{
|
|
668
|
-
const travelInfo = this.transformer.travelInfo();
|
|
669
|
-
if(!travelInfo || !travelInfo.length) {
|
|
670
|
-
this.log('info', 'No travel info to process');
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
this.log('info', `Processing ${travelInfo.length} travel info items`);
|
|
675
396
|
let travelInfoHistory = {};
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
this.log('debug', `Processing travel info ${i + 1}/${travelInfo.length}: ${travelInfo[i].object_id}`);
|
|
680
|
-
|
|
397
|
+
const travelInfo = this.transformer.travelInfo();
|
|
398
|
+
if(travelInfo && travelInfo.length) {
|
|
399
|
+
for(let i = 0; i < travelInfo.length; i++) {
|
|
681
400
|
let info = this.clean(JSON.parse(JSON.stringify(travelInfo[i])));
|
|
401
|
+
|
|
402
|
+
let id = this.findId('travels', travelInfo[i].object_id);
|
|
682
403
|
|
|
683
404
|
if(info.category_id && typeof info.category_id === 'string') {
|
|
684
405
|
info.category_id = await this.findOrCreateCategory(info.category_id);
|
|
685
406
|
}
|
|
686
407
|
|
|
687
|
-
const travelData = {...info, excursion_id: this.history.excursionId};
|
|
688
|
-
let id = this.findId('travels', travelInfo[i].object_id);
|
|
689
|
-
|
|
690
408
|
if(!id) {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
this.history.travels[travelInfo[i].object_id] = model.data.id;
|
|
695
|
-
this.saveHistoryIncremental();
|
|
696
|
-
this.log('debug', `✓ Created travel info: ${travelInfo[i].object_id}`);
|
|
697
|
-
}
|
|
409
|
+
let model = await this.createTravel({...info, excursion_id: this.history.excursionId});
|
|
410
|
+
console.log('travelInfo', model);
|
|
411
|
+
travelInfoHistory[travelInfo[i].object_id] = model.data.id;
|
|
698
412
|
} else {
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
travelInfoHistory[travelInfo[i].object_id] = model.data.id;
|
|
702
|
-
this.history.travels[travelInfo[i].object_id] = model.data.id;
|
|
703
|
-
this.saveHistoryIncremental();
|
|
704
|
-
this.log('debug', `✓ Updated travel info: ${travelInfo[i].object_id}`);
|
|
705
|
-
}
|
|
413
|
+
let model = await this.updateTravel(id, {...info, excursion_id: this.history.excursionId});
|
|
414
|
+
travelInfoHistory[travelInfo[i].object_id] = model.data.id;
|
|
706
415
|
}
|
|
707
|
-
} catch(error) {
|
|
708
|
-
this.log('error', `Failed to process travel info ${travelInfo[i].object_id}`, error.message);
|
|
709
|
-
this.saveErrorToHistory('travelInfo', travelInfo[i].object_id, error.message);
|
|
710
|
-
// Continue with next travel info instead of failing entirely
|
|
711
416
|
}
|
|
712
417
|
}
|
|
713
418
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
const nonExisting = this.difference(currentTravelIds, newTravelIds);
|
|
718
|
-
|
|
719
|
-
if(nonExisting.length > 0) {
|
|
720
|
-
this.log('info', `Deleting ${nonExisting.length} removed travel info items`);
|
|
721
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
722
|
-
try {
|
|
723
|
-
await this.retryOperation(() => this.deleteTravel(nonExisting[i]));
|
|
724
|
-
// Remove from history after successful deletion
|
|
725
|
-
for(const [key, value] of Object.entries(this.history.travels || {})) {
|
|
726
|
-
if(value === nonExisting[i]) {
|
|
727
|
-
delete this.history.travels[key];
|
|
728
|
-
this.saveHistoryIncremental();
|
|
729
|
-
this.log('debug', `✓ Deleted travel info: ${key}`);
|
|
730
|
-
break;
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
} catch(error) {
|
|
734
|
-
this.log('error', `Failed to delete travel info ${nonExisting[i]}`, error.message);
|
|
735
|
-
this.saveErrorToHistory('travelInfo', `delete-${nonExisting[i]}`, error.message);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
419
|
+
let nonExisting = this.difference(Object.values(this.history.travels), Object.values(travelInfoHistory));
|
|
420
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
421
|
+
await this.deleteTravel(nonExisting[i]);
|
|
738
422
|
}
|
|
423
|
+
|
|
424
|
+
this.history.travels = travelInfoHistory;
|
|
739
425
|
}
|
|
740
426
|
|
|
741
427
|
async documents()
|
|
742
428
|
{
|
|
743
429
|
const documents = this.transformer.documents();
|
|
744
|
-
if(!documents || !documents.length) {
|
|
745
|
-
this.log('info', 'No documents to process');
|
|
746
|
-
return;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
this.log('info', `Processing ${documents.length} documents`);
|
|
750
430
|
let documentHistory = {};
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
this.log('debug', `Processing document ${i + 1}/${documents.length}: ${documents[i].object_id}`);
|
|
755
|
-
|
|
756
|
-
const documentData = {...documents[i], excursion_id: this.history.excursionId};
|
|
431
|
+
if(documents) {
|
|
432
|
+
for(let i = 0; i < documents.length; i++) {
|
|
433
|
+
documents[i].excursion_id = this.history.excursionId;
|
|
757
434
|
let id = this.findId('documents', documents[i].object_id);
|
|
758
|
-
|
|
759
435
|
if(!id) {
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
this.saveHistoryIncremental();
|
|
765
|
-
this.log('debug', `✓ Created document: ${documents[i].object_id}`);
|
|
766
|
-
}
|
|
436
|
+
let model = await this.createDocument(documents[i]);
|
|
437
|
+
console.log('documents', model);
|
|
438
|
+
if(typeof model === 'object' && model.data && model.data.id)
|
|
439
|
+
documentHistory[documents[i].object_id] = model.data.id;
|
|
767
440
|
} else {
|
|
768
441
|
documentHistory[documents[i].object_id] = id;
|
|
769
|
-
this.history.documents[documents[i].object_id] = id;
|
|
770
|
-
this.saveHistoryIncremental();
|
|
771
|
-
this.log('debug', `✓ Document already exists: ${documents[i].object_id}`);
|
|
772
442
|
}
|
|
773
|
-
} catch(error) {
|
|
774
|
-
this.log('error', `Failed to process document ${documents[i].object_id}`, error.message);
|
|
775
|
-
this.saveErrorToHistory('documents', documents[i].object_id, error.message);
|
|
776
|
-
// Continue with next document instead of failing entirely
|
|
777
443
|
}
|
|
778
444
|
}
|
|
779
445
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
const nonExisting = this.difference(currentDocumentIds, newDocumentIds);
|
|
784
|
-
|
|
785
|
-
if(nonExisting.length > 0) {
|
|
786
|
-
this.log('info', `Deleting ${nonExisting.length} removed documents`);
|
|
787
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
788
|
-
try {
|
|
789
|
-
await this.retryOperation(() => this.deleteDocuments(nonExisting[i]));
|
|
790
|
-
// Remove from history after successful deletion
|
|
791
|
-
for(const [key, value] of Object.entries(this.history.documents || {})) {
|
|
792
|
-
if(value === nonExisting[i]) {
|
|
793
|
-
delete this.history.documents[key];
|
|
794
|
-
this.saveHistoryIncremental();
|
|
795
|
-
this.log('debug', `✓ Deleted document: ${key}`);
|
|
796
|
-
break;
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
} catch(error) {
|
|
800
|
-
this.log('error', `Failed to delete document ${nonExisting[i]}`, error.message);
|
|
801
|
-
this.saveErrorToHistory('documents', `delete-${nonExisting[i]}`, error.message);
|
|
802
|
-
}
|
|
803
|
-
}
|
|
446
|
+
let nonExisting = this.difference(Object.values(this.history.documents), Object.values(documentHistory));
|
|
447
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
448
|
+
await this.deleteDocuments(nonExisting[i]);
|
|
804
449
|
}
|
|
450
|
+
|
|
451
|
+
this.history.documents = documentHistory;
|
|
805
452
|
}
|
|
806
453
|
|
|
807
454
|
async accommodations()
|
|
808
455
|
{
|
|
809
|
-
const accommodations = this.transformer.accommodations();
|
|
810
|
-
if(!accommodations || !accommodations.length) {
|
|
811
|
-
this.log('info', 'No accommodations to process');
|
|
812
|
-
return;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
this.log('info', `Processing ${accommodations.length} accommodations`);
|
|
816
456
|
let accommodationHistory = {};
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
this.log('debug', `Processing accommodation ${i + 1}/${accommodations.length}: ${accommodations[i].object_id}`);
|
|
821
|
-
|
|
457
|
+
const accommodations = this.transformer.accommodations();
|
|
458
|
+
if(accommodations && accommodations.length) {
|
|
459
|
+
for(let i = 0; i < accommodations.length; i++) {
|
|
822
460
|
let accommodation = this.clean(JSON.parse(JSON.stringify(accommodations[i])));
|
|
823
461
|
let labels = this.getLabels(accommodations[i]);
|
|
824
462
|
|
|
825
|
-
const images = (accommodation.images
|
|
463
|
+
const images = (accommodation.images.length) ? await this.getImages(accommodation.images, 'original/lg') : {};
|
|
826
464
|
delete accommodation.images;
|
|
827
465
|
|
|
828
|
-
const accommodationData = {...accommodation, ...images, labels: labels, excursion_id: this.history.excursionId};
|
|
829
466
|
let id = this.findId('accommodations', accommodations[i].object_id);
|
|
830
|
-
|
|
831
467
|
if(!id) {
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
this.history.accommodations[accommodations[i].object_id] = model.data.id;
|
|
836
|
-
this.saveHistoryIncremental();
|
|
837
|
-
this.log('debug', `✓ Created accommodation: ${accommodations[i].object_id}`);
|
|
838
|
-
}
|
|
468
|
+
let model = await this.createAccommodation({...accommodation, ...images, labels: labels, excursion_id: this.history.excursionId});
|
|
469
|
+
console.log('accommodations', model);
|
|
470
|
+
accommodationHistory[accommodations[i].object_id] = model.data.id;
|
|
839
471
|
} else {
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
accommodationHistory[accommodations[i].object_id] = model.data.id;
|
|
843
|
-
this.history.accommodations[accommodations[i].object_id] = model.data.id;
|
|
844
|
-
this.saveHistoryIncremental();
|
|
845
|
-
this.log('debug', `✓ Updated accommodation: ${accommodations[i].object_id}`);
|
|
846
|
-
}
|
|
472
|
+
let model = await this.updateAccommodation(id, {...accommodation, ...images, labels: labels, excursion_id: this.history.excursionId});
|
|
473
|
+
accommodationHistory[accommodations[i].object_id] = model.data.id;
|
|
847
474
|
}
|
|
848
|
-
} catch(error) {
|
|
849
|
-
this.log('error', `Failed to process accommodation ${accommodations[i].object_id}`, error.message);
|
|
850
|
-
this.saveErrorToHistory('accommodations', accommodations[i].object_id, error.message);
|
|
851
|
-
// Continue with next accommodation instead of failing entirely
|
|
852
475
|
}
|
|
853
476
|
}
|
|
854
477
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
const nonExisting = this.difference(currentAccommodationIds, newAccommodationIds);
|
|
859
|
-
|
|
860
|
-
if(nonExisting.length > 0) {
|
|
861
|
-
this.log('info', `Deleting ${nonExisting.length} removed accommodations`);
|
|
862
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
863
|
-
try {
|
|
864
|
-
await this.retryOperation(() => this.deleteAccommodation(nonExisting[i]));
|
|
865
|
-
// Remove from history after successful deletion
|
|
866
|
-
for(const [key, value] of Object.entries(this.history.accommodations || {})) {
|
|
867
|
-
if(value === nonExisting[i]) {
|
|
868
|
-
delete this.history.accommodations[key];
|
|
869
|
-
this.saveHistoryIncremental();
|
|
870
|
-
this.log('debug', `✓ Deleted accommodation: ${key}`);
|
|
871
|
-
break;
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
} catch(error) {
|
|
875
|
-
this.log('error', `Failed to delete accommodation ${nonExisting[i]}`, error.message);
|
|
876
|
-
this.saveErrorToHistory('accommodations', `delete-${nonExisting[i]}`, error.message);
|
|
877
|
-
}
|
|
878
|
-
}
|
|
478
|
+
let nonExisting = this.difference(Object.values(this.history.accommodations), Object.values(accommodationHistory));
|
|
479
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
480
|
+
await this.deleteAccommodation(nonExisting[i]);
|
|
879
481
|
}
|
|
482
|
+
|
|
483
|
+
this.history.accommodations = accommodationHistory;
|
|
880
484
|
}
|
|
881
485
|
|
|
882
486
|
async destinations()
|
|
883
487
|
{
|
|
884
|
-
const destinations = await this.transformer.destinations();
|
|
885
|
-
if(!destinations || !destinations.length) {
|
|
886
|
-
this.log('info', 'No destinations to process');
|
|
887
|
-
return;
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
this.log('info', `Processing ${destinations.length} destinations`);
|
|
891
488
|
let destinationHistory = {};
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
this.log('debug', `Processing destination ${i + 1}/${destinations.length}: ${destinations[i].object_id}`);
|
|
896
|
-
|
|
489
|
+
const destinations = await this.transformer.destinations();
|
|
490
|
+
if(destinations && destinations.length) {
|
|
491
|
+
for(let i = 0; i < destinations.length; i++) {
|
|
897
492
|
let destination = this.clean(JSON.parse(JSON.stringify(destinations[i])));
|
|
898
493
|
let labels = this.getLabels(destinations[i]);
|
|
899
494
|
|
|
900
495
|
const images = (destination.images && destination.images.length) ? await this.getImages(destination.images, 'original/lg') : {};
|
|
901
496
|
delete destination.images;
|
|
902
497
|
|
|
903
|
-
const destinationData = {...destination, ...images, labels: labels, excursion_id: this.history.excursionId};
|
|
904
498
|
let id = this.findId('destinations', destinations[i].object_id);
|
|
905
|
-
|
|
906
499
|
if(!id) {
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
this.history.destinations[destinations[i].object_id] = model.data.id;
|
|
911
|
-
this.saveHistoryIncremental();
|
|
912
|
-
this.log('debug', `✓ Created destination: ${destinations[i].object_id}`);
|
|
913
|
-
}
|
|
500
|
+
let model = await this.createDestination({...destination, ...images, labels: labels, excursion_id: this.history.excursionId});
|
|
501
|
+
console.log('destination', model);
|
|
502
|
+
destinationHistory[destinations[i].object_id] = model.data.id;
|
|
914
503
|
} else {
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
destinationHistory[destinations[i].object_id] = model.data.id;
|
|
918
|
-
this.history.destinations[destinations[i].object_id] = model.data.id;
|
|
919
|
-
this.saveHistoryIncremental();
|
|
920
|
-
this.log('debug', `✓ Updated destination: ${destinations[i].object_id}`);
|
|
921
|
-
}
|
|
504
|
+
let model = await this.updateDestination(id, {...destination, ...images, labels: labels, excursion_id: this.history.excursionId});
|
|
505
|
+
destinationHistory[destinations[i].object_id] = model.data.id;
|
|
922
506
|
}
|
|
923
|
-
} catch(error) {
|
|
924
|
-
this.log('error', `Failed to process destination ${destinations[i].object_id}`, error.message);
|
|
925
|
-
this.saveErrorToHistory('destinations', destinations[i].object_id, error.message);
|
|
926
|
-
// Continue with next destination instead of failing entirely
|
|
927
507
|
}
|
|
928
508
|
}
|
|
929
509
|
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
const nonExisting = this.difference(currentDestinationIds, newDestinationIds);
|
|
934
|
-
|
|
935
|
-
if(nonExisting.length > 0) {
|
|
936
|
-
this.log('info', `Deleting ${nonExisting.length} removed destinations`);
|
|
937
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
938
|
-
try {
|
|
939
|
-
await this.retryOperation(() => this.deleteDestination(nonExisting[i]));
|
|
940
|
-
// Remove from history after successful deletion
|
|
941
|
-
for(const [key, value] of Object.entries(this.history.destinations || {})) {
|
|
942
|
-
if(value === nonExisting[i]) {
|
|
943
|
-
delete this.history.destinations[key];
|
|
944
|
-
this.saveHistoryIncremental();
|
|
945
|
-
this.log('debug', `✓ Deleted destination: ${key}`);
|
|
946
|
-
break;
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
} catch(error) {
|
|
950
|
-
this.log('error', `Failed to delete destination ${nonExisting[i]}`, error.message);
|
|
951
|
-
this.saveErrorToHistory('destinations', `delete-${nonExisting[i]}`, error.message);
|
|
952
|
-
}
|
|
953
|
-
}
|
|
510
|
+
let nonExisting = this.difference(Object.values(this.history.destinations), Object.values(destinationHistory));
|
|
511
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
512
|
+
await this.deleteDestination(nonExisting[i]);
|
|
954
513
|
}
|
|
514
|
+
|
|
515
|
+
this.history.destinations = destinationHistory;
|
|
955
516
|
}
|
|
956
517
|
|
|
957
518
|
async schemes()
|
|
958
519
|
{
|
|
959
|
-
const schemes = this.transformer.schemes(this.history);
|
|
960
|
-
if(!schemes || !schemes.length) {
|
|
961
|
-
this.log('info', 'No schemes to process');
|
|
962
|
-
return;
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
this.log('info', `Processing ${schemes.length} schemes`);
|
|
966
520
|
const schemeHistory = {};
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
this.log('debug', `Processing scheme ${i + 1}/${schemes.length}: ${schemes[i].object_id}`);
|
|
971
|
-
|
|
521
|
+
const schemes = this.transformer.schemes(this.history);
|
|
522
|
+
if(schemes && schemes.length) {
|
|
523
|
+
for(let i = 0; i < schemes.length; i++) {
|
|
972
524
|
let scheme = this.clean(JSON.parse(JSON.stringify(schemes[i])));
|
|
973
525
|
let labels = this.getLabels(schemes[i]);
|
|
974
526
|
|
|
975
|
-
const schemeData = {...scheme, labels: labels, excursion_id: this.history.excursionId};
|
|
976
527
|
let id = this.findId('schemes', schemes[i].object_id);
|
|
977
|
-
|
|
978
528
|
if(!id) {
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
this.history.schemes[schemes[i].object_id] = model.data.id;
|
|
983
|
-
this.saveHistoryIncremental();
|
|
984
|
-
this.log('debug', `✓ Created scheme: ${schemes[i].object_id}`);
|
|
985
|
-
}
|
|
529
|
+
let model = await this.createScheme({...scheme, labels: labels, excursion_id: this.history.excursionId});
|
|
530
|
+
console.log('schemes', model);
|
|
531
|
+
schemeHistory[schemes[i].object_id] = model.data.id;
|
|
986
532
|
} else {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
schemeHistory[schemes[i].object_id] = model.data.id;
|
|
990
|
-
this.history.schemes[schemes[i].object_id] = model.data.id;
|
|
991
|
-
this.saveHistoryIncremental();
|
|
992
|
-
this.log('debug', `✓ Updated scheme: ${schemes[i].object_id}`);
|
|
993
|
-
}
|
|
533
|
+
let model = await this.updateScheme(id, {...scheme, labels: labels, excursion_id: this.history.excursionId});
|
|
534
|
+
schemeHistory[schemes[i].object_id] = model.data.id;
|
|
994
535
|
}
|
|
995
|
-
} catch(error) {
|
|
996
|
-
this.log('error', `Failed to process scheme ${schemes[i].object_id}`, error.message);
|
|
997
|
-
this.saveErrorToHistory('schemes', schemes[i].object_id, error.message);
|
|
998
|
-
// Continue with next scheme instead of failing entirely
|
|
999
536
|
}
|
|
1000
537
|
}
|
|
1001
538
|
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
const nonExisting = this.difference(currentSchemeIds, newSchemeIds);
|
|
1006
|
-
|
|
1007
|
-
if(nonExisting.length > 0) {
|
|
1008
|
-
this.log('info', `Deleting ${nonExisting.length} removed schemes`);
|
|
1009
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
1010
|
-
try {
|
|
1011
|
-
await this.retryOperation(() => this.deleteScheme(nonExisting[i]));
|
|
1012
|
-
// Remove from history after successful deletion
|
|
1013
|
-
for(const [key, value] of Object.entries(this.history.schemes || {})) {
|
|
1014
|
-
if(value === nonExisting[i]) {
|
|
1015
|
-
delete this.history.schemes[key];
|
|
1016
|
-
this.saveHistoryIncremental();
|
|
1017
|
-
this.log('debug', `✓ Deleted scheme: ${key}`);
|
|
1018
|
-
break;
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
} catch(error) {
|
|
1022
|
-
this.log('error', `Failed to delete scheme ${nonExisting[i]}`, error.message);
|
|
1023
|
-
this.saveErrorToHistory('schemes', `delete-${nonExisting[i]}`, error.message);
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
539
|
+
let nonExisting = this.difference(Object.values(this.history.schemes), Object.values(schemeHistory));
|
|
540
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
541
|
+
await this.deleteScheme(nonExisting[i]);
|
|
1026
542
|
}
|
|
543
|
+
|
|
544
|
+
this.history.schemes = schemeHistory;
|
|
1027
545
|
}
|
|
1028
546
|
|
|
1029
547
|
async contacts()
|
|
1030
548
|
{
|
|
1031
|
-
const contacts = this.transformer.contacts();
|
|
1032
|
-
if(!contacts || !contacts.length) {
|
|
1033
|
-
this.log('info', 'No contacts to process');
|
|
1034
|
-
return;
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
this.log('info', `Processing ${contacts.length} contacts`);
|
|
1038
549
|
let contactHistory = {};
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
this.log('debug', `Processing contact ${i + 1}/${contacts.length}: ${contacts[i].object_id}`);
|
|
1043
|
-
|
|
550
|
+
const contacts = this.transformer.contacts();
|
|
551
|
+
if(contacts && contacts.length) {
|
|
552
|
+
for(let i = 0; i < contacts.length; i++) {
|
|
1044
553
|
let contact = this.clean(JSON.parse(JSON.stringify(contacts[i])));
|
|
1045
|
-
|
|
554
|
+
|
|
1046
555
|
let id = this.findId('contacts', contacts[i].object_id);
|
|
1047
|
-
|
|
1048
556
|
if(!id) {
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
this.history.contacts[contacts[i].object_id] = model.data.id;
|
|
1053
|
-
this.saveHistoryIncremental();
|
|
1054
|
-
this.log('debug', `✓ Created contact: ${contacts[i].object_id}`);
|
|
1055
|
-
}
|
|
557
|
+
let model = await this.createContact({...contact, excursion_id: this.history.excursionId});
|
|
558
|
+
console.log('contacts', model);
|
|
559
|
+
contactHistory[contacts[i].object_id] = model.data.id;
|
|
1056
560
|
} else {
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
contactHistory[contacts[i].object_id] = model.data.id;
|
|
1060
|
-
this.history.contacts[contacts[i].object_id] = model.data.id;
|
|
1061
|
-
this.saveHistoryIncremental();
|
|
1062
|
-
this.log('debug', `✓ Updated contact: ${contacts[i].object_id}`);
|
|
1063
|
-
}
|
|
561
|
+
let model = await this.updateContact(id, {...contact, excursion_id: this.history.excursionId});
|
|
562
|
+
contactHistory[contacts[i].object_id] = model.data.id;
|
|
1064
563
|
}
|
|
1065
|
-
} catch(error) {
|
|
1066
|
-
this.log('error', `Failed to process contact ${contacts[i].object_id}`, error.message);
|
|
1067
|
-
this.saveErrorToHistory('contacts', contacts[i].object_id, error.message);
|
|
1068
|
-
// Continue with next contact instead of failing entirely
|
|
1069
564
|
}
|
|
1070
565
|
}
|
|
1071
566
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
const nonExisting = this.difference(currentContactIds, newContactIds);
|
|
1076
|
-
|
|
1077
|
-
if(nonExisting.length > 0) {
|
|
1078
|
-
this.log('info', `Deleting ${nonExisting.length} removed contacts`);
|
|
1079
|
-
for(let i = 0; i < nonExisting.length; i++) {
|
|
1080
|
-
try {
|
|
1081
|
-
await this.retryOperation(() => this.deleteContact(nonExisting[i]));
|
|
1082
|
-
// Remove from history after successful deletion
|
|
1083
|
-
for(const [key, value] of Object.entries(this.history.contacts || {})) {
|
|
1084
|
-
if(value === nonExisting[i]) {
|
|
1085
|
-
delete this.history.contacts[key];
|
|
1086
|
-
this.saveHistoryIncremental();
|
|
1087
|
-
this.log('debug', `✓ Deleted contact: ${key}`);
|
|
1088
|
-
break;
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
} catch(error) {
|
|
1092
|
-
this.log('error', `Failed to delete contact ${nonExisting[i]}`, error.message);
|
|
1093
|
-
this.saveErrorToHistory('contacts', `delete-${nonExisting[i]}`, error.message);
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
567
|
+
let nonExisting = this.difference(Object.values(this.history.contacts), Object.values(contactHistory));
|
|
568
|
+
for(let i = 0; i < nonExisting.length; i++) {
|
|
569
|
+
await this.deleteContact(nonExisting[i]);
|
|
1096
570
|
}
|
|
571
|
+
|
|
572
|
+
this.history.contacts = contactHistory;
|
|
1097
573
|
}
|
|
1098
574
|
|
|
1099
575
|
getLabels(object)
|
|
@@ -1243,8 +719,6 @@ class Appit {
|
|
|
1243
719
|
options.headers.Authorization = `Bearer ${this.token}`;
|
|
1244
720
|
}
|
|
1245
721
|
|
|
1246
|
-
this.log('debug', `${method} request to ${path}`);
|
|
1247
|
-
|
|
1248
722
|
const req = https.request(options, res => {
|
|
1249
723
|
let result = '';
|
|
1250
724
|
res.on('data', chunk => {
|
|
@@ -1253,26 +727,24 @@ class Appit {
|
|
|
1253
727
|
|
|
1254
728
|
res.on('end', () => {
|
|
1255
729
|
try {
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
this.log('debug', `✓ ${method} ${path} successful`);
|
|
1262
|
-
resolve(parsedResult);
|
|
1263
|
-
}
|
|
1264
|
-
} catch(parseError) {
|
|
1265
|
-
this.log('error', `Failed to parse response from ${method} ${path}`, result);
|
|
1266
|
-
reject(new Error(`Invalid JSON response: ${result}`));
|
|
730
|
+
resolve(JSON.parse(result))
|
|
731
|
+
} catch {
|
|
732
|
+
console.log('ERROR');
|
|
733
|
+
console.log(result);
|
|
734
|
+
reject(false);
|
|
1267
735
|
}
|
|
736
|
+
|
|
1268
737
|
})
|
|
1269
738
|
});
|
|
1270
739
|
|
|
1271
740
|
req.on('error', error => {
|
|
1272
|
-
|
|
1273
|
-
|
|
741
|
+
console.error('***** ERROR *****');
|
|
742
|
+
console.error(error);
|
|
743
|
+
|
|
744
|
+
reject(false);
|
|
1274
745
|
});
|
|
1275
746
|
|
|
747
|
+
|
|
1276
748
|
if(payload) {
|
|
1277
749
|
req.write(payload)
|
|
1278
750
|
}
|
|
@@ -1732,88 +1204,13 @@ class Appit {
|
|
|
1732
1204
|
return await this.request('PUT', `workspaces/${workspace_id}/excursions/${this.history.excursionId}/settings`, data);
|
|
1733
1205
|
}
|
|
1734
1206
|
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
log(level, message, data = null) {
|
|
1740
|
-
const timestamp = new Date().toISOString();
|
|
1741
|
-
const logEntry = {
|
|
1742
|
-
timestamp,
|
|
1743
|
-
level,
|
|
1744
|
-
message,
|
|
1745
|
-
...(data && { data })
|
|
1746
|
-
};
|
|
1747
|
-
|
|
1748
|
-
const logString = `[${timestamp}] ${level.toUpperCase()}: ${message}`;
|
|
1749
|
-
|
|
1750
|
-
switch(level) {
|
|
1751
|
-
case 'error':
|
|
1752
|
-
console.error(logString, data || '');
|
|
1753
|
-
break;
|
|
1754
|
-
case 'warn':
|
|
1755
|
-
console.warn(logString, data || '');
|
|
1756
|
-
break;
|
|
1757
|
-
case 'info':
|
|
1758
|
-
console.log(logString, data || '');
|
|
1759
|
-
break;
|
|
1760
|
-
case 'debug':
|
|
1761
|
-
if(this.options && this.options.debug) {
|
|
1762
|
-
console.log(logString, data || '');
|
|
1763
|
-
}
|
|
1764
|
-
break;
|
|
1765
|
-
}
|
|
1766
|
-
}
|
|
1767
|
-
|
|
1768
|
-
saveHistoryIncremental() {
|
|
1769
|
-
try {
|
|
1770
|
-
this.history.lastSaved = new Date().getTime();
|
|
1771
|
-
fs.writeFileSync(this.historyPath, JSON.stringify(this.history, null, 2));
|
|
1772
|
-
this.log('debug', 'History saved incrementally');
|
|
1773
|
-
} catch(error) {
|
|
1774
|
-
this.log('error', 'Failed to save history incrementally', error);
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
|
|
1778
|
-
saveErrorToHistory(step, objectId, errorMessage) {
|
|
1779
|
-
if (!this.history.errors) {
|
|
1780
|
-
this.history.errors = [];
|
|
1781
|
-
}
|
|
1782
|
-
|
|
1783
|
-
const errorEntry = {
|
|
1784
|
-
step: step,
|
|
1785
|
-
objectId: objectId,
|
|
1786
|
-
error: errorMessage,
|
|
1787
|
-
timestamp: new Date().toISOString()
|
|
1788
|
-
};
|
|
1789
|
-
|
|
1790
|
-
this.history.errors.push(errorEntry);
|
|
1791
|
-
this.saveHistoryIncremental();
|
|
1792
|
-
this.log('debug', `Error saved to history: ${step} - ${objectId}`);
|
|
1207
|
+
async saveExplores(workspace_id, data)
|
|
1208
|
+
{
|
|
1209
|
+
return await this.request('POST', `workspaces/${workspace_id}/excursions/${this.history.excursionId}/explores`, data);
|
|
1793
1210
|
}
|
|
1794
1211
|
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
try {
|
|
1798
|
-
const result = await operation();
|
|
1799
|
-
if(attempt > 1) {
|
|
1800
|
-
this.log('info', `Operation succeeded on attempt ${attempt}`);
|
|
1801
|
-
}
|
|
1802
|
-
return result;
|
|
1803
|
-
} catch(error) {
|
|
1804
|
-
this.log('warn', `Operation failed on attempt ${attempt}/${maxRetries}`, error.message);
|
|
1805
|
-
|
|
1806
|
-
if(attempt === maxRetries) {
|
|
1807
|
-
this.log('error', `Operation failed after ${maxRetries} attempts`, error);
|
|
1808
|
-
throw error;
|
|
1809
|
-
}
|
|
1810
|
-
|
|
1811
|
-
// Exponential backoff: 1s, 2s, 4s
|
|
1812
|
-
const delay = baseDelay * Math.pow(2, attempt - 1) + Math.random() * 1000;
|
|
1813
|
-
this.log('debug', `Retrying in ${Math.round(delay)}ms`);
|
|
1814
|
-
await this.sleep(delay);
|
|
1815
|
-
}
|
|
1816
|
-
}
|
|
1212
|
+
sleep(delay) {
|
|
1213
|
+
return new Promise((resolve) => setTimeout(resolve, delay))
|
|
1817
1214
|
}
|
|
1818
1215
|
}
|
|
1819
1216
|
|