-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
executable file
·140 lines (120 loc) · 3.63 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* eslint-disable no-console */
const fs = require('fs');
const { performance } = require('perf_hooks');
const axios = require('axios');
const path = require('path');
const prompts = require('prompts');
// eslint-disable-next-line prefer-destructuring
const Spinner = require('cli-spinner').Spinner;
const gm = require('gm').subClass({ imageMagick: true });
let saveDir;
async function checkImageSize(localPath) {
return new Promise((resolve, reject) => {
gm(localPath)
.size((err, size) => {
if (err) {
return reject(err);
}
if (size.width < 1800 || size.height < 1200) {
fs.unlinkSync(localPath);
}
return resolve(true);
});
});
}
function getExtension(fileName) {
const basename = fileName.split(/[\\/]/).pop();
const pos = basename.lastIndexOf('.');
if (basename === '' || pos < 1) { return ''; }
return basename.slice(pos + 1);
}
async function downloadAndSaveImage(url, fileName) {
const extension = getExtension(url);
const localFilePath = path.resolve(__dirname, saveDir, `${fileName}.${extension}`);
const writer = fs.createWriteStream(localFilePath);
const response = await axios({
url,
method: 'GET',
responseType: 'stream',
});
response.data.pipe(writer);
return new Promise((resolve, reject) => {
writer.on('finish', resolve);
writer.on('error', reject);
})
.then(() => localFilePath);
}
async function getImageJSONDataFromGoogle(urlSlug) {
const { data: imageData } = await axios.get(`https://earthview.withgoogle.com/_api/${urlSlug}.json`);
return {
photoUrl: imageData.photoUrl,
nextSlug: imageData.nextSlug,
};
}
(async () => {
const promptsResponses = await prompts([{
type: 'text',
name: 'saveDir',
message: 'Where will images be saved? (./images)',
initial: 'images',
}, {
type: 'toggle',
name: 'verifyImageQuality',
message: 'Do you want to verify image size (min. 1800 * 1200) with imagemagick? (must be installed separately)',
initial: false,
active: 'yes',
inactive: 'no',
}]);
saveDir = promptsResponses.saveDir;
const { verifyImageQuality } = promptsResponses;
if (!fs.existsSync(saveDir)) {
fs.mkdirSync(saveDir);
}
const spinner = new Spinner({
text: 'Processing...',
stream: process.stderr,
onTick(msg) {
this.clearLine(this.stream);
this.stream.write(msg);
},
});
spinner.start();
const saveImagesPromises = [];
const imagesMap = {};
let imageName = 'queensland-australia-1908';
let i = 0;
const start = performance.now();
// eslint-disable-next-line no-constant-condition
while (true) {
let imageData;
i += 1;
try {
/* eslint-disable no-await-in-loop */
imageData = await getImageJSONDataFromGoogle(imageName);
} catch (e) {
console.log(e);
}
if (imagesMap[imageData.nextSlug]) break;
imagesMap[imageData.nextSlug] = imageData;
saveImagesPromises.push(
downloadAndSaveImage(imageData.photoUrl, imageName)
.then(async (localFilePath) => {
if (verifyImageQuality) {
await checkImageSize(localFilePath);
}
})
.catch((error) => {
console.log(error);
return Promise.resolve();
}),
);
imageName = imageData.nextSlug;
spinner.text = `Got ${i} images so far...`;
}
await Promise.all(saveImagesPromises);
const end = performance.now();
spinner.stop();
console.clear();
console.log(`Got ${i} total images. The folder '${saveDir}' now contains ${fs.readdirSync(saveDir).length} images.`);
console.log(`Time elapsed: ${Math.floor(end - start)} milliseconds.`);
})();