Initial
This commit is contained in:
237
dm-cli/AccountStatus.cpp
Normal file
237
dm-cli/AccountStatus.cpp
Normal file
@@ -0,0 +1,237 @@
|
||||
#include "AccountStatus.hpp"
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include "PrintFile.hpp"
|
||||
#include "common.hpp"
|
||||
#include "ExecCommand.hpp"
|
||||
#include "json.hpp"
|
||||
#include "base64.h"
|
||||
#include "cleanHtml.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
void AccountHelp(bool isRussian)
|
||||
{
|
||||
if (isRussian)
|
||||
{
|
||||
PrintFile(ACCOUNT_STATUS_RU);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintFile(ACCOUNT_STATUS_EN);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Получение информации аккаунта
|
||||
/// @param address адресс АПИ
|
||||
/// @param bkaddress номер кошелька
|
||||
/// @param isDebug флаг отладки
|
||||
int AccountStatus(const std::string address, const char* bkaddress, bool isDebug)
|
||||
{
|
||||
// curl "https://testnet-dm.bitdeals.org/api/v1/account/status?address=mnumHs9HQMrw2Q1iKLNnx9NzExS7nMLmyp"
|
||||
string url("curl -s \"https://");
|
||||
url += address + "/api/v1/account/status?address=" + bkaddress + "\"";
|
||||
string result = ExecCommand(url.c_str());
|
||||
nlohmann::json jsonData = nlohmann::json::parse(result);
|
||||
|
||||
string payload("");
|
||||
payload = jsonData["payload"];
|
||||
bool success = jsonData["result"]["success"];
|
||||
|
||||
string decoded = base64_decode(payload);
|
||||
string cleaned = cleanup_html(decoded);
|
||||
cout << cleaned << endl;
|
||||
if (isDebug) ShowDebug(url, result, success, decoded);
|
||||
if (success) return 0; else return 1;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Получение информации аккаунта
|
||||
/// @param address адресс АПИ
|
||||
/// @param bkaddress номер кошелька
|
||||
/// @param isDebug флаг отладки
|
||||
int AccountInfo(const std::string address, const char* bkaddress, bool isDebug) {
|
||||
|
||||
// curl -H "Content-Type: application/json" -d "{ \"code\": \"mnumHs9HQMrw2Q1iKLNnx9NzExS7nMLmyp\"}" https://testnet-dm2.bitdeals.org/api/v1/user/profile
|
||||
string url("curl -s ");
|
||||
url.append("-H \"Content-Type: application/json\" ");
|
||||
url.append("-d \"{ \\\"code\\\": \\\"");
|
||||
url.append(bkaddress);
|
||||
url.append("\\\"} \" ");
|
||||
url.append(address);
|
||||
url.append("/api/v1/user/profile");
|
||||
|
||||
string result = ExecCommand(url.c_str());
|
||||
nlohmann::json jsonData = nlohmann::json::parse(result);
|
||||
|
||||
|
||||
string bitcoin("");
|
||||
string btckey("");
|
||||
string bitmessage("");
|
||||
string pgpkey("");
|
||||
|
||||
bitcoin = bkaddress;
|
||||
btckey = jsonData["btckey"];
|
||||
bitmessage = jsonData["bitmessages"][0];
|
||||
pgpkey = jsonData["pgpkey"];
|
||||
|
||||
|
||||
|
||||
|
||||
string decoded("");
|
||||
decoded.append("bitcoin: ");
|
||||
decoded.append(bitcoin);
|
||||
decoded.append("\n");
|
||||
|
||||
decoded.append("btckey: ");
|
||||
decoded.append(btckey);
|
||||
decoded.append("\n");
|
||||
|
||||
|
||||
decoded.append("bitmessage: ");
|
||||
decoded.append(bitmessage);
|
||||
decoded.append("\n");
|
||||
|
||||
|
||||
decoded.append("pgpkey: ");
|
||||
decoded.append(pgpkey);
|
||||
decoded.append("\n");
|
||||
|
||||
cout << decoded << endl;
|
||||
|
||||
if (isDebug) ShowDebug(url, result, 1, decoded);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @brief Получение Рейтинга аккаунта
|
||||
/// @param address адресс АПИ
|
||||
/// @param bkaddress номер кошелька
|
||||
/// @param isDebug флаг отладки
|
||||
int AccountRaiting(const std::string address, const char* bkaddress, bool isDebug) {
|
||||
// curl -H "Content-Type: application/json" -d "{ \"code\": \"mnumHs9HQMrw2Q1iKLNnx9NzExS7nMLmyp\"}" https://testnet-dm2.bitdeals.org/api/v1/user/profile
|
||||
string url("curl -s ");
|
||||
url.append("-H \"Content-Type: application/json\" ");
|
||||
url.append("-d \"{ \\\"code\\\": \\\"");
|
||||
url.append(bkaddress);
|
||||
url.append("\\\"} \" ");
|
||||
url.append(address);
|
||||
url.append("/api/v1/user/profile");
|
||||
|
||||
string result = ExecCommand(url.c_str());
|
||||
nlohmann::json jsonData = nlohmann::json::parse(result);
|
||||
|
||||
|
||||
|
||||
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << "created: " << jsonData["created"] << endl;
|
||||
stream << "seller: " << endl;
|
||||
stream << " count: " << jsonData["seller"]["count"] << endl;
|
||||
stream << " positive: " << jsonData["seller"]["positive"] << endl;
|
||||
|
||||
|
||||
stream << "customer: " << endl;
|
||||
stream << " count: " << jsonData["customer"]["count"] << endl;
|
||||
stream << " positive: " << jsonData["customer"]["positive"] << endl;
|
||||
|
||||
string decoded = stream.str();
|
||||
cout << decoded << endl;
|
||||
|
||||
if (isDebug) ShowDebug(url, result, 1, decoded);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Получение Рейтинга аккаунта
|
||||
/// @param address адресс АПИ
|
||||
/// @param bkaddress номер кошелька
|
||||
/// @param isDebug флаг отладки
|
||||
/// @param fb - тип фидбэка 0- все p - 1(positive) n-2 (negative)
|
||||
int AccountFeedbacks(const std::string address, const char* bkaddress, bool isDebug, int fb) {
|
||||
|
||||
/*
|
||||
curl -X POST "https://testnet-dm2.bitdeals.org/api/v1/deal/feedback/list" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"search":[{"field":"sellercode","compare":"EQL","value":"mraXx7JrmAmuKypdJ1vseQBXySsdRZE5AC"}],"orderby":["date DESC"],"reclimit":1000,"recoffset":0}'
|
||||
|
||||
|
||||
*/
|
||||
string url("curl -s ");
|
||||
url.append("-H \"Content-Type: application/json\" ");
|
||||
|
||||
url.append("-d \"{ \\\"search\\\":[{\\\"field\\\":\\\"sellercode\\\",\\\"compare\\\": \\\"EQL\\\",\\\"value\\\":\\\"");
|
||||
url.append(bkaddress);
|
||||
url.append("\\\"}],\\\"orderby\\\":[\\\" date DESC\\\"],\\\"reclimit\\\":100,\\\"recoffset\\\":0} \" ");
|
||||
|
||||
|
||||
url.append(address);
|
||||
url.append("/api/v1/deal/feedback/list");
|
||||
|
||||
string result = ExecCommand(url.c_str());
|
||||
nlohmann::json jsonData = nlohmann::json::parse(result);
|
||||
|
||||
std::ostringstream stream;
|
||||
size_t size = jsonData.size();
|
||||
int positivefb = 0;
|
||||
int negativefb = 0;
|
||||
|
||||
for (size_t i = 0;i < size;++i) {
|
||||
// "positive"
|
||||
// "negative"
|
||||
// 0 - все p - 1(positive)n - 2 (negative)
|
||||
|
||||
auto val = jsonData[i];
|
||||
string statustext = val["statustext"];
|
||||
|
||||
if (statustext.compare("positive") == 0) positivefb++;
|
||||
if (statustext.compare("negative") == 0) negativefb++;
|
||||
if (fb == 1 && statustext.compare("positive") == 0) {
|
||||
stream << "- deal: " << val["deal"] << endl;
|
||||
stream << " date: " << val["date"] << endl;
|
||||
stream << " statustext: " << val["statustext"] << endl;
|
||||
stream << " comments: " << val["comments"] << endl;
|
||||
}
|
||||
else if (fb == 2 && statustext.compare("negative") == 0) {
|
||||
stream << "- deal: " << val["deal"] << endl;
|
||||
stream << " date: " << val["date"] << endl;
|
||||
stream << " statustext: " << val["statustext"] << endl;
|
||||
stream << " comments: " << val["comments"] << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << "- deal: " << val["deal"] << endl;
|
||||
stream << " date: " << val["date"] << endl;
|
||||
stream << " statustext: " << val["statustext"] << endl;
|
||||
stream << " comments: " << val["comments"] << endl;
|
||||
}
|
||||
|
||||
/*
|
||||
- deal: ff5f337f-e0ab-4515-857f-3a0c8530dcd3
|
||||
date: '2025-10-05T15:29:23'
|
||||
statustext: positive
|
||||
comments: positive comment about the deal
|
||||
|
||||
*/
|
||||
}
|
||||
stream << "------------Summary--------------" << endl;
|
||||
stream << "total: " << size << endl;
|
||||
stream << "positive: " << positivefb << endl;
|
||||
stream << "neegative: " << negativefb << endl;
|
||||
|
||||
string decoded = stream.str();
|
||||
cout << decoded << endl;
|
||||
|
||||
if (isDebug) ShowDebug(url, result, 1, decoded);
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
33
dm-cli/AccountStatus.hpp
Normal file
33
dm-cli/AccountStatus.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef _ACCOUNT_STATUS_
|
||||
#define _ACCOUNT_STATUS_
|
||||
#include <string>
|
||||
/// @brief ПОлучение справки о параметрах команды
|
||||
/// @param isRussian - указывает выводить ли русскую справку
|
||||
void AccountHelp(bool isRussian);
|
||||
/// @brief Получение статуса аккаунта
|
||||
/// @param address адресс АПИ
|
||||
/// @param bkaddress номер кошелька
|
||||
/// @param isDebug флаг отладки
|
||||
int AccountStatus(const std::string address, const char *bkaddress, bool isDebug);
|
||||
|
||||
/// @brief Получение информации аккаунта
|
||||
/// @param address адресс АПИ
|
||||
/// @param bkaddress номер кошелька
|
||||
/// @param isDebug флаг отладки
|
||||
int AccountInfo(const std::string address, const char* bkaddress, bool isDebug);
|
||||
|
||||
/// @brief Получение Рейтинга аккаунта
|
||||
/// @param address адресс АПИ
|
||||
/// @param bkaddress номер кошелька
|
||||
/// @param isDebug флаг отладки
|
||||
int AccountRaiting(const std::string address, const char* bkaddress, bool isDebug);
|
||||
|
||||
|
||||
/// @brief Получение Рейтинга аккаунта
|
||||
/// @param address адресс АПИ
|
||||
/// @param bkaddress номер кошелька
|
||||
/// @param isDebug флаг отладки
|
||||
/// @param fb - тип фидбэка 0- все p - 1(positive) n-2 (negative)
|
||||
int AccountFeedbacks(const std::string address, const char* bkaddress, bool isDebug, int fb);
|
||||
|
||||
#endif
|
||||
299
dm-cli/AccountUpdate.cpp
Normal file
299
dm-cli/AccountUpdate.cpp
Normal file
@@ -0,0 +1,299 @@
|
||||
#include "AccountUpdate.hpp"
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include "PrintFile.hpp"
|
||||
#include "common.hpp"
|
||||
#include "ExecCommand.hpp"
|
||||
#include "json.hpp"
|
||||
#include "base64.h"
|
||||
#include <fstream>
|
||||
#include "cleanHtml.h"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int AccountUpdate::Help()
|
||||
{
|
||||
if (this->isRussian)
|
||||
PrintFile(ACCOUNT_UPDATE_RU);
|
||||
else
|
||||
PrintFile(ACCOUNT_UPDATE_EN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AccountUpdate::AccountUpdate(const InputParser &parser, const bool isRussian)
|
||||
{
|
||||
this->parser = parser;
|
||||
this->isRussian = isRussian;
|
||||
address = (DEFAULTADDRESS);
|
||||
const string &addressarg = parser.getCmdOption("--address");
|
||||
if (!addressarg.empty())
|
||||
{
|
||||
address = addressarg;
|
||||
}
|
||||
isDebug = false;
|
||||
if (parser.cmdOptionExists("--debug"))
|
||||
{
|
||||
isDebug = true;
|
||||
}
|
||||
}
|
||||
|
||||
int AccountUpdate::Process()
|
||||
{
|
||||
if (this->parser.cmdOptionExists("--help"))
|
||||
return this->Help();
|
||||
return Update();
|
||||
}
|
||||
int AccountUpdate::ProcessUrl(std::string date, std::string signature, std::string urls)
|
||||
{
|
||||
/*
|
||||
curl -X POST "https://testnet-dm2.bitdeals.org/api/v1/client/update" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"address":"mnumHs9HQMrw2Q1iKLNnx9NzExS7nMLmyp","date":"2025-10-21","url":["https://testnet-dm2.bitdeals.org"],
|
||||
"sign":"IAGHICUSCxUrcWTMSL9j94vRufb9l5nBckahT+RznlHMPx9LTPpDHsozxVyxkpjtgrhC8eCyJKNaOw8U/v56pL0="}'
|
||||
*/
|
||||
/*
|
||||
[{{URLS}}],
|
||||
*/
|
||||
std::stringstream test(urls);
|
||||
std::string segment;
|
||||
std::vector<std::string> seglist;
|
||||
string urlout("");
|
||||
while (std::getline(test, segment, ','))
|
||||
{
|
||||
urlout.append("\\\"");
|
||||
urlout.append(segment);
|
||||
urlout.append("\\\",");
|
||||
seglist.push_back(segment);
|
||||
}
|
||||
urlout = urlout.substr(0, urlout.length() - 1);
|
||||
string data("curl -s ");
|
||||
data += ReadFile(ACCOUNT_UPDATE_URL);
|
||||
string bt("");
|
||||
bt = parser.getLast();
|
||||
data = Replace(data, string("{{ADDRESS}}"), address);
|
||||
data = Replace(data, string("{{BT}}"), bt);
|
||||
data = Replace(data, string("{{DATE}}"), date);
|
||||
data = Replace(data, string("{{SIGN}}"), signature);
|
||||
data = Replace(data, string("{{URLS}}"), urlout);
|
||||
|
||||
string result = ExecCommand(data.c_str());
|
||||
nlohmann::json jsonData = nlohmann::json::parse(result);
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << "success: " << jsonData["result"]["success"] << endl;
|
||||
stream << "message: " << jsonData["result"]["message"] << endl;
|
||||
string decoded = stream.str();
|
||||
cout << decoded << endl;
|
||||
string payload = base64_decode(jsonData["payload"]);
|
||||
if (isDebug)
|
||||
ShowDebug(data, decoded, 1, payload);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AccountUpdate::ProcessPgp(std::string date, std::string signature, std::string pgp)
|
||||
{
|
||||
|
||||
string data("curl ");
|
||||
data += ReadFile(ACCOUNT_UPDATE_PGP);
|
||||
string bt("");
|
||||
bt = parser.getLast();
|
||||
data = Replace(data, string("{{ADDRESS}}"), address);
|
||||
data = Replace(data, string("{{BT}}"), bt);
|
||||
data = Replace(data, string("{{DATE}}"), date);
|
||||
data = Replace(data, string("{{SIGN}}"), signature);
|
||||
data = Replace(data, string("{{PGP}}"), pgp);
|
||||
|
||||
string result = ExecCommand(data.c_str());
|
||||
nlohmann::json jsonData = nlohmann::json::parse(result);
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << "success: " << jsonData["result"]["success"] << endl;
|
||||
stream << "message: " << jsonData["result"]["message"] << endl;
|
||||
string decoded = stream.str();
|
||||
cout << decoded << endl;
|
||||
string payload = cleanup_html(base64_decode(jsonData["payload"]));
|
||||
if (isDebug)
|
||||
ShowDebug(data, decoded, 1, payload);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AccountUpdate::ProcessBitmessage(std::string date, std::string signature, std::string btmsg)
|
||||
{
|
||||
|
||||
string data("curl ");
|
||||
data += ReadFile(ACCOUNT_UPDATE_BTM);
|
||||
string bt("");
|
||||
bt = parser.getLast();
|
||||
data = Replace(data, string("{{ADDRESS}}"), address);
|
||||
data = Replace(data, string("{{BT}}"), bt);
|
||||
data = Replace(data, string("{{DATE}}"), date);
|
||||
data = Replace(data, string("{{SIGN}}"), signature);
|
||||
data = Replace(data, string("{{BTM}}"), btmsg);
|
||||
|
||||
string result = ExecCommand(data.c_str());
|
||||
nlohmann::json jsonData = nlohmann::json::parse(result);
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << "success: " << jsonData["result"]["success"] << endl;
|
||||
stream << "message: " << jsonData["result"]["message"] << endl;
|
||||
string decoded = stream.str();
|
||||
cout << decoded << endl;
|
||||
string payload = cleanup_html(base64_decode(jsonData["payload"]));
|
||||
if (isDebug)
|
||||
ShowDebug(data, decoded, 1, payload);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int AccountUpdate::Update()
|
||||
{
|
||||
if (!this->parser.cmdOptionExists("-d") && !this->parser.cmdOptionExists("--date"))
|
||||
{
|
||||
cout << "option -d | --date required" << endl;
|
||||
return 1;
|
||||
}
|
||||
if (!this->parser.cmdOptionExists("-s") && !this->parser.cmdOptionExists("--signature"))
|
||||
{
|
||||
cout << "option -s | --signature required" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!this->parser.cmdOptionExists("-p") && !this->parser.cmdOptionExists("--pgp") && !this->parser.cmdOptionExists("-u") && !this->parser.cmdOptionExists("--url") && !this->parser.cmdOptionExists("-b") && !this->parser.cmdOptionExists("--bitmessage"))
|
||||
{
|
||||
cout << "one of this parameter required: -p | --pgp, -u| --url, -b| --bitmessage" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
string datavalue("");
|
||||
if (this->parser.cmdOptionExists("-d"))
|
||||
{
|
||||
string vl = this->parser.getCmdOption("-d");
|
||||
if (vl.length() > 0)
|
||||
{
|
||||
datavalue = vl;
|
||||
}
|
||||
}
|
||||
if (this->parser.cmdOptionExists("--data"))
|
||||
{
|
||||
string vl = this->parser.getCmdOption("--data");
|
||||
if (vl.length() > 0)
|
||||
{
|
||||
datavalue = vl;
|
||||
}
|
||||
}
|
||||
if (datavalue.length() == 0)
|
||||
{
|
||||
cout << "data cold't be empty" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
string signvalue("");
|
||||
if (this->parser.cmdOptionExists("-s"))
|
||||
{
|
||||
string vl = this->parser.getCmdOption("-s");
|
||||
if (vl.length() > 0)
|
||||
{
|
||||
signvalue = vl;
|
||||
}
|
||||
}
|
||||
if (this->parser.cmdOptionExists("--signature"))
|
||||
{
|
||||
string vl = this->parser.getCmdOption("--signature");
|
||||
if (vl.length() > 0)
|
||||
{
|
||||
signvalue = vl;
|
||||
}
|
||||
}
|
||||
if (signvalue.length() == 0)
|
||||
{
|
||||
cout << "signature cold't be empty" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// делаем обновление url
|
||||
if (this->parser.cmdOptionExists("-u") || this->parser.cmdOptionExists("--url"))
|
||||
{
|
||||
string urlvalue("");
|
||||
if (this->parser.cmdOptionExists("-u"))
|
||||
{
|
||||
string vl = this->parser.getCmdOption("-u");
|
||||
if (vl.length() > 0)
|
||||
{
|
||||
urlvalue = vl;
|
||||
}
|
||||
}
|
||||
if (this->parser.cmdOptionExists("--url"))
|
||||
{
|
||||
string vl = this->parser.getCmdOption("--url");
|
||||
if (vl.length() > 0)
|
||||
{
|
||||
urlvalue = vl;
|
||||
}
|
||||
}
|
||||
if (urlvalue.length() == 0)
|
||||
{
|
||||
cout << "url cold't be empty" << endl;
|
||||
return 1;
|
||||
}
|
||||
return ProcessUrl(datavalue, signvalue, urlvalue);
|
||||
}
|
||||
if (this->parser.cmdOptionExists("-b") || this->parser.cmdOptionExists("--bitmessage"))
|
||||
{
|
||||
string urlvalue("");
|
||||
if (this->parser.cmdOptionExists("-b"))
|
||||
{
|
||||
string vl = this->parser.getCmdOption("-b");
|
||||
if (vl.length() > 0)
|
||||
{
|
||||
urlvalue = vl;
|
||||
}
|
||||
}
|
||||
if (this->parser.cmdOptionExists("--bitmessage"))
|
||||
{
|
||||
string vl = this->parser.getCmdOption("--bitmessage");
|
||||
if (vl.length() > 0)
|
||||
{
|
||||
urlvalue = vl;
|
||||
}
|
||||
}
|
||||
if (urlvalue.length() == 0)
|
||||
{
|
||||
cout << "bitmessage cold't be empty" << endl;
|
||||
return 1;
|
||||
}
|
||||
return ProcessBitmessage(datavalue, signvalue, urlvalue);
|
||||
}
|
||||
|
||||
else if (this->parser.cmdOptionExists("-p") || this->parser.cmdOptionExists("--pgp"))
|
||||
{
|
||||
string urlvalue("");
|
||||
if (this->parser.cmdOptionExists("-p"))
|
||||
{
|
||||
string vl = this->parser.getCmdOption("-p");
|
||||
if (vl.length() > 0)
|
||||
{
|
||||
urlvalue = vl;
|
||||
}
|
||||
}
|
||||
if (this->parser.cmdOptionExists("--pgp"))
|
||||
{
|
||||
string vl = this->parser.getCmdOption("--pgp");
|
||||
if (vl.length() > 0)
|
||||
{
|
||||
urlvalue = vl;
|
||||
}
|
||||
}
|
||||
if (urlvalue.length() == 0)
|
||||
{
|
||||
cout << "pgp cold't be empty" << endl;
|
||||
return 1;
|
||||
}
|
||||
return ProcessPgp(datavalue, signvalue, urlvalue);
|
||||
}
|
||||
cout << "no argument" << endl;
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
27
dm-cli/AccountUpdate.hpp
Normal file
27
dm-cli/AccountUpdate.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef _ACCOUNT_UPDATE_
|
||||
#define _ACCOUNT_UPDATE_
|
||||
#include <string>
|
||||
#include "InputParser.hpp"
|
||||
|
||||
class AccountUpdate {
|
||||
public:
|
||||
/// @brief Конструктор
|
||||
/// @param parser - парсер аргументов
|
||||
/// @param isRussian - вывод справки на русском
|
||||
AccountUpdate(const InputParser& parser, const bool isRussian);
|
||||
int Process();
|
||||
private:
|
||||
int ProcessUrl(std::string date, std::string signature, std::string urls);
|
||||
int ProcessBitmessage(std::string date, std::string signature, std::string btmsg);
|
||||
int ProcessPgp(std::string date, std::string signature, std::string pgp);
|
||||
InputParser parser;
|
||||
bool isRussian;
|
||||
/// @brief Получение справки о параметрах команды
|
||||
int Help();
|
||||
|
||||
/// @brief Обновление данных, url через запятую
|
||||
int Update();
|
||||
std::string address;
|
||||
bool isDebug;
|
||||
};
|
||||
#endif
|
||||
104
dm-cli/Deals.cpp
Normal file
104
dm-cli/Deals.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include "Deals.hpp"
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include "PrintFile.hpp"
|
||||
#include "common.hpp"
|
||||
#include "ExecCommand.hpp"
|
||||
#include "json.hpp"
|
||||
#include "base64.h"
|
||||
#include <fstream>
|
||||
#include "cleanHtml.h"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int Deals::HelpCreate() const {
|
||||
if (isRussian)
|
||||
PrintFile(DEALS_RU);
|
||||
else
|
||||
PrintFile(DEALS_EN);
|
||||
return 0;
|
||||
}
|
||||
int Deals::HelpDealStatus() const
|
||||
{
|
||||
if (isRussian)
|
||||
PrintFile(DEAL_STATUS_RU);
|
||||
else
|
||||
PrintFile(DEAL_STATUS_EN);
|
||||
return 0;
|
||||
}
|
||||
int Deals::HelpDealComplete() const
|
||||
{
|
||||
if (isRussian)
|
||||
PrintFile(DEAL_COMPLETE_RU);
|
||||
else
|
||||
PrintFile(DEAL_COMPLETE_EN);
|
||||
return 0;
|
||||
}
|
||||
int Deals::HelpDealCancel() const
|
||||
{
|
||||
if (isRussian)
|
||||
PrintFile(DEAL_CANCEL_RU);
|
||||
else
|
||||
PrintFile(DEAL_CANCEL_EN);
|
||||
return 0;
|
||||
|
||||
}
|
||||
int Deals::HelpDealNegative() const
|
||||
{
|
||||
if (isRussian)
|
||||
PrintFile(DEAL_NEGATIVE_RU);
|
||||
else
|
||||
PrintFile(DEAL_NEGATIVE_EN);
|
||||
return 0;
|
||||
}
|
||||
Deals::Deals(const InputParser& parser, const bool isRussian, const string address, bool isDebug)
|
||||
{
|
||||
this->parser = parser;
|
||||
this->isRussian = isRussian;
|
||||
this->address = address;
|
||||
this->isDebug = isDebug;
|
||||
}
|
||||
|
||||
int Deals::Process()
|
||||
{
|
||||
|
||||
if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("create") && this->parser.cmdOptionExists("--help"))
|
||||
return this->HelpCreate();
|
||||
if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("status") && this->parser.cmdOptionExists("--help"))
|
||||
return this->HelpDealStatus();
|
||||
if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("complete") && this->parser.cmdOptionExists("--help"))
|
||||
return this->HelpDealComplete();
|
||||
if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("cancel") && this->parser.cmdOptionExists("--help"))
|
||||
return this->HelpDealCancel();
|
||||
if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("negative") && this->parser.cmdOptionExists("--help"))
|
||||
return this->HelpDealNegative();
|
||||
|
||||
|
||||
return Update();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Deals::Update() {
|
||||
if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("create"))
|
||||
return Create();
|
||||
if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("status"))
|
||||
return Status();
|
||||
if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("complete"))
|
||||
return Complite();
|
||||
if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("cancel"))
|
||||
return Cancel();
|
||||
if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("negative"))
|
||||
return Negative();
|
||||
return 1;
|
||||
}
|
||||
int Deals::Create() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Deals::Status() { return 0; }
|
||||
int Deals::Complite() { return 0; }
|
||||
int Deals::Cancel() { return 0; }
|
||||
int Deals::Negative() { return 0; }
|
||||
36
dm-cli/Deals.hpp
Normal file
36
dm-cli/Deals.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef _DEALS_
|
||||
#define _DEALS_
|
||||
#include <string>
|
||||
#include "InputParser.hpp"
|
||||
|
||||
class Deals {
|
||||
public:
|
||||
/// @brief Конструктор
|
||||
/// @param parser - парсер аргументов
|
||||
/// @param isRussian - вывод справки на русском
|
||||
Deals(const InputParser& parser, const bool isRussian, const std::string address, bool isDebug);
|
||||
int Process();
|
||||
private:
|
||||
InputParser parser;
|
||||
bool isRussian;
|
||||
std::string address;
|
||||
bool isDebug;
|
||||
|
||||
/// @brief Получение справки о параметрах команды
|
||||
int HelpCreate() const;
|
||||
int HelpDealStatus() const;
|
||||
int HelpDealComplete() const;
|
||||
int HelpDealCancel() const;
|
||||
int HelpDealNegative() const;
|
||||
int Update();
|
||||
int Create();
|
||||
int Status();
|
||||
int Complite();
|
||||
int Cancel();
|
||||
int Negative();
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
#endif
|
||||
25
dm-cli/ExecCommand.cpp
Normal file
25
dm-cli/ExecCommand.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "ExecCommand.hpp"
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <array>
|
||||
|
||||
#ifdef WINDOWS
|
||||
#define pclose _pclose
|
||||
#define popen _popen
|
||||
#endif // WINDOWS
|
||||
|
||||
std::string ExecCommand(const char* cmd) {
|
||||
std::array<char, 512> buffer;
|
||||
std::string result;
|
||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
|
||||
if (!pipe) {
|
||||
throw std::runtime_error("popen() failed!");
|
||||
}
|
||||
while (fgets(buffer.data(), static_cast<int>(buffer.size()), pipe.get()) != nullptr) {
|
||||
result += buffer.data();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
5
dm-cli/ExecCommand.hpp
Normal file
5
dm-cli/ExecCommand.hpp
Normal file
@@ -0,0 +1,5 @@
|
||||
#ifndef _EXEC_COMMAND_H_
|
||||
#define _EXEC_COMMAND_H_
|
||||
#include <string>
|
||||
std::string ExecCommand(const char* cmd);
|
||||
#endif
|
||||
75
dm-cli/InputParser.hpp
Normal file
75
dm-cli/InputParser.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef _INPUTPARSER_
|
||||
#define _INPUTPARSER_
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
/// @brief Анализирует входящие параметры
|
||||
class InputParser
|
||||
{
|
||||
public:
|
||||
InputParser(){}
|
||||
InputParser(int &argc, char **argv)
|
||||
{
|
||||
for (int i = 1; i < argc; ++i)
|
||||
this->tokens.push_back(std::string(argv[i]));
|
||||
}
|
||||
/// @brief Пакует без параметров --debug и address
|
||||
/// @param argc
|
||||
/// @param argv
|
||||
InputParser(int &argc, char **argv, bool skip)
|
||||
{
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
std::string cur(argv[i]);
|
||||
if (cur.compare("--debug") == 0)
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (cur.compare("--address") == 0)
|
||||
{
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
this->tokens.push_back(cur);
|
||||
}
|
||||
}
|
||||
/// @brief получение строки параметров
|
||||
const std::string &getCmdOption(const std::string &option) const
|
||||
{
|
||||
std::vector<std::string>::const_iterator itr;
|
||||
itr = std::find(this->tokens.begin(), this->tokens.end(), option);
|
||||
if (itr != this->tokens.end() && ++itr != this->tokens.end())
|
||||
{
|
||||
return *itr;
|
||||
}
|
||||
static const std::string empty_string("");
|
||||
return empty_string;
|
||||
}
|
||||
/// @brief get last argument
|
||||
const std::string& getLast() {
|
||||
return tokens[tokens.size() - 1];
|
||||
}
|
||||
const void getBuffer() const
|
||||
{
|
||||
std::string ret;
|
||||
for (const auto &s : this->tokens)
|
||||
{
|
||||
if (!ret.empty())
|
||||
ret += ",";
|
||||
ret += s;
|
||||
}
|
||||
std::cout << ret << std::endl;
|
||||
}
|
||||
/// @brief существует ли параметр
|
||||
bool cmdOptionExists(const std::string &option) const
|
||||
{
|
||||
return std::find(this->tokens.begin(), this->tokens.end(), option) != this->tokens.end();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::string> tokens;
|
||||
};
|
||||
|
||||
#endif
|
||||
18
dm-cli/Makefile
Normal file
18
dm-cli/Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
CC=g++
|
||||
# CFLAGS=-c -Wall
|
||||
CFLAGS=-c -Wall -g #debug version
|
||||
# LDFLAGS=
|
||||
LDFLAGS= -g
|
||||
SOURCES=AccountStatus.cpp base64.cpp cleanHtml.cpp ExecCommand.cpp help.cpp main.cpp PrintFile.cpp ShowDebug.cpp AccountUpdate.cpp ReadFile.cpp Replace.cpp Deals.cpp
|
||||
OBJECTS=$(SOURCES:.cpp=.o)
|
||||
EXECUTABLE=dm-cli
|
||||
|
||||
all: $(SOURCES) $(EXECUTABLE)
|
||||
|
||||
$(EXECUTABLE): $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
|
||||
|
||||
.cpp.o:
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
clean:
|
||||
rm *.o
|
||||
23
dm-cli/PrintFile.cpp
Normal file
23
dm-cli/PrintFile.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "PrintFile.hpp"
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
void PrintFile(const char *fileName)
|
||||
{
|
||||
ifstream inputFile(fileName);
|
||||
if (inputFile.is_open())
|
||||
{
|
||||
string line;
|
||||
while (getline(inputFile, line))
|
||||
{
|
||||
cout << line << endl;
|
||||
}
|
||||
inputFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Error: Unable to open file " << fileName << endl;
|
||||
}
|
||||
}
|
||||
4
dm-cli/PrintFile.hpp
Normal file
4
dm-cli/PrintFile.hpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef _PRINT_FILE_
|
||||
#define _PRINT_FILE_
|
||||
void PrintFile(const char *fileName);
|
||||
#endif
|
||||
26
dm-cli/ReadFile.cpp
Normal file
26
dm-cli/ReadFile.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
#include "common.hpp"
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
std::string ReadFile(const char* filename) {
|
||||
string data("");
|
||||
ifstream inputFile(filename);
|
||||
if (inputFile.is_open())
|
||||
{
|
||||
string line;
|
||||
while (getline(inputFile, line))
|
||||
{
|
||||
data.append(line);
|
||||
// data.append("\r\n");
|
||||
}
|
||||
inputFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Error: Unable to open file " << filename << endl;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
9
dm-cli/Replace.cpp
Normal file
9
dm-cli/Replace.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <string>
|
||||
#include "common.hpp"
|
||||
std::string Replace(std::string source, std::string from, std::string out) {
|
||||
size_t start = 0, stop = 0;
|
||||
start = source.find(from);
|
||||
stop = from.length();
|
||||
if (start > -1 && stop) return source.replace(start, stop, out);
|
||||
return std::string("");
|
||||
}
|
||||
22
dm-cli/ShowDebug.cpp
Normal file
22
dm-cli/ShowDebug.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "common.hpp"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
extern char** global_argv;
|
||||
extern int global_argc;
|
||||
void ShowDebug(std::string url, std::string result, bool success, std::string decoded) {
|
||||
|
||||
std::ostringstream stream;
|
||||
for (int i = 0; i < global_argc; ++i) {
|
||||
if (i) stream << ' ';
|
||||
stream << global_argv[i];
|
||||
}
|
||||
std::string cmdstring = stream.str();
|
||||
cout << "---------------DEBUG---------------" << endl;
|
||||
cout << "command: " << cmdstring << endl;
|
||||
cout << "success: " << success << endl;
|
||||
cout << "url: " << url << endl;
|
||||
cout << "Result: " << endl << result << endl;
|
||||
cout << "Payload: " << endl << decoded << endl;
|
||||
cout << "---------------END DEBUG---------------" << endl;
|
||||
}
|
||||
9
dm-cli/account_status_en.txt
Normal file
9
dm-cli/account_status_en.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
Usage: dm-cli account status [options] <bitcoin_address>
|
||||
|
||||
Show info about a bitdeals user.
|
||||
|
||||
-f|--feedbacks [p|n] Show last 1K received feedbacks.
|
||||
Use p or n to filter only positive or negative feedbacks.
|
||||
-i|--info Show user account details.
|
||||
-r|--rating Show user rating information.
|
||||
-s|--status Show user account status (default action).
|
||||
9
dm-cli/account_status_ru.txt
Normal file
9
dm-cli/account_status_ru.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
Использование: dm-cli account status [параметры] <биткоин адрес>
|
||||
|
||||
Показать информацию о пользователе bitdeals.
|
||||
|
||||
-f|--feedbacks [p|n] Показать последнюю 1 тыс. полученных отзывов.
|
||||
Используй p или n для фильтрации только позитивных или негативных отзывов.
|
||||
-i|--info Показать данные учётной записи.
|
||||
-r|--rating Показать данные рейтинга.
|
||||
-s|--status Показать статус пользователя (действие по умолчанию).
|
||||
15
dm-cli/account_update_en.txt
Normal file
15
dm-cli/account_update_en.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
Usage: dm-cli account update [options] <bitcoin_address>
|
||||
|
||||
Update user account data.
|
||||
|
||||
To change the account data you should sign the current date and new user data
|
||||
with your bitcoin private key. For example, current date, new bitmessage, signature:
|
||||
2020-01-01
|
||||
BM-2cUuxYUFWLCrtpKRMdHCpU1QKEuFtHh7vu
|
||||
IEF1ysyhu8ps0m5xSJaZZg/5hBylmcWQQggkGO7yNN8iMf/EA2O287kxi58xCDDtxvdsC0TWqylVE5MT5CouamU=
|
||||
|
||||
-d|--date <yyyy-mm-dd> Current date.
|
||||
-s|--signature <sig> Bitcoin signature.
|
||||
-p|--pgp <pgp> Set up an armored RSA pgp key.
|
||||
-u|--url [+/-]<url> Add/remove an url to trusted list.
|
||||
-b|--bitmessage Change bitmessage address.
|
||||
94
dm-cli/base64.cpp
Normal file
94
dm-cli/base64.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "base64.h"
|
||||
|
||||
static const std::string base64_chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
|
||||
static inline bool is_base64(unsigned char c) {
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||
std::string ret;
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
size_t char_array_3[3];
|
||||
size_t char_array_4[4];
|
||||
|
||||
while (in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for (j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
std::string base64_decode(std::string const& encoded_string) {
|
||||
size_t in_len = encoded_string.size();
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
size_t in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++)
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
ret += char_array_3[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
12
dm-cli/base64.h
Normal file
12
dm-cli/base64.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _BASE64_H_
|
||||
#define _BASE64_H_
|
||||
#include <string>
|
||||
/// @brief Кодирование в BASE64
|
||||
/// @param bytes_to_encode буфер для декодирования
|
||||
/// @param in_len длина буфера
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len);
|
||||
/// @brief Декодирование из BASE64
|
||||
/// @param encoded_string Строкадля декодирования
|
||||
std::string base64_decode(std::string const& encoded_string);
|
||||
|
||||
#endif
|
||||
1
dm-cli/check.sh
Normal file
1
dm-cli/check.sh
Normal file
@@ -0,0 +1 @@
|
||||
./dm-cli --address https://testnet-dm2.bitdeals.org --debug account update -d 2020-01-01 -s IEF1ysyhu8ps0m5xSJaZZg/5hBylmcWQQggkGO7yNN8iMf/EA2O287kxi58xCDDtxvdsC0TWqylVE5MT5CouamU= -b btmmessage mnumHs9HQMrw2Q1iKLNnx9NzExS7nMLmyp
|
||||
28
dm-cli/cleanHtml.cpp
Normal file
28
dm-cli/cleanHtml.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "cleanHtml.h"
|
||||
|
||||
std::string cleanup_html(std::string const &encoded_string)
|
||||
{
|
||||
|
||||
size_t start = encoded_string.find("<pre>") + 5;
|
||||
size_t last = encoded_string.find("</pre>");
|
||||
std::string ret;
|
||||
ret = encoded_string.substr(start, last - start);
|
||||
|
||||
size_t b = 0;
|
||||
for (size_t a = b; a < ret.length(); a++)
|
||||
{
|
||||
if (ret[a] == '<')
|
||||
{
|
||||
for (size_t b = a; b < ret.length(); b++)
|
||||
{
|
||||
if (ret[b] == '>')
|
||||
{
|
||||
ret.erase(a, (b - a + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
9
dm-cli/cleanHtml.h
Normal file
9
dm-cli/cleanHtml.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef _CLEANHTML_H_
|
||||
#define _CLEANHTML_H_
|
||||
#include <string>
|
||||
|
||||
/// @brief Удаление HTML тэгов
|
||||
/// @param encoded_string срока с HTML
|
||||
std::string cleanup_html(std::string const& encoded_string);
|
||||
|
||||
#endif
|
||||
53
dm-cli/common.hpp
Normal file
53
dm-cli/common.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef _COMMON_
|
||||
#define _COMMON_
|
||||
#include <string>
|
||||
|
||||
#define PROGRAM_VERSION "1.0.1"
|
||||
#define MAIN_HELP_RU "main_help_ru.txt"
|
||||
#define MAIN_HELP_EN "main_help_en.txt"
|
||||
|
||||
#define ACCOUNT_STATUS_RU "account_status_ru.txt"
|
||||
#define ACCOUNT_STATUS_EN "account_status_en.txt"
|
||||
|
||||
#define ACCOUNT_UPDATE_RU "account_update_en.txt"
|
||||
#define ACCOUNT_UPDATE_EN "account_update_ru.txt"
|
||||
|
||||
#define DEALS_EN "deals_en.txt"
|
||||
#define DEALS_RU "deals_ru.txt"
|
||||
|
||||
#define DEAL_STATUS_RU "deal_status_ru.txt"
|
||||
#define DEAL_STATUS_EN "deal_status_en.txt"
|
||||
|
||||
#define DEAL_COMPLETE_RU "deal_complete_ru.txt"
|
||||
#define DEAL_COMPLETE_EN "deal_complete_en.txt"
|
||||
|
||||
|
||||
#define DEAL_CANCEL_RU "deal_cancel_ru.txt"
|
||||
#define DEAL_CANCEL_EN "deal_cancel_en.txt"
|
||||
|
||||
#define DEAL_NEGATIVE_RU "deal_negative_ru.txt"
|
||||
#define DEAL_NEGATIVE_EN "deal_negative_en.txt"
|
||||
|
||||
|
||||
|
||||
// LANG=ru_RU.UTF-8
|
||||
#define LANG_RU "ru_RU.UTF-8"
|
||||
#define DEFAULTADDRESS "https://127.0.0.1:4999"
|
||||
|
||||
#define ACCOUNT_UPDATE_URL "tpl/accountupdateurl.txt"
|
||||
#define ACCOUNT_UPDATE_BTM "tpl/accountupdatebtm.txt"
|
||||
#define ACCOUNT_UPDATE_PGP "tpl/accountupdatepgp.txt"
|
||||
|
||||
/*
|
||||
Show help screen.
|
||||
*/
|
||||
void show_help(bool isRulang);
|
||||
/// @brief Отображает отладочную информацию
|
||||
void ShowDebug(std::string url, std::string result, bool success, std::string decoded);
|
||||
|
||||
/// @breef read file
|
||||
std::string ReadFile(const char *filename);
|
||||
/// @breef Replace in string
|
||||
std::string Replace(std::string source, std::string from, std::string out);
|
||||
|
||||
#endif
|
||||
1
dm-cli/createdistr.sh
Normal file
1
dm-cli/createdistr.sh
Normal file
@@ -0,0 +1 @@
|
||||
tar -czvf dm-cli_distr.tar.gz tpl dm-cli *.txt
|
||||
12
dm-cli/deal_cancel_en.txt
Normal file
12
dm-cli/deal_cancel_en.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Usage: dm-cli deal cancel [options] <bitcoin_address>
|
||||
|
||||
Cancel a deal
|
||||
|
||||
To cancel a deal you should sign the deal payment address and feeback text message
|
||||
with the seller bitcoin private key. For example, address, feedback, signature:
|
||||
2NEVoXnRgUeb3j17s7pP6DoFHBVHMb94gF5
|
||||
seller random cancel reason text
|
||||
IEOGJ5q/a2cWJPMosQmCHNN6RsXF8Xy/UgaazIoY2i5udbw/v38g1/PdWs451dvFr9Iq/Bq5YL2YdpUFTuijQ60=
|
||||
|
||||
-m|--message <text> Deal cancel reason text message
|
||||
-s|--signature <sig> Bitcoin signature.
|
||||
12
dm-cli/deal_cancel_ru.txt
Normal file
12
dm-cli/deal_cancel_ru.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Использование: dm-cli deal cancel [параметры] <биткоин адрес>
|
||||
|
||||
Отменить сделку
|
||||
|
||||
Для отмены сделки вы должны подписать адрес оплаты сделки и текст отзыва биткоин
|
||||
ключом продавца. Например, адрес, отзыв, подпись:
|
||||
2NEVoXnRgUeb3j17s7pP6DoFHBVHMb94gF5
|
||||
seller random cancel reason text
|
||||
IEOGJ5q/a2cWJPMosQmCHNN6RsXF8Xy/UgaazIoY2i5udbw/v38g1/PdWs451dvFr9Iq/Bq5YL2YdpUFTuijQ60=
|
||||
|
||||
-m|--message <text> Текст сообщения с причино отмены сделки
|
||||
-s|--signature <sig> Биткоин подпись.
|
||||
6
dm-cli/deal_complete_en.txt
Normal file
6
dm-cli/deal_complete_en.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Usage: dm-cli deal complete [options] { <bitcoin_address>|<deal_code> }
|
||||
|
||||
Complete a deal
|
||||
|
||||
-p|--positive Complete deal with positive feedback. (default action)
|
||||
-r|--refund <num> Refund % number of a deal sum to the customer. Format: 100.00[%]
|
||||
6
dm-cli/deal_complete_ru.txt
Normal file
6
dm-cli/deal_complete_ru.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Использование: dm-cli deal complete [параметры] { <биткоин адес>|<код сделки> }
|
||||
|
||||
Завершить сделку
|
||||
|
||||
-p|--positive Завершить сделку с позитивным отзывом. (действие по умолчанию)
|
||||
-r|--refund <num> Возврат % от суммы сделки покупателю. Формат: 100.00[%]
|
||||
12
dm-cli/deal_negative_en.txt
Normal file
12
dm-cli/deal_negative_en.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Usage: dm-cli deal negative [options] <bitcoin_address>
|
||||
|
||||
Leave a negative feedback
|
||||
|
||||
To leave a negative feedback you should sign the deal payment address and feeback text message
|
||||
with the customer bitcoin private key. For example, address, feedback, signature:
|
||||
2NEVoXnRgUeb3j17s7pP6DoFHBVHMb94gF5
|
||||
customer random feedback text
|
||||
H1u44C5cyEeKjHqnNnn09B8mIRMdqgR8PD9AeF8mv+cCEqM9HPkcWLrc8a/v2po2YmXJSeya6uy0XaLnmmmO/1o=
|
||||
|
||||
-m|--message <text> Deal feedback text message
|
||||
-s|--signature <sig> Bitcoin signature.
|
||||
12
dm-cli/deal_negative_ru.txt
Normal file
12
dm-cli/deal_negative_ru.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Использование: dm-cli deal negative [options] <биткоин адрес>
|
||||
|
||||
Оставить негативный отзыв
|
||||
|
||||
Для оставления негативного отзыва ва должны подписать адрес оплаты сделки и текст отзыва биткоин
|
||||
ключом покупателя. Например, адрес, отзыв, подпись:
|
||||
2NEVoXnRgUeb3j17s7pP6DoFHBVHMb94gF5
|
||||
customer random feedback text
|
||||
H1u44C5cyEeKjHqnNnn09B8mIRMdqgR8PD9AeF8mv+cCEqM9HPkcWLrc8a/v2po2YmXJSeya6uy0XaLnmmmO/1o=
|
||||
|
||||
-m|--message <text> Текст сообщения отзыва
|
||||
-s|--signature <sig> Биткоин подпись.
|
||||
7
dm-cli/deal_status_en.txt
Normal file
7
dm-cli/deal_status_en.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Usage: dm-cli deal status { <bitcoin_address>|<deal_code> }
|
||||
|
||||
Show a deal data details
|
||||
|
||||
To show a deal details use a bitcoin payment address or a deal code.
|
||||
|
||||
-i|--is-paid Check a deal is Paid. Returns an exit code 0 if deal is Paid, or non-zero otherwise.
|
||||
7
dm-cli/deal_status_ru.txt
Normal file
7
dm-cli/deal_status_ru.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Использование: dm-cli deal status { <биткоин адрес>|<код сделки> }
|
||||
|
||||
Показать детали сделки
|
||||
|
||||
Чтобы показать детали сделки используйте адрес оплаты сделки или код сделки.
|
||||
|
||||
-i|--is-paid Проверить является ли сделка оплаченной. Возвращает exit code 0 если сделка является оплаченной, или не ноль в других случаях.
|
||||
17
dm-cli/deals_en.txt
Normal file
17
dm-cli/deals_en.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
Usage: dm-cli deal create [options]
|
||||
|
||||
Create a new deal
|
||||
|
||||
[smhd] means seconds, minutes, hours, days.
|
||||
For example: --leave-before 2020-01-01, or --leave-before 10d.
|
||||
|
||||
-a|--at Deal site
|
||||
-s|--seller Seller user in deal
|
||||
-c|--customer Customer user in deal
|
||||
-t|--type [prepayment|postpayment]
|
||||
Deal type
|
||||
-s|--sum Deal sum in BTC
|
||||
-l|--leave-before { <yyyy-mm-dd> [hh:mm:ss UTC] | <time>[smhd] }
|
||||
Deal end date (deal duration); default: 14d
|
||||
-p|--pay { <yyyy-mm-dd> [hh:mm:ss UTC] | <time>[smhd] }
|
||||
Time for make payment; default: 1d
|
||||
17
dm-cli/deals_ru.txt
Normal file
17
dm-cli/deals_ru.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
Использование: dm-cli deal create [параметры]
|
||||
|
||||
Создать новую сделку
|
||||
|
||||
[smhd] означает секунды, минуты, часы, дни.
|
||||
Например: --leave-before 2020-01-01, or --leave-before 10d.
|
||||
|
||||
-a|--at Сайт проведения сделки
|
||||
-s|--seller Продавец в сделке
|
||||
-c|--customer Покупатель в сделке
|
||||
-t|--type [prepayment|postpayment]
|
||||
Тип сделки
|
||||
-s|--sum Сумма сделки в BTC
|
||||
-l|--leave-before { <гггг-мм-дд> [чч:мм:сс UTC] | <время>[smhd] }
|
||||
Время окончания сделки (длительность сделки), по умолчанию: 14d
|
||||
-p|--pay { <гггг-мм-дд> [чч:мм:сс UTC] | <время>[smhd] }
|
||||
Время для оплаты сделки; по умолчанию: 1d
|
||||
19
dm-cli/help.cpp
Normal file
19
dm-cli/help.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include "common.hpp"
|
||||
#include "PrintFile.hpp"
|
||||
|
||||
void show_help(bool isRulang)
|
||||
{
|
||||
|
||||
if (isRulang)
|
||||
{
|
||||
PrintFile(MAIN_HELP_RU);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintFile(MAIN_HELP_EN);
|
||||
}
|
||||
}
|
||||
22875
dm-cli/json.hpp
Normal file
22875
dm-cli/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
115
dm-cli/main.cpp
Normal file
115
dm-cli/main.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#include "common.hpp"
|
||||
#include "InputParser.hpp"
|
||||
#include <iostream>
|
||||
#include "AccountStatus.hpp"
|
||||
#include "AccountUpdate.hpp"
|
||||
#include "Deals.hpp"
|
||||
|
||||
using namespace std;
|
||||
char** global_argv;
|
||||
int global_argc;
|
||||
const char *GetEnv(const char *tag, const char *def = nullptr) noexcept
|
||||
{
|
||||
const char *ret = getenv(tag);
|
||||
return ret ? ret : def;
|
||||
}
|
||||
bool IsRuLang()
|
||||
{
|
||||
|
||||
if (GetEnv("LANG"))
|
||||
{
|
||||
string rulang("ru_RU.UTF-8");
|
||||
string curlang(GetEnv("LANG"));
|
||||
if (rulang.compare(curlang) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
global_argv = argv;
|
||||
global_argc = argc;
|
||||
InputParser input(argc, argv);
|
||||
int retcode = 0;
|
||||
bool isRuLang = IsRuLang();
|
||||
bool isDebug = false;
|
||||
|
||||
string address(DEFAULTADDRESS);
|
||||
|
||||
if (input.cmdOptionExists("--debug"))
|
||||
{
|
||||
isDebug = true;
|
||||
}
|
||||
|
||||
const string &addressarg = input.getCmdOption("--address");
|
||||
if (!addressarg.empty())
|
||||
{
|
||||
address = addressarg;
|
||||
}
|
||||
if (input.cmdOptionExists("--version"))
|
||||
{
|
||||
cout << "Version: " << PROGRAM_VERSION << endl;
|
||||
return retcode;
|
||||
}
|
||||
|
||||
if (input.cmdOptionExists("account") && input.cmdOptionExists("status"))
|
||||
{
|
||||
if (input.cmdOptionExists("--help"))
|
||||
{
|
||||
AccountHelp(isRuLang);
|
||||
return retcode;
|
||||
}
|
||||
if (input.cmdOptionExists("-i") || input.cmdOptionExists("--info"))
|
||||
{
|
||||
return AccountInfo(address, argv[argc - 1], isDebug);
|
||||
}
|
||||
// -r|--rating Показать данные рейтинга.
|
||||
if (input.cmdOptionExists("-r") || input.cmdOptionExists("--raiting"))
|
||||
{
|
||||
return AccountRaiting(address, argv[argc - 1], isDebug);
|
||||
}
|
||||
if (input.cmdOptionExists("-s") || input.cmdOptionExists("--status"))
|
||||
{
|
||||
return AccountStatus(address, argv[argc - 1], isDebug);
|
||||
}
|
||||
// -f|--feedbacks [p|n] Показать последнюю 1 тыс. полученных отзывов. Используй p или n для фильтрации только позитивных или негативных
|
||||
if (input.cmdOptionExists("-f") || input.cmdOptionExists("--feedbacks"))
|
||||
{
|
||||
int fb = 0; // all
|
||||
const string &fbp = input.getCmdOption("-f");
|
||||
if (!fbp.empty())
|
||||
{
|
||||
if (fbp.compare("p") == 0)
|
||||
fb = 1;
|
||||
if (fbp.compare("n") == 0)
|
||||
fb = 2;
|
||||
}
|
||||
const string &fbps = input.getCmdOption("--feedbacks");
|
||||
if (!fbps.empty())
|
||||
{
|
||||
if (fbps.compare("p") == 0)
|
||||
fb = 1;
|
||||
if (fbps.compare("n") == 0)
|
||||
fb = 2;
|
||||
}
|
||||
return AccountFeedbacks(address, argv[argc - 1], isDebug, fb);
|
||||
}
|
||||
return AccountStatus(address, argv[argc - 1], isDebug);
|
||||
}
|
||||
|
||||
if (input.cmdOptionExists("account") && input.cmdOptionExists("update")) {
|
||||
AccountUpdate acu(input, isRuLang);
|
||||
return acu.Process();
|
||||
}
|
||||
if (input.cmdOptionExists("deal")) {
|
||||
Deals deals(input, isRuLang, address,isDebug);
|
||||
return deals.Process();
|
||||
}
|
||||
|
||||
show_help(isRuLang);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
23
dm-cli/main_help_en.txt
Normal file
23
dm-cli/main_help_en.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
Usage: dm-cli [global] <group> [<args>]
|
||||
|
||||
Global options:
|
||||
--debug print debug information, input and output API requests
|
||||
--address <ip:port> address of the bitdeals dm, default: 127.0.0.1:4999
|
||||
--help print condensed help for all subcommands
|
||||
--version print version string
|
||||
|
||||
dm-cli account status <bitcoin_address>
|
||||
Show account data details
|
||||
dm-cli account update [options]
|
||||
Update your account data
|
||||
|
||||
dm-cli deal create
|
||||
Create a new deal
|
||||
dm-cli deal status
|
||||
Show deal data details
|
||||
dm-cli deal complete
|
||||
Complete deal
|
||||
dm-cli deal cancel
|
||||
Cancel deal
|
||||
dm-cli deal negative
|
||||
Leave negative feedback
|
||||
23
dm-cli/main_help_ru.txt
Normal file
23
dm-cli/main_help_ru.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
Использование: dm-cli [глобальные параметры] <группа> [<аргументы>]
|
||||
|
||||
Глобальные параметры:
|
||||
--debug выводить отладочную информацию, входные и выходные API-запросы
|
||||
--address <ip:port> адрес модуля сделок (dm), по умолчанию: 127.0.0.1:4999
|
||||
--help вывести краткую справку по всем подкомандам
|
||||
--version вывести строку версии
|
||||
|
||||
dm-cli account status <биткоин адрес>
|
||||
Показать учётные данные аккаунта
|
||||
dm-cli account update [параметры]
|
||||
Изменить учётные данные аккаунта
|
||||
|
||||
dm-cli deal create
|
||||
Создать новую сделку
|
||||
dm-cli deal status
|
||||
Показать данные сделки
|
||||
dm-cli deal complete
|
||||
Завершить сделку
|
||||
dm-cli deal cancel
|
||||
Отменить сделку
|
||||
dm-cli deal negative
|
||||
Оставить негативный отзыв
|
||||
1
dm-cli/tpl/accountupdatebtm.txt
Normal file
1
dm-cli/tpl/accountupdatebtm.txt
Normal file
@@ -0,0 +1 @@
|
||||
-X POST "{{ADDRESS}}/api/v1/client/update" -H "Content-Type: application/json" -d "{\"address\":\"{{BT}}\",\"date\":\"{{DATE}}\",\"bitmessage\":[\"{{BTM}}\"],\"sign\":\"{{SIGN}}\"}"
|
||||
1
dm-cli/tpl/accountupdatepgp.txt
Normal file
1
dm-cli/tpl/accountupdatepgp.txt
Normal file
@@ -0,0 +1 @@
|
||||
-X POST "{{ADDRESS}}/api/v1/client/update" -H "Content-Type: application/json" -d "{\"address\":\"{{BT}}\",\"date\":\"{{DATE}}\",\"pgp\":\"{{PGP}}\",\"sign\":\"{{SIGN}}\"}"
|
||||
1
dm-cli/tpl/accountupdateurl.txt
Normal file
1
dm-cli/tpl/accountupdateurl.txt
Normal file
@@ -0,0 +1 @@
|
||||
-X POST "{{ADDRESS}}/api/v1/client/update" -H "Content-Type: application/json" -d "{\"address\":\"{{BT}}\",\"date\":\"{{DATE}}\",\"url\":[{{URLS}}], \"sign\":\"{{SIGN}}\"}"
|
||||
Reference in New Issue
Block a user