source: trunk/src/halTorrent.hpp @ 453

Revision 453, 17.9 KB checked in by Eoin, 12 years ago (diff)

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