mirror of
1
2
Fork 0
ucaptcha/src/helpers/fetchImagesJob.js

142 lines
3.6 KiB
JavaScript

import cron from 'cron';
import request from 'request';
import path from 'path';
import Jimp from 'jimp';
import fs from 'fs';
import db from './db/index.js';
import {IMAGES_FOLDER} from '../R.js';
import utils from '../helpers/utils.js';
const CronJob = cron.CronJob;
const initialMat = new Array(16).fill(0);
/**
* @typedef {object} currentPageItem
* @property {string} id
* @property {string} sequence_id
* @property {string} sequence_index
* @property {string} lat
* @property {string} ing
* @property {string} name
* @property {string} lth_name
* @property {string} th_name
* @property {string} date_added
* @property {string} timestamp
* @property {string|any} match_segment_id
* @property {string} match_lat
* @property {string} match_lng
* @property {string} way_id
* @property {string} shot_date
* @property {string} heading
* @property {string} headers
* @property {string} gps_accuracy
* @property {string} username
*/
/**
* @typedef {object} OSCResponse.status
* @property {string} apiCode
* @property {string} apiMessage
* @property {number} httpCode
* @property {string} httpMessage
*/
// * @param {import('../types/OSCResponse.js').status} status
/**
* @typedef {object} OSCResponse
* @property {OSCResponse.status} status
* @property {Array.<currentPageItem>} currentPageItems
* @property {Array.<string>} totalFilteredItems
*/
/**
* Save an image to disk
* @param {string} filepath
* @param {string} uri
*/
async function saveImage(filepath, uri) {
return new Promise((resolve, reject)=>{
Jimp.read(uri)
.then((image)=>{
let x;
if (image.getWidth() / 2 < 400) {
x = 0;
} else {
x = image.getWidth() / 2 - 200;
}
const y = image.getHeight() - 400;
image
.crop(x, y, 384, 384)
.write(filepath, (err)=>{
if (err) {
reject(err);
} else {
resolve();
}
});
});
});
}
/**
* @typedef {object} geoImageRequest
* @property {number} [lat]
* @property {number} [lng]
* @property {number} [radius]
*/
/** @type {geoImageRequest} geoImageRequestDefaults */
const geoImageRequestDefaults = {
lat: 40.624592,
lng: -81.785149,
radius: 5000,
};
/**
* fetch and saves image from nearby photos
* @param {geoImageRequest} [geoImageRequest] - Optional set a geoImageReqest
*/
export function fetchImages(geoImageRequest) {
// Only collect images if:
// a. In production
// b. There are not at least 20 files in `IMAGES_FOLDER`
if (process.env.NODE_ENV === 'development') {
const files = fs.readdirSync(IMAGES_FOLDER).length;
if (files > 20) {
console.log('In development, so fetchImages not run.');
return;
}
}
console.log('Collecting images...');
const formData = {
...geoImageRequestDefaults,
...geoImageRequest,
};
request('https://openstreetcam.org/1.0/list/nearby-photos/', {formData, method: 'POST'}, async (apiError, _, body) => {
if (apiError) throw apiError;
/** @type {OSCResponse} */
const json = JSON.parse(body);
for (const item of (json).currentPageItems) {
const filename = `${utils.randomBytes(12)}`;
const filepath = path.join(IMAGES_FOLDER, filename + '.jpg');
await saveImage(filepath, `https://openstreetcam.org/${item.lth_name}`);
await db.setMat({
file: filename,
mat: initialMat,
num: 0,
obj: [0],
});
}
});
}
export const fetchImagesJob = new CronJob('0 0 0 * * *', () => {
fetchImages(geoImageRequestDefaults);
}, null, true);
export default {
fetchImages,
fetchImagesJob,
};