19 const std::string& client_id,
20 const std::filesystem::path& listening_dir,
21 const std::string& connection_prefix ,
25 , m_listening_ip(listening_ip)
26 , m_client_id(client_id)
28 TLOG() <<
"DAB " << __LINE__ <<
" " << listening_dir;
30 std::string file_path_str = listening_dir.string();
35 TLOG() <<
"DAB " << __LINE__ <<
" " << file_path_str;
36 pos = file_path_str.find(x, pos);
37 if (pos == std::string::npos) {
41 file_path_str.replace(pos, x.length(),
"");
43 TLOG() <<
"DAB " << __LINE__ <<
" " << file_path_str;
44 if (file_path_str.length() == 0) {
45 file_path_str =
"blah";
47 TLOG() <<
"DAB " << __LINE__ <<
" " << file_path_str;
49 TLOG() <<
"DAB " << __LINE__ <<
" " << file_path_str;
62 if (msg.has_value()) {
65 TLOG() <<
"debug : no notification received, timeout";
82 while (running_flag.load()) {
84 TLOG() <<
"debug : no bookkeeper connected, looking for connections";
89 if (msg.has_value()) {
104 const std::string& protocol,
105 const std::set<std::string>& dest_clients,
106 const std::set<std::filesystem::path>& files,
107 const nlohmann::json& protocol_options )
114 if (ses !=
nullptr) {
115 TLOG() <<
"debug : transfer " << transfer_id <<
" already exists !";
119 TLOG() <<
"debug : creating new transfer with protocol " << protocol;
122 if (!_protocol.has_value()) {
130 for (
const auto& file : files) {
132 if (!std::filesystem::exists(file)) {
161 for (
const auto& client : dest_clients) {
163 TLOG() <<
"debug : notifying client " << client;
168 s.get_transfer_options().export_to_string());
171 for (
auto file : s.get_transfer_options().get_transfers_meta()) {
176 file->export_to_string());
239 if (transfer_id.find(
"ses") == std::string::npos) {
244 if (s.get_session_id() == transfer_id) {
256 const std::filesystem::path& work_dir,
258 const std::set<std::string>& dest_clients )
267 m_sessions.emplace_back(std::move(new_session));
269 m_sessions.back().set_target_clients(dest_clients);
278 for (
const std::filesystem::path& f : to_share) {
279 TLOG() <<
"debug : Sharing " << f.filename();
286 fmeta->export_to_string());
303 if (action.has_value() ==
false) {
307 switch (action.value()) {
310 TLOG() <<
"debug : receive connection request, sending available files";
311 std::set<std::filesystem::path> to_share;
342 auto fmeta = std::make_shared<TransferMetadata>(notif.
m_data,
false);
346 for (
auto& s : sessions_ref) {
347 TLOG() <<
"debug : session " << s.get_session_id();
348 if (s.get_session_id().find(notif.
m_target_id) != std::string::npos) {
349 TLOG() <<
"debug : session found";
350 fmeta->set_dest(s.get_ip());
364 if (ses !=
nullptr) {
381 if (ses !=
nullptr) {
398 if (ses !=
nullptr) {
415 if (ses !=
nullptr) {
432 if (ses !=
nullptr) {
468 for (
size_t i = 0; i <
m_sessions.size(); i++) {
469 if (s->get_session_id() == session_id) {
491 std::filesystem::path folder)
493 if (folder.empty()) {
497 TLOG() <<
"debug : scanning files in " << folder;
500 for (
const auto& entry : std::filesystem::directory_iterator(folder)) {
502 if (previous_scan.insert(entry.path()).second) {
503 TLOG() <<
"debug : found new file " << entry.path();
506 bool already_active =
false;
509 if (s.get_transfer_options() == metadata) {
510 already_active =
true;
515 if (!already_active) {
526 for (
const auto& entry : std::filesystem::directory_iterator(folder)) {
528 if (previous_scan.insert(entry.path()).second) {
529 TLOG() <<
"debug : found new file " << entry.path();
531 std::shared_ptr<TransferMetadata> metadata = std::make_shared<TransferMetadata>(entry.path());
535 auto expect_ref = s.get_transfer_options().get_expected_files();
536 if (expect_ref.find(metadata->get_file_name()) != expect_ref.end()) {
537 s.add_file(metadata);
544 TLOG() <<
"debug : " << entry.path() <<
" not wanted yet, deleting from scan list";
545 previous_scan.erase(entry.path());
550 }
else if (entry.is_directory()) {
551 TLOG() <<
"debug : found directory " << entry.path();
559std::shared_ptr<TransferMetadata>
562 return std::make_shared<TransferMetadata>(src, std::filesystem::file_size(src),
get_ip());
568 TLOG() <<
"BBB " << __LINE__ <<
" my_conn=\"" <<
m_my_conn <<
"\"";
571 std::string str1 = c;
574 if (str1.starts_with(
"snbmodules_")) {
575 str1 = str1.substr(11);
577 if (str2.starts_with(
"snbmodules_")) {
578 str2 = str2.substr(11);
581 if (str1.starts_with(
"snb-sample-config-")) {
582 str1 = str1.substr(18);
584 if (str2.starts_with(
"snb-sample-config-")) {
585 str2 = str2.substr(18);
588 TLOG() <<
"BBB " << __LINE__ <<
" c=\"" << c <<
"\" client_id=" <<
get_client_id() <<
" " << str1 <<
" " << str2;
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
void create_new_transfer(const std::string &transfer_id, const std::string &protocol, const std::set< std::string > &dest_clients, const std::set< std::filesystem::path > &files, const nlohmann::json &protocol_options=nlohmann::json())
Create a new transfer.
void cancel_transfer(const std::string &transfer_id)
std::string get_client_id() const
TransferSession & create_session(GroupMetadata transfer_options, e_session_type type, std::string id, const std::filesystem::path &work_dir, IPFormat ip=IPFormat(), const std::set< std::string > &dest_clients=std::set< std::string >())
Create a new session, you can precise the IP address of the session forcing to use a specific network...
void start_transfer(const std::string &transfer_id)
Start, pause, resume or cancel a transfer.
TransferClient(const IPFormat &listening_ip, const std::string &client_id, const std::filesystem::path &listening_dir, const std::string &connection_prefix="snbmodules", int timeout_send=10, int timeout_receive=100)
TransferClient constructor.
std::string get_my_conn()
TransferSession * get_session(std::string transfer_id)
std::filesystem::path m_listening_dir
Listening directory, directory where the client will listen for incoming files and files to share.
void remove_session(const std::string &session_id)
Add a session to the client.
std::map< std::string, std::shared_ptr< TransferMetadata > > m_available_files
Map of available files (key = file path, value = file metadata)
std::filesystem::path get_listening_dir() const
void scan_available_files(std::set< std::filesystem::path > &previous_scan, bool nested=false, std::filesystem::path folder=std::filesystem::path())
Scan available files in the listening directory.
bool start(int timeout)
Start the client in curent thread.
std::string m_my_conn
Connection uuid of the client, retrieved using the notification interface and calling get_my_conn()
std::vector< TransferSession > m_sessions
Map of active sessions (key = session ID, value = session)
void share_available_files(const std::set< std::filesystem::path > &to_share, const std::string &dest)
Share available files (in m_listening_dir)
void pause_transfer(const std::string &transfer_id)
std::shared_ptr< TransferMetadata > create_metadata_from_file(const std::filesystem::path &src)
Create a metadata from a file.
std::vector< TransferSession > & get_sessions()
std::string generate_session_id(const std::string &transferid, const std::string &dest="")
Function to generate session ID.
void resume_transfer(const std::string &transfer_id)
IPFormat m_listening_ip
IP address of the client.
bool do_work(std::atomic< bool > &running_flag)
Start function to use in a thread.
bool action_on_receive_notification(NotificationData notif) override
Action to do when the client receive a notification.
TransferSession class contained in a client, is a wrapper for a transfer. extend notification interfa...
bool resume_file(TransferMetadata &f_meta, bool is_multiple=false)
bool cancel_file(TransferMetadata &f_meta, bool is_multiple=false)
bool update_metadata_to_bookkeeper(TransferMetadata &f_meta)
const GroupMetadata & get_transfer_options() const
bool start_file(TransferMetadata &f_meta)
Start the session by downloading or uploading files depending on the type of session TODO : separate ...
static std::string session_type_to_string(e_session_type e)
bool update_metadatas_to_bookkeeper()
bool pause_file(TransferMetadata &f_meta, bool is_multiple=false)
e_session_type
Different type of session.
@ Downloader
TransferSession used to download files from uploaders client.
@ Uploader
TransferSession used to upload files to downloaders client.
NotificationWrongDestinationError
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk size
void warning(const Issue &issue)
void error(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)
static std::optional< e_protocol_type > string_to_protocols(std::string s)