Ver código fonte

dev: add WeatherService

- adds weather service
- updates IdentificationService to add ip_user property
KernelDeimos 2 semanas atrás
pai
commit
ea241540b9

+ 4 - 0
src/backend/src/modules/external-extras/ExternalExtrasModule.js

@@ -13,6 +13,10 @@ class ExternalExtrasModule extends AdvancedBase {
             const { NewsDataService } = require('./NewsDataService');
             services.registerService('newsdata', NewsDataService);
         }
+        if ( !! config?.services?.weather ) {
+            const { WeatherService } = require('./WeatherService');
+            services.registerService('weather', WeatherService);
+        }
     }
 }
 

+ 92 - 0
src/backend/src/modules/external-extras/WeatherService.js

@@ -0,0 +1,92 @@
+const BaseService = require('../../services/BaseService');
+const { Context } = require('../../util/context');
+
+class WeatherService extends BaseService {
+    async ['__on_driver.register.interfaces'] () {
+        const svc_registry = this.services.get('registry');
+        const col_interfaces = svc_registry.get('interfaces');
+        
+        const common = {
+            default_parameter: 'q',
+            parameters: {
+                '*': {
+                    type: 'json',
+                },
+            },
+            result: {
+                type: 'json'
+            },
+        };
+        
+        col_interfaces.set('weather', {
+            description: 'weatherapi.com',
+            methods: {
+                weather: {
+                    description: 'Report current weather in the specified location',
+                    ...common,
+                },
+                forecast: {
+                    description: 'Report the weather forecast for the specified location',
+                    ...common,
+                },
+            }
+        });
+    }
+    async _init () {
+        this.baseURL = 'https://api.weatherapi.com/v1';
+    }
+    static IMPLEMENTS = {
+        weather: {
+            // We call this "weather" instead of "current" so that it can be
+            // the default method for the weather driver.
+            async weather (parameters) {
+                return await this.general('current.json', parameters);
+            },
+            async forecast (parameters) {
+                // Okay this is kinda dumb but the default behavior for forecast
+                // is that it forecasts 1 day - the current day. I'm going to make
+                // the default 5 days here because I think that's what most people
+                // will expect.
+                
+                if ( parameters.days === undefined ) {
+                    parameters.days = 5;
+                }
+                
+                return await this.general('forecast.json', parameters);
+            }
+        }
+    }
+
+    async general (component, parameters) {
+        const require = this.require;
+
+        const axios = require('axios');
+        const querystring = require('querystring');
+        
+        if ( ! parameters.q ) {
+            const requester = Context.get('requester');
+            parameters.q = requester.ip_user ??
+                '-77.6776746,165.2019492'; // McMurdo Station, Antarctica
+        }
+        
+        const qstr = querystring.stringify({
+            ...parameters,
+            key: this.config.apiKey,
+        });
+        
+        const req_options = {
+            method: 'GET',
+            url: this.baseURL + `/${component}?` + qstr,
+        };
+        
+        console.log('debug the request', req_options);
+
+        const resp = await axios.request(req_options);
+        
+        return resp.data;
+    }
+}
+
+module.exports = {
+    WeatherService,
+};

+ 2 - 0
src/backend/src/services/abuse-prevention/IdentificationService.js

@@ -57,6 +57,8 @@ class Requester {
             ua: req.headers['user-agent'],
             ip: req.connection.remoteAddress,
             ip_forwarded: req.headers['x-forwarded-for'],
+            ip_user: req.headers['x-forwarded-for'] ||
+                req.connection.remoteAddress,
             origin: req.headers['origin'],
             referer: req.headers['referer'],
             referer_origin,