@bytebrand/export-cars 1.8.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/app.module.js +7 -5
- package/dist/app.module.js.map +1 -1
- package/dist/configs/alleskralle.config.js +3 -1
- package/dist/configs/alleskralle.config.js.map +1 -1
- package/dist/configs/as24.config.js.map +1 -1
- package/dist/configs/autoboerse.config.js +1 -1
- package/dist/configs/autouncle.config.js +1 -1
- package/dist/configs/config.d.ts +3 -1
- package/dist/configs/config.js +6 -4
- package/dist/configs/config.js.map +1 -1
- package/dist/configs/criteo.config.js +2 -1
- package/dist/configs/criteo.config.js.map +1 -1
- package/dist/configs/dasparking.config.js +1 -1
- package/dist/configs/kleinanzeigefocus.config.js +2 -2
- package/dist/configs/kleinanzeigefocus.config.js.map +1 -1
- package/dist/configs/meinstadt.config.js +0 -1
- package/dist/configs/meinstadt.config.js.map +1 -1
- package/dist/configs/ooyyo.config.js +1 -0
- package/dist/configs/ooyyo.config.js.map +1 -1
- package/dist/constants/modix/index.d.ts +1 -0
- package/dist/constants/modix/index.js +1 -0
- package/dist/constants/modix/index.js.map +1 -1
- package/dist/enums/file-types.enum.js +0 -1
- package/dist/enums/file-types.enum.js.map +1 -1
- package/dist/enums/image-type.enum.d.ts +4 -0
- package/dist/enums/image-type.enum.js +9 -0
- package/dist/enums/image-type.enum.js.map +1 -0
- package/dist/enums/index.d.ts +1 -0
- package/dist/enums/index.js +1 -0
- package/dist/enums/index.js.map +1 -1
- package/dist/exporters/auto24.exporter.js +1 -1
- package/dist/exporters/auto24.exporter.js.map +1 -1
- package/dist/exporters/fb.exporter.js +1 -3
- package/dist/exporters/fb.exporter.js.map +1 -1
- package/dist/exporters/ooyyo.exporter.js +1 -1
- package/dist/exporters/ooyyo.exporter.js.map +1 -1
- package/dist/interfaces/params.interface.d.ts +1 -6
- package/dist/services/{marketing-images.service.d.ts → images.service.d.ts} +9 -5
- package/dist/services/images.service.js +151 -0
- package/dist/services/images.service.js.map +1 -0
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/index.js.map +1 -1
- package/dist/transformers/auto24.transfomer.d.ts +4 -6
- package/dist/transformers/auto24.transfomer.js +10 -27
- package/dist/transformers/auto24.transfomer.js.map +1 -1
- package/dist/transformers/autouncle.transformer.d.ts +5 -5
- package/dist/transformers/autouncle.transformer.js +9 -33
- package/dist/transformers/autouncle.transformer.js.map +1 -1
- package/dist/transformers/fb.transformer.d.ts +2 -3
- package/dist/transformers/fb.transformer.js +8 -26
- package/dist/transformers/fb.transformer.js.map +1 -1
- package/dist/transformers/google.transformer.d.ts +5 -5
- package/dist/transformers/google.transformer.js +10 -26
- package/dist/transformers/google.transformer.js.map +1 -1
- package/dist/transformers/modix.transformer.js +1 -2
- package/dist/transformers/modix.transformer.js.map +1 -1
- package/dist/transformers/ooyyo.transformer.d.ts +4 -5
- package/dist/transformers/ooyyo.transformer.js +7 -17
- package/dist/transformers/ooyyo.transformer.js.map +1 -1
- package/dist/transformers/rubrikk.transformer.d.ts +4 -4
- package/dist/transformers/rubrikk.transformer.js +5 -13
- package/dist/transformers/rubrikk.transformer.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/app.module.ts +6 -12
- package/src/configs/alleskralle.config.ts +3 -1
- package/src/configs/as24.config.ts +1 -1
- package/src/configs/auto24.config.ts +1 -1
- package/src/configs/autoboerse.config.ts +2 -2
- package/src/configs/autouncle.config.ts +1 -1
- package/src/configs/config.ts +3 -2
- package/src/configs/criteo.config.ts +3 -2
- package/src/configs/dasparking.config.ts +1 -1
- package/src/configs/{kleinanzeigefocus.config.ts → kleinanzeigeFocus.config.ts} +3 -3
- package/src/configs/meinstadt.config.ts +1 -1
- package/src/configs/ooyyo.config.ts +2 -1
- package/src/constants/modix/index.ts +1 -0
- package/src/enums/file-types.enum.ts +1 -1
- package/src/enums/image-type.enum.ts +4 -0
- package/src/enums/index.ts +1 -0
- package/src/exporters/auto24.exporter.ts +2 -4
- package/src/exporters/fb.exporter.ts +3 -3
- package/src/exporters/ooyyo.exporter.ts +3 -4
- package/src/interfaces/params.interface.ts +1 -6
- package/src/services/images.service.ts +161 -0
- package/src/services/index.ts +1 -2
- package/src/transformers/auto24.transfomer.ts +8 -31
- package/src/transformers/autouncle.transformer.ts +9 -35
- package/src/transformers/fb.transformer.ts +16 -44
- package/src/transformers/google.transformer.ts +10 -28
- package/src/transformers/modix.transformer.ts +3 -2
- package/src/transformers/ooyyo.transformer.ts +4 -18
- package/src/transformers/rubrikk.transformer.ts +5 -16
- package/dist/services/marketing-images.service.js +0 -58
- package/dist/services/marketing-images.service.js.map +0 -1
- package/src/services/marketing-images.service.ts +0 -70
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bytebrand/export-cars",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "bytebrand",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"engines": {
|
|
67
67
|
"node": ">=14.0.0"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "16478e91b8dadf07e870437edeef4a0e82ca6627"
|
|
70
70
|
}
|
package/src/app.module.ts
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import { CacheModule, Module } from '@nestjs/common';
|
|
2
1
|
import Bottleneck from 'bottleneck';
|
|
3
2
|
|
|
3
|
+
import { CacheModule, Module } from '@nestjs/common';
|
|
4
|
+
|
|
5
|
+
import { ConfigService, RulesService, LoaderService, UserService, CarService, ImagesService } from './services';
|
|
6
|
+
import { RequestService } from './services/request.service';
|
|
7
|
+
import { MappingService } from './services/mapping.service';
|
|
4
8
|
import { InputQuestions } from './input.questions';
|
|
5
9
|
import { ExportRunner } from './export.command';
|
|
6
|
-
import {
|
|
7
|
-
ConfigService,
|
|
8
|
-
RequestService,
|
|
9
|
-
MappingService,
|
|
10
|
-
CarService,
|
|
11
|
-
UserService,
|
|
12
|
-
LoaderService,
|
|
13
|
-
RulesService,
|
|
14
|
-
MarketingImagesService
|
|
15
|
-
} from './services';
|
|
16
10
|
|
|
17
11
|
@Module({
|
|
18
12
|
imports: [
|
|
@@ -28,7 +22,7 @@ import {
|
|
|
28
22
|
UserService,
|
|
29
23
|
LoaderService,
|
|
30
24
|
RulesService,
|
|
31
|
-
|
|
25
|
+
ImagesService,
|
|
32
26
|
{
|
|
33
27
|
provide: Bottleneck,
|
|
34
28
|
useValue: new Bottleneck({ maxConcurrent: 10 }),
|
|
@@ -7,6 +7,8 @@ export class AlleskralleConfig extends Config {
|
|
|
7
7
|
super(params);
|
|
8
8
|
this.campaign = ExportType.ALLESKRALLE;
|
|
9
9
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.ALLESKRALLE}-export`;
|
|
10
|
-
this.outputFiles = [
|
|
10
|
+
this.outputFiles = [
|
|
11
|
+
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.ALLESKRALLE}.${FileType.XML}`,
|
|
12
|
+
];
|
|
11
13
|
}
|
|
12
14
|
}
|
|
@@ -8,7 +8,7 @@ export class Auto24Config extends Config {
|
|
|
8
8
|
this.campaign = ExportType.AUTO24;
|
|
9
9
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.AUTO24}-export`;
|
|
10
10
|
this.outputFiles = [
|
|
11
|
-
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.AUTO24}.${FileType.XML}`,
|
|
11
|
+
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.AUTO24}.${FileType.XML}`,
|
|
12
12
|
];
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -7,9 +7,9 @@ export class AutoboerseConfig extends Config {
|
|
|
7
7
|
super(params);
|
|
8
8
|
this.campaign = ExportType.AUTOBOERSE;
|
|
9
9
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.AUTOBOERSE}-export`;
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
this.outputFiles = [
|
|
12
|
-
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.AUTOBOERSE}.${FileType.XML}
|
|
12
|
+
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.AUTOBOERSE}.${FileType.XML}`,
|
|
13
13
|
];
|
|
14
14
|
this.imageUrl = this.environmentConfig[params.environment].imageUrl;
|
|
15
15
|
}
|
|
@@ -7,7 +7,7 @@ export class AutouncleConfig extends Config {
|
|
|
7
7
|
super(params);
|
|
8
8
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.AUTOUNCLE}-export`;
|
|
9
9
|
this.outputFiles = [
|
|
10
|
-
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.AUTOUNCLE}.${FileType.JSON}
|
|
10
|
+
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.AUTOUNCLE}.${FileType.JSON}`,
|
|
11
11
|
];
|
|
12
12
|
}
|
|
13
13
|
}
|
package/src/configs/config.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Environment } from '../enums
|
|
2
|
-
import { ExportType } from '../enums';
|
|
1
|
+
import { Environment, ExportType, ImageType } from '../enums';
|
|
3
2
|
import { Params } from '../interfaces/params.interface';
|
|
4
3
|
|
|
5
4
|
export class Config {
|
|
@@ -10,6 +9,8 @@ export class Config {
|
|
|
10
9
|
imboUrl: string;
|
|
11
10
|
imageUrl: string;
|
|
12
11
|
baseImageUrl: string;
|
|
12
|
+
imageType: ImageType;
|
|
13
|
+
isNewCar: boolean;
|
|
13
14
|
isCriteo: boolean;
|
|
14
15
|
criteoMarketingImagesConfigId: number;
|
|
15
16
|
exportType: ExportType;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExportType, FileType } from 'src/enums';
|
|
1
|
+
import { ExportType, FileType, ImageType } from 'src/enums';
|
|
2
2
|
import { Params } from '../interfaces/params.interface';
|
|
3
3
|
import { Config } from './config';
|
|
4
4
|
|
|
@@ -7,8 +7,9 @@ export class CriteoConfig extends Config {
|
|
|
7
7
|
super(params);
|
|
8
8
|
this.campaign = ExportType.CRITEO;
|
|
9
9
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.CRITEO}-export`;
|
|
10
|
+
this.imageType = ImageType.marketing;
|
|
10
11
|
this.outputFiles = [
|
|
11
|
-
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.CRITEO}.${FileType.XML}
|
|
12
|
+
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.CRITEO}.${FileType.XML}`,
|
|
12
13
|
];
|
|
13
14
|
this.isCriteo = true;
|
|
14
15
|
}
|
|
@@ -8,7 +8,7 @@ export class DasparkingConfig extends Config {
|
|
|
8
8
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.DASPARKING}-export`;
|
|
9
9
|
this.campaign = ExportType.DASPARKING;
|
|
10
10
|
this.outputFiles = [
|
|
11
|
-
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.DASPARKING}.${FileType.XML}
|
|
11
|
+
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.DASPARKING}.${FileType.XML}`,
|
|
12
12
|
];
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Params } from '../interfaces/params.interface';
|
|
2
2
|
import { Config } from './config';
|
|
3
|
-
import { ExportType, FileType } from '../enums';
|
|
3
|
+
import { ExportType, FileType, ImageType } from '../enums';
|
|
4
4
|
|
|
5
5
|
export class KleinanzeigeFocusConfig extends Config {
|
|
6
6
|
constructor(params: Params) {
|
|
7
7
|
super(params);
|
|
8
8
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.KLEINANZEIGE_FOCUS}-export`;
|
|
9
|
-
this.
|
|
9
|
+
this.imageType = ImageType.default;
|
|
10
10
|
this.outputFiles = [
|
|
11
|
-
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.KLEINANZEIGE_FOCUS}.${FileType.XML}
|
|
11
|
+
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.KLEINANZEIGE_FOCUS}.${FileType.XML}`,
|
|
12
12
|
];
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -5,7 +5,7 @@ import { ExportType, FileType } from '../enums';
|
|
|
5
5
|
export class MeinstadtConfig extends Config {
|
|
6
6
|
constructor(params: Params) {
|
|
7
7
|
super(params);
|
|
8
|
-
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.MEINSTADT}-export
|
|
8
|
+
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.MEINSTADT}-export`;
|
|
9
9
|
this.outputFiles = [
|
|
10
10
|
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.MEINSTADT}.${FileType.JSON}`,
|
|
11
11
|
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.MEINSTADT}.${FileType.ZIP}`,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Params } from '../interfaces/params.interface';
|
|
2
2
|
import { Config } from './config';
|
|
3
|
-
import { ExportType, FileType } from '../enums';
|
|
3
|
+
import { ExportType, FileType, ImageType } from '../enums';
|
|
4
4
|
|
|
5
5
|
export class OoyyoConfig extends Config {
|
|
6
6
|
constructor(params: Params) {
|
|
7
7
|
super(params);
|
|
8
8
|
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.OOYYO}-export`;
|
|
9
|
+
this.imageType = ImageType.default;
|
|
9
10
|
this.outputFiles = [
|
|
10
11
|
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.OOYYO}.${FileType.XML}`,
|
|
11
12
|
`${this.pathesConfig.localConvertedDirectory}/autode-${ExportType.OOYYO}.${FileType.TAR_GZ}`,
|
package/src/enums/index.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { ModuleRef } from '@nestjs/core';
|
|
|
3
3
|
|
|
4
4
|
import { CronicleUtils } from '@bytebrand/cronicle-helper';
|
|
5
5
|
import { FsChunkInterface } from '@bytebrand/chunkable';
|
|
6
|
-
import { Zipper } from '@bytebrand/zipper';
|
|
7
6
|
|
|
8
7
|
import { CarService, RulesService, ConfigService, LoaderService } from '../services';
|
|
9
8
|
import { Auto24Transformer } from '../transformers/auto24.transfomer';
|
|
@@ -18,7 +17,7 @@ export class Auto24Exporter implements Exporter {
|
|
|
18
17
|
private loaderService: LoaderService,
|
|
19
18
|
private moduleRef: ModuleRef,
|
|
20
19
|
private rulesService: RulesService,
|
|
21
|
-
) {
|
|
20
|
+
) {}
|
|
22
21
|
|
|
23
22
|
async export(): Promise<void> {
|
|
24
23
|
const [fileXml] = this.configService.config.outputFiles;
|
|
@@ -37,10 +36,9 @@ export class Auto24Exporter implements Exporter {
|
|
|
37
36
|
for (let i = 0; i < chunk.data.length; i += 1) {
|
|
38
37
|
const data = chunk.data[i];
|
|
39
38
|
const { car, images } = data;
|
|
40
|
-
await xmlBuilder.addItem(auto24Transformer.transform(car, images), 'Deutschland');
|
|
39
|
+
await xmlBuilder.addItem(await auto24Transformer.transform(car, images), 'Deutschland');
|
|
41
40
|
this.carService.counter.countCar(images);
|
|
42
41
|
}
|
|
43
|
-
|
|
44
42
|
}
|
|
45
43
|
});
|
|
46
44
|
|
|
@@ -30,9 +30,9 @@ export class FbExporter implements Exporter {
|
|
|
30
30
|
const fbTransformer = await this.moduleRef.create(FbTransformer);
|
|
31
31
|
|
|
32
32
|
await this.loaderService.process(async (chunk: FsChunkInterface) => {
|
|
33
|
-
const chunkData = chunk.data.filter(car => this.carService.filterCar(car, this.rulesService.rules));
|
|
34
|
-
chunk.data = null;
|
|
35
|
-
for (const data of
|
|
33
|
+
// const chunkData = chunk.data.filter(car => this.carService.filterCar(car, this.rulesService.rules));
|
|
34
|
+
// chunk.data = null;
|
|
35
|
+
for (const data of chunk.data) {
|
|
36
36
|
const ownerId = get(data.car, 'metaData.ownerId', null);
|
|
37
37
|
const owner = await this.carService.getOwner(ownerId);
|
|
38
38
|
const car = await fbTransformer.transform({ owner, ...data });
|
|
@@ -16,13 +16,13 @@ export class OoyyoExporter implements Exporter {
|
|
|
16
16
|
private loaderService: LoaderService,
|
|
17
17
|
private moduleRef: ModuleRef,
|
|
18
18
|
private rulesService: RulesService,
|
|
19
|
-
) {
|
|
19
|
+
) {}
|
|
20
20
|
|
|
21
21
|
async export(): Promise<void> {
|
|
22
22
|
const [fileXml, fileGZ] = this.configService.config.outputFiles;
|
|
23
23
|
await CronicleUtils.ensureDir(this.configService.config.pathesConfig.localConvertedDirectory);
|
|
24
24
|
await CronicleUtils.emptyDir(this.configService.config.pathesConfig.localConvertedDirectory);
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
const ooyyoXmlBuilder = new OoyyoXmlBuilder(fileXml);
|
|
27
27
|
await ooyyoXmlBuilder.buildStart();
|
|
28
28
|
|
|
@@ -35,11 +35,10 @@ export class OoyyoExporter implements Exporter {
|
|
|
35
35
|
for (let i = 0; i < chunk.data.length; i += 1) {
|
|
36
36
|
const data = chunk.data[i];
|
|
37
37
|
const { car, images } = data;
|
|
38
|
-
await ooyyoXmlBuilder.addItem(ooyyoTransformer.transform(car, images));
|
|
38
|
+
await ooyyoXmlBuilder.addItem(await ooyyoTransformer.transform(car, images));
|
|
39
39
|
|
|
40
40
|
this.carService.counter.countCar(images);
|
|
41
41
|
}
|
|
42
|
-
|
|
43
42
|
}
|
|
44
43
|
});
|
|
45
44
|
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Environment, ExportType } from '../enums';
|
|
2
2
|
|
|
3
3
|
export interface Params {
|
|
4
4
|
environment: Environment;
|
|
5
|
-
carDetailsUrl?: string;
|
|
6
5
|
exportType?: ExportType;
|
|
7
6
|
apikey?: string;
|
|
8
7
|
String?: string;
|
|
9
8
|
Number?: string;
|
|
10
9
|
Date?: string;
|
|
11
10
|
isNewCar?: boolean;
|
|
12
|
-
isCriteo?: boolean;
|
|
13
|
-
dealers?: string;
|
|
14
11
|
cpc?: string;
|
|
15
12
|
ownerId?: string;
|
|
16
|
-
fileName?: string;
|
|
17
|
-
googleSheetsApiKey?: string;
|
|
18
13
|
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { DataSchemes } from '@bytebrand/car-schema';
|
|
3
|
+
import { ImboImageResponseInterface } from '@bytebrand/chunkable';
|
|
4
|
+
import { get, toString } from 'lodash';
|
|
5
|
+
import { isNotEmptyArray } from '../utils/validator.utils';
|
|
6
|
+
import { ConfigService } from './config.service';
|
|
7
|
+
import { ImageType } from '../enums';
|
|
8
|
+
import { MarketingImageConfigInterface, MarketingImageConfigsInterface } from '@bytebrand/autode-request';
|
|
9
|
+
import { UserService } from './user.service';
|
|
10
|
+
import { FB_MAX_IMAGE_COUNT_FOR_DEAFULT } from '../constants/fb.constants';
|
|
11
|
+
|
|
12
|
+
@Injectable()
|
|
13
|
+
export class ImagesService {
|
|
14
|
+
constructor(private readonly configService: ConfigService, private readonly userService: UserService) {}
|
|
15
|
+
|
|
16
|
+
async getImages(
|
|
17
|
+
car: DataSchemes.Car,
|
|
18
|
+
images: ImboImageResponseInterface[],
|
|
19
|
+
imageType: ImageType,
|
|
20
|
+
): Promise<Array<string>> {
|
|
21
|
+
if (imageType === ImageType.default) {
|
|
22
|
+
return this.getDefaultImages(car, images);
|
|
23
|
+
} else {
|
|
24
|
+
const carId = toString(get(car, '_id', ''));
|
|
25
|
+
return await this.getMarketingImages(images, carId);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getDefaultImages(car: DataSchemes.Car, images: ImboImageResponseInterface[]): Array<string> {
|
|
30
|
+
const defaultImages = [
|
|
31
|
+
'https://images.auto.de/carimage/noimage/7pNvWELuWhZX/large-cached.jpeg',
|
|
32
|
+
'https://images.auto.de/carimage/noimage/GvyXmrpaf1D6/large-cached.jpeg',
|
|
33
|
+
'https://images.auto.de/carimage/noimage/gY1zF8PXzH2W/large-cached.jpeg',
|
|
34
|
+
'https://images.auto.de/carimage/noimage/pFyfBsqBHEso/large-cached.jpeg',
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
if (!isNotEmptyArray(images)) {
|
|
38
|
+
return defaultImages;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const firstImageId = get(car, 'metaData.mainImageId', null);
|
|
42
|
+
const secondImageId = get(car, 'metaData.secImageId', null);
|
|
43
|
+
const thirdImageId = get(car, 'metaData.thirdImageId', null);
|
|
44
|
+
|
|
45
|
+
if (firstImageId) {
|
|
46
|
+
images.forEach((image, index) => {
|
|
47
|
+
if (firstImageId === image.imageIdentifier) {
|
|
48
|
+
const tmp = images[index];
|
|
49
|
+
images[index] = images[0];
|
|
50
|
+
images[0] = tmp;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (secondImageId) {
|
|
56
|
+
images.forEach((image, index) => {
|
|
57
|
+
if (secondImageId === image.imageIdentifier) {
|
|
58
|
+
const tmp = images[index];
|
|
59
|
+
images[index] = images[1];
|
|
60
|
+
images[1] = tmp;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (thirdImageId) {
|
|
66
|
+
images.forEach((image, index) => {
|
|
67
|
+
if (thirdImageId === image.imageIdentifier) {
|
|
68
|
+
const tmp = images[index];
|
|
69
|
+
images[index] = images[2];
|
|
70
|
+
images[2] = tmp;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const carId = toString(get(car, '_id', ''));
|
|
76
|
+
|
|
77
|
+
const transformedImages = this.generateImageLinks(images, carId);
|
|
78
|
+
if (transformedImages.length < 17) {
|
|
79
|
+
transformedImages.push(...defaultImages);
|
|
80
|
+
}
|
|
81
|
+
return transformedImages;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
generateImageLinks(images: ImboImageResponseInterface[], carId: string) {
|
|
85
|
+
return images.map((image: ImboImageResponseInterface) => {
|
|
86
|
+
return `${this.configService.config.baseImageUrl}/carimage/${carId}/${image.imageIdentifier}/large`;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async getMarketingImages(images: any, carId: string): Promise<string[]> {
|
|
91
|
+
const imageUrl = this.configService.config.imageUrl;
|
|
92
|
+
const transformedImages = this.transformImagesArrayIntoObject(images);
|
|
93
|
+
const configs = this.configService.config.isCriteo
|
|
94
|
+
? await this.userService.getMarketingImageConfig(this.configService.config.criteoMarketingImagesConfigId)
|
|
95
|
+
: ((await this.getMarketingImageConfigs()) as any);
|
|
96
|
+
const marketingImageConfigs = this.transform(configs);
|
|
97
|
+
|
|
98
|
+
const defImages = [
|
|
99
|
+
{ url: 'https://images.auto.de/carimage/noimage/7pNvWELuWhZX/large-cached.jpeg' },
|
|
100
|
+
{ url: 'https://images.auto.de/carimage/noimage/GvyXmrpaf1D6/large-cached.jpeg' },
|
|
101
|
+
{ url: 'https://images.auto.de/carimage/noimage/gY1zF8PXzH2W/large-cached.jpeg' },
|
|
102
|
+
{ url: 'https://images.auto.de/carimage/noimage/pFyfBsqBHEso/large-cached.jpeg' },
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
const imageUrls = [];
|
|
106
|
+
|
|
107
|
+
for (let i = 0; i < marketingImageConfigs.length; i++) {
|
|
108
|
+
const marketingImage = marketingImageConfigs[i];
|
|
109
|
+
for (let i = 0; i < marketingImage.marketingImageCodes.length; i++) {
|
|
110
|
+
const imageCode = marketingImage.marketingImageCodes[i];
|
|
111
|
+
const imageId = transformedImages[imageCode];
|
|
112
|
+
if (imageId) {
|
|
113
|
+
imageUrls.push(this.getImagePathWithExtenstion(imageUrl, carId, imageId, configs));
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (imageUrls.length < FB_MAX_IMAGE_COUNT_FOR_DEAFULT) {
|
|
119
|
+
imageUrls.push(...defImages);
|
|
120
|
+
}
|
|
121
|
+
return imageUrls;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async getMarketingImageConfigs(): Promise<MarketingImageConfigsInterface> {
|
|
125
|
+
const configs = await this.userService.getMarketingImageConfigs();
|
|
126
|
+
const { id } = configs.find(config => config.channelCode.includes(this.configService.config.exportType));
|
|
127
|
+
|
|
128
|
+
return this.userService.getMarketingImageConfig(id);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private transformImagesArrayIntoObject(images: { [imageCode: string]: string }[]) {
|
|
132
|
+
const result: { [imageCode: string]: string } = {};
|
|
133
|
+
images.forEach(image => {
|
|
134
|
+
const imageCode = image.imageCodePredicted.split('-')[0];
|
|
135
|
+
result[imageCode] = image.imageIdentifier;
|
|
136
|
+
});
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private transform(config: MarketingImageConfigInterface): { marketingImageCodes: string[] }[] {
|
|
141
|
+
return config.marketingImages.map(marketingImage => {
|
|
142
|
+
return {
|
|
143
|
+
marketingImageCodes: marketingImage.imageCodes,
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
protected getChannelPath(imageUrl: string, carId: string): string {
|
|
149
|
+
return `${imageUrl}/${[carId[0], carId[1], carId[2], carId].join('/')}`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
protected getImagePathWithExtenstion(
|
|
153
|
+
imageUrl: string,
|
|
154
|
+
carId: string,
|
|
155
|
+
imageId: string,
|
|
156
|
+
config: MarketingImageConfigsInterface,
|
|
157
|
+
): string {
|
|
158
|
+
const { channelCode, imageExtension } = config;
|
|
159
|
+
return `${this.getChannelPath(imageUrl, carId)}/${channelCode.replace(/ /g, '-')}-${imageId}.${imageExtension}`;
|
|
160
|
+
}
|
|
161
|
+
}
|
package/src/services/index.ts
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import { Translator } from '@bytebrand/schema-tools';
|
|
2
2
|
import { de } from '@bytebrand/i18n-dictionaries';
|
|
3
|
-
import { get,
|
|
3
|
+
import { get, isEmpty, isNil, toString } from 'lodash';
|
|
4
4
|
import * as moment from 'moment';
|
|
5
5
|
import { DataSchemes } from '@bytebrand/car-schema';
|
|
6
6
|
import { ImboImageResponseInterface } from '@bytebrand/chunkable';
|
|
7
7
|
import { Auto24XmlItem } from '../interfaces';
|
|
8
8
|
import { Injectable } from '@nestjs/common';
|
|
9
|
-
import { ConfigService } from '../services
|
|
9
|
+
import { ConfigService, ImagesService } from '../services';
|
|
10
10
|
import { isNotEmptyArray } from '../utils/validator.utils';
|
|
11
|
+
import { ImageType } from '../enums';
|
|
11
12
|
|
|
12
13
|
@Injectable()
|
|
13
14
|
export class Auto24Transformer {
|
|
14
15
|
private translator: Translator;
|
|
15
16
|
|
|
16
|
-
constructor(private configService: ConfigService) {
|
|
17
|
+
constructor(private configService: ConfigService, private readonly imageService: ImagesService) {
|
|
17
18
|
this.translator = new Translator(de);
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
transform(car: DataSchemes.Car, imboImages: ImboImageResponseInterface[]): Auto24XmlItem {
|
|
21
|
+
async transform(car: DataSchemes.Car, imboImages: ImboImageResponseInterface[]): Promise<Auto24XmlItem> {
|
|
21
22
|
const carId = toString(get(car, '_id', ''));
|
|
22
|
-
|
|
23
|
+
const transformedImages = await this.imageService.getImages(car, imboImages, ImageType.default);
|
|
23
24
|
let userlink = `https://www.${this.configService.config.domain}/search/vehicle/${carId}`;
|
|
24
25
|
if (this.configService.config.campaign) {
|
|
25
26
|
userlink += `?source=classifieds&medium=listing&campaign=${this.configService.config.campaign}`;
|
|
@@ -37,9 +38,9 @@ export class Auto24Transformer {
|
|
|
37
38
|
consumptionK: toString(get(car, 'consumption.consumptionCombined', '')),
|
|
38
39
|
co2: toString(get(car, 'environmentEmissions.co2', '')),
|
|
39
40
|
efficiencyclass: this.translateSelector(get(car, 'environmentEmissions.energyEfficiencyClass', '')),
|
|
40
|
-
image:
|
|
41
|
+
image: transformedImages[0],
|
|
41
42
|
registration: this.getRegistrationField(get(car, 'mainData.firstRegistration') as number),
|
|
42
|
-
images:
|
|
43
|
+
images: transformedImages,
|
|
43
44
|
price: toString(get(car, 'price.currentSalesPrice', '')),
|
|
44
45
|
power: toString(get(car, 'engineData.powerKW', '')),
|
|
45
46
|
zip: toString(get(car, 'location.zipCode', '')),
|
|
@@ -132,28 +133,4 @@ export class Auto24Transformer {
|
|
|
132
133
|
})
|
|
133
134
|
.join(', ');
|
|
134
135
|
}
|
|
135
|
-
|
|
136
|
-
private getImagesField(carId: string, images: ImboImageResponseInterface[]): string[] {
|
|
137
|
-
if (isNotEmptyArray(images)) {
|
|
138
|
-
return images.map((image: ImboImageResponseInterface) => {
|
|
139
|
-
return this.buildLargeImageUrl(carId, image.imageIdentifier);
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
return [];
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
private getImageField(carId: string, mainImageId: string, images: ImboImageResponseInterface[]): string {
|
|
146
|
-
if (isNil(mainImageId) || isEmpty(mainImageId)) {
|
|
147
|
-
if (isNotEmptyArray(images)) {
|
|
148
|
-
const firstImageId = first(images);
|
|
149
|
-
return this.buildLargeImageUrl(carId, firstImageId.imageIdentifier);
|
|
150
|
-
}
|
|
151
|
-
return '';
|
|
152
|
-
}
|
|
153
|
-
return this.buildLargeImageUrl(carId, mainImageId);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
private buildLargeImageUrl(carId: string, imageId: string): string {
|
|
157
|
-
return `${this.configService.config.imageUrl}/carimage/${carId}/${imageId}/large`;
|
|
158
|
-
}
|
|
159
136
|
}
|
|
@@ -5,18 +5,18 @@ import * as moment from 'moment';
|
|
|
5
5
|
import { DataSchemes } from '@bytebrand/car-schema';
|
|
6
6
|
import { DePostalCodesService } from '@bytebrand/car-basic-data-scope';
|
|
7
7
|
import { DePostalCodesEntryInterface } from '@bytebrand/car-basic-data-scope/dist/interfaces/DePostalCodesInterface';
|
|
8
|
-
import { ConfigService } from '../services';
|
|
8
|
+
import { ConfigService, ImagesService } from '../services';
|
|
9
9
|
import { Injectable } from '@nestjs/common';
|
|
10
10
|
import { DEFAULT_ADDR1, DEFAULT_CITY, DEFAULT_ZIP, MIN_MILEAGES } from '../constants/autouncle.contants';
|
|
11
11
|
import { AutouncleJsonItem } from '../interfaces';
|
|
12
|
-
import {
|
|
12
|
+
import { ImboImageResponseInterface } from '@bytebrand/chunkable';
|
|
13
13
|
|
|
14
14
|
@Injectable()
|
|
15
15
|
export class AutouncleTransformer {
|
|
16
16
|
private translator: TranslatorExtended;
|
|
17
17
|
private postalCodesService: DePostalCodesService;
|
|
18
18
|
|
|
19
|
-
constructor(private configService: ConfigService) {
|
|
19
|
+
constructor(private configService: ConfigService, private imageService: ImagesService) {
|
|
20
20
|
const dict = { ...de, ...deVehicleProps, ...deVehicleDetailsPage };
|
|
21
21
|
this.translator = new TranslatorExtended(dict);
|
|
22
22
|
this.postalCodesService = DePostalCodesService.getInstance();
|
|
@@ -28,7 +28,7 @@ export class AutouncleTransformer {
|
|
|
28
28
|
owner,
|
|
29
29
|
}: {
|
|
30
30
|
car: DataSchemes.Car;
|
|
31
|
-
images:
|
|
31
|
+
images: ImboImageResponseInterface[];
|
|
32
32
|
metadata?: unknown;
|
|
33
33
|
owner: unknown;
|
|
34
34
|
}): Promise<AutouncleJsonItem> {
|
|
@@ -61,7 +61,7 @@ export class AutouncleTransformer {
|
|
|
61
61
|
seller_name: 'auto.de',
|
|
62
62
|
seller_id: toString(get(car, 'metaData.ownerId', '')),
|
|
63
63
|
description: toString(get(car, 'offer.offerDescription', '')),
|
|
64
|
-
images: this.getImagesField(
|
|
64
|
+
images: this.getImagesField(car, images),
|
|
65
65
|
fuel_economy: toString(get(car, 'consumption.consumptionCombined', '')),
|
|
66
66
|
co2_emission: toString(get(car, 'environmentEmissions.co2', '')),
|
|
67
67
|
co2_effiency_class: toString(get(car, 'environmentEmissions.energyEfficiencyClass', '')),
|
|
@@ -230,35 +230,9 @@ export class AutouncleTransformer {
|
|
|
230
230
|
return '';
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
private getImagesField(
|
|
234
|
-
|
|
235
|
-
{ url
|
|
236
|
-
|
|
237
|
-
{ url: 'https://images.auto.de/carimage/noimage/gY1zF8PXzH2W/large-cached.jpeg' },
|
|
238
|
-
{ url: 'https://images.auto.de/carimage/noimage/pFyfBsqBHEso/large-cached.jpeg' },
|
|
239
|
-
];
|
|
240
|
-
if (isNotEmptyArray(images)) {
|
|
241
|
-
const imageList = images.sort(this.setMainImageFirst(mainImageId)).map((image: any) => {
|
|
242
|
-
return { url: this.buildLargeImageUrl(carId, image.imageIdentifier) };
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
if (imageList.length < 17) {
|
|
246
|
-
imageList.push(...defImages);
|
|
247
|
-
}
|
|
248
|
-
return imageList;
|
|
249
|
-
}
|
|
250
|
-
return defImages;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
private buildLargeImageUrl(carId: string, imageId: string): string {
|
|
254
|
-
return `${this.configService.config.imageUrl}/carimage/${carId}/${imageId}/large`;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
private setMainImageFirst(mainImageId: string): (current: any, next: any) => number {
|
|
258
|
-
return (current: any, next: any): number => {
|
|
259
|
-
if (current.imageIdentifier === mainImageId) return -1;
|
|
260
|
-
if (next.imageIdentifier === mainImageId) return 1;
|
|
261
|
-
return 0;
|
|
262
|
-
};
|
|
233
|
+
private getImagesField(car: DataSchemes.Car, images: ImboImageResponseInterface[]): { url: string }[] {
|
|
234
|
+
return this.imageService.getDefaultImages(car, images).map(url => {
|
|
235
|
+
return { url };
|
|
236
|
+
});
|
|
263
237
|
}
|
|
264
238
|
}
|