torrust_index_backend/console/commands/
import_tracker_statistics.rs

1//! It imports statistics for all torrents from the linked tracker.
2//!
3//! It imports the number of seeders and leechers for all torrents from the
4//! associated tracker.
5//!
6//! You can execute it with: `cargo run --bin import_tracker_statistics`.
7//!
8//! After running it you will see the following output:
9//!
10//! ```text
11//! Importing statistics from linked tracker ...
12//! Loading configuration from config file `./config.toml`
13//! Tracker url: udp://localhost:6969
14//! ```
15//!
16//! Statistics are also imported:
17//!
18//! - Periodically by the importer job. The importer job is executed every hour
19//! by default. See [`TrackerStatisticsImporter`](crate::config::TrackerStatisticsImporter)
20//! for more details.
21//! - When a new torrent is added.
22//! - When the API returns data about a torrent statistics are collected from
23//! the tracker in real time.
24use std::env;
25use std::sync::Arc;
26
27use derive_more::{Display, Error};
28use text_colorizer::Colorize;
29
30use crate::bootstrap::config::init_configuration;
31use crate::bootstrap::logging;
32use crate::databases::database;
33use crate::tracker::service::Service;
34use crate::tracker::statistics_importer::StatisticsImporter;
35
36const NUMBER_OF_ARGUMENTS: usize = 0;
37
38#[derive(Debug, Display, PartialEq, Error)]
39#[allow(dead_code)]
40pub enum ImportError {
41    #[display(fmt = "internal server error")]
42    WrongNumberOfArgumentsError,
43}
44
45fn parse_args() -> Result<(), ImportError> {
46    let args: Vec<String> = env::args().skip(1).collect();
47
48    if args.len() != NUMBER_OF_ARGUMENTS {
49        eprintln!(
50            "{} wrong number of arguments: expected {}, got {}",
51            "Error".red().bold(),
52            NUMBER_OF_ARGUMENTS,
53            args.len()
54        );
55        print_usage();
56        return Err(ImportError::WrongNumberOfArgumentsError);
57    }
58
59    Ok(())
60}
61
62fn print_usage() {
63    eprintln!(
64        "{} - imports torrents statistics from linked tracker.
65
66        cargo run --bin import_tracker_statistics
67
68        ",
69        "Tracker Statistics Importer".green()
70    );
71}
72
73/// Import Tracker Statistics Command
74///
75/// # Panics
76///
77/// Panics if arguments cannot be parsed.
78pub async fn run_importer() {
79    parse_args().expect("unable to parse command arguments");
80    import().await;
81}
82
83/// Import Command Arguments
84///
85/// # Panics
86///
87/// Panics if `Configuration::load_from_file` has any error.
88pub async fn import() {
89    println!("Importing statistics from linked tracker ...");
90
91    let configuration = init_configuration().await;
92
93    let log_level = configuration.settings.read().await.log_level.clone();
94
95    logging::setup(&log_level);
96
97    let cfg = Arc::new(configuration);
98
99    let settings = cfg.settings.read().await;
100
101    let tracker_url = settings.tracker.url.clone();
102
103    eprintln!("Tracker url: {}", tracker_url.green());
104
105    let database = Arc::new(
106        database::connect(&settings.database.connect_url)
107            .await
108            .expect("unable to connect to db"),
109    );
110
111    let tracker_service = Arc::new(Service::new(cfg.clone(), database.clone()).await);
112    let tracker_statistics_importer =
113        Arc::new(StatisticsImporter::new(cfg.clone(), tracker_service.clone(), database.clone()).await);
114
115    tracker_statistics_importer
116        .import_all_torrents_statistics()
117        .await
118        .expect("should import all torrents statistics");
119}