source: trunk/src/halTorrent.hpp @ 456

Revision 456, 18.3 KB checked in by Eoin, 12 years ago (diff)

Refactoring trackers and file_priorities to properties.

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