<commit_before>#include <algorithm>
#include <cstring>
#include <cpr/cpr.h>
#include <utils.h>
#include "command.h"
#include "../CommandHandler.h"
#include "../OptionParser.h"

/* full name of the command */
CMDNAME("ge");
/* description of the command */
CMDDESCR("look up item prices");
/* command usage synopsis */
CMDUSAGE("$ge [-n AMT] ITEM");

static const std::string EXCHANGE_API =
	"https://api.rsbuddy.com/grandExchange?a=guidePrice&i=";

static bool getamt(char *num, int64_t *amt);
static int64_t extract_price(const std::string &resp);

/* ge: look up item prices */
std::string CommandHandler::ge(struct cmdinfo *c)
{
	if (!m_GEReader.active())
		return CMDNAME + ": GE reader is inactive";

	std::string output, name;
	int64_t amt, price;
	cpr::Response resp;
	Json::Value item;

	int opt;
	OptionParser op(c->fullCmd, "n:");
	static struct OptionParser::option long_opts[] = {
		{ "amount", REQ_ARG, 'n' },
		{ "help", NO_ARG, 'h' },
		{ 0, 0, 0 }
	};

	amt = 1;
	while ((opt = op.getopt_long(long_opts)) != EOF) {
		switch (opt) {
		case 'h':
			return HELPMSG(CMDNAME, CMDUSAGE, CMDDESCR);
		case 'n':
			if (!getamt(op.optarg(), &amt))
				return CMDNAME + ": invalid number -- '"
					+ std::string(op.optarg()) + "'";
			break;
		case '?':
			return std::string(op.opterr());
		default:
			return "";
		}
	}

	if (op.optind() == c->fullCmd.length())
		return USAGEMSG(CMDNAME, CMDUSAGE);

	name = c->fullCmd.substr(op.optind());
	std::replace(name.begin(), name.end(), '_', ' ');

	/* find item in database */
	if ((item = m_GEReader.getItem(name)).empty())
		return CMDNAME + ": item not found: " + name;

	/* read ge api and extract data */
	resp = cpr::Get(cpr::Url(EXCHANGE_API + item["id"].asString()),
		cpr::Header{{ "Connection", "close" }});
	if ((price = extract_price(resp.text)) == -1)
		return CMDNAME + ": could not extract price";

	output = "[GE] ";
	if (amt != 1)
		output += utils::formatInteger(std::to_string(amt)) + "x ";
	output += item["name"].asString() + ": ";
	output += utils::formatInteger(std::to_string(amt * price)) + " gp";

	return output;
}

/* getamt: read number from string num into amt */
static bool getamt(char *num, int64_t *amt)
{
	int n, last, mult;
<commit_msg>Size fix<commit_after>#include <algorithm>
#include <cstring>
#include <cpr/cpr.h>
#include <utils.h>
#include "command.h"
#include "../CommandHandler.h"
#include "../OptionParser.h"

/* full name of the command */
CMDNAME("ge");
/* description of the command */
CMDDESCR("look up item prices");
/* command usage synopsis */
CMDUSAGE("$ge [-n AMT] ITEM");

static const std::string EXCHANGE_API =
	"https://api.rsbuddy.com/grandExchange?a=guidePrice&i=";

static bool getamt(char *num, int64_t *amt);
static int64_t extract_price(const std::string &resp);

/* ge: look up item prices */
std::string CommandHandler::ge(struct cmdinfo *c)
{
	if (!m_GEReader.active())
		return CMDNAME + ": GE reader is inactive";

	std::string output, name;
	int64_t amt, price;
	cpr::Response resp;
	Json::Value item;

	int opt;
	OptionParser op(c->fullCmd, "n:");
	static struct OptionParser::option long_opts[] = {
		{ "amount", REQ_ARG, 'n' },
		{ "help", NO_ARG, 'h' },
		{ 0, 0, 0 }
	};

	amt = 1;
	while ((opt = op.getopt_long(long_opts)) != EOF) {
		switch (opt) {
		case 'h':
			return HELPMSG(CMDNAME, CMDUSAGE, CMDDESCR);
		case 'n':
			if (!getamt(op.optarg(), &amt))
				return CMDNAME + ": invalid number -- '"
					+ std::string(op.optarg()) + "'";
			break;
		case '?':
			return std::string(op.opterr());
		default:
			return "";
		}
	}

	if (op.optind() == c->fullCmd.length())
		return USAGEMSG(CMDNAME, CMDUSAGE);

	name = c->fullCmd.substr(op.optind());
	std::replace(name.begin(), name.end(), '_', ' ');

	/* find item in database */
	if ((item = m_GEReader.getItem(name)).empty())
		return CMDNAME + ": item not found: " + name;

	/* read ge api and extract data */
	resp = cpr::Get(cpr::Url(EXCHANGE_API + item["id"].asString()),
		cpr::Header{{ "Connection", "close" }});
	if ((price = extract_price(resp.text)) == -1)
		return CMDNAME + ": could not extract price";

	output = "[GE] ";
	if (amt != 1)
		output += utils::formatInteger(std::to_string(amt)) + "x ";
	output += item["name"].asString() + ": ";
	output += utils::formatInteger(std::to_string(amt * price)) + " gp";

	return output;
}

/* getamt: read number from string num into amt */
static bool getamt(char *num, int64_t *amt)
{
	size_t last;
	int64_t n, mult;

{'fraction_non_alphanumeric': 0.19376541825521418, 'fraction_numerical': 0.006727965911639381, 'mean_word_length': 4.162037037037037, 'pattern_counts': {'":': 10, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5954118', 'n_tokens_mistral': 1755, 'n_tokens_neox': 1665, 'n_words': 412}