master ohmu/fastfetch-openbsd / src / detection / weather / weather.c
ohmu  ·  2026-10-15
 1#include "weather.h"
 2#include "common/networking.h"
 3
 4#define FF_UNITIALIZED ((const char*) (uintptr_t) -1)
 5static FFNetworkingState state;
 6static const char* status = FF_UNITIALIZED;
 7
 8void ffPrepareWeather(FFWeatherOptions* options) {
 9    if (status != FF_UNITIALIZED) {
10        fputs("Error: Weather module can only be used once due to internal limitations\n", stderr);
11        exit(1);
12    }
13
14    state.timeout = options->timeout;
15
16    FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/");
17    if (options->location.length) {
18        ffStrbufAppend(&path, &options->location);
19    }
20    ffStrbufAppendS(&path, "?format=");
21    ffStrbufAppend(&path, &options->outputFormat);
22    switch (instance.config.display.tempUnit) {
23        case FF_TEMPERATURE_UNIT_CELSIUS:
24            ffStrbufAppendS(&path, "&m");
25            break;
26        case FF_TEMPERATURE_UNIT_FAHRENHEIT:
27            ffStrbufAppendS(&path, "&u");
28            break;
29        default:
30            break;
31    }
32    status = ffNetworkingSendHttpRequest(&state, "wttr.in", 80, path.chars, "User-Agent: curl/0.0.0\r\n");
33}
34
35const char* ffDetectWeather(FFWeatherOptions* options, FFstrbuf* result) {
36    if (status == FF_UNITIALIZED) {
37        ffPrepareWeather(options);
38    }
39
40    if (status != nullptr) {
41        const char* error = status;
42        ffNetworkingResetState(&state);
43        status = FF_UNITIALIZED;
44        return error;
45    }
46
47    ffStrbufEnsureFree(result, 4095);
48    const char* error = ffNetworkingRecvHttpResponse(&state, result);
49
50    ffNetworkingResetState(&state);
51    status = FF_UNITIALIZED;
52
53    if (error == nullptr) {
54        ffStrbufSubstrAfterFirstS(result, "\r\n\r\n");
55        ffStrbufTrimRightSpace(result);
56    } else {
57        return error;
58    }
59
60    if (result->length == 0) {
61        return "Empty server response received";
62    }
63
64    return nullptr;
65}