51 lines
1.5 KiB
C++
51 lines
1.5 KiB
C++
#pragma once
|
|
#include <thread>
|
|
#include <atomic>
|
|
#include <mutex>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <optional>
|
|
#include "Config.hpp"
|
|
#include "State.hpp"
|
|
#include "Scraper.hpp"
|
|
#include "DiscordNotifier.hpp"
|
|
|
|
// Owns the background watch loop (equivalent to python's `bot_loop`) plus
|
|
// all the mutating operations the Flask `/api/*` routes used to expose.
|
|
// The Discord bot's slash-command handlers call straight into this class.
|
|
class SniperEngine {
|
|
public:
|
|
SniperEngine(AppConfig& config, SniperState& state, DiscordNotifier& notifier);
|
|
~SniperEngine();
|
|
|
|
bool start(std::string* error_out = nullptr);
|
|
void stop();
|
|
bool isRunning() const;
|
|
|
|
// Fire-and-forget manual rescan of a single URL (spawns a detached thread,
|
|
// matching python's api_scan_now()).
|
|
void scanNow(const std::string& url);
|
|
|
|
bool addLink(LinkConfig link);
|
|
bool removeLink(const std::string& url);
|
|
bool togglePause(const std::string& url, bool* now_paused_out = nullptr);
|
|
|
|
std::vector<LinkConfig> links();
|
|
int intervalSeconds() const;
|
|
void setIntervalSeconds(int seconds);
|
|
|
|
private:
|
|
AppConfig& config_;
|
|
SniperState& state_;
|
|
DiscordNotifier& notifier_;
|
|
Scraper scraper_;
|
|
|
|
std::mutex links_mtx_;
|
|
std::thread worker_;
|
|
std::atomic<bool> stop_requested_{false};
|
|
|
|
void loop();
|
|
void runOneScan(const LinkConfig& cfg, bool isManual);
|
|
static std::string getChangeText(size_t n, const std::optional<std::vector<std::string>>& old);
|
|
};
|