@bytebrand/export-cars 0.0.2

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.
Files changed (39) hide show
  1. package/.prettierrc +14 -0
  2. package/dist/config/ConfigBuilder.d.ts +5 -0
  3. package/dist/config/ConfigBuilder.js +90 -0
  4. package/dist/config/ConfigBuilder.js.map +1 -0
  5. package/dist/config/index.d.ts +1 -0
  6. package/dist/config/index.js +7 -0
  7. package/dist/config/index.js.map +1 -0
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +64 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/interfaces/index.d.ts +0 -0
  12. package/dist/interfaces/index.js +1 -0
  13. package/dist/interfaces/index.js.map +1 -0
  14. package/dist/modules/acrhiver/TarArchiver.d.ts +6 -0
  15. package/dist/modules/acrhiver/TarArchiver.js +52 -0
  16. package/dist/modules/acrhiver/TarArchiver.js.map +1 -0
  17. package/dist/modules/acrhiver/index.d.ts +2 -0
  18. package/dist/modules/acrhiver/index.js +7 -0
  19. package/dist/modules/acrhiver/index.js.map +1 -0
  20. package/dist/modules/car-exporter/index.d.ts +2 -0
  21. package/dist/modules/car-exporter/index.js +10 -0
  22. package/dist/modules/car-exporter/index.js.map +1 -0
  23. package/dist/modules/car-loader/index.d.ts +2 -0
  24. package/dist/modules/car-loader/index.js +12 -0
  25. package/dist/modules/car-loader/index.js.map +1 -0
  26. package/index.js +2 -0
  27. package/package.json +42 -0
  28. package/readme.md +7 -0
  29. package/src/config/ConfigBuilder.ts +91 -0
  30. package/src/config/index.ts +1 -0
  31. package/src/index.ts +62 -0
  32. package/src/interfaces/index.ts +0 -0
  33. package/src/modules/acrhiver/TarArchiver.ts +32 -0
  34. package/src/modules/acrhiver/index.ts +6 -0
  35. package/src/modules/car-exporter/index.ts +11 -0
  36. package/src/modules/car-loader/index.ts +10 -0
  37. package/tsconfig.json +34 -0
  38. package/tslint.json +51 -0
  39. package/types/basic-ftp.d.ts +72 -0
