public TorrentInfo GetTorrentInfo(string hash) { EnsureLoggedInAsync().Wait(); var torrentQuery = new TorrentListQuery() { Hashes = new string[] { hash } }; return(_client.GetTorrentListAsync(torrentQuery).Result.FirstOrDefault()); }
protected sealed override async Task <int> OnExecuteAuthenticatedAsync(QBittorrentClient client, CommandLineApplication app, IConsole console) { if (Hash.Length < 40 && !(AllowAll && IsAll)) { var torrents = await client.GetTorrentListAsync(); var matching = torrents .Where(t => t.Hash.StartsWith(Hash, StringComparison.InvariantCultureIgnoreCase)) .ToList(); if (matching.Count == 0) { console.WriteLineColored($"No torrent matching hash {Hash} is found.", ColorScheme.Current.Warning); return(ExitCodes.NotFound); } if (matching.Count == 1) { Hash = matching[0].Hash; } else { console.WriteLineColored($"The are several torrents matching partial hash {Hash}:", ColorScheme.Current.Normal); var numbers = (int)Math.Log10(matching.Count) + 1; var nameWidth = Console.BufferWidth - (numbers + 45); for (int i = 0; i < matching.Count; i++) { var torrent = matching[i]; var name = torrent.Name.Length < nameWidth ? torrent.Name : torrent.Name.Substring(0, nameWidth - 3) + "..."; console.WriteLineColored($"[{(i + 1).ToString().PadLeft(numbers)}] {torrent.Hash} {name}", ColorScheme.Current.Normal); } int index = 0; while (index <= 0 || index > matching.Count) { index = Prompt.GetInt("Please, select the required one:"); } Hash = matching[index - 1].Hash; } } return(await OnExecuteTorrentSpecificAsync(client, app, console)); }
protected override async Task <int> OnExecuteAuthenticatedAsync(QBittorrentClient client, CommandLineApplication app, IConsole console) { var query = new TorrentListQuery { Category = Category, Filter = Enum.TryParse(Filter, true, out TorrentListFilter filter) ? filter : TorrentListFilter.All, SortBy = Sort != null ? (SortColumns.TryGetValue(Sort, out var sort) ? sort : null) : null, ReverseSort = Reverse, Limit = Limit, Offset = Offset }; var torrents = await client.GetTorrentListAsync(query); Print(torrents, Verbose); return(ExitCodes.Success); }
private static async Task RunOptions(Options opts) { if (opts.DryRun) { Console.WriteLine($"Dry run!"); } var deleteCount = 0; long spaceSaved = 0; var client = new QBittorrentClient(new Uri(opts.Url)); await client.LoginAsync(opts.Username, opts.Password); var torrents = await client.GetTorrentListAsync(); foreach (var directory in Directory.GetDirectories(opts.Path).OrderBy(x => x)) { var dirName = Path.GetFileName(directory); if (!torrents.Any(x => x.Name == dirName)) { var dirSize = DirSize(new DirectoryInfo(directory)); Console.WriteLine($"Deleting: ({BytesToString(dirSize)}) {directory}"); if (!opts.DryRun) { Directory.Delete(directory, true); } deleteCount++; spaceSaved += dirSize; } } Console.WriteLine($"Deleted {deleteCount} of left behind torrents which saves {BytesToString(spaceSaved)}."); }
protected override async Task <int> OnExecuteTorrentSpecificAsync(QBittorrentClient client, CommandLineApplication app, IConsole console) { if (AutomaticTorrentManagement == null && FirstLastPriority == null && ForceStart == null && Sequential == null && SuperSeeding == null) { var torrent = await GetTorrent(); var doc = new Document( new Grid { Stroke = UIHelper.NoneStroke, Columns = { UIHelper.FieldsColumns }, Children = { UIHelper.Row("Automatic Torrent Management", torrent.AutomaticTorrentManagement), UIHelper.Row("First/last piece prioritized", torrent.FirstLastPiecePrioritized), UIHelper.Row("Force start", torrent.ForceStart), UIHelper.Row("Sequential download", torrent.SequentialDownload), UIHelper.Row("Super seeding", torrent.SuperSeeding), } } ).SetColors(ColorScheme.Current.Normal); ConsoleRenderer.RenderDocument(doc); } else { var torrentTask = new Lazy <Task <TorrentInfo> >(GetTorrent, LazyThreadSafetyMode.ExecutionAndPublication); await Task.WhenAll( SetAutomaticTorrentManagement(), SetForceStart(), SetSuperSeeding(), SetFirstLastPriority(torrentTask), SetSequential(torrentTask)); } return(ExitCodes.Success); async Task <TorrentInfo> GetTorrent() { var torrents = await client.GetTorrentListAsync(); return(torrents.Single(t => string.Equals(t.Hash, Hash, StringComparison.InvariantCultureIgnoreCase))); } async Task SetFirstLastPriority(Lazy <Task <TorrentInfo> > torrentTask) { if (FirstLastPriority != null) { var torrent = await torrentTask.Value; if (torrent.FirstLastPiecePrioritized != FirstLastPriority) { await client.ToggleFirstLastPiecePrioritizedAsync(Hash); } } } async Task SetSequential(Lazy <Task <TorrentInfo> > torrentTask) { if (Sequential != null) { var torrent = await torrentTask.Value; if (torrent.SequentialDownload != Sequential) { await client.ToggleSequentialDownloadAsync(Hash); } } } async Task SetAutomaticTorrentManagement() { if (AutomaticTorrentManagement != null) { await client.SetAutomaticTorrentManagementAsync(Hash, AutomaticTorrentManagement.Value); } } async Task SetForceStart() { if (ForceStart != null) { await client.SetForceStartAsync(Hash, ForceStart.Value); } } async Task SetSuperSeeding() { if (SuperSeeding != null) { await client.SetSuperSeedingAsync(Hash, SuperSeeding.Value); } } }
static void Main(string[] args) { List <string> removeHashes = new List <string>(); Dictionary <string, MetricsTorrent> torrentMetrics = new Dictionary <string, MetricsTorrent>(); CLOptions options = null; Parser.Default.ParseArguments <CLOptions>(args) .WithParsed <CLOptions>(o => { options = o; }); Console.WriteLine($"Starting Prometheus scrape listener on {options.PrometheusAddress}:{options.PrometheusPort}"); var promServer = new MetricServer(options.PrometheusAddress, options.PrometheusPort); promServer.Start(); Console.WriteLine($"Creating qbittorrent WebAPI client on {options.QbittorrentIpAddress}:{options.QbittorrentPort}"); QBittorrentClient client = new QBittorrentClient(new Uri($"http://{options.QbittorrentIpAddress}:{options.QbittorrentPort}")); bool reconnectRequired = true; for (; ;) { try { if (reconnectRequired) { try { var logoutTask = client.LogoutAsync(); logoutTask.Wait(); } catch { } var loginTask = client.LoginAsync(options.QbittorrentUsername, options.QbittorrentPassword); loginTask.Wait(); } reconnectRequired = false; if (options.Verbose) { Console.WriteLine($"Processing Qbittorrent Poll at {DateTime.Now}"); } var getTorrentListTask = client.GetTorrentListAsync(); getTorrentListTask.Wait(); var response = getTorrentListTask.Result; if (response != null) { foreach (var trackedTorrent in torrentMetrics) { trackedTorrent.Value.BeginPoll(); } // summarize all sub-torrent data foreach (var torrent in response) { if (torrentMetrics.ContainsKey(torrent.Hash)) { torrentMetrics[torrent.Hash].UpdateStatus(torrent); } else { var newTorrent = new MetricsTorrent(torrent, options); torrentMetrics.Add(torrent.Hash, newTorrent); newTorrent.UpdateStatus(torrent); } } foreach (var trackedTorrent in torrentMetrics) { trackedTorrent.Value.EndPoll(); if (trackedTorrent.Value.TorrentDeleted) { removeHashes.Add(trackedTorrent.Value.Hash); } } foreach (var item in removeHashes) { torrentMetrics.Remove(item); } removeHashes.Clear(); } } catch (Exception ex) { Console.WriteLine($"Fatal Error: {ex.Message}"); reconnectRequired = true; } System.Threading.Thread.Sleep(TimeSpan.FromSeconds(options.QbitorrentPollSeconds)); } }