source: trunk/src/halTorrent.hpp @ 506

Revision 506, 19.8 KB checked in by Eoin, 12 years ago (diff)

Queue configuration applies correctly.

Line 
1
2//         Copyright Eóin O'Callaghan 2006 - 2007.
3// Distributed under the Boost Software License, Version 1.0.
4//    (See accompanying file LICENSE_1_0.txt or copy at
5//          http://www.boost.org/LICENSE_1_0.txt)
6
7#pragma once
8
9#include <string>
10#include <vector>
11#include <set>
12
13#include <boost/foreach.hpp>
14#include <boost/format.hpp>
15#include <boost/array.hpp>
16#include <boost/lexical_cast.hpp>
17#include <boost/bind.hpp>
18
19#include <boost/smart_ptr.hpp>
20
21#include <boost/noncopyable.hpp>
22
23#include <boost/signal.hpp>
24#include <boost/optional.hpp>
25#include <boost/function.hpp>
26
27#include <boost/smart_ptr.hpp>
28#include <boost/algorithm/string.hpp>
29
30#include <boost/filesystem/path.hpp>
31#include <boost/filesystem/operations.hpp>
32#include <boost/filesystem/fstream.hpp>
33
34#include <stlsoft/properties/method_properties.hpp>
35#include <stlsoft/util/operator_bool_adaptor.hpp>
36
37
38//#if BOOST_VERSION < 103500
39//#include <asio/ip/tcp.hpp>
40//#include <asio/ip/udp.hpp>
41//#else
42#include <boost/asio/ip/tcp.hpp>
43#include <boost/asio/ip/udp.hpp>
44//#endif
45
46#include "halTypes.hpp"
47
48namespace libtorrent { struct peer_info; }
49
50namespace hal
51{
52
53struct queue_settings
54{
55        friend class boost::serialization::access;
56        template<class Archive>
57        void serialize(Archive& ar, const unsigned int version)
58        {       
59                ar & BOOST_SERIALIZATION_NVP(auto_manage_interval);
60                ar & BOOST_SERIALIZATION_NVP(active_downloads);
61                ar & BOOST_SERIALIZATION_NVP(active_seeds);
62                ar & BOOST_SERIALIZATION_NVP(seeds_hard_limit);
63                ar & BOOST_SERIALIZATION_NVP(seed_ratio_limit);
64                ar & BOOST_SERIALIZATION_NVP(seed_ratio_time_limit);
65                ar & BOOST_SERIALIZATION_NVP(seed_time_limit);
66                ar & BOOST_SERIALIZATION_NVP(dont_count_slow_torrents);
67                ar & BOOST_SERIALIZATION_NVP(auto_scrape_min_interval);
68                ar & BOOST_SERIALIZATION_NVP(auto_scrape_interval);
69                ar & BOOST_SERIALIZATION_NVP(close_redundant_connections);
70        }
71
72        bool operator==(const queue_settings& s) const
73        {
74                return (auto_manage_interval == s.auto_manage_interval &&
75                        active_downloads == s.active_downloads &&
76                        active_seeds == s.active_seeds &&
77                        seeds_hard_limit == s.seeds_hard_limit &&
78                        seed_ratio_limit == s.seed_ratio_limit &&
79                        seed_ratio_time_limit == s.seed_ratio_time_limit &&
80                        seed_time_limit == s.seed_time_limit &&
81                        dont_count_slow_torrents == s.dont_count_slow_torrents &&
82                        auto_scrape_min_interval == s.auto_scrape_min_interval &&
83                        auto_scrape_interval == s.auto_scrape_interval &&
84                        close_redundant_connections == s.close_redundant_connections);
85        }
86       
87        bool operator!=(const queue_settings& s) const
88        {
89                return !(*this == s);
90        }
91
92        int auto_manage_interval;
93
94        int active_downloads;
95        int active_seeds;
96        int seeds_hard_limit;
97        float seed_ratio_limit;
98        float seed_ratio_time_limit;
99        int seed_time_limit;
100        bool dont_count_slow_torrents;
101
102        int auto_scrape_min_interval;
103        int auto_scrape_interval;
104        bool close_redundant_connections;
105};
106       
107struct torrentBriefDetail
108{
109        std::wstring filename;
110        std::wstring status;
111        std::pair<float,float> speed;
112        float completion;
113        int peers;
114        int seeds;
115};
116
117struct PeerDetail
118{
119        PeerDetail(const std::wstring& ip_address) :
120                ipAddress(ip_address)
121        {}
122        PeerDetail(libtorrent::peer_info& peerInfo);
123       
124        bool operator==(const PeerDetail& peer) const
125        {
126                return (ipAddress == peer.ipAddress);
127        }
128       
129        bool operator<(const PeerDetail& peer) const
130        {
131                return (ipAddress < peer.ipAddress);
132        }
133       
134        std::wstring ipAddress;
135        std::wstring country;
136        std::pair<float,float> speed;
137        bool seed;
138        std::wstring client;
139        std::wstring status;
140};
141
142typedef boost::shared_ptr<PeerDetail> PeerDetail_ptr;
143typedef std::vector<PeerDetail> PeerDetails;
144
145struct FileDetail
146{
147        FileDetail(boost::filesystem::wpath p, boost::int64_t s=0, float pg=0, int pr=1, size_t o=0, unsigned t=FileDetail::file) :
148                branch(p.branch_path()),
149                filename(p.leaf()),
150                type(t),
151                size(s),
152                progress(pg),
153                priority(pr),
154                order_(o)
155        {}
156       
157        bool operator==(const FileDetail& file) const
158        {
159                return (branch == file.branch);
160        }
161       
162        bool operator<(const FileDetail& file) const
163        {
164                return (branch < file.branch);
165        }
166       
167        enum FileType
168        {
169                folder,
170                file
171        };
172       
173        size_t order() const { return order_; }
174       
175        boost::filesystem::wpath branch;
176        std::wstring filename;
177        unsigned type;
178        boost::int64_t size;
179        float progress;
180        int priority;
181       
182private:
183        size_t order_;
184};
185
186inline bool FileDetailNamesEqual(const FileDetail& l, const FileDetail& r)
187{
188        return l.filename == r.filename;
189}
190
191inline bool FileDetailNamesLess(const FileDetail& l, const FileDetail& r)
192{
193        return l.filename < r.filename;
194}
195
196typedef std::vector<FileDetail> FileDetails;
197
198class TorrentDetail 
199{
200public:
201        TorrentDetail(std::wstring n, std::wstring f, std::wstring sd, std::wstring s, std::wstring cT, std::pair<float,float> sp=std::pair<float,float>(0,0),
202                        float c=0, float d=0, size_type tWD=0, size_type tW=0, size_type tU=0, size_type tpU=0, size_type tD=0, size_type tpD=0, boost::tuple<size_type, size_type, size_type, size_type> connections = boost::tuple<size_type, size_type, size_type, size_type>(0,0,0,0), float r=0, 
203                        boost::posix_time::time_duration eta=boost::posix_time::seconds(0), boost::posix_time::time_duration uIn=boost::posix_time::seconds(0),
204                        boost::posix_time::time_duration actve=boost::posix_time::seconds(0), boost::posix_time::time_duration seding=boost::posix_time::seconds(0), boost::posix_time::ptime srt=boost::posix_time::second_clock::universal_time(), boost::posix_time::ptime fin=boost::posix_time::second_clock::universal_time()) :
205                filename_(f),
206                name_(n),
207                saveDir_(sd),
208                state_(s),
209                currentTracker_(cT),
210                speed_(sp),
211                completion_(c),
212                distributed_copies_(d),
213                totalWantedDone_(tWD),
214                totalWanted_(tW),
215                totalUploaded_(tU),
216                totalPayloadUploaded_(tpU),
217                totalDownloaded_(tD),
218                totalPayloadDownloaded_(tpD),
219                peers_(connections.get<0>()),
220                connectedPeers_(connections.get<1>()),
221                seeds_(connections.get<2>()),
222                connectedSeeds_(connections.get<3>()),
223                ratio_(r),
224                estimatedTimeLeft_(eta),
225                updateTrackerIn_(uIn),
226                peerDetailsFilled_(false),
227                fileDetailsFilled_(false),
228                active_(actve),
229                seeding_(seding),
230                startTime_(srt),
231                finishTime_(fin)
232        {}
233
234        TorrentDetail() :       
235                peerDetailsFilled_(false),
236                fileDetailsFilled_(false)
237        {};     
238       
239        enum state
240        {
241                torrent_active = 0,
242                torrent_paused,
243                torrent_stopped,
244                torrent_pausing,
245                torrent_stopping
246        };
247       
248//      const std::wstring& filename() const { return filename_; }
249        const std::wstring& name() const { return name_; }
250        const std::wstring& saveDirectory() const { return saveDir_; }
251        const std::wstring& state() const { return state_; }
252        const std::wstring& currentTracker() const { return currentTracker_; }
253       
254        std::pair<float,float> speed() const { return speed_; }
255        const float& completion() const { return completion_; }
256        const float& distributedCopies() const { return distributed_copies_; }
257       
258        size_type totalUploaded() const { return totalUploaded_; }
259        size_type totalPayloadUploaded() const { return totalPayloadUploaded_; }
260        size_type totalDownloaded() const { return totalDownloaded_; }
261        size_type totalPayloadDownloaded() const { return totalPayloadDownloaded_; }
262        size_type totalWantedDone() const { return totalWantedDone_; }
263        size_type totalWanted() const { return totalWanted_; }
264       
265        size_type peers() const { return peers_; }
266        size_type peersConnected() const { return connectedPeers_; }
267        size_type seeds() const { return seeds_; }
268        size_type seedsConnected() const { return connectedSeeds_; }
269       
270        float ratio() { return ratio_; }
271       
272        const boost::posix_time::time_duration& estimatedTimeLeft() { return estimatedTimeLeft_; }
273        const boost::posix_time::time_duration& updateTrackerIn() { return updateTrackerIn_; }
274       
275        const PeerDetails& peerDetails() const;
276        const FileDetails& fileDetails() const;
277       
278        const boost::posix_time::time_duration& active() { return active_; }
279        const boost::posix_time::time_duration& seeding() { return seeding_; }
280        const boost::posix_time::ptime& startTime() { return startTime_; }
281        const boost::posix_time::ptime& finishTime() { return finishTime_; }
282       
283public:
284        std::wstring filename_;
285        std::wstring name_;
286        std::wstring saveDir_;
287        std::wstring state_;
288        std::wstring currentTracker_;
289
290        std::pair<float,float> speed_;         
291        float completion_;     
292        float distributed_copies_;
293       
294        size_type totalWantedDone_;
295        size_type totalWanted_;
296        size_type totalUploaded_;
297        size_type totalPayloadUploaded_;
298        size_type totalDownloaded_;
299        size_type totalPayloadDownloaded_;
300       
301        size_type peers_;
302        size_type connectedPeers_;
303        size_type seeds_;
304        size_type connectedSeeds_;
305       
306        float ratio_;
307       
308        boost::posix_time::time_duration estimatedTimeLeft_;
309        boost::posix_time::time_duration updateTrackerIn_;
310       
311        boost::posix_time::time_duration active_;
312        boost::posix_time::time_duration seeding_;
313        boost::posix_time::ptime startTime_;
314        boost::posix_time::ptime finishTime_;
315       
316private:
317        mutable bool peerDetailsFilled_;
318        mutable PeerDetails peerDetails_;
319       
320        mutable bool fileDetailsFilled_;
321        mutable FileDetails fileDetails_;
322};
323
324typedef boost::shared_ptr<TorrentDetail> TorrentDetail_ptr;
325typedef boost::scoped_ptr<TorrentDetail> TorrentDetail_sptr;
326typedef boost::weak_ptr<TorrentDetail> TorrentDetail_wptr;
327typedef std::vector<TorrentDetail_ptr> TorrentDetail_vec;
328typedef std::map<std::wstring, TorrentDetail_ptr> TorrentDetail_map;
329
330class TorrentDetails
331{
332public: 
333        void sort(boost::function<bool (const TorrentDetail_ptr&, const TorrentDetail_ptr&)> fn) const;
334       
335        const TorrentDetail_vec torrents() const 
336        {
337                mutex_t::scoped_lock l(mutex_); 
338                return torrents_; 
339        }
340       
341        const TorrentDetail_vec selectedTorrents() const 
342        { 
343                mutex_t::scoped_lock l(mutex_); 
344                return selectedTorrents_; 
345        }
346       
347        const TorrentDetail_ptr focusedTorrent() const 
348        {
349                mutex_t::scoped_lock l(mutex_); 
350                return selectedTorrent_; 
351        }
352       
353        const TorrentDetail_ptr get(std::wstring filename) const
354        {
355                mutex_t::scoped_lock l(mutex_); 
356               
357                TorrentDetail_map::const_iterator i = torrentMap_.find(filename);
358               
359                if (i != torrentMap_.end())
360                        return i->second;
361                else
362                        return TorrentDetail_ptr();
363        }
364       
365        friend class bit;
366
367private:
368        void clearAll(const mutex_t::scoped_lock&)
369        {
370                // !! No mutex lock, it should only be call from functions which
371                // have the lock themselves, hence the unused function param
372               
373                torrents_.clear();
374                torrentMap_.clear();
375                selectedTorrents_.clear();
376                selectedTorrent_.reset();
377        }
378
379        mutable TorrentDetail_vec torrents_;
380       
381        TorrentDetail_map torrentMap_;
382        TorrentDetail_vec selectedTorrents_;
383        TorrentDetail_ptr selectedTorrent_;
384       
385        mutable mutex_t mutex_;
386};
387
388struct tracker_detail
389{
390        tracker_detail() {}
391        tracker_detail(std::wstring u, int t) : url(u), tier(t) {}
392       
393        bool operator<(const tracker_detail& t) const
394        {
395                return (tier < t.tier);
396        }
397       
398        std::wstring url;
399        int tier;
400};
401
402typedef std::vector<tracker_detail> tracker_details_t;
403
404struct web_seed_or_dht_node_detail
405{
406        web_seed_or_dht_node_detail();
407        web_seed_or_dht_node_detail(std::wstring u);
408        web_seed_or_dht_node_detail(std::wstring u, int p);
409               
410        std::wstring url;
411        int port;
412        std::wstring type;
413};
414
415typedef std::vector<pair<fs::wpath, size_type> > file_size_pairs_t;
416
417struct dht_node_detail
418{
419        dht_node_detail() {}
420        dht_node_detail(std::wstring u, int p) : url(u), port(p) {}
421       
422        std::wstring url;
423        int port;
424};
425
426typedef std::vector<dht_node_detail> dht_node_details_t;
427
428struct web_seed_detail
429{
430        web_seed_detail() {}
431        web_seed_detail(std::wstring u) : url(u) {}
432       
433        std::wstring url;
434};
435
436typedef std::vector<web_seed_detail> web_seed_details_t;
437
438struct create_torrent_params
439{
440        create_torrent_params() {}
441
442        std::wstring creator;
443        std::wstring comment;
444        int piece_size;
445        bool private_torrent;
446
447        file_size_pairs_t file_size_pairs;
448        fs::wpath root_path;
449
450        tracker_details_t trackers;
451        dht_node_details_t dht_nodes;
452        web_seed_details_t web_seeds;
453};
454
455class EventDetail;
456
457struct SessionDetail
458{
459        int port;
460       
461        std::pair<double, double> speed;
462       
463        bool dht_on;
464        size_t dht_nodes;
465        size_t dht_torrents;
466       
467        bool ip_filter_on;
468        size_t ip_ranges_filtered;
469};
470
471typedef boost::function<bool (size_t, size_t, size_t)> filterCallback;
472typedef boost::function<bool (size_t, std::wstring)> progress_callback;
473typedef boost::function<void (int)> report_num_active;
474typedef std::pair<wstring, wstring> wstring_pair;
475typedef std::pair<float, float> float_pair;
476typedef std::pair<int, int> int_pair;
477typedef std::pair<std::vector<int>, int> vec_int_pair;
478
479class bit_impl;
480class torrent_internal;
481
482class bit
483{
484public: 
485
486        class null_torrent : public std::exception
487        {
488        public:
489                null_torrent() {}               
490                virtual ~null_torrent() throw () {}
491        };
492
493        class torrent : public stlsoft::operator_bool_adaptor<torrent>
494        {
495                typedef torrent class_type;
496
497        public:
498                class exec_around_ptr
499                {
500                public:
501                        class proxy 
502                        {
503                        public:
504                                explicit proxy(torrent_internal* t);
505
506                                torrent_internal* operator->() 
507                                {
508                                        return t_;
509                                }
510
511                                ~proxy ();
512
513                        private:
514                                torrent_internal* t_;
515                                mutex_t::scoped_lock l_;
516                        };
517
518                        exec_around_ptr() {}
519                        exec_around_ptr(boost::shared_ptr<torrent_internal> p) : ptr(p) {}
520
521                        proxy operator->() const
522                        {
523                                if (!ptr)
524                                        throw null_torrent();
525
526                                return proxy(&(*ptr));
527                        }
528
529                        operator bool() const { return ptr; }
530
531                private:
532                        boost::shared_ptr<torrent_internal> ptr;
533                };
534
535                torrent();
536                torrent(boost::shared_ptr<torrent_internal> p);
537
538                const std::wstring get_name() const;
539
540                float get_ratio() const;
541                void set_ratio(float new_ratio);
542               
543                std::pair<int, int> get_connection_limits() const;
544                void set_connection_limits(const std::pair<int, int>&);
545                std::pair<float, float> get_rate_limits() const;
546                void set_rate_limits(const std::pair<float, float>&);
547
548                wpath get_save_directory() const;
549                void set_save_directory(const wpath&);
550                wpath get_move_to_directory() const;
551                void set_move_to_directory(const wpath&);
552
553                std::pair<wstring, wstring> get_tracker_login() const;
554                void set_tracker_login(const std::pair<wstring, wstring>&);
555
556                std::vector<tracker_detail> get_trackers() const;
557                void set_trackers(const std::vector<tracker_detail>&);
558
559                bool get_is_active() const;
560                bool get_in_session() const;
561
562                void set_file_priorities(const vec_int_pair&);
563
564        public:
565                STLSOFT_METHOD_PROPERTY_GET_EXTERNAL(const std::wstring, class_type, 
566                        get_name, name);
567
568                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(float, float, class_type, 
569                        get_ratio, set_ratio, ratio);
570
571                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(int_pair, const int_pair&, class_type, 
572                        get_connection_limits, set_connection_limits, connection_limits);
573                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(float_pair, const float_pair&, class_type, 
574                        get_rate_limits, set_rate_limits, rate_limits);
575               
576                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(wpath, const wpath&, class_type, 
577                        get_save_directory, set_save_directory, save_directory);
578                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(wpath, const wpath&, class_type, 
579                        get_move_to_directory, set_move_to_directory, move_to_directory);
580
581                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(wstring_pair, const wstring_pair&, 
582                        class_type, get_tracker_login, set_tracker_login, tracker_login);
583
584                STLSOFT_METHOD_PROPERTY_GET_EXTERNAL(bool, class_type, 
585                        get_is_active, is_active);
586                STLSOFT_METHOD_PROPERTY_GET_EXTERNAL(bool, class_type, 
587                        get_in_session, in_session);
588
589                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(std::vector<tracker_detail>, const std::vector<tracker_detail>&, 
590                        class_type, get_trackers, set_trackers, trackers);
591
592                STLSOFT_METHOD_PROPERTY_SET_EXTERNAL(const vec_int_pair&, class_type, 
593                        set_file_priorities, file_priorities);
594
595                void reset_trackers();
596
597                bool is_open() const;
598
599
600        private:
601                exec_around_ptr ptr;
602        };
603
604        enum mappings
605        {
606                mappingNone = 0,
607                mappingUPnP,
608                mappingNatPMP
609        };
610
611        void shutDownSession();
612        void save_torrent_data();
613
614        bool create_torrent(const create_torrent_params& params, fs::wpath out_file, progress_callback fn);
615
616        template<typename T>
617        torrent get(T t)
618        {
619                return get_wstr(to_wstr_shim(t));
620        }
621       
622        template<>
623        torrent get(const hal::TorrentDetail_ptr t)
624        {
625                if (t) 
626                        return get_wstr(t->name());
627                else
628                        return torrent();
629        }       
630       
631        bool listen_on(std::pair<int, int> const& portRange);
632        int is_listening_on();
633        void stop_listening();
634       
635        bool ensure_dht_on();
636        void ensure_dht_off();
637       
638        void ensure_pe_on(int enc_level, int in_enc_policy, int out_enc_policy, bool prefer_rc4);
639        void ensure_pe_off();
640       
641        bool ensure_ip_filter_on(progress_callback fn);
642        void ensure_ip_filter_off();
643
644        void set_mapping(int mapping);
645
646        void ip_v4_filter_block(boost::asio::ip::address_v4 first, boost::asio::ip::address_v4 last);
647        void ip_v6_filter_block(boost::asio::ip::address_v6 first, boost::asio::ip::address_v6 last);
648        bool ip_filter_import_dat(boost::filesystem::path file, progress_callback fn, bool octalFix);
649        size_t ip_filter_size();
650        void clear_ip_filter(); 
651       
652        void setSessionHalfOpenLimit(int halfConn);
653        void set_session_limits(int maxConn, int maxUpload);
654        void set_session_speed(float download, float upload);
655        void set_dht_settings(int max_peers_reply, int search_branching, 
656                int service_port, int max_fail_count);
657        void set_timeouts(int peers, int tracker);
658
659        queue_settings get_queue_settings();
660        void set_queue_settings(const queue_settings& s);
661       
662        const SessionDetail getSessionDetails();
663
664        void setTorrentDefaults(int maxConn, int maxUpload, float download, float upload);     
665        void add_torrent(boost::filesystem::wpath file, boost::filesystem::wpath saveDirectory, 
666                bool startPaused=false, bool compactStorage=false, 
667                boost::filesystem::wpath moveToDirectory=L"", bool useMoveTo=false);
668       
669        void getAllPeerDetails(const std::string& filename, PeerDetails& peerContainer);
670        void getAllPeerDetails(const std::wstring& filename, PeerDetails& peerContainer);
671        void getAllFileDetails(const std::string& filename, FileDetails& fileDetails);
672        void getAllFileDetails(const std::wstring& filename, FileDetails& fileDetails);
673       
674        void resume_all();
675        void close_all(boost::optional<report_num_active> fn);
676       
677        bool isTorrent(const std::string& filename);
678        bool isTorrent(const std::wstring& filename);   
679       
680        void pauseTorrent(const std::string& filename);
681        void pauseTorrent(const std::wstring& filename);
682        void resumeTorrent(const std::string& filename);
683        void resumeTorrent(const std::wstring& filename);
684        void stopTorrent(const std::string& filename);
685        void stopTorrent(const std::wstring& filename);
686        bool isTorrentActive(const std::string& filename);
687        bool isTorrentActive(const std::wstring& filename);
688        void reannounceTorrent(const std::string& filename);
689        void reannounceTorrent(const std::wstring& filename);
690        void recheckTorrent(const std::string& filename);
691        void recheckTorrent(const std::wstring& filename);
692       
693        void pauseAllTorrents();
694        void unpauseAllTorrents();
695
696        template<typename S>
697        void remove_torrent(S filename)
698        { 
699                remove_torrent_wstr(to_wstr_shim(filename)); 
700        }       
701
702        template<typename S>
703        void remove_torrent_wipe_files(S filename)
704        { 
705                remove_torrent_wipe_files_wstr(to_wstr_shim(filename)); 
706        }       
707
708        void startEventReceiver();
709        void stopEventReceiver();
710       
711        friend bit& bittorrent();
712       
713        int defTorrentMaxConn();
714        int defTorrentMaxUpload();
715        float defTorrentDownload();
716        float defTorrentUpload();       
717
718        const TorrentDetails& torrentDetails();
719        const TorrentDetails& updateTorrentDetails(const std::wstring& focused, const std::set<std::wstring>& selected);
720       
721private:
722        bit();
723        boost::scoped_ptr<bit_impl> pimpl;
724
725        torrent get_wstr(const std::wstring& filename);
726       
727        void remove_torrent_wstr(const std::wstring& filename);
728        void remove_torrent_wipe_files_wstr(const std::wstring&  filename);
729       
730        TorrentDetails torrentDetails_;
731};
732
733bit& bittorrent();
734
735};
Note: See TracBrowser for help on using the repository browser.