package/.prettierrc ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "useTabs": false,
3
+ "eslintIntegration": true,
4
+ "parser": "typescript",
5
+ "typescriptEnable": [
6
+ "typescript",
7
+ "typescriptreact"
8
+ ],
9
+ "trailingComma": "all",
10
+ "tabWidth": 2,
11
+ "singleQuote": true,
12
+ "bracketSpacing": true,
13
+ "arrowParens": "always"
14
+ }
@@ -0,0 +1,5 @@
1
+ import { ConfigInterface, CronicleJobInterface } from '@bytebrand/chunkable';
2
+ export declare class ConfigBuilder {
3
+ static defaultConfig: ConfigInterface;
4
+ static mkConfig(job: CronicleJobInterface): ConfigInterface;
5
+ }
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class ConfigBuilder {
4
+ static mkConfig(job) {
5
+ const developRoot = 'autode-dev.de';
6
+ const stageRoot = 'autode-stage.de';
7
+ const productionRoot = 'auto.de';
8
+ const developConfig = {
9
+ chunk_limit: job.params.limit,
10
+ root: developRoot,
11
+ environment: job.params.environment,
12
+ id: job.id,
13
+ projectRelatedParameters: {
14
+ apikey: job.params.apikey,
15
+ cbdUrl: `https://www.${developRoot}/service/car-basic-data`,
16
+ },
17
+ pathes: {
18
+ localDirectory: 'resources/json_dev',
19
+ localConvertedDirectory: 'resources/csv_dev',
20
+ remoteDirectory: 'import_dev',
21
+ baseFileName: 'cars',
22
+ },
23
+ ftpConfig: {
24
+ DEFAULT_FTP_HOST: '185.15.211.90',
25
+ DEFAULT_FTP_PORT: '21',
26
+ DEFAULT_FTP_USER: 'jelastic-ftp',
27
+ DEFAULT_FTP_PASS: '7D413EB6L6',
28
+ },
29
+ };
30
+ const stageConfig = {
31
+ chunk_limit: job.params.limit,
32
+ root: developRoot,
33
+ environment: job.params.environment,
34
+ id: job.id,
35
+ projectRelatedParameters: {
36
+ apikey: job.params.apikey,
37
+ cbdUrl: `https://www.${stageRoot}/service/car-basic-data`,
38
+ },
39
+ pathes: {
40
+ localDirectory: 'resources/json_stage',
41
+ localConvertedDirectory: 'resources/csv_stage',
42
+ remoteDirectory: 'import_stage',
43
+ baseFileName: 'cars',
44
+ },
45
+ ftpConfig: {
46
+ DEFAULT_FTP_HOST: '185.15.211.90',
47
+ DEFAULT_FTP_PORT: '21',
48
+ DEFAULT_FTP_USER: 'jelastic-ftp',
49
+ DEFAULT_FTP_PASS: '7D413EB6L6',
50
+ },
51
+ };
52
+ const productionConfig = {
53
+ chunk_limit: job.params.limit,
54
+ root: developRoot,
55
+ environment: job.params.environment,
56
+ id: job.id,
57
+ projectRelatedParameters: {
58
+ apikey: job.params.apikey,
59
+ cbdUrl: `https://www.${productionRoot}/service/car-basic-data`,
60
+ },
61
+ pathes: {
62
+ localDirectory: 'resources/json_prod',
63
+ localConvertedDirectory: 'resources/csv_prod',
64
+ remoteDirectory: 'import',
65
+ baseFileName: 'cars',
66
+ },
67
+ ftpConfig: {
68
+ DEFAULT_FTP_HOST: '185.15.211.90',
69
+ DEFAULT_FTP_PORT: '21',
70
+ DEFAULT_FTP_USER: 'jelastic-ftp',
71
+ DEFAULT_FTP_PASS: '7D413EB6L6',
72
+ },
73
+ };
74
+ switch (job.params.environment) {
75
+ case 'develop':
76
+ ConfigBuilder.defaultConfig = developConfig;
77
+ return developConfig;
78
+ case 'stage':
79
+ ConfigBuilder.defaultConfig = stageConfig;
80
+ return stageConfig;
81
+ case 'production':
82
+ ConfigBuilder.defaultConfig = productionConfig;
83
+ return productionConfig;
84
+ default:
85
+ return null;
86
+ }
87
+ }
88
+ }
89
+ exports.ConfigBuilder = ConfigBuilder;
90
+ //# sourceMappingURL=ConfigBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigBuilder.js","sourceRoot":"","sources":["../../src/config/ConfigBuilder.ts"],"names":[],"mappings":";;AAEA,MAAa,aAAa;IAExB,MAAM,CAAC,QAAQ,CAAC,GAAyB;QACvC,MAAM,WAAW,GAAG,eAAe,CAAC;QACpC,MAAM,SAAS,GAAG,iBAAiB,CAAC;QACpC,MAAM,cAAc,GAAG,SAAS,CAAC;QAEjC,MAAM,aAAa,GAAoB;YACrC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK;YAC7B,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW;YACnC,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,wBAAwB,EAAE;gBACxB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM;gBACzB,MAAM,EAAE,eAAe,WAAW,yBAAyB;aAC5D;YACD,MAAM,EAAE;gBACN,cAAc,EAAE,oBAAoB;gBACpC,uBAAuB,EAAE,mBAAmB;gBAC5C,eAAe,EAAE,YAAY;gBAC7B,YAAY,EAAE,MAAM;aACrB;YACD,SAAS,EAAE;gBACT,gBAAgB,EAAE,eAAe;gBACjC,gBAAgB,EAAE,IAAI;gBACtB,gBAAgB,EAAE,cAAc;gBAChC,gBAAgB,EAAE,YAAY;aAC/B;SACF,CAAC;QACF,MAAM,WAAW,GAAoB;YACnC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK;YAC7B,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW;YACnC,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,wBAAwB,EAAE;gBACxB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM;gBACzB,MAAM,EAAE,eAAe,SAAS,yBAAyB;aAC1D;YACD,MAAM,EAAE;gBACN,cAAc,EAAE,sBAAsB;gBACtC,uBAAuB,EAAE,qBAAqB;gBAC9C,eAAe,EAAE,cAAc;gBAC/B,YAAY,EAAE,MAAM;aACrB;YACD,SAAS,EAAE;gBACT,gBAAgB,EAAE,eAAe;gBACjC,gBAAgB,EAAE,IAAI;gBACtB,gBAAgB,EAAE,cAAc;gBAChC,gBAAgB,EAAE,YAAY;aAC/B;SACF,CAAC;QACF,MAAM,gBAAgB,GAAoB;YACxC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK;YAC7B,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW;YACnC,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,wBAAwB,EAAE;gBACxB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM;gBACzB,MAAM,EAAE,eAAe,cAAc,yBAAyB;aAC/D;YACD,MAAM,EAAE;gBACN,cAAc,EAAE,qBAAqB;gBACrC,uBAAuB,EAAE,oBAAoB;gBAC7C,eAAe,EAAE,QAAQ;gBACzB,YAAY,EAAE,MAAM;aACrB;YACD,SAAS,EAAE;gBACT,gBAAgB,EAAE,eAAe;gBACjC,gBAAgB,EAAE,IAAI;gBACtB,gBAAgB,EAAE,cAAc;gBAChC,gBAAgB,EAAE,YAAY;aAC/B;SACF,CAAC;QAEF,QAAQ,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE;YAC9B,KAAK,SAAS;gBACZ,aAAa,CAAC,aAAa,GAAG,aAAa,CAAC;gBAC5C,OAAO,aAAa,CAAC;YACvB,KAAK,OAAO;gBACV,aAAa,CAAC,aAAa,GAAG,WAAW,CAAC;gBAC1C,OAAO,WAAW,CAAC;YACrB,KAAK,YAAY;gBACf,aAAa,CAAC,aAAa,GAAG,gBAAgB,CAAC;gBAC/C,OAAO,gBAAgB,CAAC;YAC1B;gBACE,OAAO,IAAI,CAAC;SACf;IACH,CAAC;CACF;AAxFD,sCAwFC"}
@@ -0,0 +1 @@
1
+ export * from './ConfigBuilder';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ function __export(m) {
3
+ for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
4
+ }
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ __export(require("./ConfigBuilder"));
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":";;;;;AAAA,qCAAgC"}
@@ -0,0 +1 @@
1
+ import 'reflect-metadata';
package/dist/index.js ADDED
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ require("reflect-metadata");
12
+ const chunkable_1 = require("@bytebrand/chunkable");
13
+ const config_1 = require("./config");
14
+ const index_1 = require("./modules/car-loader/index");
15
+ const acrhiver_1 = require("./modules/acrhiver");
16
+ const car_exporter_1 = require("./modules/car-exporter");
17
+ const ftp_1 = require("@bytebrand/chunkable/dist/ftp");
18
+ const rl = require('readline').createInterface({ input: process.stdin });
19
+ rl.on('line', (line) => __awaiter(this, void 0, void 0, function* () {
20
+ try {
21
+ const job = {
22
+ id: 'sdsdsd',
23
+ params: {
24
+ apikey: 'AIzaSyD57yo222EMQjyHQKCDsLILrHh3AzOGtmU',
25
+ environment: 'production',
26
+ // apikey: 'AIzaSyC-jmLAkt2pVO0t-beLIuZJwR4jiGpzYyU',
27
+ // environment: 'develop',
28
+ limit: 1000,
29
+ },
30
+ };
31
+ // const job: ChunkableInterfaces.CronicleJobInterface = JSON.parse(line);
32
+ process.stdout.write(`Running job: ${job.id}: ${JSON.stringify(job)}\n`);
33
+ const config = config_1.ConfigBuilder.mkConfig(job);
34
+ chunkable_1.FTP.initFTPConnections(config.ftpConfig, 'general').then(() => __awaiter(this, void 0, void 0, function* () {
35
+ const loader = index_1.getLoader(config);
36
+ const archiver = acrhiver_1.getArhiver(config);
37
+ const exporter = car_exporter_1.getExporter(Object.assign(config, { eventEmitter: ftp_1.getEventEmitter('general') }));
38
+ loader.onFinish((chunks) => {
39
+ process.stdout.write(`${JSON.stringify({ progress: 0.33 })}\n`);
40
+ return archiver.start(chunks);
41
+ });
42
+ archiver.onFinish((chunks) => {
43
+ loader.clear();
44
+ process.stdout.write(`${JSON.stringify({ progress: 0.66 })}\n`);
45
+ return exporter.start(chunks);
46
+ });
47
+ loader.start();
48
+ exporter.onChunk((chunk) => {
49
+ archiver.clear();
50
+ process.stdout.write(`${JSON.stringify({ progress: 1 })}\n`);
51
+ process.stdout.write(`${JSON.stringify({ complete: 1, code: 0 })}\n`);
52
+ process.exit();
53
+ // rl.close();
54
+ return Promise.resolve(true);
55
+ });
56
+ }));
57
+ // rl.close();
58
+ }
59
+ catch (e) {
60
+ // rl.close();
61
+ process.stderr.write(`${JSON.stringify({ complete: 1, code: 1, description: e.message })}\n`);
62
+ }
63
+ }));
64
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
File without changes
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { AbstractChunkable, Interfaces } from '@bytebrand/chunkable';
2
+ export declare class TarArchiver extends AbstractChunkable {
3
+ doChunk(chunk?: Interfaces.ChunkInterface): Promise<boolean>;
4
+ clear(): Promise<void>;
5
+ doStart(chunks?: Interfaces.ChunkInterface[]): any;
6
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __importStar = (this && this.__importStar) || function (mod) {
11
+ if (mod && mod.__esModule) return mod;
12
+ var result = {};
13
+ if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
14
+ result["default"] = mod;
15
+ return result;
16
+ };
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ const chunkable_1 = require("@bytebrand/chunkable");
22
+ const tar = __importStar(require("tar"));
23
+ const moment_1 = __importDefault(require("moment"));
24
+ const fs_1 = __importDefault(require("fs"));
25
+ class TarArchiver extends chunkable_1.AbstractChunkable {
26
+ doChunk(chunk) {
27
+ throw new Error('This converter works with full data use doStart');
28
+ }
29
+ clear() {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ for (const chunk of this.chunks) {
32
+ fs_1.default.unlinkSync(this.getChunkPath(chunk));
33
+ }
34
+ });
35
+ }
36
+ doStart(chunks) {
37
+ const archiveChunk = this.createChunk(moment_1.default().format('DD_MM_YY'), 'tgz');
38
+ archiveChunk.currentLocation = this.pathesConfig.localDirectory;
39
+ const options = {
40
+ gzip: true,
41
+ file: this.getChunkPath(archiveChunk),
42
+ cwd: this.pathesConfig.localDirectory,
43
+ };
44
+ const files = chunks.map((chunk) => this.getChunkFileName(chunk));
45
+ return tar.create(options, files).then(() => {
46
+ this.chunks.push(archiveChunk);
47
+ return this.onFinishCallback([archiveChunk]);
48
+ });
49
+ }
50
+ }
51
+ exports.TarArchiver = TarArchiver;
52
+ //# sourceMappingURL=TarArchiver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TarArchiver.js","sourceRoot":"","sources":["../../../src/modules/acrhiver/TarArchiver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,oDAAqE;AACrE,yCAA2B;AAC3B,oDAA4B;AAC5B,4CAAoB;AAEpB,MAAa,WAAY,SAAQ,6BAAiB;IAChD,OAAO,CAAC,KAAiC;QACvC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAEK,KAAK;;YACT,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE;gBAC/B,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;aACzC;QACH,CAAC;KAAA;IAED,OAAO,CAAC,MAAoC;QAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1E,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC;QAChE,MAAM,OAAO,GAAwC;YACnD,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC;YACrC,GAAG,EAAE,IAAI,CAAC,YAAY,CAAC,cAAc;SACtC,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;QAElE,OAAQ,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAS,CAAC,IAAI,CAAC,GAAG,EAAE;YACnD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC/B,OAAO,IAAI,CAAC,gBAAgB,CAAC,CAAE,YAAY,CAAE,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA1BD,kCA0BC"}
@@ -0,0 +1,2 @@
1
+ import { ChunkableFactoryInterface } from '@bytebrand/chunkable';
2
+ export declare const getArhiver: ChunkableFactoryInterface;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const TarArchiver_1 = require("./TarArchiver");
4
+ exports.getArhiver = (config) => {
5
+ return new TarArchiver_1.TarArchiver({ pathesConfig: config.pathes, limit: config.chunk_limit });
6
+ };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/acrhiver/index.ts"],"names":[],"mappings":";;AAAA,+CAA4C;AAG/B,QAAA,UAAU,GAA8B,CAAC,MAAuB,EAAE,EAAE;IAC/E,OAAQ,IAAI,yBAAW,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,CAAuB,CAAC;AAC5G,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { ChunkableFactoryInterface } from '@bytebrand/chunkable';
2
+ export declare const getExporter: ChunkableFactoryInterface;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const chunkable_1 = require("@bytebrand/chunkable");
4
+ exports.getExporter = (config) => {
5
+ return new chunkable_1.Exporters.FtpCarsJsonExporter(config.eventEmitter, {
6
+ pathesConfig: config.pathes,
7
+ limit: config.chunk_limit,
8
+ });
9
+ };
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/car-exporter/index.ts"],"names":[],"mappings":";;AAAA,oDAAkG;AAGrF,QAAA,WAAW,GAA8B,CACpD,MAA6D,EAC7D,EAAE;IACF,OAAO,IAAI,qBAAS,CAAC,mBAAmB,CAAC,MAAM,CAAC,YAAY,EAAE;QAC5D,YAAY,EAAE,MAAM,CAAC,MAAM;QAC3B,KAAK,EAAE,MAAM,CAAC,WAAW;KAC1B,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { ChunkableFactoryInterface } from '@bytebrand/chunkable';
2
+ export declare const getLoader: ChunkableFactoryInterface;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const chunkable_1 = require("@bytebrand/chunkable");
4
+ exports.getLoader = (config) => {
5
+ return new chunkable_1.Loaders.CarBasicDataCarsLoader({
6
+ pathesConfig: config.pathes,
7
+ limit: config.chunk_limit,
8
+ cbdUrl: config.projectRelatedParameters.cbdUrl,
9
+ apikey: config.projectRelatedParameters.apikey,
10
+ });
11
+ };
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/car-loader/index.ts"],"names":[],"mappings":";;AAAA,oDAAgG;AAEnF,QAAA,SAAS,GAA8B,CAAC,MAAuB,EAAE,EAAE;IAC9E,OAAO,IAAI,mBAAO,CAAC,sBAAsB,CAAC;QACxC,YAAY,EAAE,MAAM,CAAC,MAAM;QAC3B,KAAK,EAAE,MAAM,CAAC,WAAW;QACzB,MAAM,EAAE,MAAM,CAAC,wBAAwB,CAAC,MAAM;QAC9C,MAAM,EAAE,MAAM,CAAC,wBAAwB,CAAC,MAAM;KAC/C,CAAC,CAAC;AACL,CAAC,CAAC"}
package/index.js ADDED
@@ -0,0 +1,2 @@
1
+ require('ts-node').register('./tsconfig.json');
2
+ require('./src/index');
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@bytebrand/export-cars",
3
+ "version": "0.0.2",
4
+ "description": "Run python ML script for find good and bad prices on car list",
5
+ "author": "Bytebrand <info@bytebrand.net>",
6
+ "license": "UNLICENSED",
7
+ "main": "index.js",
8
+ "scripts": {
9
+ "test": "echo \"Error: no test specified\" && exit 1",
10
+ "lint": "./node_modules/.bin/tslint -c tslint.json -p tsconfig.json",
11
+ "build": "tsc -d -p tsconfig.json",
12
+ "prepublishOnly": "npm run build",
13
+ "cleardist": "rm -rf dist/*"
14
+ },
15
+ "dependencies": {
16
+ "@bytebrand/car-basic-data-scope": "~2.0.11",
17
+ "@bytebrand/car-schema": "~0.14.12",
18
+ "@bytebrand/chunkable": "^2.1.2",
19
+ "@bytebrand/event-emitter": "^1.0.8",
20
+ "@bytebrand/ftp-queue-subscriber": "^1.0.16",
21
+ "basic-ftp": "^3.1.1",
22
+ "lodash": "^4.17.11",
23
+ "moment": "^2.24.0",
24
+ "python-shell": "^1.0.7",
25
+ "request": "^2.88.0",
26
+ "tar": "^4.4.8"
27
+ },
28
+ "devDependencies": {
29
+ "@types/lodash": "^4.14.120",
30
+ "@types/mongodb": "^3.1.19",
31
+ "@types/mysql": "^2.15.5",
32
+ "@types/node": "^10.12.7",
33
+ "@types/tar": "^4.0.0",
34
+ "reflect-metadata": "^0.1.13",
35
+ "ts-node": "^6.0.0",
36
+ "tslint": "^5.9.1",
37
+ "tslint-config-airbnb": "^5.8.0",
38
+ "tslint-eslint-rules": "^5.1.0",
39
+ "typescript": "^3.2.4"
40
+ },
41
+ "gitHead": "3c136f2e0a3de5c31e62651b8d3de1b02d7e4723"
42
+ }
package/readme.md ADDED
@@ -0,0 +1,7 @@
1
+ start script
2
+
3
+ ``node index.js``
4
+
5
+ after it type next line
6
+
7
+ ``{"id": 1, "params": {"apikey": "", "environment": "develop", "limit": "200", "ftpHost": "", "ftpUser": "", "ftpPassword": ""}}``
@@ -0,0 +1,91 @@
1
+ import { ConfigInterface, CronicleJobInterface } from '@bytebrand/chunkable';
2
+
3
+ export class ConfigBuilder {
4
+ static defaultConfig: ConfigInterface;
5
+ static mkConfig(job: CronicleJobInterface): ConfigInterface {
6
+ const developRoot = 'autode-dev.de';
7
+ const stageRoot = 'autode-stage.de';
8
+ const productionRoot = 'auto.de';
9
+
10
+ const developConfig: ConfigInterface = {
11
+ chunk_limit: job.params.limit,
12
+ root: developRoot,
13
+ environment: job.params.environment,
14
+ id: job.id,
15
+ projectRelatedParameters: {
16
+ apikey: job.params.apikey,
17
+ cbdUrl: `https://www.${developRoot}/service/car-basic-data`,
18
+ },
19
+ pathes: {
20
+ localDirectory: 'resources/json_dev',
21
+ localConvertedDirectory: 'resources/csv_dev',
22
+ remoteDirectory: 'import_dev',
23
+ baseFileName: 'cars',
24
+ },
25
+ ftpConfig: {
26
+ DEFAULT_FTP_HOST: '185.15.211.90',
27
+ DEFAULT_FTP_PORT: '21',
28
+ DEFAULT_FTP_USER: 'jelastic-ftp',
29
+ DEFAULT_FTP_PASS: '7D413EB6L6',
30
+ },
31
+ };
32
+ const stageConfig: ConfigInterface = {
33
+ chunk_limit: job.params.limit,
34
+ root: developRoot,
35
+ environment: job.params.environment,
36
+ id: job.id,
37
+ projectRelatedParameters: {
38
+ apikey: job.params.apikey,
39
+ cbdUrl: `https://www.${stageRoot}/service/car-basic-data`,
40
+ },
41
+ pathes: {
42
+ localDirectory: 'resources/json_stage',
43
+ localConvertedDirectory: 'resources/csv_stage',
44
+ remoteDirectory: 'import_stage',
45
+ baseFileName: 'cars',
46
+ },
47
+ ftpConfig: {
48
+ DEFAULT_FTP_HOST: '185.15.211.90',
49
+ DEFAULT_FTP_PORT: '21',
50
+ DEFAULT_FTP_USER: 'jelastic-ftp',
51
+ DEFAULT_FTP_PASS: '7D413EB6L6',
52
+ },
53
+ };
54
+ const productionConfig: ConfigInterface = {
55
+ chunk_limit: job.params.limit,
56
+ root: developRoot,
57
+ environment: job.params.environment,
58
+ id: job.id,
59
+ projectRelatedParameters: {
60
+ apikey: job.params.apikey,
61
+ cbdUrl: `https://www.${productionRoot}/service/car-basic-data`,
62
+ },
63
+ pathes: {
64
+ localDirectory: 'resources/json_prod',
65
+ localConvertedDirectory: 'resources/csv_prod',
66
+ remoteDirectory: 'import',
67
+ baseFileName: 'cars',
68
+ },
69
+ ftpConfig: {
70
+ DEFAULT_FTP_HOST: '185.15.211.90',
71
+ DEFAULT_FTP_PORT: '21',
72
+ DEFAULT_FTP_USER: 'jelastic-ftp',
73
+ DEFAULT_FTP_PASS: '7D413EB6L6',
74
+ },
75
+ };
76
+
77
+ switch (job.params.environment) {
78
+ case 'develop':
79
+ ConfigBuilder.defaultConfig = developConfig;
80
+ return developConfig;
81
+ case 'stage':
82
+ ConfigBuilder.defaultConfig = stageConfig;
83
+ return stageConfig;
84
+ case 'production':
85
+ ConfigBuilder.defaultConfig = productionConfig;
86
+ return productionConfig;
87
+ default:
88
+ return null;
89
+ }
90
+ }
91
+ }
@@ -0,0 +1 @@
1
+ export * from './ConfigBuilder';
package/src/index.ts ADDED
@@ -0,0 +1,62 @@
1
+ import 'reflect-metadata';
2
+ import { Interfaces as ChunkableInterfaces, FTP as ChunkableFtp, AbstractChunkable } from '@bytebrand/chunkable';
3
+ import { ConfigBuilder } from './config';
4
+ import { getLoader } from './modules/car-loader/index';
5
+ import { getArhiver } from './modules/acrhiver';
6
+ import { getExporter } from './modules/car-exporter';
7
+ import { getEventEmitter } from '@bytebrand/chunkable/dist/ftp';
8
+
9
+ const rl = require('readline').createInterface({ input: process.stdin });
10
+
11
+ rl.on('line', async (line: string) => {
12
+ try {
13
+ const job: ChunkableInterfaces.CronicleJobInterface = {
14
+ id: 'sdsdsd',
15
+ params: {
16
+ apikey: 'AIzaSyD57yo222EMQjyHQKCDsLILrHh3AzOGtmU',
17
+ environment: 'production',
18
+ // apikey: 'AIzaSyC-jmLAkt2pVO0t-beLIuZJwR4jiGpzYyU',
19
+ // environment: 'develop',
20
+ limit: 1000,
21
+ },
22
+ };
23
+ // const job: ChunkableInterfaces.CronicleJobInterface = JSON.parse(line);
24
+
25
+ process.stdout.write(`Running job: ${job.id}: ${JSON.stringify(job)}\n`);
26
+
27
+ const config: ChunkableInterfaces.ConfigInterface = ConfigBuilder.mkConfig(job);
28
+
29
+ ChunkableFtp.initFTPConnections(config.ftpConfig, 'general').then(async () => {
30
+ const loader: AbstractChunkable = getLoader(config);
31
+ const archiver: AbstractChunkable = getArhiver(config);
32
+ const exporter: AbstractChunkable = getExporter(
33
+ Object.assign(config, { eventEmitter: getEventEmitter('general') }),
34
+ );
35
+
36
+ loader.onFinish((chunks: ChunkableInterfaces.ChunkInterface[]) => {
37
+ process.stdout.write(`${JSON.stringify({ progress: 0.33 })}\n`);
38
+ return archiver.start(chunks);
39
+ });
40
+ archiver.onFinish((chunks: ChunkableInterfaces.ChunkInterface[]) => {
41
+ loader.clear();
42
+ process.stdout.write(`${JSON.stringify({ progress: 0.66 })}\n`);
43
+ return exporter.start(chunks);
44
+ });
45
+ loader.start();
46
+
47
+ exporter.onChunk((chunk) => {
48
+ archiver.clear();
49
+ process.stdout.write(`${JSON.stringify({ progress: 1 })}\n`);
50
+
51
+ process.stdout.write(`${JSON.stringify({ complete: 1, code: 0 })}\n`);
52
+ process.exit();
53
+ // rl.close();
54
+ return Promise.resolve(true);
55
+ });
56
+ });
57
+ // rl.close();
58
+ } catch (e) {
59
+ // rl.close();
60
+ process.stderr.write(`${JSON.stringify({ complete: 1, code: 1, description: e.message })}\n`);
61
+ }
62
+ });
File without changes
@@ -0,0 +1,32 @@
1
+ import { AbstractChunkable, Interfaces } from '@bytebrand/chunkable';
2
+ import * as tar from 'tar';
3
+ import moment from 'moment';
4
+ import fs from 'fs';
5
+
6
+ export class TarArchiver extends AbstractChunkable {
7
+ doChunk(chunk?: Interfaces.ChunkInterface): Promise<boolean> {
8
+ throw new Error('This converter works with full data use doStart');
9
+ }
10
+
11
+ async clear() {
12
+ for (const chunk of this.chunks) {
13
+ fs.unlinkSync(this.getChunkPath(chunk));
14
+ }
15
+ }
16
+
17
+ doStart(chunks?: Interfaces.ChunkInterface[]) {
18
+ const archiveChunk = this.createChunk(moment().format('DD_MM_YY'), 'tgz');
19
+ archiveChunk.currentLocation = this.pathesConfig.localDirectory;
20
+ const options: tar.FileOptions & tar.CreateOptions = {
21
+ gzip: true,
22
+ file: this.getChunkPath(archiveChunk),
23
+ cwd: this.pathesConfig.localDirectory,
24
+ };
25
+ const files = chunks.map((chunk) => this.getChunkFileName(chunk));
26
+
27
+ return (tar.create(options, files) as any).then(() => {
28
+ this.chunks.push(archiveChunk);
29
+ return this.onFinishCallback([ archiveChunk ]);
30
+ });
31
+ }
32
+ }
@@ -0,0 +1,6 @@
1
+ import { TarArchiver } from './TarArchiver';
2
+ import { AbstractChunkable, ConfigInterface, ChunkableFactoryInterface } from '@bytebrand/chunkable';
3
+
4
+ export const getArhiver: ChunkableFactoryInterface = (config: ConfigInterface) => {
5
+ return (new TarArchiver({ pathesConfig: config.pathes, limit: config.chunk_limit }) as AbstractChunkable);
6
+ };
@@ -0,0 +1,11 @@
1
+ import { Exporters, ConfigInterface, ChunkableFactoryInterface, FTP } from '@bytebrand/chunkable';
2
+ import { EventEmitter } from '@bytebrand/event-emitter';
3
+
4
+ export const getExporter: ChunkableFactoryInterface = (
5
+ config: ConfigInterface & { eventEmitter: EventEmitter<any> },
6
+ ) => {
7
+ return new Exporters.FtpCarsJsonExporter(config.eventEmitter, {
8
+ pathesConfig: config.pathes,
9
+ limit: config.chunk_limit,
10
+ });
11
+ };
@@ -0,0 +1,10 @@
1
+ import { Loaders, ConfigInterface, ChunkableFactoryInterface, FTP } from '@bytebrand/chunkable';
2
+
3
+ export const getLoader: ChunkableFactoryInterface = (config: ConfigInterface) => {
4
+ return new Loaders.CarBasicDataCarsLoader({
5
+ pathesConfig: config.pathes,
6
+ limit: config.chunk_limit,
7
+ cbdUrl: config.projectRelatedParameters.cbdUrl,
8
+ apikey: config.projectRelatedParameters.apikey,
9
+ });
10
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "compilerOptions": {
3
+ "paths": { "*": ["types/*"] },
4
+ "types": [
5
+ "node"
6
+ ],
7
+ "typeRoots": [
8
+ "./node_modules/@types",
9
+ "./types"
10
+ ],
11
+ "module": "commonjs",
12
+ "esModuleInterop": true,
13
+ "target": "ES2016",
14
+ "noImplicitAny": true,
15
+ "moduleResolution": "node",
16
+ "allowSyntheticDefaultImports": true,
17
+ "experimentalDecorators": true,
18
+ "emitDecoratorMetadata": true,
19
+ "sourceMap": true,
20
+ "outDir": "dist",
21
+ "rootDir": "src",
22
+ "baseUrl": ".",
23
+ "allowJs": false
24
+ },
25
+ "include": [
26
+ "src/**/*", "types/basic-ftp.d.ts"
27
+ ],
28
+ "exclude": [
29
+ "dist",
30
+ "doc",
31
+ "node_modules",
32
+ "index.js"
33
+ ]
34
+ }
package/tslint.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "extends": [
3
+ "tslint-config-airbnb",
4
+ "tslint-eslint-rules"
5
+ ],
6
+ "rules": {
7
+ "class-name": true,
8
+ "comment-format": [true, "check-space"],
9
+ "indent": [true, "spaces"],
10
+ "one-line": [true, "check-open-brace", "check-whitespace"],
11
+ "no-var-keyword": true,
12
+ "semicolon": [true, "always"],
13
+ "variable-name": false,
14
+ "whitespace": [
15
+ true,
16
+ "check-branch",
17
+ "check-decl",
18
+ "check-operator",
19
+ "check-module",
20
+ "check-separator",
21
+ "check-type"
22
+ ],
23
+ "max-line-length": [true, 185],
24
+ "ter-indent": [true, 2, { "SwitchCase": 1 }],
25
+ "import-name": false,
26
+ "typedef-whitespace": [
27
+ true,
28
+ {
29
+ "call-signature": "nospace",
30
+ "index-signature": "nospace",
31
+ "parameter": "nospace",
32
+ "property-declaration": "nospace",
33
+ "variable-declaration": "nospace"
34
+ },
35
+ {
36
+ "call-signature": "onespace",
37
+ "index-signature": "onespace",
38
+ "parameter": "onespace",
39
+ "property-declaration": "onespace",
40
+ "variable-declaration": "onespace"
41
+ }
42
+ ],
43
+ "ter-arrow-parens": true,
44
+ "array-bracket-spacing": true,
45
+ "no-internal-module": true,
46
+ "no-trailing-whitespace": false,
47
+ "no-null-keyword": false,
48
+ "prefer-const": true,
49
+ "jsdoc-format": true
50
+ }
51
+ }
@@ -0,0 +1,72 @@
1
+ export class Client {
2
+ constructor(timeout?: number);
3
+ ftp: any;
4
+ prepareTransfer: any;
5
+ parseList: any;
6
+ busy: boolean;
7
+ access(options: any): any;
8
+ cd(path: any): any;
9
+ clearWorkingDir(): void;
10
+ close(): void;
11
+ connect(host: any, port: any): any;
12
+ download(writableStream: any, remoteFilename: any, startAt?: any): Promise<any>;
13
+ downloadDir(localDirPath: any): Promise<any>;
14
+ ensureDir(remoteDirPath: any): Promise<any>;
15
+ features(): any;
16
+ lastMod(filename: any): any;
17
+ list(): Promise<any>;
18
+ login(user: any, password: any): Promise<any>;
19
+ pwd(): Promise<any>;
20
+ remove(filename: any, ignoreErrorCodes: any): Promise<any>;
21
+ removeDir(remoteDirPath: any): Promise<any>;
22
+ rename(path: any, newPath: any): Promise<any>;
23
+ send(command: any, ignoreErrorCodes: any): any;
24
+ size(filename: any): any;
25
+ trackProgress(handler: any): void;
26
+ upload(readableStream: any, remoteFilename: any): any;
27
+ uploadDir(localDirPath: any, remoteDirName: any): void;
28
+ useDefaultSettings(): void;
29
+ useTLS(options: any, command: any): any;
30
+ get(...args: any[]): Promise<any>;
31
+ }
32
+ export class FTPContext {
33
+ constructor(timeout: any, encoding: any);
34
+ encoding: any;
35
+ tlsOptions: any;
36
+ ipFamily: any;
37
+ verbose: any;
38
+ socket: any;
39
+ dataSocket: any;
40
+ close(): void;
41
+ enableControlTimeout(enabled: any): void;
42
+ handle(command: any, handler: any): any;
43
+ log(message: any): void;
44
+ send(command: any): void;
45
+ }
46
+ export class FileInfo {
47
+ static Permission: any;
48
+ static Type: any;
49
+ constructor(name: any);
50
+ name: any;
51
+ type: any;
52
+ size: any;
53
+ hardLinkCount: any;
54
+ permissions: any;
55
+ link: any;
56
+ group: any;
57
+ user: any;
58
+ date: any;
59
+ }
60
+ export namespace utils {
61
+ class TransferResolver {
62
+ constructor(ftp: any);
63
+ ftp: any;
64
+ result: any;
65
+ confirmed: any;
66
+ confirm(task: any): void;
67
+ reject(task: any, reason: any): void;
68
+ resolve(task: any, result: any): void;
69
+ }
70
+ function parseIPv4PasvResponse(message: any): any;
71
+ function upgradeSocket(socket: any, options: any): any;
72
+ }