142 lines
3.6 KiB
JavaScript
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,
|
|
};
|