Esempio n. 1
0
 public void RemoveTorrent(torrent_handle torrentHandle, bool deleteFromDisk)
 {
     try
     {
         torrentHandle.pause();
         _session.remove_torrent(torrentHandle, deleteFromDisk ? 1 : 0);
     }
     catch
     {
         //
     }
     finally
     {
         torrentHandle.Dispose();
     }
 }
Esempio n. 2
0
        /// <summary>
        /// Download media
        /// </summary>
        /// <param name="media">Media file <see cref="IMediaFile"/></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="torrent_handle"/></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, MediaType type, int uploadLimit, int downloadLimit,
                                          IProgress <double> downloadProgress, IProgress <BandwidthRate> bandwidthRate, IProgress <int> nbSeeds, IProgress <int> nbPeers,
                                          torrent_handle handle,
                                          session session, Action buffered, Action cancelled, CancellationTokenSource cts)
        {
            handle.set_upload_limit(uploadLimit * 1024);
            handle.set_download_limit(downloadLimit * 1024);
            var alreadyBuffered    = false;
            var bandwidth          = new Progress <BandwidthRate>();
            var prog               = new Progress <double>();
            var playingProgress    = new Progress <double>();
            var playingProgression = 0d;

            playingProgress.ProgressChanged += (sender, d) =>
            {
                playingProgression = d;
            };

            IProgress <PieceAvailability> pieceAvailability = new Progress <PieceAvailability>();
            Stopwatch sw = new Stopwatch();

            sw.Start();

            while (!cts.IsCancellationRequested)
            {
                using (var status = handle.status())
                {
                    var filePath = string.Empty;
                    var progress = status.progress * 100d;
                    if (status.has_metadata)
                    {
                        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 numFiles  = handle.torrent_file().num_files();
                        var fileIndex = -1;
                        for (var i = 0; i < numFiles; i++)
                        {
                            var path = handle.torrent_file().file_at(i);
                            if (path.EndsWith(".mp4") || path.EndsWith(".mkv") ||
                                path.EndsWith(".mov") || path.EndsWith(".avi"))
                            {
                                fileIndex = i;
                                filePath  = $@"{Directory.GetParent(status.save_path)}\{path}";
                            }
                        }

                        var fileProgress = handle.file_progress(1)[fileIndex];
                        var eta          = sw.GetEta(fileProgress, handle.torrent_file().total_size());
                        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
                        });

                        var numPieces = handle.torrent_file().num_pieces() - 1;
                        var cursor    = Math.Floor((numPieces - 3 * numPieces / 100d) * playingProgression);
                        var pieces    = handle.piece_priorities()
                                        .Select((piece, index) => new { Piece = piece, Index = index })
                                        .ToList();

                        var lastPieceAvailableIndex = 0;
                        foreach (var piece in pieces.Where(a => a.Index >= cursor))
                        {
                            if (!handle.have_piece(piece.Index))
                            {
                                handle.set_piece_deadline(piece.Index, 50);
                                foreach (var otherPiece in pieces.Where(a => a.Index != piece.Index))
                                {
                                    handle.reset_piece_deadline(otherPiece.Index);
                                }

                                break;
                            }
                            else
                            {
                                lastPieceAvailableIndex = piece.Index;
                                handle.reset_piece_deadline(piece.Index);
                            }
                        }

                        pieceAvailability.Report(new PieceAvailability(numPieces, pieces.FirstOrDefault(a => a.Index >= cursor - 3 * numPieces / 100d).Index, lastPieceAvailableIndex));
                    }

                    handle.flush_cache();
                    if (handle.need_save_resume_data())
                    {
                        handle.save_resume_data(1);
                    }

                    double minimumBuffering;
                    switch (type)
                    {
                    case MediaType.Show:
                        minimumBuffering = Constants.MinimumShowBuffering;
                        break;

                    default:
                        minimumBuffering = Constants.MinimumMovieBuffering;
                        break;
                    }

                    if (progress >= minimumBuffering && !alreadyBuffered)
                    {
                        buffered.Invoke();
                        if (!string.IsNullOrEmpty(filePath))
                        {
                            alreadyBuffered = true;
                            media.FilePath  = filePath;
                            BroadcastMediaBuffered(media, prog, bandwidth, playingProgress, (Progress <PieceAvailability>)pieceAvailability);
                        }

                        if (!alreadyBuffered)
                        {
                            session.remove_torrent(handle, 0);
                            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 (TaskCanceledException)
                    {
                        cancelled.Invoke();
                        sw.Stop();
                        try
                        {
                            session.remove_torrent(handle, 1);
                        }
                        catch (Exception) { }
                        break;
                    }
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Download media
        /// </summary>
        /// <param name="media">Media file <see cref="IMediaFile"/></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="torrent_handle"/></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, MediaType type, int uploadLimit, int downloadLimit,
                                          IProgress <double> downloadProgress,
                                          IProgress <BandwidthRate> bandwidthRate, IProgress <int> nbSeeds, IProgress <int> nbPeers, torrent_handle 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>();

            while (!cts.IsCancellationRequested)
            {
                using (var status = handle.status())
                {
                    var progress = status.progress * 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);
                    bandwidthRate.Report(new BandwidthRate
                    {
                        DownloadRate = downRate,
                        UploadRate   = upRate
                    });

                    ((IProgress <double>)prog).Report(progress);
                    ((IProgress <BandwidthRate>)bandwidth).Report(new BandwidthRate
                    {
                        DownloadRate = downRate,
                        UploadRate   = upRate
                    });

                    handle.flush_cache();
                    if (handle.need_save_resume_data())
                    {
                        handle.save_resume_data(1);
                    }

                    double minimumBuffering;
                    switch (type)
                    {
                    case MediaType.Movie:
                        minimumBuffering = Constants.MinimumMovieBuffering;
                        break;

                    case MediaType.Show:
                        minimumBuffering = Constants.MinimumShowBuffering;
                        break;

                    case MediaType.Unkown:
                        minimumBuffering = Constants.MinimumMovieBuffering;
                        break;

                    default:
                        minimumBuffering = Constants.MinimumMovieBuffering;
                        break;
                    }

                    if (progress >= minimumBuffering && !alreadyBuffered)
                    {
                        buffered.Invoke();
                        foreach (
                            var filePath in
                            Directory
                            .GetFiles(status.save_path, "*.*",
                                      SearchOption.AllDirectories)
                            .Where(s => s.Contains(handle.torrent_file().name()) &&
                                   (s.EndsWith(".mp4") || s.EndsWith(".mkv") ||
                                    s.EndsWith(".mov") || s.EndsWith(".avi")))
                            )
                        {
                            alreadyBuffered = true;
                            media.FilePath  = filePath;
                            BroadcastMediaBuffered(media, prog, bandwidth);

                            break;
                        }

                        if (!alreadyBuffered)
                        {
                            session.remove_torrent(handle, 0);
                            if (type == MediaType.Unkown)
                            {
                                Messenger.Default.Send(
                                    new UnhandledExceptionMessage(
                                        new PopcornException(
                                            "There is no media file in the torrent you dropped in the UI.")));
                            }
                            else
                            {
                                Messenger.Default.Send(
                                    new UnhandledExceptionMessage(
                                        new PopcornException("There is no media file in the torrent.")));
                            }

                            break;
                        }
                    }

                    if (status.is_finished)
                    {
                        session.remove_torrent(handle, 0);
                        break;
                    }

                    try
                    {
                        await Task.Delay(1000, cts.Token);
                    }
                    catch (TaskCanceledException)
                    {
                        cancelled.Invoke();
                        break;
                    }
                }
            }
        }
Esempio n. 4
0
        /// <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="torrent_handle"/></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,
                                          torrent_handle 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;

            while (!cts.IsCancellationRequested)
            {
                using (var status = handle.status())
                {
                    var progress = 0d;
                    if (status.has_metadata)
                    {
                        var numFiles = handle.torrent_file().files().num_files();
                        var totalSizeExceptIgnoredFiles = handle.torrent_file().total_size();
                        handle.flush_cache();
                        if (mediaIndex == -1 || string.IsNullOrEmpty(filePath))
                        {
                            for (var i = 0; i < numFiles; i++)
                            {
                                var currentSize = handle.torrent_file().files().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 -= handle.torrent_file().files().file_size(i);
                                }
                            }

                            filePath = handle.torrent_file().files().file_path(mediaIndex, savePath);
                        }

                        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, 0);
                            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, 1);
                        }
                        catch (Exception)
                        {
                            // ignored
                        }

                        break;
                    }
                }
            }
        }