20 const std::string& src,
21 const std::set<std::string>& dests,
22 const std::set<std::filesystem::path>& files,
23 const nlohmann::json& protocol_options)
30 (void)protocol_options;
94 TLOG() <<
"Exiting...";
103 TLOG() <<
"Creating new transfer ...";
104 TLOG() <<
"Choose protocol in the list";
107 TLOG() << enum_i <<
" - "
111 std::cin >> protocol;
114 TLOG() <<
"Invalid protocol";
118 TLOG() <<
"Choose clients (q when finished)";
119 std::set<std::string> choosen_clients;
128 TLOG() <<
"Invalid client";
132 choosen_clients.emplace(client);
134 if (choosen_clients.empty()) {
135 TLOG() <<
"No client selected";
138 if (choosen_clients.size() < 2) {
139 TLOG() <<
"At least 2 clients are required";
143 TLOG() <<
"Choose file to transmit (q when finished)";
144 std::set<std::shared_ptr<TransferMetadata>> choosen_files;
146 uint64_t initial_size = choosen_files.size();
153 for (
const std::string& client : choosen_clients) {
157 for (std::shared_ptr<TransferMetadata> filemeta : list) {
158 if (filemeta->get_file_name() == file) {
159 choosen_files.emplace(filemeta);
168 if (initial_size == choosen_files.size()) {
169 TLOG() <<
"Invalid file";
173 if (choosen_files.empty()) {
174 TLOG() <<
"No file selected";
184 TLOG() <<
"Choose transfers to start ... ";
185 std::set<std::string> choosen_transfers;
194 TLOG() <<
"Invalid transfer";
197 choosen_transfers.emplace(input);
199 if (choosen_transfers.size() == 0) {
200 TLOG() <<
"No transfer selected";
204 for (
const auto& transfer : choosen_transfers) {
211 TLOG() <<
"Unknown command";
219 TLOG() <<
"Starting transfer " << transfer_id;
223 std::string session_name = client;
224 session_name +=
"_ses";
225 session_name += transfer_id;
237 TLOG() <<
"JAB " << __LINE__;
240 TLOG() <<
"JAB " << __LINE__ <<
" " << client;
243 TLOG() <<
"JAB " << __LINE__;
245 auto time_point = std::chrono::high_resolution_clock::now();
247 while (running_flag.load()) {
248 TLOG() <<
"JAB " << __LINE__;
252 TLOG() <<
"JAB " << __LINE__;
253 if (msg.has_value()) {
254 TLOG() <<
"JAB " << __LINE__;
257 TLOG() <<
"JAB " << __LINE__;
260 std::this_thread::sleep_for(std::chrono::milliseconds(100));
263 if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - time_point)
265 time_point = std::chrono::high_resolution_clock::now();
275 auto time_point = std::chrono::high_resolution_clock::now();
284 if (msg.has_value()) {
289 getline(std::cin, input);
290 if (input.empty() ==
false) {
304 std::this_thread::sleep_for(std::chrono::milliseconds(100));
307 if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - time_point)
309 time_point = std::chrono::high_resolution_clock::now();
372 if (action.has_value() ==
false) {
377 switch (action.value()) {
379 if (notif.
m_data ==
"end") {
410 std::ostream* output =
nullptr;
411 std::ostream* output_line_log =
nullptr;
412 std::string sep =
";";
416 output =
new std::ofstream();
417 output_line_log =
new std::ofstream();
419 dynamic_cast<std::ofstream*
>(output_line_log)
422 dynamic_cast<std::ofstream*
>(output)->clear();
427 if (
dynamic_cast<std::ofstream*
>(output_line_log)->tellp() == 0) {
428 *output_line_log <<
"time" << sep <<
"file_name" << sep <<
"file_full_path" << sep <<
"group_id" << sep
429 <<
"src_ip" << sep <<
"size" << sep
431 <<
"dest_ip" << sep <<
"start_time" << sep <<
"duration" << sep <<
"progress" << sep <<
"speed"
432 << sep <<
"state" << sep
434 <<
"end_time" << sep <<
"error" << sep << std::endl;
443 *output <<
"Connected clients :" << std::endl;
446 bool is_session =
false;
448 if (client.first.find(
"ses") != std::string::npos) {
449 *output <<
"\t* Session " << client.first <<
" is active" << std::endl;
452 *output <<
"> Client " << client.first <<
" is connected" << std::endl;
456 for (
const auto& file : client.second) {
458 *output_line_log << std::chrono::duration_cast<std::chrono::seconds>(
459 std::chrono::system_clock::now().time_since_epoch())
461 << sep << file->get_file_name() << sep << file->get_file_path() << sep << file->get_group_id()
462 << sep << file->get_src().get_ip_port() << sep << file->get_size() << sep
464 << file->get_dest().get_ip_port() << sep << file->get_start_time_str() << sep
465 << file->get_total_duration_ms() << sep << file->get_progress() << sep
469 << file->get_end_time_str() << sep << file->get_error_code() << sep
475 *output <<
"\t\t - ";
481 *output << file->get_file_name() <<
"\t" << file->get_size() <<
" bytes\tfrom " << file->get_src().get_ip_port()
485 << (file->get_transmission_speed() == 0 ?
"-" : std::to_string(file->get_transmission_speed()))
486 <<
"Bi/s\t" << file->get_start_time_str() <<
"\t" << file->get_total_duration_ms() <<
"ms\t"
487 << file->get_end_time_str() <<
"\t" << file->get_error_code() <<
"\t" << std::endl;
489 *output <<
"Available file " << file->get_file_path() <<
"\t" << file->get_size() <<
" bytes\tfrom "
490 << file->get_src().get_ip_port() <<
"\t" << std::endl;
494 *output << std::endl <<
"Active Transfers :" << std::endl;
496 *output <<
"Group ID\t" <<
"Protocol\t" <<
"Src\t" <<
"IP\t" <<
"Status\t" << std::endl;
500 << g.get_source_id() <<
"\t" << g.get_source_ip().get_ip_port() <<
"\t"
503 for (
const std::shared_ptr<TransferMetadata>& fmeta : g.get_transfers_meta()) {
504 *output <<
"\t- " << fmeta->get_file_name() <<
"\t" << fmeta->get_src().get_ip_port() <<
" to "
509 for (
const std::string& f : g.get_expected_files()) {
510 *output <<
"\t- " << f <<
"\t" <<
"Expected" << std::endl;
515 dynamic_cast<std::ofstream*
>(output)->close();
516 dynamic_cast<std::ofstream*
>(output_line_log)->close();
526 std::shared_ptr<TransferMetadata> file = std::make_shared<TransferMetadata>(data,
false);
527 std::string group_id_tmp = file->get_group_id();
529 std::vector<std::shared_ptr<TransferMetadata>>& tr_vector =
get_transfers()[client_id];
530 for (std::shared_ptr<TransferMetadata>& tr : tr_vector) {
533 tr->from_string(data);
553 std::string group_id_tmp = grp_transfers.
get_group_id();
void do_work(std::atomic< bool > &running_flag)
Start the bookkeeper thread to receive notifications.
void request_update_metadata(bool force=false)
Request the update of the metadata from every known clients to the bookkeeper. Only get from group tr...
void start_transfers(const std::string &transfer_id)
Start a new transfer.
std::map< std::string, GroupMetadata > m_grp_transfers
map of group_id -> group_transfers
std::map< std::string, std::set< std::string > > m_clients_per_grp_transfer
map of grp_transfer_id -> clients_id
bool action_on_receive_notification(NotificationData notif) override
Action to do when receiving a notification.
bool start()
Start the bookkeeper, Only used for stand alone application.
void request_connection_and_available_files(const std::string &client)
Send a notification to a clients id or connection to get available files.
void display_information()
Display the information of the bookkeeper either on the normal log or on a specific file depending on...
void create_new_transfer(const std::string &protocol, const std::string &src, const std::set< std::string > &dests, const std::set< std::filesystem::path > &files, const nlohmann::json &protocol_options=nlohmann::json())
void add_update_grp_transfer(GroupMetadata grp_transfers)
void add_update_transfer(const std::string &client_id, const std::string &data)
std::map< std::string, GroupMetadata > & get_grp_transfers()
std::map< std::string, std::vector< std::shared_ptr< TransferMetadata > > > m_transfers
Map of files/current transfers, client_id -> set of transfers.
std::string m_file_log_path
should the information pannel of transfers be displayed on the normal log or a specific file
int m_refresh_rate
Refresh rate of the information pannel of transfers in seconds.
std::map< std::string, std::vector< std::shared_ptr< TransferMetadata > > > & get_transfers()
std::string get_client_name_from_session_name(const std::string &session_name) const
Usefull convertion from session id to client id.
void input_action(char input)
Do action depending on the input, Used for stand alone application TODO: remake.
std::string get_bookkeeper_id() const
std::optional< NotificationData > listen_for_notification(const std::string &id, const std::string &expected_from="", int timeout=-1, int tries=-1)
Listen for a notification.
void lookups_connections()
Get the list of every connections, must have the prefix first in the name of the connection and the n...
bool send_notification(const notification_type::e_notification_type ¬if, const std::string &src, const std::string &dst, const std::string &id_conn, const std::string &data="", int tries=-1)
Send a notification during m_timeout_send ms.
const std::vector< std::string > & get_bookkeepers_conn() const
Init the connection interface, Only used for standalone application.
const std::set< std::string > & get_clients_conn() const
NotificationWrongDestinationError
void warning(const Issue &issue)
NotificationData class, represent a notification.
std::string m_data
Data of the notification, can be empty.
std::string m_source_id
Source ID.
std::string m_target_id
Target ID.
std::string m_notification
Notification type.
static std::optional< e_notification_type > string_to_notification(std::string s)
e_protocol_type
Different type of protocols available for communication.
static std::string protocols_to_string(e_protocol_type e)
static std::string status_to_string(e_status e)