private void SaveResumeDataAlert(Core.save_resume_data_alert a) { Interlocked.MemoryBarrier(); TorrentHandle h = null; BinaryWriter bw = null; FileStream fs = null; try { h = a.handle; using (TorrentInfo ti = h.torrent_file()) using (Sha1Hash hash = h.info_hash()) { log.Debug("processing {0}", ti.name()); string newfilePath = ("./Fastresume/" + hash.ToString() + ".fastresume"); var data = Core.Util.bencode(a.resume_data); fs = new FileStream(newfilePath, FileMode.OpenOrCreate); bw = new BinaryWriter(fs); bw.Write(data); bw.Close(); log.Debug("done {0}", ti.name()); } //log.Debug(" for {0}", h.torrent_file().name()); //string newfilePath = ("./Fastresume/" + h.info_hash().ToString() + ".fastresume"); //var data = Core.Util.bencode(a.resume_data); //fs = new FileStream(newfilePath, FileMode.OpenOrCreate); //bw = new BinaryWriter(fs); //bw.Write(data); //bw.Close(); } finally { if (!ReferenceEquals(null, h)) { h.Dispose(); } if (!ReferenceEquals(null, bw)) { bw.Dispose(); } if (!ReferenceEquals(null, fs)) { fs.Dispose(); } } Interlocked.Decrement(ref outstanding_resume_data); if (outstanding_resume_data == 0 && no_more_resume) { no_more_data.Set(); } }
private Torrent(AddTorrentParams addParams, Session session) { fastResumeDir = Path.Combine(appDataFolder, ".resume"); torrentDir = Path.Combine(appDataFolder, ".torrents"); activeTorrentsFile = Path.Combine(appDataFolder, ".download"); LoadTorrentState(ref addParams); handle = session.AddTorrent(addParams); handle.SequentialDownload = true; handle.AutoManaged = false; handle.FlushCache(); this.session = session; Url = addParams.Url; active = true; }
public TorrentInfo(TorrentHandle t) { RanCommand = false; this.Torrent = t; this.StatusData = t.QueryStatus(); this.MainAppWindow = (App.Current.MainWindow as MainWindow); this.PickedMovieData = new IMDBSRSerializeable <IMovieDBSearchResult>(); this.Trackers = new ObservableCollection <TrackerInfo>(); if (t.HasMetadata) { SetupTorrent(); } PopulateTrackerList(); }
internal static ITorrent CreateFromHandle(TorrentHandle handle, ITorrentMetadataRepository metadataRepository) { using (handle) using (var file = handle.TorrentFile) using (var status = handle.QueryStatus()) { var t = new Torrent { InfoHash = handle.InfoHash.ToHex(), Name = status.Name, SavePath = status.SavePath, Size = file == null ? -1 : file.TotalSize, Progress = status.Progress, DownloadSpeed = status.DownloadRate, UploadSpeed = status.UploadRate, TotalDownloadedBytes = status.TotalDownload, TotalUploadedBytes = status.TotalUpload, State = (Common.BitTorrent.TorrentState)(int) status.State, Paused = status.Paused, Files = new ITorrentFile[file == null ? 0 : file.NumFiles], Peers = handle.GetPeerInfo().Select(Peer.CreateFromPeerInfo).ToArray() }; t.Label = metadataRepository.GetLabel(t.InfoHash); // If no torrent file (ie. downloading metadata) if (file == null) { return(t); } var progresses = handle.GetFileProgresses(); var priorities = handle.GetFilePriorities(); for (var i = 0; i < file.NumFiles; i++) { var entry = file.FileAt(i); var torrentFile = TorrentFile.CreateFromEntry(entry, progresses[i], priorities[i]); t.Files[i] = torrentFile; } return(t); } }
internal static ITorrent CreateFromHandle(TorrentHandle handle, ITorrentMetadataRepository metadataRepository) { using (handle) using (var file = handle.TorrentFile) using (var status = handle.QueryStatus()) { var t = new Torrent { InfoHash = handle.InfoHash.ToHex(), Name = status.Name, SavePath = status.SavePath, Size = file == null ? -1 : file.TotalSize, Progress = status.Progress, DownloadSpeed = status.DownloadRate, UploadSpeed = status.UploadRate, TotalDownloadedBytes = status.TotalDownload, TotalUploadedBytes = status.TotalUpload, State = (Common.BitTorrent.TorrentState) (int) status.State, Paused = status.Paused, Files = new ITorrentFile[file == null ? 0 : file.NumFiles], Peers = handle.GetPeerInfo().Select(Peer.CreateFromPeerInfo).ToArray() }; t.Label = metadataRepository.GetLabel(t.InfoHash); // If no torrent file (ie. downloading metadata) if (file == null) return t; var progresses = handle.GetFileProgresses(); var priorities = handle.GetFilePriorities(); for (var i = 0; i < file.NumFiles; i++) { var entry = file.FileAt(i); var torrentFile = TorrentFile.CreateFromEntry(entry, progresses[i], priorities[i]); t.Files[i] = torrentFile; } return t; } }
public void AddTorrentFromFile() { try { if (!IsDisposed) { byte[] bytes = File.ReadAllBytes(torrentFilePath); ti = new TorrentInfo(bytes); using (cMainForm.session) { cMainForm.session.ListenOn(6881, 6889); #region Torrent Parameters AddTorrentParams addParams = new AddTorrentParams(); if (unlimitedDownloadSpeed == false) { addParams.DownloadLimit = maxDownloadSpeed * 1024;//Transform byte to kB } if (unlimitedUploadSpeed == false) { addParams.UploadLimit = maxUploadSpeed * 1024; } addParams.TorrentInfo = ti; addParams.SavePath = string.Concat(saveFilePath, @"\", ti.Name); //This is weird, check it out later string resumeFile = Path.ChangeExtension(torrentFilePath, "resume"); if (File.Exists(resumeFile)) { addParams.ResumeData = File.ReadAllBytes(resumeFile);// Loading the resume data will load all torrents settings } #endregion // Add a torrent to the session and get a `TorrentHandle` in return. There is only one session that contains many handles. handle = cMainForm.session.AddTorrent(addParams); handle.SetPriority(128); if (handle.NeedSaveResumeData() == true) { SaveResumeData(); } SetLimitString(); cMainForm.mainForm.RunOnUIThread(() => cMainForm.mainForm.AddToMainList(ti.Name, ti.TotalSize, torrentIndex)); while (true) { if (pause == true) { PauseHandle(); } else if (handle.IsPaused == true && pause == false) { ResumeHandle(); } // Get a `TorrentStatus` instance from the handle. TorrentStatus status = handle.QueryStatus(); IEnumerable <PeerInfo> connectedPeers; connectedPeers = handle.GetPeerInfo(); if (status.IsSeeding) { break; } elapsedTime = status.ActiveTime; downloaded = status.Progress * 100; uploaded = status.TotalUpload * 100; uploadSpeed = status.UploadRate; downloadSpeed = status.DownloadRate; currentStatus = status.State.ToString(); UpdateProgressBar(downloaded); if (connectedPeers.Count() > 0 && cMainForm.mainForm.mainToolStripBottom.SelectedIndex == 2)//2 is client tab { cMainForm.mainForm.RunOnUIThread(() => cMainForm.mainForm.AddToClientList(connectedPeers, torrentIndex)); } if (cMainForm.mainForm.mainToolStripBottom.SelectedIndex == 0)//0 is info tab { cMainForm.mainForm.RunOnUIThread(() => cMainForm.mainForm.UpdateInfoTabData(downloaded.ToString(), uploaded.ToString(), uploadSpeed, downloadSpeed, formattedDownLimit, formattedUpLimit, currentStatus, elapsedTime.ToString(), torrentIndex)); } ; cMainForm.mainForm.RunOnUIThread(() => cMainForm.mainForm.EditMainList(downloaded.ToString(), uploadSpeed, downloadSpeed, currentStatus, torrentIndex)); Thread.Sleep(100); } } } } catch (Exception ex) { MessageBox.Show(ex.ToString(), "AddTorrentFromFile -- " + ex, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public void AddTorrentFromMagnet() { try { if (!IsDisposed) { using (cMainForm.session) { MagnetLink magnet = null; try { magnet = new MagnetLink(magnetLink); } catch { MessageBox.Show("Invalid magnet link", "Error"); return; } cMainForm.session.ListenOn(6881, 6889); #region Torrent Parameters AddTorrentParams addParams = new AddTorrentParams(); if (unlimitedDownloadSpeed == false) { addParams.DownloadLimit = maxDownloadSpeed * 1024;//Transform byte to kB } if (unlimitedUploadSpeed == false) { addParams.UploadLimit = maxUploadSpeed * 1024; } if (magnet.Name != null) { addParams.Name = magnet.Name; } addParams.Url = magnetLink; addParams.SavePath = saveFilePath; //This is weird, check it out later #endregion // Add a torrent to the session and get a `TorrentHandle` in return. There is only one session that contains many handles. handle = cMainForm.session.AddTorrent(addParams); handle.SetPriority(128); SetLimitString(); cMainForm.mainForm.RunOnUIThread(() => cMainForm.mainForm.AddToMainList(magnet.Name, handle.QueryStatus().TotalPayloadDownload, torrentIndex)); //ti doesn't exist here, you need to use info hash to get the name and size while (true) { if (pause == true) { PauseHandle(); } else if (handle.IsPaused == true && pause == false) { ResumeHandle(); } // Get a `TorrentStatus` instance from the handle. TorrentStatus status = handle.QueryStatus(); IEnumerable <PeerInfo> connectedPeers; connectedPeers = handle.GetPeerInfo(); if (status.IsSeeding) //If download is finished { break; } elapsedTime = status.ActiveTime; downloaded = status.Progress * 100; uploadSpeed = status.UploadRate; downloadSpeed = status.DownloadRate; currentStatus = status.State.ToString(); UpdateProgressBar(downloaded); if (connectedPeers.Count() > 0 && cMainForm.mainForm.mainToolStripBottom.SelectedIndex == 2)//2 is client tab { cMainForm.mainForm.RunOnUIThread(() => cMainForm.mainForm.AddToClientList(connectedPeers, torrentIndex)); } if (cMainForm.mainForm.mainToolStripBottom.SelectedIndex == 0)//0 is info tab { cMainForm.mainForm.RunOnUIThread(() => cMainForm.mainForm.UpdateInfoTabData(downloaded.ToString(), uploaded.ToString(), uploadSpeed, downloadSpeed, formattedDownLimit, formattedUpLimit, currentStatus, elapsedTime.ToString(), torrentIndex)); } if (cMainForm.mainForm.mainToolStripBottom.SelectedIndex == 1) //1 is file tab { cMainForm.mainForm.RunOnUIThread(() => cMainForm.mainForm.AddFilesToList(GetFilePriorities(), torrentIndex)); //Should send list of files instead of priorities but i don't know how to get the files :( } cMainForm.mainForm.RunOnUIThread(() => cMainForm.mainForm.EditMainList(downloaded.ToString(), uploadSpeed, downloadSpeed, currentStatus, torrentIndex)); Thread.Sleep(1); } } } } catch (Exception ex) { MessageBox.Show(ex.ToString(), "AddTorrentFromMagnet -- " + ex, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Download media /// </summary> /// <param name="media">Media file <see cref="IMediaFile"/></param> /// <param name="savePath">Save path of the media</param> /// <param name="type">Media type <see cref="MediaType"/></param> /// <param name="uploadLimit">Upload limit</param> /// <param name="downloadLimit">Download limit</param> /// <param name="downloadProgress">Download progress</param> /// <param name="bandwidthRate">Download rate</param> /// <param name="nbSeeds">Number of seeders</param> /// <param name="nbPeers">Number of peers</param> /// <param name="handle"><see cref="TorrentHandle"/></param> /// <param name="session"><see cref="Session"/></param> /// <param name="buffered">Action to execute when media has been buffered</param> /// <param name="cancelled">Action to execute when media download has been cancelled</param> /// <param name="cts"><see cref="CancellationTokenSource"/></param> /// <returns><see cref="Task"/></returns> private async Task HandleDownload(T media, string savePath, MediaType type, int uploadLimit, int downloadLimit, IProgress <double> downloadProgress, IProgress <BandwidthRate> bandwidthRate, IProgress <int> nbSeeds, IProgress <int> nbPeers, TorrentHandle handle, Session session, Action buffered, Action cancelled, CancellationTokenSource cts) { handle.set_upload_limit(uploadLimit * 1024); handle.set_download_limit(downloadLimit * 1024); handle.set_sequential_download(true); var alreadyBuffered = false; var bandwidth = new Progress <BandwidthRate>(); var prog = new Progress <double>(); var playingProgress = new Progress <double>(); var sw = new Stopwatch(); sw.Start(); var mediaIndex = -1; long maxSize = 0; var filePath = string.Empty; using var torrentFile = handle.torrent_file(); var torrentStorage = torrentFile.files(); while (!cts.IsCancellationRequested) { using var status = handle.status(); var progress = 0d; if (status.has_metadata) { var totalSizeExceptIgnoredFiles = torrentFile.total_size(); if (mediaIndex == -1 || string.IsNullOrEmpty(filePath)) { var numFiles = torrentStorage.num_files(); for (var i = 0; i < numFiles; i++) { var currentSize = torrentStorage.file_size(i); if (currentSize > maxSize) { maxSize = currentSize; mediaIndex = i; } } for (var i = 0; i < numFiles; i++) { if (i != mediaIndex) { handle.file_priority(i, 0); totalSizeExceptIgnoredFiles -= torrentStorage.file_size(i); } } var fullPath = torrentStorage.file_path(mediaIndex, savePath); var shortPath = Directory.GetParent(fullPath).FullName.GetShortPath(); filePath = Path.Combine(shortPath, torrentStorage.file_name(mediaIndex)); } var fileProgressInBytes = handle.file_progress(1)[mediaIndex]; progress = (double)fileProgressInBytes / (double)totalSizeExceptIgnoredFiles * 100d; var downRate = Math.Round(status.download_rate / 1024d, 0); var upRate = Math.Round(status.upload_rate / 1024d, 0); nbSeeds.Report(status.num_seeds); nbPeers.Report(status.num_peers); downloadProgress.Report(progress); var eta = sw.GetEta(fileProgressInBytes, totalSizeExceptIgnoredFiles); bandwidthRate.Report(new BandwidthRate { DownloadRate = downRate, UploadRate = upRate, ETA = eta }); ((IProgress <double>)prog).Report(progress); ((IProgress <BandwidthRate>)bandwidth).Report(new BandwidthRate { DownloadRate = downRate, UploadRate = upRate, ETA = eta }); } double minimumBuffering; switch (type) { case MediaType.Show: minimumBuffering = Constants.MinimumShowBuffering; break; default: minimumBuffering = Constants.MinimumMovieBuffering; break; } if (mediaIndex != -1 && progress >= minimumBuffering && !alreadyBuffered) { buffered.Invoke(); if (!string.IsNullOrEmpty(filePath)) { alreadyBuffered = true; media.FilePath = filePath; BroadcastMediaBuffered(media, prog, bandwidth, playingProgress); } if (!alreadyBuffered) { session.remove_torrent(handle); if (type == MediaType.Unkown) { Messenger.Default.Send( new UnhandledExceptionMessage( new PopcornException( LocalizationProviderHelper.GetLocalizedValue <string>( "NoMediaInDroppedTorrent")))); } else { Messenger.Default.Send( new UnhandledExceptionMessage( new PopcornException( LocalizationProviderHelper.GetLocalizedValue <string>("NoMediaInTorrent")))); } break; } } try { await Task.Delay(1000, cts.Token); } catch (Exception ex) when(ex is TaskCanceledException || ex is ObjectDisposedException) { cancelled.Invoke(); sw.Stop(); try { session.remove_torrent(handle); } catch (Exception) { // ignored } break; } } }
/// <summary> /// Download a movie /// </summary> /// <param name="movie">The movie to download</param> private async Task DownloadMovie(MovieFullDetails movie) { using (Session session = new Session()) { IsDownloadingMovie = true; // Inform subscribers we're actually loading a movie OnDownloadingMovie(new EventArgs()); // Listening to a port which is randomly between 6881 and 6889 session.ListenOn(6881, 6889); var addParams = new AddTorrentParams { // Where do we save the video file SavePath = Constants.MovieDownloads, // At this time, no quality selection is available in the interface, so we take the lowest Url = movie.Torrents.Aggregate((i1, i2) => (i1.SizeBytes < i2.SizeBytes ? i1 : i2)).Url }; TorrentHandle handle = session.AddTorrent(addParams); // We have to download sequentially, so that we're able to play the movie without waiting handle.SequentialDownload = true; bool alreadyBuffered = false; while (IsDownloadingMovie) { TorrentStatus status = handle.QueryStatus(); double progress = status.Progress * 100.0; // Inform subscribers of our progress OnLoadingMovieProgress(new MovieLoadingProgressEventArgs(progress, status.DownloadRate / 1024)); // We consider 2% of progress is enough to start playing if (progress >= Constants.MinimumBufferingBeforeMoviePlaying && !alreadyBuffered) { try { // We're looking for video file foreach (string directory in Directory.GetDirectories(Constants.MovieDownloads)) { foreach ( string filePath in Directory.GetFiles(directory, "*" + Constants.VideoFileExtension) ) { // Inform subscribers we have finished buffering the movie OnBufferedMovie(new MovieBufferedEventArgs(filePath)); alreadyBuffered = true; } } } catch (Exception e) { Console.WriteLine(e.Message); } } // Let sleep for a second before updating the torrent status await Task.Delay(1000, CancellationDownloadingToken.Token).ContinueWith(_ => { if (CancellationDownloadingToken.IsCancellationRequested && session != null) { OnStoppedDownloadingMovie(new EventArgs()); IsDownloadingMovie = false; session.RemoveTorrent(handle, true); } }).ConfigureAwait(false); } } }
public TorrentFileInfo(TorrentHandle handle, int fileindex) { this.fileindex = fileindex; this.handle = handle; }