PublicIP: support JSON config

This commit is contained in:
李通洲
2023-06-08 09:41:22 +08:00
committed by 李通洲
parent a4a801d83a
commit 7f9ff587ce
12 changed files with 182 additions and 89 deletions
+14
View File
@@ -0,0 +1,14 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
typedef struct FFPublicIpOptions
{
const char* moduleName;
FFModuleArgs moduleArgs;
FFstrbuf url;
uint32_t timeout;
} FFPublicIpOptions;
+137
View File
@@ -0,0 +1,137 @@
#include "fastfetch.h"
#include "common/printing.h"
#include "common/networking.h"
#include "modules/publicip/publicip.h"
#define FF_PUBLICIP_DISPLAY_NAME "Public IP"
#define FF_PUBLICIP_NUM_FORMAT_ARGS 1
static FFNetworkingState state;
static int status = -1;
void ffPreparePublicIp(FFPublicIpOptions* options)
{
if (options->url.length == 0)
status = ffNetworkingSendHttpRequest(&state, "ipinfo.io", "/ip", NULL);
else
{
FF_STRBUF_AUTO_DESTROY host = ffStrbufCreateCopy(&options->url);
ffStrbufSubstrAfterFirstS(&host, "://");
uint32_t pathStartIndex = ffStrbufFirstIndexC(&host, '/');
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
if(pathStartIndex != host.length)
{
ffStrbufAppendNS(&path, pathStartIndex, host.chars + (host.length - pathStartIndex));
host.length = pathStartIndex;
host.chars[pathStartIndex] = '\0';
}
status = ffNetworkingSendHttpRequest(&state, host.chars, path.length == 0 ? "/" : path.chars, NULL);
}
}
void ffPrintPublicIp(FFinstance* instance, FFPublicIpOptions* options)
{
if (status == -1)
ffPreparePublicIp(options);
if (status == 0)
{
ffPrintError(instance, FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs, "Failed to connect to an IP detection server");
return;
}
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(4096);
bool success = ffNetworkingRecvHttpResponse(&state, &result, options->timeout);
if (success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n");
if (!success || result.length == 0)
{
ffPrintError(instance, FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs, "Failed to receive the server response");
return;
}
if (options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(instance, FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs.key);
ffStrbufPutTo(&result, stdout);
}
else
{
ffPrintFormat(instance, FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs, FF_PUBLICIP_NUM_FORMAT_ARGS, (FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &result}
});
}
}
void ffInitPublicIpOptions(FFPublicIpOptions* options)
{
options->moduleName = FF_PUBLICIP_MODULE_NAME;
ffOptionInitModuleArg(&options->moduleArgs);
ffStrbufInit(&options->url);
options->timeout = 0;
}
bool ffParsePublicIpCommandOptions(FFPublicIpOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_PUBLICIP_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
if (strcasecmp(subKey, "url") == 0)
{
ffOptionParseString(key, value, &options->url);
return true;
}
if (strcasecmp(subKey, "timeout") == 0)
{
options->timeout = ffOptionParseUInt32(key, value);
return true;
}
return false;
}
void ffDestroyPublicIpOptions(FFPublicIpOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
ffStrbufDestroy(&options->url);
}
#ifdef FF_HAVE_JSONC
void ffParsePublicIpJsonObject(FFinstance* instance, json_object* module)
{
FFPublicIpOptions __attribute__((__cleanup__(ffDestroyPublicIpOptions))) options;
ffInitPublicIpOptions(&options);
if (module)
{
json_object_object_foreach(module, key, val)
{
if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs))
continue;
if (strcasecmp(key, "url") == 0)
{
ffStrbufSetS(&options.url, json_object_get_string(val));
continue;
}
if (strcasecmp(key, "timeout") == 0)
{
options.timeout = (uint32_t) json_object_get_int(val);
continue;
}
ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key);
}
}
ffPrintPublicIp(instance, &options);
}
#endif
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include "fastfetch.h"
#define FF_PUBLICIP_MODULE_NAME "PublicIp"
void ffPreparePublicIp(FFPublicIpOptions* options);
void ffPrintPublicIp(FFinstance* instance, FFPublicIpOptions* options);
void ffInitPublicIpOptions(FFPublicIpOptions* options);
bool ffParsePublicIpCommandOptions(FFPublicIpOptions* options, const char* key, const char* value);
void ffDestroyPublicIpOptions(FFPublicIpOptions* options);
#ifdef FF_HAVE_JSONC
#include "common/jsonconfig.h"
void ffParsePublicIpJsonObject(FFinstance* instance, json_object* module);
#endif