Things have been a little quiet around Fragments lately, but behind the scenes work has continued nonetheless.
Now, after a little over a year of work, I am proud to announce Fragments 2.0!
Until recently Fragments was written in Vala, and used libtransmission as a backend. This had some disadvantages, e.g. a vapi file has to be maintained (the glue between the Transmission C API, and the Fragments Vala code).
In addition to that there are considerations from the Transmission maintainers to replace the C API with C++. This would mean that Fragments would not be able to use the Transmission API without creating (and maintaining) another wrapper (C++ -> C). In the long run I didn’t think this was very realistic.
And to be honest, Fragments was my last Vala application, and I was thinking for a long time how I could replace it with Rust 😉
The new beginning
The first thing I needed was a suitable BitTorrent backend. Since I have neither the knowledge nor the time to write my own BitTorrent implementation in the long run, my only option was to fall back on something already existing. Unfortunately, there is currently no BitTorrent implementation written in Rust that is comparable to libtransmission in terms of stability and features.
After a few brainstorming sessions I came up with the idea to continue using Transmission, but not via the C API, but to use transmission-daemon, and then communicate via its HTTP RPC API. This has several advantages:
- Clean abstraction between the BitTorrent backend, and the actual application (this has some nice side effects, more on that later!)
- Already existing features in Fragments 1 can be ported directly
- The later migration from Vala to Rust is completely seamless from the end-user’s point of view, as transmission-daemon can directly take over the already existing configuration files etc. from Fragments 1.
I needed to create a new client that would allow me to communicate with the Transmission RPC API. This was fortunately not a huge challenge in Rust thanks to serde-json. To keep this abstraction consistent, I decided not to develop this client in-tree within the Fragments source code, but to publish it as a separate crate on crates.io: transmission-client
This crate takes care of RPC communication only, and can therefore be easily reused in other Rust apps. However, from a Fragments perspective, it would be beneficial if I would be able to use the Transmission API using the GObject type system. So I decided to develop a second crate: transmission-gobject. This wraps the API of the first crate into gtk-rs gobjects. This has the advantage that I can easily embed the transmission data in the Fragments interface, because everything is available as a object with properties, and models. I could therefore concentrate on the pure application in Fragments and didn’t have to worry about technical aspects of the BitTorrent backend.
To visualize the whole thing:
When starting Fragments, the transmission-daemon process also gets started automatically in the background.
Due to the strict abstraction on the network level, there is a big advantage: It does not matter if Fragments connects to its “own” transmission-daemon, or if it connects to a remote transmission server. Likewise, Fragments can be used to remotely control another Fragments session.
For example, I have Transmission installed on my Synology NAS, and use it as a “download server”. I can now connect to it directly from within Fragments:
It is also possible to switch between the individual “connections” directly within the app:
Of course there are a lot of other new features, like a new torrent dialog window:
Torrent rows have context menus now to access important actions more quickly:
The magnet link of already added torrents can now be copied to the clipboard:
Completely overhauled preferences with more options like setting a separate path for incomplete torrents, queue management, behavior when new torrents are added and much more granular network configuration with the possibility to test the connection:
Fragments 2.0 can be downloaded and installed from Flathub:
I would like to thank Maximiliano and Chris, both helped me a lot with the Rust + GTK4 port, and Tobias who helped me with the updated design!