public void InvalidMagnetLink3() { InfoHash hash = Create(); string magnet = string.Format("magnet:?xt=urn:btih:", hash.ToHex()); MagnetLink other = new MagnetLink(magnet); Assert.AreEqual(hash, other.InfoHash, "#1"); }
public void MagnetLink() { var hash = Create(); var magnet = string.Format("magnet:?xt=urn:btih:{0}", hash.ToHex()); var other = new MagnetLink(magnet); Assert.Equal(hash, other.InfoHash); }
public void InvalidMagnetLink4() { InfoHash hash = Create(); string magnet = string.Format("magnet:?xt=urn:btih:23526246235623564234365879634581726345981", hash.ToHex()); MagnetLink other = new MagnetLink(magnet); Assert.AreEqual(hash, other.InfoHash, "#1"); }
public void InvalidMagnetLink4() { var hash = Create(); var magnet = string.Format("magnet:?xt=urn:btih:23526246235623564234365879634581726345981", hash.ToHex()); MagnetLink other = null; Assert.Throws<FormatException>(() => other = new MagnetLink(magnet)); //Assert.Equal(hash, other.InfoHash); }
public void InvalidMagnetLink3() { var hash = Create(); var magnet = string.Format("magnet:?xt=urn:btih:", hash.ToHex()); MagnetLink other = null; Assert.Throws<FormatException>(() => other = new MagnetLink(magnet)); //Assert.Equal(hash, other.InfoHash); }
public void InfoHashTest() { MagnetLink link = new MagnetLink("magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"); Assert.AreEqual(InfoHash.FromBase32 ("YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"), link.InfoHash , "#1"); //base32 InfoHash initial = new InfoHash (System.Text.Encoding.ASCII.GetBytes("foobafoobafoobafooba")); link = new MagnetLink("magnet:?xt=urn:sha1:MZXW6YTBMZXW6YTBMZXW6YTBMZXW6YTB"); Assert.AreEqual(initial, link.InfoHash , "#2"); //base40 = hex InfoHash hash = Create(); string hex = hash.ToHex(); link = new MagnetLink("magnet:?xt=urn:btih:" + hex); Assert.AreEqual(hash, link.InfoHash , "#3"); }
public void InfoHashTest() { var link = new MagnetLink("magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"); Assert.Equal(InfoHash.FromBase32("YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"), link.InfoHash); //base32 var initial = new InfoHash(Encoding.ASCII.GetBytes("foobafoobafoobafooba")); link = new MagnetLink("magnet:?xt=urn:sha1:MZXW6YTBMZXW6YTBMZXW6YTBMZXW6YTB"); Assert.Equal(initial, link.InfoHash); //base40 = hex var hash = Create(); var hex = hash.ToHex(); link = new MagnetLink("magnet:?xt=urn:btih:" + hex); Assert.Equal(hash, link.InfoHash); }
private void AddClicked(object sender, RoutedEventArgs e) { if (customDestinationTextBox.IsFocused) { return; } try { string name; if (magnetLinkRadioButton.IsChecked.Value) { MagnetLink = new MagnetLink(magnetLinkTextBox.Text); name = HttpUtility.HtmlDecode(HttpUtility.UrlDecode(MagnetLink.Name)); } else { Torrent = Torrent.Load(torrentFileTextBox.Text); name = Torrent.Name; } if (defaultDestinationRadioButton.IsChecked.Value) { DestinationPath = DefaultLocation; } else if (recentRadioButton.IsChecked.Value) { var recent = recentItemsComboBox.SelectedItem as FolderBrowserItem; DestinationPath = recent.FullPath; } else { DestinationPath = customDestinationTextBox.Text; } Settings.RecentDownloadLocations = new[] { DestinationPath } .Concat(Settings.RecentDownloadLocations.Where(r => r != DestinationPath)).ToArray(); DestinationPath = Path.Combine(DestinationPath, ClientManager.CleanFileName(name)); } catch { MessageBox.Show("Unable to load this torrent.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return; } DialogResult = true; Close(); }
protected virtual string GetInfoHash(XElement item) { var magnetUrl = GetMagnetUrl(item); if (magnetUrl.IsNotNullOrWhiteSpace()) { try { return(MagnetLink.Parse(magnetUrl).InfoHash.ToHex()); } catch { } } return(null); }
/// <summary> /// Downloads the .torrent metadata for the provided MagnetLink. /// </summary> /// <param name="magnetLink">The MagnetLink to get the metadata for.</param> /// <param name="token">The cancellation token used to to abort the download. This method will /// only complete if the metadata successfully downloads, or the token is cancelled.</param> /// <returns></returns> public async Task<ReadOnlyMemory<byte>> DownloadMetadataAsync (MagnetLink magnetLink, CancellationToken token) { await MainLoop; var manager = new TorrentManager (this, magnetLink, "", new TorrentSettings ()); var metadataCompleted = new TaskCompletionSource<ReadOnlyMemory<byte>> (); using var registration = token.Register (() => metadataCompleted.TrySetResult (null)); manager.MetadataReceived += (o, e) => metadataCompleted.TrySetResult (e); await Register (manager, isPublic: false); await manager.StartAsync (metadataOnly: true); var data = await metadataCompleted.Task; await manager.StopAsync (); await RemoveAsync (manager); token.ThrowIfCancellationRequested (); return data; }
private static MagnetLink ParseHorribleSubNode(XmlNode item) { (var title, var link, var pubdate) = (item.SelectSingleNode("title")?.InnerText, item.SelectSingleNode("link")?.InnerText, DateTime.Parse(item.SelectSingleNode("pubDate")?.InnerText)); var magnet = new MagnetLink { Name = title, Remote = link, Date = pubdate, Hash = link.Split('&')[0], Trackers = link.Split(new[] { "&tr=" }, StringSplitOptions.None).Skip(1).ToList() }; return(magnet); }
#pragma warning disable CS0618 // Type or member is obsolete async Task <TorrentManager> AddAsync(MagnetLink magnetLink, Torrent torrent, string saveDirectory, TorrentSettings settings) { saveDirectory = string.IsNullOrEmpty(saveDirectory) ? Environment.CurrentDirectory : Path.GetFullPath(saveDirectory); TorrentManager manager; if (magnetLink != null) { var metadataSaveFilePath = Path.Combine(Settings.MetadataSaveDirectory, magnetLink.InfoHash.ToHex() + ".torrent"); manager = new TorrentManager(magnetLink, saveDirectory, settings, metadataSaveFilePath); } else { manager = new TorrentManager(torrent, saveDirectory, settings); } await Register(manager); return(manager); }
/// <summary> /// Creates a StreamProvider for the given <see cref="MagnetLink"/> so that files /// contained within the torrent can be accessed as they are downloading. /// </summary> /// <param name="engine">The engine used to host the download.</param> /// <param name="saveDirectory">The directory where the torrents data will be saved</param> /// <param name="magnetLink">The MagnetLink to download</param> /// <param name="metadataSaveDirectory">The directory where the metadata will be saved. The /// filename will be constucted by appending '.torrent' to the value returned by <see cref="InfoHash.ToHex ()"/> /// </param> public StreamProvider(ClientEngine engine, string saveDirectory, MagnetLink magnetLink, string metadataSaveDirectory) { Engine = engine; var path = Path.Combine(metadataSaveDirectory, $"{magnetLink.InfoHash.ToHex ()}.torrent"); Manager = new TorrentManager(magnetLink, saveDirectory, new TorrentSettings(), path); Manager.ChangePicker(Picker = new StreamingPiecePicker(new StandardPicker())); // If the metadata for this MagnetLink has been downloaded/cached already, we will synchronously // load it here and will have access to the list of Files. Otherwise we need to wait. if (Manager.HasMetadata) { Files = Manager.Files; } else { Manager.MetadataReceived += (o, e) => Files = Manager.Files; } }
public async void Download(SearchResponse sr, long chatId) { System.Console.WriteLine($"downloading {sr.Title}..."); //services var transmission = _scope.CreateScope().ServiceProvider.GetRequiredService <TransmissionService>().Client; var database = _scope.CreateScope().ServiceProvider.GetRequiredService <DatabaseContext>(); System.Console.WriteLine(Directory.GetCurrentDirectory()); var torrentSettings = new TorrentSettings(); NewTorrent torrent; System.Console.WriteLine("trying with magnet"); var metadata = await _engine.DownloadMetadataAsync(MagnetLink.Parse(sr.MagnetUrl), CancellationToken.None); System.Console.WriteLine("downloaded metadata"); torrent = new NewTorrent() { Metainfo = Convert.ToBase64String(metadata) }; var torrentInfo = transmission.TorrentAdd(torrent); if (database.ActiveTorrents.Any(at => at.TorrentId == torrentInfo.ID)) { return; } var activeTorrent = new ActiveTorrent() { ChatId = chatId, TorrentId = torrentInfo.ID, IsFinished = false, }; database.ActiveTorrents.Add(activeTorrent); database.SaveChanges(); }
public TorrentManager(MagnetLink magnetLink, string savePath, TorrentSettings settings, string torrentSave) { Check.MagnetLink(magnetLink); Check.InfoHash(magnetLink.InfoHash); Check.SavePath(savePath); Check.Settings(settings); Check.TorrentSave(torrentSave); this.infohash = magnetLink.InfoHash; this.settings = settings; this.torrentSave = torrentSave; IList <RawTrackerTier> announces = new RawTrackerTiers(); if (magnetLink.AnnounceUrls != null) { announces.Add(magnetLink.AnnounceUrls); } Initialise(savePath, "", announces); }
public async Task RecreateManager() { if (Manager != null) { if (Engine.Contains(Manager)) { await Engine.RemoveAsync(Manager); } Manager.Dispose(); } TorrentDict = CreateTorrent(piecelength, files, tier); Torrent = Torrent.Load(TorrentDict); var magnetLink = new MagnetLink(Torrent.InfoHash, null, tier[0].ToArray(), null, null); Manager = MetadataMode ? await Engine.AddAsync(magnetLink, savePath, new TorrentSettings()) : await Engine.AddAsync(Torrent, savePath, new TorrentSettings()); }
public void InfoHashTest() { MagnetLink link = new MagnetLink("magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"); Assert.Equal(InfoHash.FromBase32("YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"), link.InfoHash); //base32 InfoHash initial = new InfoHash(System.Text.Encoding.ASCII.GetBytes("foobafoobafoobafooba")); link = new MagnetLink("magnet:?xt=urn:sha1:MZXW6YTBMZXW6YTBMZXW6YTBMZXW6YTB"); Assert.Equal(initial, link.InfoHash); //base40 = hex InfoHash hash = Create(); string hex = hash.ToHex(); link = new MagnetLink("magnet:?xt=urn:btih:" + hex); Assert.Equal(hash, link.InfoHash); }
private void rssEntryAddClicked(object sender, RoutedEventArgs e) { var button = (sender as Button); var entry = (RssFeedEntry)button.Tag; var magnetLink = new MagnetLink(entry.Link); if (!SettingsManager.PromptForSaveOnShellLinks) { AddTorrent(magnetLink, SettingsManager.DefaultDownloadLocation); } else { var window = new AddTorrentWindow(SettingsManager); window.MagnetLink = magnetLink; if (window.ShowDialog().Value) { AddTorrent(window.MagnetLink, window.DestinationPath); } } }
/// <summary> /// Downloads the .torrent metadata for the provided MagnetLink. /// </summary> /// <param name="magnetLink">The MagnetLink to get the metadata for.</param> /// <param name="token">The cancellation token used to to abort the download. This method will /// only complete if the metadata successfully downloads, or the token is cancelled.</param> /// <returns></returns> public async Task <byte[]> DownloadMetadataAsync(MagnetLink magnetLink, CancellationToken token) { var manager = new TorrentManager(magnetLink); var metadataCompleted = new TaskCompletionSource <byte[]> (); using var registration = token.Register(() => metadataCompleted.TrySetResult(null)); manager.MetadataReceived += (o, e) => metadataCompleted.TrySetResult(e); await Register(manager, isPublic : false); await manager.StartAsync(metadataOnly : true); var data = await metadataCompleted.Task; await manager.StopAsync(); await Unregister(manager); token.ThrowIfCancellationRequested(); return(data); }
public IActionResult MagnetDetail(string hash) { if (string.IsNullOrEmpty(hash) || hash.Length != 40) { return(new RedirectResult("/error")); } var model = new MagnetLink(); var cacheKey = $"d_m_{hash}"; if (!_memoryCache.TryGetValue(cacheKey, out model)) { model = _magnetSearchService.MagnetLinkInfo(hash); if (model == null) { return(new RedirectResult("/error")); } _memoryCache.Set(cacheKey, model, new TimeSpan(0, 30, 0)); } return(View(model)); }
public TorrentManager(MagnetLink magnetLink, StorageFolder savePath, TorrentSettings settings, StorageFolder torrentSaveFolder) { Check.MagnetLink(magnetLink); Check.InfoHash(magnetLink.InfoHash); Check.SaveFolder(savePath); Check.Settings(settings); Check.TorrentSave(torrentSaveFolder); InfoHash = magnetLink.InfoHash; Settings = settings; _torrentSaveFolder = torrentSaveFolder; IList <RawTrackerTier> announces = new RawTrackerTiers(); if (magnetLink.AnnounceUrls != null) { announces.Add(magnetLink.AnnounceUrls); } Initialise(savePath, "", announces); }
static async Task Main() { var magnetLink = MagnetLink.Parse(MagnetUrl); var cacheDir = Path.Join(Path.GetTempPath(), "BitTorrentStorage"); var config = new BitTorrentStorageConfig(cacheDir); using var btsStorage = BtsClient.Initialize(config); Console.WriteLine("Initializing the torrent."); using var torrentManager = await btsStorage.OpenMagnetLink(magnetLink); Console.WriteLine("Starting BitTorrentStorage FUSE."); Console.WriteLine($"Mounting to \"{MountPath}\"."); var fs = new BtsFs(torrentManager) { MountPoint = MountPath }; Directory.CreateDirectory(MountPath); fs.Start(); }
public static byte[] GetMagnetFromCache(MagnetLink mg) { for (int i = 0; i < TorrentCaches.Length; i++) { try { byte[] res = TorrentCaches[i].Fetch(mg); if (res != null) { return(res); } } catch { continue; } } return(null); }
protected virtual string GetInfoHash(XElement item) { if (InfoHashElementName.IsNotNullOrWhiteSpace()) { return(item.FindDecendants(InfoHashElementName).FirstOrDefault().Value); } var magnetUrl = GetMagnetUrl(item); if (magnetUrl.IsNotNullOrWhiteSpace()) { try { return(MagnetLink.Parse(magnetUrl).InfoHash.ToHex()); } catch { } } return(null); }
public TorrentManager(MagnetLink magnetLink, string savePath, TorrentSettings settings, string torrentSave) { Torrent torrent; Check.MagnetLink(magnetLink); Check.InfoHash(magnetLink.InfoHash); Check.SavePath(savePath); Check.Settings(settings); Check.TorrentSave(torrentSave); this.infohash = magnetLink.InfoHash; this.settings = settings; this.torrentSave = torrentSave; IList <RawTrackerTier> announces = new RawTrackerTiers(); if (magnetLink.AnnounceUrls != null) { announces.Add(magnetLink.AnnounceUrls); } this.webseeds = new List <String>(); if (magnetLink.Webseeds != null) { foreach (string webseed in magnetLink.Webseeds) { this.webseeds.Add(webseed); } } if (Torrent.TryLoad(torrentSave, out torrent) && torrent.InfoHash == magnetLink.InfoHash) { this.torrent = torrent; Initialise(savePath, "", announces); ChangePicker(CreateStandardPicker()); return; } Initialise(savePath, "", announces); }
public async void AddTorrentByMagnet(string magnet, bool notifyIfAdded = true) { MagnetLink mg = null; try { mg = new MagnetLink(magnet); } catch { MessageBox.Show("Invalid magnet link", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return; } if (this.ContainTorrent(mg.InfoHash.ToHex())) { if (notifyIfAdded) { NotificationManager.Notify(new TorrentAlreadyAddedNotification(mg.Name, mg.InfoHash.ToHex())); } return; } if (App.Settings.PreferMagnetCacheWebsites) { byte[] torrent_data = await System.Threading.Tasks.Task.Run <byte[]>(() => State.GetMagnetFromCache(mg)); if (torrent_data != null) { string path = this.SaveMagnetLink(torrent_data, mg.Name); this.AddTorrentByPath(path); return; } } this.LibtorrentSession.AsyncAddTorrent(new Ragnar.AddTorrentParams() { SavePath = App.Settings.DefaultDownloadPath, Url = magnet, Name = string.IsNullOrEmpty(mg.Name) ? "" : mg.Name }); //NotificationManager.Notify(new MagnetLinkNotification(MagnetLinkNotification.EventType.MetadataDownloadStarted, mg)); }
public PeriodicTorrent AddTorrent(MagnetLink link, string path, bool suppressMessages = false) { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var name = HttpUtility.HtmlDecode(HttpUtility.UrlDecode(link.Name)); var cache = Path.Combine( SettingsManager.TorrentCachePath, ClientManager.CleanFileName(name) + ".torrent"); for (int i = 0; i < link.AnnounceUrls.Count; i++) { link.AnnounceUrls[i] = HttpUtility.UrlDecode(HttpUtility.UrlDecode(link.AnnounceUrls[i])); } var wrapper = new TorrentWrapper(link, path, new TorrentSettings(), cache); if (Client.Torrents.Any(t => t.Torrent.InfoHash == wrapper.InfoHash)) { if (!suppressMessages) { MessageBox.Show(name + " has already been added.", "Error"); } return(null); } var periodic = Client.AddTorrent(wrapper); periodic.CacheFilePath = cache; periodic.UpdateInfo(); var serializer = new JsonSerializer(); using (var writer = new StreamWriter(Path.Combine(SettingsManager.TorrentCachePath, Path.GetFileNameWithoutExtension(periodic.CacheFilePath) + ".info"))) serializer.Serialize(new JsonTextWriter(writer), periodic.TorrentInfo); return(periodic); }
public PrioritizedTorrentManager(int priority, MagnetLink magnetLink, string savePath, TorrentSettings settings, string torrentSave) : base(magnetLink, savePath, settings, torrentSave) { this.Priority = priority; }
public UserTorrentManager(MagnetLink magnetLink, string savePath, TorrentSettings settings, string torrentSave) : base(magnetLink, savePath, settings, torrentSave) { }
public void NameTest() { var other = new MagnetLink("magnet:?dn=foo"); Assert.NotNull(other.Name); Assert.Equal("foo", other.Name); }
internal async Task StreamAsync(MagnetLink magnetLink, CancellationToken token) => await StreamAsync(await Engine.AddStreamingAsync(magnetLink, DownloadDirectory), token);
public Task <TorrentManager> AddStreamingAsync(MagnetLink magnetLink, string saveDirectory, TorrentSettings settings) => AddStreamingAsync(magnetLink, null, saveDirectory, settings);
public void TrackersTest() { MagnetLink other = new MagnetLink("magnet:?tr=http://example.com/announce&tr.2=http://example.com/announce2"); Assert.IsNotNull (other.AnnounceUrls, "#1"); Assert.IsTrue (other.AnnounceUrls.Contains ("http://example.com/announce"), "#2"); Assert.IsTrue (other.AnnounceUrls.Contains ("http://example.com/announce2"), "#3"); }
public void TrackersTest() { var other = new MagnetLink("magnet:?tr=http://example.com/announce&tr.2=http://example.com/announce2"); Assert.NotNull(other.AnnounceUrls); Assert.True(other.AnnounceUrls.Contains("http://example.com/announce")); Assert.True(other.AnnounceUrls.Contains("http://example.com/announce2")); }
public void TrackersUrlEncodedTest() { var other = new MagnetLink("magnet:?xt=urn:ed2k:354B15E68FB8F36D7CD88FF94116CDC1" + "&xl=10826029&dn=mediawiki-1.15.1.tar.gz"+ "&xt=urn:tree:tiger:7N5OAMRNGMSSEUE3ORHOKWN4WWIQ5X4EBOOTLJY" + "&xt=urn:btih:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C" + "&tr=http%3A%2F%2Ftracker.example.org%2Fannounce.php%3Fuk%3D1111111111%26" + "&tr=udp%3A%2F%2Fexample.org%3A28191" + "&tr=tcp%3A%2F%2F%5B2001%3Adb8%3A85a3%3A8d3%3A1319%3A8a2e%3A370%3A7348%5D"); Assert.IsNotNull(other.AnnounceUrls, "#1"); Assert.IsTrue(other.AnnounceUrls.Contains("http://tracker.example.org/announce.php?uk=1111111111&"), "#2"); Assert.IsTrue(other.AnnounceUrls.Contains("udp://example.org:28191"), "#3"); Assert.IsTrue(other.AnnounceUrls.Contains("tcp://[2001:db8:85a3:8d3:1319:8a2e:370:7348]"), "#4"); }
static void TestMagnetLink() { var ubuntuMagnetLink = "magnet:?xt=urn:btih:e4be9e4db876e3e3179778b03e906297be5c8dbe&dn=ubuntu-18.04-desktop-amd64.iso&tr=http://torrent.ubuntu.com:6969/announce"; var magnetLink = MagnetLink.Resolve(ubuntuMagnetLink); }
public async Task DownloadAsync(MagnetLink link) { var engine = new ClientEngine(); var manager = await engine.AddStreamingAsync(link, "downloads"); var times = new List <(string message, TimeSpan time)> (); var overall = Stopwatch.StartNew(); var firstPeerFound = Stopwatch.StartNew(); var firstPeerConnected = Stopwatch.StartNew(); manager.PeerConnected += (o, e) => { if (!firstPeerConnected.IsRunning) { return; } firstPeerConnected.Stop(); lock (times) times.Add(("First peer connected. Time since torrent started: ", firstPeerConnected.Elapsed)); }; manager.PeersFound += (o, e) => { if (!firstPeerFound.IsRunning) { return; } firstPeerFound.Stop(); lock (times) times.Add(($"First peers found via {e.GetType ().Name}. Time since torrent started: ", firstPeerFound.Elapsed)); }; manager.PieceHashed += (o, e) => { if (manager.State != TorrentState.Downloading) { return; } lock (times) times.Add(($"Piece {e.PieceIndex} hashed. Time since torrent started: ", overall.Elapsed)); }; await manager.StartAsync(); await manager.WaitForMetadataAsync(); var largestFile = manager.Files.OrderByDescending(t => t.Length).First(); var stream = await manager.StreamProvider.CreateStreamAsync(largestFile, false); // Read the middle await TimedRead(manager, stream, stream.Length / 2, times); // Then the start await TimedRead(manager, stream, 0, times); // Then the last piece await TimedRead(manager, stream, stream.Length - 2, times); // Then the 3rd last piece await TimedRead(manager, stream, stream.Length - manager.PieceLength * 3, times); // Then the 5th piece await TimedRead(manager, stream, manager.PieceLength * 5, times); // Then 1/3 of the way in await TimedRead(manager, stream, stream.Length / 3, times); // Then 2/3 of the way in await TimedRead(manager, stream, stream.Length / 3 * 2, times); // Then 1/5 of the way in await TimedRead(manager, stream, stream.Length / 5, times); // Then 4/5 of the way in await TimedRead(manager, stream, stream.Length / 5 * 4, times); lock (times) { foreach (var p in times) { Console.WriteLine($"{p.message} {p.time.TotalSeconds:0.00} seconds"); } } await manager.StopAsync(); }
public Task <bool> RemoveAsync(MagnetLink magnetLink) => RemoveAsync(magnetLink, RemoveMode.CacheDataOnly);
public Task <TorrentManager> AddStreamingAsync(MagnetLink magnetLink, string saveDirectory) => AddStreamingAsync(magnetLink, saveDirectory, new TorrentSettings());
public void NameTest() { MagnetLink other = new MagnetLink("magnet:?dn=foo"); Assert.IsNotNull (other.Name, "#1"); Assert.AreEqual ("foo", other.Name, "#2"); }
public Task <bool> RemoveAsync(MagnetLink magnetLink) { magnetLink = magnetLink ?? throw new ArgumentNullException(nameof(magnetLink)); return(RemoveAsync(magnetLink.InfoHash)); }
public TorrentHandler(MagnetLink ML, string DownloadDir = DOWNLOAD_DIR) { InitBase(DownloadDir); TM = new TorrentManager(ML, Environment.ExpandEnvironmentVariables(DownloadDir), TS, Environment.ExpandEnvironmentVariables(TORRENT_DIR)); Assign(); }