rakshasa / rtorrent

rTorrent BitTorrent client
https://github.com/rakshasa/rtorrent/wiki
GNU General Public License v2.0
4.05k stars 412 forks source link

how to bind a callback function for specific events #1160

Closed Young-Flash closed 8 months ago

Young-Flash commented 2 years ago

How can I do if I want to do somethings when download state changes (downloading-> completed, downloading -> stop), to put it another way, how can I get notification when the event I care about occurs ? Thanks for any suggestions

kannibalox commented 2 years ago

The various events are listed here: https://rtorrent-docs.readthedocs.io/en/latest/cmd-ref.html#event-commands, and example of how to bind to them is here: https://github.com/rakshasa/rtorrent/wiki/Common-Tasks-in-rTorrent#send-email-for-completed-downloads. If you're on 0.9.8, event.system.shutdown and event.system.startup_done also exist.

N.B. Do not bind anything noisy to event.download.inserted, on startup it gets called for every single existing torrent.

Young-Flash commented 2 years ago

Hi kannibalox, thanks for your reply. I've seen https://github.com/rakshasa/rtorrent/wiki/Common-Tasks-in-rTorrent#send-email-for-completed-downloads before, the action which will be take is defined in rtorrennt.rc. But what I want to do is to bind a callback function inside the code, for example, I am developing a client for rtorrent, they comminicate via webseocket protocal, I want rtorrent to notify the client when the download status of the item changes. I seen the following code:https://github.com/rakshasa/rtorrent/blob/1e400144828c937cb3a8cbd05191db9d95ee1676/src/core/download_list.cc?_pjax=%23js-repo-pjax-container#L68-L69 this method will be call when the state of torrent changes, so my current idea is judge the event_name in this method, when it is the event I care about, excute the callback function, like this:

#define DL_TRIGGER_EVENT(download, event_name) \
  rpc::commands.call_catch(event_name, rpc::make_target(download), torrent::Object(), "Event '" event_name "' failed: "); \
  notify(event_name);

void notify(const char* event_name) {
  if (event_name =="event.download.finished") {
    // do something
  }
}

How do you think about this, is there a better way to achieve this goal ? Thanks again for your reply :smiley:

kannibalox commented 2 years ago

The example you've provided would still be much easier to accomplish without modifying the code, via the event commands. Even a lot of internal logic acts based on them (e.g. the !-prefixed commands that rtxmlrpc method.list_keys '' event.download.finished displays)