Рефакторинг Storage.

Диалог SubscribeCase доведен до рабочего состояния.
This commit is contained in:
Kirill Kirilenko 2022-11-20 01:39:47 +03:00
parent 61246591f0
commit c9a587f1b7
6 changed files with 60 additions and 57 deletions

View file

@ -40,7 +40,7 @@ void Bot::setupCommands()
}); });
} }
void Bot::notifyUser(int userId, void Bot::notifyUser(UserId userId,
const std::string& caseNumber, const std::string& caseNumber,
std::string caseUrl, std::string caseUrl,
const CaseHistoryItem& item) const CaseHistoryItem& item)

View file

@ -15,7 +15,7 @@ class Bot
public: public:
explicit Bot(boost::asio::io_context& asioContext, LocalStorage& storage, bool& terminationFlag); explicit Bot(boost::asio::io_context& asioContext, LocalStorage& storage, bool& terminationFlag);
void notifyUser(int userId, void notifyUser(UserId userId,
const std::string& caseNumber, const std::string& caseNumber,
std::string caseUrl, std::string caseUrl,
const CaseHistoryItem& item); const CaseHistoryItem& item);

View file

@ -5,7 +5,7 @@
#include <fstream> #include <fstream>
using json = nlohmann::json; using json = nlohmann::ordered_json;
std::uint32_t parseTime(const std::string& str) std::uint32_t parseTime(const std::string& str)
{ {
@ -30,23 +30,22 @@ void loadStorage(LocalStorage& storage)
std::ifstream ifs("storage.json"); std::ifstream ifs("storage.json");
if (ifs.is_open()) if (ifs.is_open())
{ {
auto data = json::parse(ifs); auto jsonStorage = json::parse(ifs);
storage.token = data.at("token").get<std::string>(); storage.token = jsonStorage.at("token").get<std::string>();
storage.checkTime = parseTime(data.at("check_time").get<std::string>()); storage.checkTime = parseTime(jsonStorage.at("check_time").get<std::string>());
for (const auto& subscription : data.at("subscriptions")) for (const auto& jsonUserData : jsonStorage.at("user_data"))
{ {
Subscription s; UserData userData;
s.userId = subscription.at("user_id"); auto userId = jsonUserData.at("user_id").get<UserId>();
for (const auto& counter : subscription.at("counters")) for (const auto& jsonCaseSubscription : jsonUserData.at("case_subscriptions"))
{ {
Counter c; UserData::CaseSubscription caseSubscription;
c.courtId = counter.at("court").get<int>(); auto caseNumber = jsonCaseSubscription.at("case").get<std::string>();
c.caseNumber = counter.at("case").get<std::string>(); caseSubscription.counter = jsonCaseSubscription.at("counter").get<std::size_t>();
c.value = counter.at("value").get<std::size_t>(); userData.caseSubscriptions[caseNumber] = caseSubscription;
s.counters.push_back(std::move(c));
} }
storage.subscriptions.push_back(std::move(s)); storage.userData[userId] = std::move(userData);
} }
} }
else else
@ -55,30 +54,29 @@ void loadStorage(LocalStorage& storage)
void saveStorage(const LocalStorage& storage) void saveStorage(const LocalStorage& storage)
{ {
json data; json jsonStorage;
data["token"] = storage.token; jsonStorage["token"] = storage.token;
data["check_time"] = timeToString(storage.checkTime); jsonStorage["check_time"] = timeToString(storage.checkTime);
data["subscriptions"] = json::array(); jsonStorage["user_data"] = json::array();
for (const auto& subscription : storage.subscriptions) for (const auto& subscription : storage.userData)
{ {
json jsonSubscription; json jsonUserData;
jsonSubscription["user_id"] = subscription.userId; jsonUserData["user_id"] = subscription.first;
jsonSubscription["counters"] = json::array(); jsonUserData["case_subscriptions"] = json::array();
for (const auto& counter : subscription.counters) for (const auto& caseSubscription : subscription.second.caseSubscriptions)
{ {
json jsonCounter; json jsonCaseSubscription;
jsonCounter["court"] = counter.courtId; jsonCaseSubscription["case"] = caseSubscription.first;
jsonCounter["case"] = counter.caseNumber; jsonCaseSubscription["counter"] = caseSubscription.second.counter;
jsonCounter["value"] = counter.value; jsonUserData["case_subscriptions"].push_back(std::move(jsonCaseSubscription));
jsonSubscription["counters"].push_back(std::move(jsonCounter));
} }
data["subscriptions"].push_back(std::move(jsonSubscription)); jsonStorage["user_data"].push_back(std::move(jsonUserData));
} }
std::ofstream ofs("storage.json"); std::ofstream ofs("storage.json");
if (ofs.is_open()) if (ofs.is_open())
ofs << std::setw(2) << data; ofs << std::setw(2) << jsonStorage;
else else
throw std::runtime_error("failed to save storage"); throw std::runtime_error("failed to save storage");
} }

View file

@ -2,26 +2,26 @@
#define COURT_MONITOR_STORAGE_H #define COURT_MONITOR_STORAGE_H
#include <cstddef> #include <cstddef>
#include <map>
#include <string> #include <string>
#include <vector> #include <vector>
struct Counter using UserId = std::int64_t;
struct UserData
{ {
int courtId = 0; struct CaseSubscription
std::string caseNumber; {
std::size_t value = 0; std::size_t counter = 0;
}; };
struct Subscription std::map<std::string, CaseSubscription> caseSubscriptions;
{
int userId = 0;
std::vector<Counter> counters;
}; };
struct LocalStorage struct LocalStorage
{ {
std::string token; std::string token;
std::vector<Subscription> subscriptions; std::map<UserId, UserData> userData;
std::uint32_t checkTime; // секунды с 00:00 std::uint32_t checkTime; // секунды с 00:00
}; };

View file

@ -38,6 +38,7 @@ struct SubscribeCaseStateMachine : StateMachine<SubscribeCaseStateMachine, Waiti
} }
LocalStorage& storage; LocalStorage& storage;
std::string caseNumber; std::string caseNumber;
CaseDetails caseDetails;
}; };
namespace { namespace {
@ -87,13 +88,14 @@ struct GettingCaseDetails : State<GettingCaseDetails, SubscribeCaseStateMachine>
try try
{ {
auto details = getCaseDetails(ioContext, machine.caseNumber); machine.caseDetails = getCaseDetails(ioContext, machine.caseNumber);
std::string text; std::string text;
fmt::format_to(std::back_inserter(text), "Проверьте информацию:\n{}\n", details.name); fmt::format_to(std::back_inserter(text), "Проверьте информацию:\n{}\n",
for (const auto& participant : details.participants) machine.caseDetails.name);
for (const auto& participant : machine.caseDetails.participants)
fmt::format_to(std::back_inserter(text), "{}: {}\n", participant.title, fmt::format_to(std::back_inserter(text), "{}: {}\n", participant.title,
participant.name); participant.name);
fmt::format_to(std::back_inserter(text), "Судья: {}", details.judgeName); fmt::format_to(std::back_inserter(text), "Судья: {}", machine.caseDetails.judgeName);
banana::api::inline_keyboard_markup_t keyboard; banana::api::inline_keyboard_markup_t keyboard;
keyboard.inline_keyboard.resize(1); keyboard.inline_keyboard.resize(1);
@ -148,8 +150,10 @@ struct WaitingForConfirmation : State<WaitingForConfirmation, SubscribeCaseState
if (*event.query.data == "yes") if (*event.query.data == "yes")
{ {
// TODO auto& userData = machine.storage.userData[machine.userId];
userData.caseSubscriptions[machine.caseNumber].counter =
machine.caseDetails.history.size();
saveStorage(machine.storage);
return transit<Subscribed>(); return transit<Subscribed>();
} }
else if (*event.query.data == "no") else if (*event.query.data == "no")

View file

@ -19,19 +19,20 @@ boost::asio::io_context asioContext;
void processAllSubscriptions(LocalStorage& storage, Bot& bot) void processAllSubscriptions(LocalStorage& storage, Bot& bot)
{ {
for (auto& subscription : storage.subscriptions) for (auto& userData : storage.userData)
{ {
try try
{ {
LOG(main, "* Processing subscriptions for user {}", subscription.userId); const auto& userId = userData.first;
for (auto& counter : subscription.counters) LOG(main, "* Processing subscriptions for user {}", userId);
for (auto& caseSubscription : userData.second.caseSubscriptions)
{ {
LOG(main, "** Processing case {}", counter.caseNumber); const auto& caseNumber = caseSubscription.first;
auto details = getCaseDetails(asioContext, counter.caseNumber); LOG(main, "** Processing case {}", caseNumber);
for (std::size_t i = counter.value; i < details.history.size(); i++) auto details = getCaseDetails(asioContext, caseNumber);
bot.notifyUser(subscription.userId, counter.caseNumber, details.url, for (std::size_t i = caseSubscription.second.counter; i < details.history.size(); i++)
details.history[i]); bot.notifyUser(userId, caseNumber, details.url, details.history[i]);
counter.value = details.history.size(); caseSubscription.second.counter = details.history.size();
} }
} }
catch (const std::exception& e) catch (const std::exception& e)