示例#1
0
        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();
            }
        }
示例#2
0
 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;
 }
示例#3
0
        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();
        }
示例#4
0
        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);
                    }
        }
示例#5
0
        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;
            }
        }
示例#6
0
        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);
            }
        }
示例#7
0
        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);
            }
        }
示例#8
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="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;
                }
            }
        }
示例#9
0
        /// <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);
                }
            }
        }
示例#10
0
 public TorrentFileInfo(TorrentHandle handle, int fileindex)
 {
     this.fileindex = fileindex;
     this.handle    = handle;
 }