hekmon / transmissionrpc Goto Github PK
View Code? Open in Web Editor NEWGolang bindings for Transmission RPC API
License: MIT License
Golang bindings for Transmission RPC API
License: MIT License
Hey, I've been messing around with a tool using this package and I'm running into a little issue: Using the TorrentAdd call is resulting in a torrent that hasn't started properly and just hangs around with no download and 0 discovered peers until I pause it, wait a few seconds, and then resume it. Is this normal? How do I add a torrent that actually starts properly?
When running go get github.com/hekmon/transmissionrpc/v2
, the follow message is returned.
go get: module github.com/hekmon/transmissionrpc@upgrade found (v1.1.0), but does not contain package github.com/hekmon/transmissionrpc/v2
the go-humanize package is already being used by more than 8k packages. so i suggest that using that is more reasonable. as an added benefit, it also supports converting time (which can be used for the eta
and etaIdle
fields).
Based on the transmission-rpc documentation, ids arrays can be as follows:
All torrents are used if the "ids" argument is omitted.
"ids" should be one of the following:
(1) an integer referring to a torrent id
(2) a list of torrent id numbers, sha1 hash strings, or both
(3) a string, "recently-active", for recently-active torrents
I've been trying out, and I may be missing something (or messing with something, I'm kinda newbie with golang), but I think your library does not support option 2, right?
It would be really nice to allow searching via hashes, many applications do not return the numeric id and, instead, use the string hash (like sonarr).
Hi!
I'm running into issues with TorrentSet and seedIdleLimit
not being set. All limits are fine.
The struct takes a time.Duration
but the spec for both v3 and v4+ needs a number.
Have I misunderstood something or should it be like that? I can see the TorrentSetPayload MarshalJSON function but running with a debugger it does not seem to run it.
While the TorrentSetPayload
is using Peerlimit
, Torrent
and TorrentAddPayload
are using PeerLimit
.
torrent_mutators.go
44: Peerlimit *int64 `json:"peer-limit"` // maximum number of peers
$ ack -w PeerLimit
torrent_add.go
76: PeerLimit *int64 `json:"peer-limit"` // maximum number of peers
torrent_accessors.go
157: PeerLimit *int64 `json:"peer-limit"`
Just stumbled on it when trying to dynamically compare Torrent
field values with configuration I have and dynamically (againπ, basically like MarshalJSON
does here also) generating TorrentSetPayload if there are differences.
I could make also PR if this change is ok but might break functionality for other using this?
Hi
The TrackerReplace
field of []string type
in type TorrentSetPayload struct
does not work as intended. It's used by TorrentSet method (corresponding to transmission torrent-set rpc method) to edit the torrent tracker. TR will return an "invalid argument" rpc error. I have tested it in Transmission 3.0 for Linux.
It should be in []interface{}
type and the <trackerId/new announce URLs> pairs should be passed as mixed types of int64 / string
.
Hello,
I'm currently working on making this library compliant with Transmission RPC spec v17. I'm wondering what the reason is behind the MarshalJSON function for TorrentSetPayload instead of using omitempty
. I'm sure there is a valid reason, I'm just trying to understand the code better.
Thanks for making this! Also: I noticed in the other issue, you mentioned you don't have time to maintain this. I would gladly take over maintainership if that is fine with you. I have forked this repo but I've had to change the Go modules to my repo in order to test my changes. This seems like it would conflict with making a pull request since both repos would be using different module URLs. I'm fairly new to this and I've never made PRs for Go projects before, so maybe there is a way to workaround this. Or else if you'd like to archive this repo and we can just use mine as the new one. I'm open to discussion about this.
Best regards
The error is 'torrent-get' rpc method failed: can't unmarshall request answer body: json: cannot unmarshal bool into Go struct field torrentGetResults.arguments.torrents of type int64
I call it as torrents, err := transmission.TorrentGetAll(context.TODO())
Everything was working fine until I updated to Transmission 4
If you're considering dropping a v3 tag after we figure out the RPC version changes...
I'd like to suggest a few things.
https
and a string for uri
, can we consider just providing a full url? Then the implementer can decide how their users input data, and split or join it themselves. This removes the need to join all the pieces in this library and run url.Parse
.time.Duration
for HTTPTimeout, can we just take in an http.Client
? This also removes the need for a dependency on hashicorp's cleanhttp module. You can let the implementer pass in their own client with a timeout pre-applied. The reason I want this is so I can log payloads and produce metrics with http.Transport
middleware.I'm happy to drop in a pull request if you're open to these changes.
Note: I'm happy to attempt the PR if you let me know which strategy you'd prefer, please let me know.
I'd like to either export file2base64
or provide another function which takes a filename and a TorrentAddPayload
.
Let's say I want to add a torrent in a paused state. I can easily do this with a URL:
url := "http://..."
paused := true
payload := &transmissionrpc.TorrentAddPayload{
Filename: &url,
Paused: &paused,
}
torrent, err = client.TorrentAdd(payload)
If I want to add a file, there's the wrapper:
filename := "foo.torrent"
client.TorrentAddFile(filename)
But if I want to add that file paused, I need to reinvent TorrentAddFile
, which is painful as file2base64
is not exported.
Hi!
Transmission 3.0 was released with some changes in the RPC protocol. I could not find the exact list of changes, but it appears that some fields have changed types. For example trackerStats
now uses bool
for lastAnnounceTimedOut
.
This breaks JSON unmarshal due to type mismatches:
'torrent-get' rpc method failed: can't unmarshall request answer body: json: cannot unmarshal bool into Go struct field torrentGetResults.arguments.torrents of type int64
Cheers,
I've been trying this on my own with no luck*, let's see what do you think about it.
The idea is to be able to run some actions, like TorrentRenamePath
or TorrentSetLocation
, directly from the torrent object, so, instead of doing this:
ids := []string{"7C03A705D4BBF4F74A97401FD0165CC4D7E7DDD4"}
fields := []string{"id", "files", "hashString"}
torrents, err := client.TorrentGetHashes(fields, ids)
if err != nil {
panic(err)
}
err = client.TorrentRenamePath(*torrents[0].ID, "FileName.mkv", "NewFileName.mkv")
if err != nil {
panic(err)
}
Be able to do this:
ids := []string{"7C03A705D4BBF4F74A97401FD0165CC4D7E7DDD4"}
fields := []string{"id", "files", "hashString"}
torrents, err := client.TorrentGetHashes(fields, ids)
if err != nil {
panic(err)
}
err = torrent[0].RenamePath("FileName.mkv", "NewFileName.mkv")
if err != nil {
panic(err)
}
As said, I've tried this on my own.. but I started coding golang just three days ago and obviously my skills are still far from good.
Couldn't think in a way to use the Client
inside a Torrent
function, so I decided to try binding the Client to every Torrent to be able to access it later inside the function (again, I'm a newbie :)):
First I added the Client
property to the Torrent
struct:
type Torrent struct {
// Original code below
Client *Client
}
Then I defined a new Torrents
type for the [] *Torrent
type with a BindClient
to bind the client to every torrent:
type Torrents []*Torrent
func (t Torrents) BindClient(client *Client) {
for _, torrent := range t {
torrent.BindClient(client)
}
}
// And a BindClient method for the Torrent:
func (t *Torrent) BindClient(client *Client) {
t.Client = client
}
Obviously, after adding that Torrents
type, I've searched-and-replaced all the []*Torrent
matches in the code with Torrents
.
Finally, in the torrentGet
and torrentGetHash
methods I bind the client to every torrent:
func (c *Client) torrentGet(fields []string, ids []int64) (torrents Torrents, err error) {
// Original code below
torrents = result.Torrents
// Addition
torrents.BindClient(c)
return
}
func (c *Client) torrentGetHash(fields []string, ids []string) (torrents Torrents, err error) {
// Original code below
torrents = result.Torrents
// Addition
torrents.BindClient(c)
return
}
And the RenamePath
method looks like this:
// RenamePath directly from torrent
func (t *Torrent) RenamePath(path, name string) (err error) {
return t.Client.TorrentRenamePath(*t.ID, path, name)
}
Doing this it works.... but I'm not really sure this is the best way. I think it would be better if can be done during the unmarshalling, but couldn't find a way to do it.
Edit: I neither like binding the client to every torrent, maybe there's a better way (?)
Please, let me know your thoughts π
* Edit2: I started creating the issue saying "with no luck" because at the very start of writing it I had a syntax error on my code which was making it fail, but it works as said later.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.