6static void ensure_directory_exists(
const fs::path& path)
9 if(path.has_extension())
11 fs::create_directories(fs::path(path).parent_path(), err);
15 fs::create_directories(path, err);
25 const std::vector<std::string>& synced_ext,
31 std::lock_guard<std::mutex> lock(mutex_);
32 auto&
mapping = mapping_[ref_ext];
45 std::lock_guard<std::mutex> lock(mutex_);
58auto syncer::get_mapping(
const std::string& ext) -> mapping
60 std::lock_guard<std::mutex> lock(mutex_);
61 auto it = mapping_.find(ext);
62 if(it != mapping_.end())
70auto syncer::get_on_created_callback(
const std::string& ext) -> on_entry_created_t
72 return get_mapping(ext).on_entry_created;
75auto syncer::get_on_modified_callback(
const std::string& ext) -> on_entry_modified_t
77 return get_mapping(ext).on_entry_modified;
80auto syncer::get_on_removed_callback(
const std::string& ext) -> on_entry_removed_t
82 return get_mapping(ext).on_entry_removed;
85auto syncer::get_on_renamed_callback(
const std::string& ext) -> on_entry_renamed_t
87 return get_mapping(ext).on_entry_renamed;
90void syncer::sync(
const fs::path& reference_dir,
const fs::path& synced_dir)
95 std::lock_guard<std::mutex> lock(mutex_);
96 reference_dir_ = reference_dir;
97 synced_dir_ = synced_dir;
98 reference_dir_.make_preferred();
99 synced_dir_.make_preferred();
100 ensure_directory_exists(reference_dir_);
101 ensure_directory_exists(synced_dir_);
104 const auto on_change = [
this](
const auto& entries,
bool is_initial_listing)
106 for(
const auto&
entry : entries)
108 bool is_directory = (
entry.type == fs::file_type::directory);
109 auto entry_path =
entry.path;
110 std::string entry_extension;
111 while(entry_path.has_extension())
113 entry_extension = entry_path.extension().string() + entry_extension;
114 entry_path.replace_extension();
120 const auto synced_entries = this->get_synced_entries(
entry.path, is_directory);
122 for(
const auto& synced_entry : synced_entries)
124 ensure_directory_exists(synced_entry);
127 auto callback = this->get_on_created_callback(entry_extension);
130 callback(entry_extension,
entry.path, synced_entries, is_initial_listing);
136 auto callback = this->get_on_modified_callback(entry_extension);
139 const auto synced_entries = this->get_synced_entries(
entry.path, is_directory);
140 callback(entry_extension,
entry.path, synced_entries, is_initial_listing);
146 const auto callback = this->get_on_removed_callback(entry_extension);
150 const auto synced_entries = this->get_synced_entries(
entry.path, is_directory);
151 callback(entry_extension,
entry.path, synced_entries);
157 const auto last_synced_entries = this->get_synced_entries(
entry.last_path, is_directory);
158 const auto synced_entries = this->get_synced_entries(
entry.path, is_directory);
159 auto callback = this->get_on_renamed_callback(entry_extension);
161 if(callback && synced_entries.size() == last_synced_entries.size())
163 std::vector<rename_pair_t> synced_renamed;
164 synced_renamed.reserve(synced_entries.size());
166 for(std::size_t i = 0; i < synced_entries.size(); ++i)
168 const auto& last_synced_entry = last_synced_entries[i];
169 const auto& synced_entry = synced_entries[i];
171 synced_renamed.emplace_back(std::move(p));
174 callback(entry_extension, p, synced_renamed);
184 using namespace std::literals;
185 const fs::path watch_dir = get_watch_path();
189auto syncer::get_synced_entries(
const fs::path& path,
bool is_directory) -> std::vector<fs::path>
191 std::vector<fs::path> synced_entries;
192 auto synced_dir = get_synced_directory(path);
196 synced_entries.emplace_back(std::move(synced_dir));
200 auto entry_path = path;
201 std::string entry_extension;
202 while(entry_path.has_extension())
204 auto ext = entry_path.extension().string() + entry_extension;
205 entry_extension = ext;
206 entry_path.replace_extension();
210 std::lock_guard<std::mutex> lock(mutex_);
211 auto it = mapping_.find(entry_extension);
212 if(it != mapping_.end())
214 const auto& mapping = it->second;
215 const auto& extensions = mapping.extensions;
217 synced_entries.reserve(extensions.size());
218 for(
const auto& cache_ext : extensions)
220 fs::path file = synced_dir / path.filename();
221 file.concat(cache_ext);
223 synced_entries.emplace_back(std::move(file));
229 return synced_entries;
232auto syncer::get_watch_path() -> fs::path
234 std::lock_guard<std::mutex> lock(mutex_);
235 const fs::path watch_dir = reference_dir_;
239auto syncer::get_synced_directory(
const fs::path& path) -> fs::path
244 std::lock_guard<std::mutex> lock(mutex_);
245 result =
fs::replace(path, reference_dir_, synced_dir_);
249 if(fs::is_directory(path, err) || !path.has_extension())
254 return result.parent_path();
A filter that combines include and exclude patterns for file/directory filtering.
std::pair< fs::path, fs::path > rename_pair_t
std::function< void(const std::string &, const fs::path &, const std::vector< fs::path > &, bool)> on_entry_created_t
std::function< void(const std::string &, const fs::path &, const std::vector< fs::path > &, bool)> on_entry_modified_t
void unsync()
Stops syncing.
void set_mapping(const std::string &ref_ext, const std::vector< std::string > &synced_ext, on_entry_created_t on_entry_created, on_entry_modified_t on_entry_modified, on_entry_removed_t on_entry_removed, on_entry_renamed_t on_entry_renamed)
Remaps a specific extension of the reference directory to extensions of the synced directory....
std::function< void(const std::string &, const rename_pair_t &, const std::vector< rename_pair_t > &)> on_entry_renamed_t
void sync(const fs::path &reference_dir, const fs::path &synced_dir)
Start syncing the synced_dir with reference to the reference_dir i.e changes that occur in the refere...
void set_directory_mapping(on_entry_created_t on_entry_created, on_entry_modified_t on_entry_modified, on_entry_removed_t on_entry_removed, on_entry_renamed_t on_entry_renamed)
std::function< void(const std::string &, const fs::path &, const std::vector< fs::path > &)> on_entry_removed_t
static void unwatch(std::uint64_t key)
Un-watches a previously registered file or directory.
static auto watch(const fs::path &path, const pattern_filter &filter, bool recursive, bool initial_list, clock_t::duration poll_interval, notify_callback callback) -> std::uint64_t
Watches a file or directory for modification and call back the specified std::function....
path replace(const path &_path, const path &_sequence, const path &_new_sequence)
Replacing any occurences of the specified path sequence with another.
std::vector< std::string > extensions
on_entry_removed_t on_entry_removed
on_entry_modified_t on_entry_modified
on_entry_renamed_t on_entry_renamed
on_entry_created_t on_entry_created