diff --git a/src/command_events.cc b/src/command_events.cc index 65d18228..2d7f9f03 100644 --- a/src/command_events.cc +++ b/src/command_events.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -45,6 +46,7 @@ #include #include #include +#include #include "core/download.h" #include "core/download_list.h" @@ -306,6 +308,27 @@ d_multicall(const torrent::Object::list_type& args) { return resultRaw; } +static void +call_watch_command(const std::string& command, const std::string& path) { + rpc::commands.call_catch(command.c_str(), rpc::make_target(), path); +} + +torrent::Object +directory_watch_added(const torrent::Object::list_type& args) { + if (args.size() != 2) + throw torrent::input_error("Too few arguments."); + + const std::string& path = args.front().as_string(); + const std::string& command = args.back().as_string(); + + if (!control->directory_events()->open()) + throw torrent::input_error("Could not open inotify:" + std::string(rak::error_number::current().c_str())); + + control->directory_events()->notify_on(path.c_str(), + torrent::directory_events::flag_on_added | torrent::directory_events::flag_on_updated, + tr1::bind(&call_watch_command, command, tr1::placeholders::_1)); +} + void initialize_command_events() { CMD2_ANY_STRING ("on_ratio", tr1::bind(&apply_on_ratio, tr1::placeholders::_2)); @@ -335,4 +358,6 @@ initialize_command_events() { CMD2_ANY_LIST ("download_list", tr1::bind(&apply_download_list, tr1::placeholders::_2)); CMD2_ANY_LIST ("d.multicall2", tr1::bind(&d_multicall, tr1::placeholders::_2)); + + CMD2_ANY_LIST ("directory.watch.added", tr1::bind(&directory_watch_added, tr1::placeholders::_2)); } diff --git a/src/control.cc b/src/control.cc index 29603594..bb18ab60 100644 --- a/src/control.cc +++ b/src/control.cc @@ -39,6 +39,7 @@ #include #include #include +#include #include "core/manager.h" #include "core/download_store.h" @@ -66,6 +67,7 @@ Control::Control() : m_commandScheduler(new rpc::CommandScheduler()), m_objectStorage(new rpc::object_storage()), + m_directory_events(new torrent::directory_events()), m_tick(0), m_shutdownReceived(false), @@ -93,6 +95,7 @@ Control::~Control() { delete m_core; delete m_dhtManager; + delete m_directory_events; delete m_commandScheduler; delete m_objectStorage; } @@ -157,6 +160,7 @@ Control::handle_shutdown() { worker_thread->queue_item(&ThreadBase::stop_thread); torrent::connection_manager()->listen_close(); + m_directory_events->close(); m_core->shutdown(false); if (!m_taskShutdown.is_queued()) diff --git a/src/control.h b/src/control.h index 29f3bcbd..474614a3 100644 --- a/src/control.h +++ b/src/control.h @@ -68,6 +68,10 @@ namespace rpc { class object_storage; } +namespace torrent { + class directory_events; +} + class Control { public: Control(); @@ -99,6 +103,8 @@ public: rpc::CommandScheduler* command_scheduler() { return m_commandScheduler; } rpc::object_storage* object_storage() { return m_objectStorage; } + torrent::directory_events* directory_events() { return m_directory_events; } + uint64_t tick() const { return m_tick; } void inc_tick() { m_tick++; } @@ -118,8 +124,9 @@ private: input::Manager* m_input; input::InputEvent* m_inputStdin; - rpc::CommandScheduler* m_commandScheduler; - rpc::object_storage* m_objectStorage; + rpc::CommandScheduler* m_commandScheduler; + rpc::object_storage* m_objectStorage; + torrent::directory_events* m_directory_events; uint64_t m_tick;