torrust / torrust-tracker Goto Github PK
View Code? Open in Web Editor NEWA modern and feature-rich (private) BitTorrent tracker.
Home Page: https://torrust.com
License: GNU Affero General Public License v3.0
A modern and feature-rich (private) BitTorrent tracker.
Home Page: https://torrust.com
License: GNU Affero General Public License v3.0
Hi, i use the Docker Image for the tracker (zorlin/torrust-tracker:latest).
I want to start the tracker container but i got an error on startup.
Log from Docker:
thread 'main' panicked at 'Errors while processing config: invalid type: map, expected a sequence.', src/main.rs:14:13
stack backtrace:
0: 0x55f40c838dd0 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h3a4fd1617b9f81b2
1: 0x55f40c75de2c - core::fmt::write::hc66d2af0ccaccee2
2: 0x55f40c8379c4 - std::io::Write::write_fmt::hb1a454562d1b17db
3: 0x55f40c83805b - std::panicking::default_hook::{{closure}}::he9dcee375802d06d
5: 0x55f40c857f38 - std::panicking::begin_panic_handler::{{closure}}::he95030897fea293f
6: 0x55f40c857eb6 - std::sys_common::backtrace::__rust_end_short_backtrace::h30b6536126307786
7: 0x55f40c857e72 - rust_begin_unwind
4: 0x55f40c8375e6 - std::panicking::rust_panic_with_hook::h2bc35758f3276b28
8: 0x55f40c6d5180 - std::panicking::begin_panic_fmt::h2ae61d76d5df6610
9: 0x55f40c71b258 - torrust_tracker::main::{{closure}}::h70430145baa8c73c
12: 0x55f40c962eeb - main
13: 0x7f460f9ffa03 - <unknown>
11: 0x55f40c6e2ec3 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4c9494818b3759b3
10: 0x55f40c9648ac - torrust_tracker::main::hbc87628ae0972e78
My Config:
log_level = "info"
mode = "private"
db_path = "data.db"
cleanup_interval = 600
cleanup_peerless = true
external_ip = "0.0.0.0"
peer_timeout = 900
[udp_trackers]
enabled = false
bind_address = "0.0.0.0:6969"
[http_trackers]
enabled = true
bind_address = "0.0.0.0:6969"
on_reverse_proxy = true
announce_interval = 120
ssl_enabled = false
ssl_bind_address = "0.0.0.0:6868"
ssl_cert_path = ""
ssl_key_path = ""
[http_api]
enabled = true
bind_address = "0.0.0.0:1212"
[http_api.access_tokens]
admin = "Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx6"
I dont see a problem in the config? Need a hint ;)
Greets
Hi !
I just picked up your project, after my own GOLANG torrent tracker project hit a brick wall (literally), which was the Garbage Collector. Currently I am using your tracker software, but noticed a lot of flaws and possible huge improvements, using my own project as blue-print.
Some of the features I'm working on, and have already fixed:
I'm currently working on this on my own gitea server, but I could offer later a simple merge to your repository here.
Most of the fixes above, are personal preferences, and optional. Also, some small security improvements and memory usage optimizations :)
Oh right, and it shouldn't be breaking your current indexer project, as it's just purely internal improvements.
I'm not sure what I may be missing.
Everything seem to be working and all categories etc. show up.
Account created access seem to work. Doing a test with the debian net ISO and or any other torrent and I get " only
.torrent files can be uploaded" even though they are .torrent files.
Is MySQL planned? This looks interesting and maybe beneficial for my project here https://github.com/HDInnovations/UNIT3D-Community-Edition
Request without token:
$ curl -i http://127.0.0.1:1212/api/torrents
HTTP/1.1 500 Internal Server Error
content-type: text/plain; charset=utf-8
content-length: 51
date: Wed, 10 Aug 2022 08:32:46 GMT
Unhandled rejection: Err { reason: "unauthorized" }
Request with token:
$ curl -i http://127.0.0.1:1212/api/torrents?token=MyAccessToken
HTTP/1.1 200 OK
content-type: application/json
content-length: 2
date: Wed, 10 Aug 2022 08:45:47 GMT
[]
I think the response code should be 401
for this endpoint.
NOTE for other endpoints: if knowing the resource URL implies getting info you should not have, then you should return
404
instead of403
(Insecure Direct Object References (IDOR)).
I'm having troubles using the HTTP tracker over a reverse proxy if it is possible? I'm using caddy to reverse proxy the port assigned to the http_tracker
section but upon creating a torrent and trying to connect two clients it does not download. I'm able to navigate to the domain I set in the proxy and it connects to the http tracker.
As a test I tried creating a torrent using the IP:PORT such as http://1.1.1.1:6969/announce
and I was able to get two clients to share data but not through the reverse proxy.
Do you know what may be happening?
log_level = "info"
mode = "public"
db_path = "data.db"
cleanup_interval = 600
external_ip = "PUBLIC_SERVER_IP"
[udp_tracker]
bind_address = "0.0.0.0:6969"
announce_interval = 120
[http_tracker]
enabled = true
bind_address = "0.0.0.0:6969"
announce_interval = 120
ssl_enabled = false
ssl_cert_path = ""
ssl_key_path = ""
Would be a neat thing to have when the focus of the site is to seed for long periods of time. Also especially helpful when you've got too many torrents and having to change the tracker URL to match the key is a pain. Of course, there's the option to change the expiry length to a random huge number but having an option to outright disable expiry checks is a bit cleaner in my opinion. In its place, we could have an option for the key be manually regenerated when needed.
I've an error when starting tracker :
thread 'main' panicked at 'Errors while processing config: TrackerModeIncompatible.', src/main.rs:14:13
stack backtrace:
0: rust_begin_unwind
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/panicking.rs:584:5
1: core::panicking::panic_fmt
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/panicking.rs:143:14
2: core::panicking::panic_display
3: torrust_tracker::main::{{closure}}
4: torrust_tracker::main
Here is my config file :
log_level = "info"
mode = "private_listed"
db_path = "data.db"
persistence = true
cleanup_interval = 600
cleanup_peerless = false
external_ip = "0.0.0.0"
announce_interval = 120
announce_interval_min = 120
peer_timeout = 900
on_reverse_proxy = true
[[http_trackers]]
enabled = true
bind_address = "0.0.0.0:6969"
ssl_enabled = false
ssl_bind_address = "0.0.0.0:6868"
ssl_cert_path = ""
ssl_key_path = ""
[[udp_trackers]]
enabled = false
bind_address = "0.0.0.0:6969"
[http_api]
enabled = true
bind_address = "10.8.0.40:1212"
[http_api.access_tokens]
admin = "xxxxxxxxxxxxxx"
I'm trying to compile the torrust tracker on a fresh Ubuntu 20.04 VPS. Help ๐
Compiling torrust-tracker v2.1.2 (/opt/torrust/torrust-tracker)
error: could not compiletorrust-tracker
Caused by:
process didn't exit successfully:rustc --crate-name torrust_tracker --edition=2018 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,future-incompat --crate-type bin --emit=dep-info,link -C opt-level=3 -C lto=fat -C metadata=abe589342472d11d -C extra-filename=-abe589342472d11d --out-dir /opt/torrust/torrust-tracker/target/release/deps -L dependency=/opt/torrust/torrust-tracker/target/release/deps --extern aquatic_udp_protocol=/opt/torrust/torrust-tracker/target/release/deps/libaquatic_udp_protocol-256099ae6a911d5f.rlib --extern binascii=/opt/torrust/torrust-tracker/target/release/deps/libbinascii-9acfca8516b6a49b.rlib --extern byteorder=/opt/torrust/torrust-tracker/target/release/deps/libbyteorder-a702fa3de9d93cfd.rlib --extern chrono=/opt/torrust/torrust-tracker/target/release/deps/libchrono-010dffbe121777a9.rlib --extern config=/opt/torrust/torrust-tracker/target/release/deps/libconfig-099683e27e43327d.rlib --extern derive_more=/opt/torrust/torrust-tracker/target/release/deps/libderive_more-692afb38f795b77c.so --extern env_logger=/opt/torrust/torrust-tracker/target/release/deps/libenv_logger-c3fde9307b1bf67d.rlib --extern external_ip=/opt/torrust/torrust-tracker/target/release/deps/libexternal_ip-7a2196c7896b0ddc.rlib --extern fern=/opt/torrust/torrust-tracker/target/release/deps/libfern-d875b3da92fde325.rlib --extern hex=/opt/torrust/torrust-tracker/target/release/deps/libhex-698b34e1c9f6cfdc.rlib --extern log=/opt/torrust/torrust-tracker/target/release/deps/liblog-5cfdbebb2ffcf419.rlib --extern percent_encoding=/opt/torrust/torrust-tracker/target/release/deps/libpercent_encoding-7c21edb5ded068c3.rlib --extern r2d2=/opt/torrust/torrust-tracker/target/release/deps/libr2d2-78c16af48b279186.rlib --extern r2d2_sqlite=/opt/torrust/torrust-tracker/target/release/deps/libr2d2_sqlite-114e9752096032e8.rlib --extern rand=/opt/torrust/torrust-tracker/target/release/deps/librand-12f552a3a8bf93df.rlib --extern serde=/opt/torrust/torrust-tracker/target/release/deps/libserde-8a17fcae9b1387aa.rlib --extern serde_bencode=/opt/torrust/torrust-tracker/target/release/deps/libserde_bencode-f98c8dd0e18fa1f5.rlib --extern serde_bytes=/opt/torrust/torrust-tracker/target/release/deps/libserde_bytes-eb192722ce71a6b7.rlib --extern serde_json=/opt/torrust/torrust-tracker/target/release/deps/libserde_json-2937bc685dbbc7b2.rlib --extern thiserror=/opt/torrust/torrust-tracker/target/release/deps/libthiserror-ea1533eb85d848d9.rlib --extern tokio=/opt/torrust/torrust-tracker/target/release/deps/libtokio-e4f904d0b7baee09.rlib --extern toml=/opt/torrust/torrust-tracker/target/release/deps/libtoml-f6ae5c7bb1775a19.rlib --extern torrust_tracker=/opt/torrust/torrust-tracker/target/release/deps/libtorrust_tracker-76439efdbbd1d5ef.rlib --extern warp=/opt/torrust/torrust-tracker/target/release/deps/libwarp-9411289a13052a90.rlib -L native=/opt/torrust/torrust-tracker/target/release/build/ring-cce19ede844b507a/out
(signal: 9, SIGKILL: kill)
BEP 15: https://www.bittorrent.org/beps/bep_0015.html
This is what the BEP 15 says about the connection ID:
UDP connections / spoofing
In the ideal case, only 2 packets would be necessary. However, it is possible to spoof the source address of a UDP packet. The tracker has to ensure this doesn't occur, so it calculates a value (connection_id) and sends it to the client. If the client spoofed it's source address, it won't receive this value (unless it's sniffing the network). The connection_id will then be send to the tracker again in packet 3. The tracker verifies the connection_id and ignores the request if it doesn't match. Connection IDs should not be guessable by the client. This is comparable to a TCP handshake and a syn cookie like approach can be used to storing the connection IDs on the tracker side. A connection ID can be used for multiple requests. A client can use a connection ID until one minute after it has received it. Trackers should accept the connection ID until two minutes after it has been send.
And this is the current implementation:
pub fn get_connection_id(remote_address: &SocketAddr) -> ConnectionId {
match std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH) {
Ok(duration) => ConnectionId(((duration.as_secs() / 3600) | ((remote_address.port() as u64) << 36)) as i64),
Err(_) => ConnectionId(0x7FFFFFFFFFFFFFFF),
}
}
Originally posted by @josecelano in #60 (comment)
We have the cspell
word list in the IDE settings. I would move it to a .cspell.json
file in the root dir:
{
"version": "0.2",
"language": "en",
"ignorePaths": [
".vscode",
"**/.git/**",
"**/vscode-extension/**",
"megalinter"
],
"words": [
"byteorder",
"hasher",
"leechers",
"nanos",
"rngs",
"Seedable",
"thiserror",
"torrust",
"typenum"
]
}
Hello @WarmBeer,
I would like to propose that we change the license of this repository (Torrust Tracker) to the Apache License 2.0.
My primary motivation for promoting this change is to have bi-directional license comparably with the aquatic: high-performance open BitTorrent tracker.
Currently our license permits us to take code from aquatic's repository, however, we are not able to return the favor of allowing our code to be copied by @greatest-ape.
It should be noted that we in-fact already depend on some of aquatic's code by using the crate: UDP BitTorrent tracker protocol to support our udp tracker implementation.
Other Contributors: @naim94a @Power2All @josecelano @da2ce7 @pataquets @Aimless321 @ftsimas @makefu
In-Copy @cgbosse
Question: Are there any real benefits for using the AGPL for Torrust-Tracker?
Question: Do you support the idea of moving Torrust Tracker to the "Apache License 2.0" and are also happy to change the license of your contributions in support ?
As of this commit, the statistics tracker runs automatically despite what the configuration says. This can result in degraded performance for users who do not need a statistic tracker.
Hi,
I can see in the documentation : https://torrust.com/torrust-tracker/api/#tracker-keys that we can generate or delete tracker keys.
But is it possible to add existing tracker keys ? I'm migrating from another famous tracker, and I want to keep my existing users tracker key from my database.
The keys are in similar format.
Thanks
error: linking with cc
failed: exit status: 1
|
= note: "cc" "-m64" "/opt/torrust/torrust-tracker/target/release/deps/torrust_tracker-165bb573ecdbab69.torrust_tracker.f579bc99-cgu.15.rcgu.o" "-Wl,--as-needed" "-L" "/opt/torrust/torrust-tracker/target/release/deps" "-L" "/opt/torrust/torrust-tracker/target/release/build/ring-ecc3597f7d7a4ca7/out" "-L" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/tmp/rustcZhuAJZ/libring-d64a3dd64087f741.rlib" "-Wl,--start-group" "-Wl,--end-group" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-de69d754321a9c93.rlib" "-Wl,-Bdynamic" "-lsqlite3" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/opt/torrust/torrust-tracker/target/release/deps/torrust_tracker-165bb573ecdbab69" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-Wl,-O1" "-nodefaultlibs"
= note: /usr/bin/ld: cannot find -lsqlite3
collect2: error: ld returned 1 exit status
Please update the documentation as the code on torrust.com is incorrect (missing double [[brackets]]
) and include more user friendly explanation of all new/old config options and how to use new mysql drivers
Running this command: cargo build --release
I get this error:
Compiling torrust-tracker v2.3.1 (/home/josecelano/Documents/github/committer/josecelano/torrust/torrust-tracker)
error: linking with `cc` failed: exit status: 1
|
= note: "cc" "-m64" "/home/josecelano/Documents/github/committer/josecelano/torrust/torrust-tracker/target/release/deps/torrust_tracker-f15f39c58031f268.torrust_tracker.62a1bfbb-cgu.15.rcgu.o" "-Wl,--as-needed" "-L" "/home/josecelano/Documents/github/committer/josecelano/torrust/torrust-tracker/target/release/deps" "-L" "/home/josecelano/Documents/github/committer/josecelano/torrust/torrust-tracker/target/release/build/ring-96dd4b021d812ff3/out" "-L" "/home/josecelano/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/tmp/rustcDRLr5y/libring-8001bcf1c21935fb.rlib" "-Wl,--start-group" "-Wl,--end-group" "/home/josecelano/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-acf5ff6e9595d982.rlib" "-Wl,-Bdynamic" "-lsqlite3" "-lssl" "-lcrypto" "-lz" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/home/josecelano/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/home/josecelano/Documents/github/committer/josecelano/torrust/torrust-tracker/target/release/deps/torrust_tracker-f15f39c58031f268" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-Wl,-O1" "-nodefaultlibs"
= note: /usr/bin/ld: cannot find -lsqlite3
collect2: error: ld returned 1 exit status
error: could not compile `torrust-tracker` due to previous error
Source code for udp request parsing (and seemingly other code) is quite obviously copied from aquatic. Please note that it is distributed under a license that requires attribution ;-)
torrust-tracker/src/tracker/tracker.rs
Line 225 in 065ca80
Should also resize the torrents BTreeMap after torrent cleanup, so that it can release unneeded memory allocation back to the OS.
Wouldn't it be useful to publish it on https://crates.io/?
I would like to write more documentation for the package. For example, for API endpoints like this:
If we do that, we can automatically have online documentation on https://docs.rs/.
If for some reason, we do not want to publish it yet, we could deploy the documentation to GitHub Pages.
Rename the field valid_until
in the auth key generation endpoint:
POST /api/key/:expiry_time
{
"key": "IaWDneuFNZi8IB4MPA3qW1CD0M30EZSM",
"valid_until": "24525324523452"
"expiry_time": "2015-05-22T14:56:28.000Z"
}
valid_until
is the current field. Timestamp.expiry_time
is the new field. Datetime ISO with timezone.Originally posted by @da2ce7 in torrust/torrust-index#78 (comment)
Currently the UDP server is required in the config.toml, while the HTTP server is optional.
Is Docker support planned? A docker container for the tracker and backend/frontend would be amazing.
https://blog.logrocket.com/packaging-a-rust-web-service-using-docker/
Hello, there seems to be an error with packed data when scraping announce both udp and http/s.
The format should be d5:filesd20
, but on gbitt and torrust it is random, sometimes it is d5:filesd50
, d5:filesd54
, etc. Thats why almost all scrapers returns invalid data for info hash.
Seems like it is using aquatic source for scraping, but aquatic returns correct bytes of 20, where torrust doesn't.
I'm working on this PR #123. I needed to move the SQLite database from the root folder to a new storage
folder, and some tests have been broken.
The problem is the tests are using the default location for the SQLite database, which is the file data.db
in the root folder and one test is also creating the database if it does not exist.
We have to fix it. We need to use a different location to isolate tests from the default location for the production database. And we should also use an independent database for each test.
We did it for the newer API tests here. We just need to do the same.
If you remove both the config.toml
and the data.db
file in the root folder, you'll see how the data.db
file is created again.
Torrust won't compile to armv7-unknown-linux-gnueabihf (Raspberry Pi etc..).
With many torrents, a u32 is too small for the uploaded, downloaded, left and corrupt bytes values. 4294967295 is only a 4GiB file...
It would be crazy cool if like Aquatic this supported webtorrent.
Currently the tracker stats are output in json, it'd be pretty neat if we could have them available via prometheus so we could hook them into things like grafana etc.
https://docs.rs/prometheus_exporter/latest/prometheus_exporter/
Maybe we could have a config option for json or prometheus?
Obviously this isn't important or anything, would be a "nice to have". Thanks for everything you do guys and girls! :)
The tracker has an endpoint to generate new keys.
The response for that endpoint was like:
{
"key": "IaWDneuFNZi8IB4MPA3qW1CD0M30EZSM",
"valid_until": 1674804892
}
But now is like this:
{
"key": "IaWDneuFNZi8IB4MPA3qW1CD0M30EZSM",
"valid_until":
{
"secs": 1674804892,
"nanos": 423855037
}
}
The change was introduced in this commit cab093c by @da2ce7.
The struct:
pub struct AuthKey {
pub key: String,
pub valid_until: Option<u64>,
}
changed to:
pub struct AuthKey {
pub key: String,
pub valid_until: Option<DurationSinceUnixEpoch>,
}
Since we automatically build the json objects exposed in the API, that change was exposed to API consumers.
This change affected the [backend](More info: torrust/torrust-index#78).
IP Addresses can change over time, so it would be useful for tracker operators if they could set a dynamic DNS as external IP. Currently the external_ip config option only supports an IP address.
When you run the tracker the first time, you see this output:
No config file found.
Creating config file..
thread 'main' panicked at 'Please edit the config.TOML in the root folder and restart the tracker.', src/main.rs:22:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Running the tracker without the setting file has a side effect. It creates a setting file with the default configuration.
$ cat config.toml
log_level = "info"
mode = "public"
db_driver = "Sqlite3"
db_path = "data.db"
announce_interval = 120
min_announce_interval = 120
max_peer_timeout = 900
on_reverse_proxy = false
external_ip = "0.0.0.0"
tracker_usage_statistics = true
persistent_torrent_completed_stat = false
inactive_peer_cleanup_interval = 600
remove_peerless_torrents = true
[[udp_trackers]]
enabled = false
bind_address = "0.0.0.0:6969"
[[http_trackers]]
enabled = false
bind_address = "0.0.0.0:6969"
ssl_enabled = false
ssl_cert_path = ""
ssl_key_path = ""
[http_api]
enabled = true
bind_address = "127.0.0.1:1212"
[http_api.access_tokens]
admin = "MyAccessToken"
I suggest showing a message like this:
No config file found: "config.toml".
You can create the default settings file running: cargo run --bin install
That "install" binary could be extended in the feature to be an installation assistant if you run it in interactive mode.
But the main reason for this change is I'm working on setting up docker configuration to automate deployments for the Turrust tracker and running a process that returns an error that could lead to errors while building docker images or others tasks.
On the other hand, I always prefer to be explicit about side effects. Besides, showing an error the first time you run a tracker could make people think the application is not good.
If you do not like that approach, the second option could be to ask the user if they want to create that file, but I do not like that option because it forces the app to be always interactive. We should have added an option to avoid that question in this case and return an error message with an error return value (not a panic message).
@Power2All, @WarmBeer Here are some ideas to improve tracker usability which I have in mind. Would like to know if this is out of scope or it is possible to be added without hurting performance.
GET /api/peers/:peer_id
- Return all peers with selected peer_id
and include info_hash + peers stats for easier data manipulation.GET /api/peers/:ip
- Return all peers with selected ip
and include info_hash + peers stats for easier data manipulation.GET /api/peers/:priv_key
- Return all peers with selected priv_key
and include info_hash + peers stats for easier data manipulation.GET /api/key_status/:priv_key
- Check if priv_key
is used by multiple IP addresses and return number | false
to check if someone is sharing keyip
and port
from peers or rename ip
to be ip_addr = ip:port
and include separate ip
+ port
fields.Those are current ideas to make private tracker more advanced and easier to use.
I propose to move proposals and feature requests to discussions.
We could define both as new categories. For example:
This issue would be a proposal.
Discussions can be converted into issues. They should be well-defined to be added and included as issues. Some of them may even require a TEP.
The goal is to keep the issues list clean with only: bugs and well-defined tasks.
pub struct TorrentPeer {
pub peer_id: PeerId,
pub peer_addr: SocketAddr,
#[serde(serialize_with = "ser_instant")]
pub updated: std::time::Instant,
#[serde(with = "NumberOfBytesDef")]
pub uploaded: NumberOfBytes,
#[serde(with = "NumberOfBytesDef")]
pub downloaded: NumberOfBytes,
#[serde(with = "NumberOfBytesDef")]
pub left: NumberOfBytes,
#[serde(with = "AnnounceEventDef")]
pub event: AnnounceEvent,
}
@WarmBeer , would not it be nice to rename the updated
field like this:
#[serde(serialize_with = "ser_instant")]
#[serde(rename(deserialize = "updated_milliseconds_ago", serialize = "updated_milliseconds_ago"))]
pub updated: std::time::Instant,
To get a json like this:
{
"info_hash": "4beb7001cb833968582c67f55cc59dcc6c8d3fe5",
"seeders": 1,
"completed": 0,
"leechers": 0,
"peers": [
{
"peer_id": {
"id": "2d7142343431302d7358376d33786d2877674179",
"client": "qBittorrent"
},
"peer_addr": "192.168.1.88:17548",
"updated_milliseconds_ago": 385,
"uploaded": 0,
"downloaded": 0,
"left": 0,
"event": "None"
}
]
}
I generally like to add the units in the attribute name.
We can use any other name like: not_updated_duration_in_msecs
, not_updated_duration_in_msecs
, ...
Originally posted by @josecelano in #60 (comment)
Statistics which will show how much has been transferred, how many people downloaded, how many people are downloading, graph, etc will look awesome
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.