#pragma once #include "config.h" #include "posts.h" #include "state.h" #include "td/tl/TlObject.h" #include "tg.h" #include "vk.h" #include #include #include namespace manager { namespace td_api = td::td_api; using posts::AbstractPost; class RepostManager; struct NewPostFetcher { struct fetcher_state { int sourceIndex; bool ready = false; bool needRequest = true; long offset = 0, count = 3; std::vector posts; }; bool working = false; RepostManager *mgr; std::vector vkState, tgState; std::function&&)> onDone; std::function onError; inline NewPostFetcher(RepostManager *m) : mgr(m) {}; void fetch(bool fetchVk, bool fetchTg, decltype(onDone) onDone, decltype(onError) onError); private: void reset_state(); void continue_fetch(); void check_vk_posts(int index, std::vector posts); void check_tg_posts(int index, std::vector> posts); }; class RepostManager { friend struct NewPostFetcher; public: RepostManager(uv_loop_t *eventLoop, tg::AuthCodeProvider tgCodeProvider, tg::PasswordProvider tgPasswordProvider, state::AppState *appState, config::AppConfig *config); RepostManager(RepostManager&) = delete; ~RepostManager(); void start(); private: void on_clients_ready(); void load_more_telegram_chats(); void on_new_posts(std::vector posts); void on_tg_message(td_api::updateNewMessage &update); bool recheck_vk_posts(std::function onDone); void collect_all_vk_posts(const std::variant wall, std::function)> callback); void collect_all_tg_posts(long channel, std::function>)> callback); void collect_last_vk_posts(const std::variant wall, int count, std::function)> callback); void collect_last_tg_posts(long channel, int count, std::function>)> callback); void collect_vk_posts_from(const std::variant wall, int offset, int count, std::function)> callback); void collect_tg_posts_from(long channel, long from, int count, std::function>)> callback); void collect_vk_posts_from__intermediate(const std::variant wall, int offset, int count, std::shared_ptr> intermediateResult, std::function)> callback); void collect_tg_posts_from__intermediate(long channel, long from, int count, std::shared_ptr>> intermediateResult, std::function>)> callback); bool drop_posts_older_than(std::vector &posts, long lastPostId); std::optional to_abstract_post(const vk::Post &post, int sourceIndex); std::optional to_abstract_post(const td_api::message &post, int sourceIndex); std::vector to_abstract_posts(std::vector &posts, int sourceIndex); std::vector to_abstract_posts(std::vector> &posts, int sourceIndex); void enqueue_for_repost(std::vector posts); static void repost_timer_callback(uv_timer_t *h); static void check_timer_callback(uv_timer_t *h); void repost(AbstractPost &post); state::AppState *m_appState; config::AppConfig *m_appConfig; vk::VKClient m_vk; tg::TelegramClient m_tg; NewPostFetcher m_fetcher; std::queue m_repostQueue; std::queue m_unprocessedTgPosts; uv_timer_t *m_repostTimer = nullptr; bool m_checkTimerStarted = false; uv_timer_t *m_checkTimer = nullptr; int m_nRequiredChats; int m_nLoadedRequiredChats = 0; }; }