mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-21 09:38:01 +02:00
78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
import Logger from '@joplin/utils/Logger';
|
|
import shim from './shim';
|
|
|
|
const logger = Logger.create('geolocation-node');
|
|
|
|
interface CurrentPositionResponseCoordinates {
|
|
longitude: number;
|
|
latitude: number;
|
|
altitude: number;
|
|
}
|
|
|
|
interface CurrentPositionResponse {
|
|
timestamp: number;
|
|
coords: CurrentPositionResponseCoordinates;
|
|
}
|
|
|
|
interface CurrentPositionOptions {}
|
|
|
|
type GeoipService = ()=> Promise<CurrentPositionResponse>;
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
|
const fetchJson = async (url: string): Promise<any> => {
|
|
let r = await shim.fetch(url);
|
|
if (!r.ok) throw new Error(`Could not get geolocation: ${await r.text()}`);
|
|
r = await r.json();
|
|
return r;
|
|
};
|
|
|
|
const geoipServices: Record<string, GeoipService> = {
|
|
|
|
ipwhois: async (): Promise<CurrentPositionResponse> => {
|
|
const r = await fetchJson('https://ipwho.is/');
|
|
if (!('latitude' in r) || !('longitude' in r)) throw new Error(`Invalid geolocation response: ${r ? JSON.stringify(r) : '<null>'}`);
|
|
|
|
return {
|
|
timestamp: Date.now(),
|
|
coords: {
|
|
longitude: r.longitude,
|
|
altitude: 0,
|
|
latitude: r.latitude,
|
|
},
|
|
};
|
|
},
|
|
|
|
geoplugin: async (): Promise<CurrentPositionResponse> => {
|
|
const r = await fetchJson('http://www.geoplugin.net/json.gp');
|
|
if (!('geoplugin_latitude' in r) || !('geoplugin_longitude' in r)) throw new Error(`Invalid geolocation response: ${r ? JSON.stringify(r) : '<null>'}`);
|
|
|
|
return {
|
|
timestamp: Date.now(),
|
|
coords: {
|
|
longitude: Number(r.geoplugin_longitude),
|
|
altitude: 0,
|
|
latitude: Number(r.geoplugin_latitude),
|
|
},
|
|
};
|
|
},
|
|
|
|
};
|
|
|
|
export default class {
|
|
public static async currentPosition(options: CurrentPositionOptions = null) {
|
|
if (!options) options = {};
|
|
|
|
for (const [serviceName, handler] of Object.entries(geoipServices)) {
|
|
try {
|
|
const response = await handler();
|
|
return response;
|
|
} catch (error) {
|
|
logger.warn(`Could not get geolocation from service "${serviceName}"`);
|
|
logger.warn(error);
|
|
}
|
|
}
|
|
|
|
throw new Error('Could not get geolocation from any of the services');
|
|
}
|
|
}
|