source: trunk/src/halTorrent.hpp @ 739

Revision 739, 20.5 KB checked in by Eoin, 11 years ago (diff)

Cleaning up torrent removal code.

Line 
1
2//         Copyright Eóin O'Callaghan 2006 - 2009.
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#include <boost/noncopyable.hpp>
21
22#include <boost/signal.hpp>
23#include <boost/optional.hpp>
24#include <boost/function.hpp>
25
26#include <boost/smart_ptr.hpp>
27
28#include <boost/filesystem/path.hpp>
29#include <boost/filesystem/operations.hpp>
30#include <boost/filesystem/fstream.hpp>
31*/
32
33#include <boost/algorithm/string.hpp>
34
35#include <stlsoft/properties/method_properties.hpp>
36#include <stlsoft/util/operator_bool_adaptor.hpp>
37
38#include <boost/asio/ip/tcp.hpp>
39#include <boost/asio/ip/udp.hpp>
40
41#include "halTypes.hpp"
42#include "halPeers.hpp"
43
44namespace hal
45{
46
47template<typename T>
48bool hal_details_ptr_compare(T l, T r, size_t index = 0, bool cmp_less = true)
49{
50        if (cmp_less)
51                return l->less(*r, index);
52        else
53                return r->less(*l, index);
54}
55
56template<typename T>
57bool hal_details_compare(T l, T r, size_t index = 0, bool cmp_less = true)
58{
59        if (cmp_less)
60                return l.less(r, index);
61        else
62                return r.less(l, index);
63}
64
65inline boost::wformat wform(const std::wstring & f_string) 
66{
67    using namespace boost::io;
68
69        boost::wformat fmter(f_string);
70    fmter.exceptions( no_error_bits  );
71    return fmter;
72}
73
74struct torrentBriefDetail
75{
76        std::wstring filename;
77        std::wstring status;
78        std::pair<float,float> speed;
79        float completion;
80        int peers;
81        int seeds;
82};
83
84struct queue_settings;
85struct timeouts;
86struct dht_settings;
87struct cache_settings;
88struct pe_settings;
89struct connections;
90struct cache_details;
91
92
93struct file_details
94{
95        enum details
96        {
97                filename_e = 0,
98                branch_e,
99                size_e,
100                progress_e,
101                priority_e,
102                type_e
103        };
104
105        file_details(boost::filesystem::wpath p, 
106                        boost::int64_t s=0, 
107                        boost::int64_t pg=0, 
108                        int pr=1, 
109                        size_t o=0, 
110                        unsigned t=file_details::file) :
111                branch(p.parent_path()),
112                filename(p.filename()),
113                type(t),
114                size(s),
115                progress(pg),
116                priority(pr),
117                order_(o)
118        {}
119       
120        bool operator==(const file_details& file) const
121        {
122                return (branch == file.branch);
123        }
124       
125        bool operator<(const file_details& file) const
126        {
127                return (branch < file.branch);
128        }
129       
130        bool less(const file_details& r, size_t index = 0) const;
131        std::wstring to_wstring(size_t index = 0);
132       
133        enum file_type
134        {
135                folder,
136                file
137        };
138       
139        size_t order() const { return order_; }
140       
141        boost::filesystem::wpath branch;
142        std::wstring filename;
143        unsigned type;
144        boost::int64_t size;
145        boost::int64_t progress;
146        int priority;
147       
148private:
149        size_t order_;
150};
151
152inline bool file_details_names_equal(const file_details& l, const file_details& r)
153{
154        return l.filename == r.filename;
155}
156
157inline bool file_details_names_less(const file_details& l, const file_details& r)
158{
159        return l.filename < r.filename;
160}
161
162typedef std::vector<file_details> file_details_vec;
163
164void file_details_sort(file_details_vec& f, size_t index, bool cmp_less = true);
165
166class torrent_details 
167{
168public:
169        torrent_details(std::wstring n, std::wstring f, 
170                        std::wstring sd, 
171                        std::wstring s, 
172                        std::wstring cT, 
173                        std::pair<float,float> sp=std::pair<float,float>(0,0),
174                        float c=0, float d=0, 
175                        size_type tWD=0, size_type tW=0, 
176                        size_type tU=0, size_type tpU=0, 
177                        size_type tD=0, size_type tpD=0, 
178                        boost::tuple<size_type, size_type, size_type, size_type> connections = 
179                                boost::tuple<size_type, size_type, size_type, size_type>(0,0,0,0), 
180                        float r=0, 
181                        boost::posix_time::time_duration eta=boost::posix_time::seconds(0), 
182                        boost::posix_time::time_duration uIn=boost::posix_time::seconds(0),
183                        boost::posix_time::time_duration actve=boost::posix_time::seconds(0), 
184                        boost::posix_time::time_duration seding=boost::posix_time::seconds(0), 
185                        boost::posix_time::ptime srt=boost::posix_time::second_clock::universal_time(), 
186                        boost::posix_time::ptime fin=boost::posix_time::second_clock::universal_time(), 
187                        int q_p=-1, 
188                        bool man=false) :
189                filename_(f),
190                name_(n),
191                saveDir_(sd),
192                state_(s),
193                currentTracker_(cT),
194                speed_(sp),
195                completion_(c),
196                distributed_copies_(d),
197                total_wanted_done_(tWD),
198                total_wanted_(tW),
199                total_uploaded_(tU),
200                total_payload_uploaded_(tpU),
201                total_downloaded_(tD),
202                total_payload_downloaded_(tpD),
203                peers_(connections.get<0>()),
204                connected_peers_(connections.get<1>()),
205                seeds_(connections.get<2>()),
206                connected_seeds_(connections.get<3>()),
207                ratio_(r),
208                estimated_time_left_(eta),
209                update_tracker_in_(uIn),
210                peer_details_filled_(false),
211                file_details_filled_(false),
212                active_(actve),
213                seeding_(seding),
214                start_time_(srt),
215                finish_time_(fin),
216                queue_position_(q_p),
217                managed_(man)
218        {}
219
220        torrent_details() :     
221                peer_details_filled_(false),
222                file_details_filled_(false)
223        {};     
224       
225        enum state
226        {
227                torrent_active = 0,
228                torrent_paused,
229                torrent_stopped,
230                torrent_pausing,
231                torrent_stopping,
232                torrent_in_error
233        };
234
235        enum details
236        {
237                name_e = 0,
238                state_e,
239                progress_e,
240                speed_down_e,
241                speed_up_e,
242                peers_e,
243                seeds_e,
244                eta_e,
245                distributed_copies_e,
246                tracker,
247                update_tracker_in_e,
248                ratio_e,
249                total_wanted_e,
250                completed_e,
251                remaining_e,
252                downloaded_e,
253                uploaded_e,
254                active_time_e,
255                seeding_time_e,
256                start_time_e,
257                finish_time_e,
258                managed_e,
259                queue_position_e
260        };
261       
262//      const std::wstring& filename() const { return filename_; }
263        const std::wstring& name() const { return name_; }
264        const std::wstring& save_directory() const { return saveDir_; }
265        const std::wstring& state() const { return state_; }
266        const std::wstring& current_tracker() const { return currentTracker_; }
267       
268        std::pair<float,float> speed() const { return speed_; }
269        const float& completion() const { return completion_; }
270        const float& distributed_copies() const { return distributed_copies_; }
271       
272        size_type total_uploaded() const { return total_uploaded_; }
273        size_type total_payload_uploaded() const { return total_payload_uploaded_; }
274        size_type total_downloaded() const { return total_downloaded_; }
275        size_type total_payload_downloaded() const { return total_payload_downloaded_; }
276        size_type total_wanted_done() const { return total_wanted_done_; }
277        size_type total_wanted() const { return total_wanted_; }
278       
279        size_type peers() const { return peers_; }
280        size_type peers_connected() const { return connected_peers_; }
281        size_type seeds() const { return seeds_; }
282        size_type seeds_connected() const { return connected_seeds_; }
283       
284        float ratio() { return ratio_; }
285       
286        const boost::posix_time::time_duration& estimated_time_left() { return estimated_time_left_; }
287        const boost::posix_time::time_duration& update_tracker_in() { return update_tracker_in_; }
288       
289        const peer_details_vec& get_peer_details() const;
290        const file_details_vec& get_file_details() const;
291       
292        const boost::posix_time::time_duration& active() { return active_; }
293        const boost::posix_time::time_duration& seeding() { return seeding_; }
294        const boost::posix_time::ptime& start_time() { return start_time_; }
295        const boost::posix_time::ptime& finish_time() { return finish_time_; }
296
297        int queue_position() const { return queue_position_; }
298        bool managed() const { return managed_; }
299
300        bool less(const torrent_details& r, size_t index = 0) const;
301        std::wstring to_wstring(size_t index = 0);
302       
303public:
304        std::wstring filename_;
305        std::wstring name_;
306        std::wstring saveDir_;
307        std::wstring state_;
308        std::wstring currentTracker_;
309
310        std::pair<float,float> speed_;         
311        float completion_;     
312        float distributed_copies_;
313       
314        size_type total_wanted_done_;
315        size_type total_wanted_;
316        size_type total_uploaded_;
317        size_type total_payload_uploaded_;
318        size_type total_downloaded_;
319        size_type total_payload_downloaded_;
320       
321        size_type peers_;
322        size_type connected_peers_;
323        size_type seeds_;
324        size_type connected_seeds_;
325       
326        float ratio_;
327       
328        boost::posix_time::time_duration estimated_time_left_;
329        boost::posix_time::time_duration update_tracker_in_;
330       
331        boost::posix_time::time_duration active_;
332        boost::posix_time::time_duration seeding_;
333        boost::posix_time::ptime start_time_;
334        boost::posix_time::ptime finish_time_;
335
336        int queue_position_;
337        bool managed_;
338       
339private:
340        mutable bool peer_details_filled_;
341        mutable peer_details_vec peer_details_;
342       
343        mutable bool file_details_filled_;
344        mutable file_details_vec file_details_;
345};
346
347typedef boost::shared_ptr<torrent_details> torrent_details_ptr;
348typedef boost::scoped_ptr<torrent_details> torrent_details_sptr;
349typedef boost::weak_ptr<torrent_details> torrent_details_wptr;
350typedef std::vector<torrent_details_ptr> torrent_details_vec;
351typedef std::map<std::wstring, torrent_details_ptr> torrent_details_map;
352
353class torrent_details_manager
354{
355public: 
356        void sort(size_t index, bool cmp_less = true) const;
357       
358        const torrent_details_vec torrents() const 
359        {
360                mutex_t::scoped_lock l(mutex_); 
361                return torrents_; 
362        }
363       
364        const torrent_details_vec selectedTorrents() const 
365        { 
366                mutex_t::scoped_lock l(mutex_); 
367                return selectedTorrents_; 
368        }
369       
370        const torrent_details_ptr focusedTorrent() const 
371        {
372                mutex_t::scoped_lock l(mutex_); 
373                return selectedTorrent_; 
374        }
375
376        const std::set<wstring>& selected_names() const { return selected_names_; }
377       
378        const torrent_details_ptr get(std::wstring filename) const
379        {
380                mutex_t::scoped_lock l(mutex_); 
381               
382                torrent_details_map::const_iterator i = torrentMap_.find(filename);
383               
384                if (i != torrentMap_.end())
385                        return i->second;
386                else
387                        return torrent_details_ptr();
388        }
389       
390        friend class bit;
391
392private:
393        void clearAll(const mutex_t::scoped_lock&)
394        {
395                // !! No mutex lock, it should only be called from functions which
396                // have the lock themselves, hence the unused function param
397               
398                torrents_.clear();
399                torrentMap_.clear();
400                selectedTorrents_.clear();
401                selectedTorrent_.reset();
402        }
403
404        mutable torrent_details_vec torrents_;
405       
406        torrent_details_map torrentMap_;
407        torrent_details_vec selectedTorrents_;
408        torrent_details_ptr selectedTorrent_;
409        std::set<wstring> selected_names_;
410       
411        mutable mutex_t mutex_;
412};
413
414struct tracker_detail
415{
416        tracker_detail() {}
417        tracker_detail(std::wstring u, int t) : url(u), tier(t) {}
418       
419        bool operator<(const tracker_detail& t) const
420        {
421                return (tier < t.tier);
422        }
423       
424        std::wstring url;
425        int tier;
426};
427
428typedef std::vector<tracker_detail> tracker_details_t;
429
430struct web_seed_or_dht_node_detail
431{
432        web_seed_or_dht_node_detail();
433        web_seed_or_dht_node_detail(std::wstring u);
434        web_seed_or_dht_node_detail(std::wstring u, int p);
435               
436        std::wstring url;
437        int port;
438        std::wstring type;
439};
440
441typedef std::vector<pair<fs::wpath, size_type> > file_size_pairs_t;
442
443struct dht_node_detail
444{
445        dht_node_detail() {}
446        dht_node_detail(std::wstring u, int p) : url(u), port(p) {}
447       
448        std::wstring url;
449        int port;
450};
451
452typedef std::vector<dht_node_detail> dht_node_details_t;
453
454struct web_seed_detail
455{
456        web_seed_detail() {}
457        web_seed_detail(std::wstring u) : url(u) {}
458       
459        std::wstring url;
460};
461
462typedef std::vector<web_seed_detail> web_seed_details_t;
463
464struct create_torrent_params
465{
466        create_torrent_params() {}
467
468        std::wstring creator;
469        std::wstring comment;
470        int piece_size;
471        bool private_torrent;
472
473        file_size_pairs_t file_size_pairs;
474        fs::wpath root_path;
475
476        tracker_details_t trackers;
477        dht_node_details_t dht_nodes;
478        web_seed_details_t web_seeds;
479};
480
481class EventDetail;
482
483struct SessionDetail
484{
485        int port;
486       
487        std::pair<double, double> speed;
488       
489        bool dht_on;
490        size_t dht_nodes;
491        size_t dht_torrents;
492       
493        bool ip_filter_on;
494        size_t ip_ranges_filtered;
495};
496
497typedef boost::function<bool (size_t, size_t, size_t)> filterCallback;
498typedef boost::function<bool (size_t, size_t, std::wstring)> progress_callback;
499typedef boost::function<void (int)> report_num_active;
500typedef boost::function<void (wpath path, boost::shared_ptr<file_details_vec> files)> remove_files;
501typedef std::pair<wstring, wstring> wstring_pair;
502typedef std::pair<float, float> float_pair;
503typedef std::pair<int, int> int_pair;
504typedef std::pair<std::vector<int>, int> vec_int_pair;
505
506class bit_impl;
507class torrent_internal;
508
509class bit
510{
511public:         
512
513        enum mappings
514        {
515                mappingNone = 0,
516                mappingUPnP,
517                mappingNatPMP
518        };
519
520        enum allocations
521        {
522                sparse_allocation = 1,
523                compact_allocation,
524                full_allocation
525        };
526
527        enum queue_adjustments
528        {
529                move_up = 0,
530                move_down,
531                move_to_top,
532                move_to_bottom
533        };
534
535        class null_torrent : public std::exception
536        {
537        public:
538                null_torrent() {}               
539                virtual ~null_torrent() throw () {}
540        };
541
542        class torrent : public stlsoft::operator_bool_adaptor<torrent>
543        {
544                typedef torrent class_type;
545
546        public:
547                class exec_around_ptr
548                {
549                public:
550                        class proxy 
551                        {
552                        public:
553                                explicit proxy(torrent_internal* t);
554
555                                torrent_internal* operator->() 
556                                {
557                                        return t_;
558                                }
559
560                                ~proxy ();
561
562                        private:
563                                torrent_internal* t_;
564                                mutex_t::scoped_lock l_;
565                        };
566
567                        exec_around_ptr() {}
568                        exec_around_ptr(boost::shared_ptr<torrent_internal> p) : ptr(p) {}
569
570                        proxy operator->() const
571                        {
572                                if (!ptr)
573                                        throw null_torrent();
574
575                                return proxy(&(*ptr));
576                        }
577
578                        operator bool() const { return ptr; }
579
580                private:
581                        boost::shared_ptr<torrent_internal> ptr;
582                };
583
584                torrent();
585                torrent(boost::shared_ptr<torrent_internal> p);
586
587                const std::wstring get_name() const;
588
589                float get_ratio() const;
590                void set_ratio(float new_ratio);
591               
592                std::pair<int, int> get_connection_limits() const;
593                void set_connection_limits(const std::pair<int, int>&);
594                std::pair<float, float> get_rate_limits() const;
595                void set_rate_limits(const std::pair<float, float>&);
596
597                wpath get_save_directory() const;
598                void set_save_directory(const wpath&);
599                wpath get_move_to_directory() const;
600                void set_move_to_directory(const wpath&);
601
602                std::pair<wstring, wstring> get_tracker_login() const;
603                void set_tracker_login(const std::pair<wstring, wstring>&);
604
605                std::vector<tracker_detail> get_trackers() const;
606                void set_trackers(const std::vector<tracker_detail>&);
607
608                bool get_is_active() const;
609                bool get_in_session() const;
610
611                void set_file_priorities(const vec_int_pair&);
612
613                void set_managed(bool);
614                bool get_managed() const;
615
616        public:
617                STLSOFT_METHOD_PROPERTY_GET_EXTERNAL(const std::wstring, class_type, 
618                        get_name, name);
619
620                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(float, float, class_type, 
621                        get_ratio, set_ratio, ratio);
622
623                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(int_pair, const int_pair&, class_type, 
624                        get_connection_limits, set_connection_limits, connection_limits);
625                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(float_pair, const float_pair&, class_type, 
626                        get_rate_limits, set_rate_limits, rate_limits);
627               
628                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(wpath, const wpath&, class_type, 
629                        get_save_directory, set_save_directory, save_directory);
630                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(wpath, const wpath&, class_type, 
631                        get_move_to_directory, set_move_to_directory, move_to_directory);
632
633                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(wstring_pair, const wstring_pair&, 
634                        class_type, get_tracker_login, set_tracker_login, tracker_login);
635
636                STLSOFT_METHOD_PROPERTY_GET_EXTERNAL(bool, class_type, 
637                        get_is_active, is_active);
638                STLSOFT_METHOD_PROPERTY_GET_EXTERNAL(bool, class_type, 
639                        get_in_session, in_session);
640
641                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(std::vector<tracker_detail>, const std::vector<tracker_detail>&, 
642                        class_type, get_trackers, set_trackers, trackers);
643
644                STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(bool, bool, class_type, 
645                        get_managed, set_managed, managed);
646
647                STLSOFT_METHOD_PROPERTY_SET_EXTERNAL(const vec_int_pair&, class_type, 
648                        set_file_priorities, file_priorities);
649
650                void reset_trackers();
651                bool is_open() const;
652                void adjust_queue_position(bit::queue_adjustments adjust);
653
654        private:
655                exec_around_ptr ptr;
656        };
657
658        void shutdown_session();
659        void save_torrent_data();
660
661        bool create_torrent(const create_torrent_params& params, fs::wpath out_file, progress_callback fn);
662
663        template<typename T>
664        torrent get(T t)
665        {
666                return get_wstr(to_wstr_shim(t));
667        }
668       
669        template<>
670        torrent get(const hal::torrent_details_ptr t)
671        {
672                if (t) 
673                        return get_wstr(t->name());
674                else
675                        return torrent();
676        }       
677
678        torrent get_wstr(const std::wstring& filename);
679       
680        bool listen_on(std::pair<int, int> const& portRange);
681        int is_listening_on();
682        void stop_listening();
683       
684        bool ensure_dht_on(const dht_settings& dht);
685        void ensure_dht_off();
686       
687        void ensure_pe_on(const pe_settings& pe);
688        void ensure_pe_off();
689       
690        bool ensure_ip_filter_on(progress_callback fn);
691        void ensure_ip_filter_off();
692
693        void set_resolve_countries(bool);
694        void start_smart_ban_plugin();
695        void start_ut_pex_plugin();
696        void start_ut_metadata_plugin();
697        void start_metadata_plugin();
698
699        void set_mapping(bool upnp, bool nat_pmp);
700        std::wstring upnp_router_model();
701
702        void ip_v4_filter_block(boost::asio::ip::address_v4 first, boost::asio::ip::address_v4 last);
703        void ip_v6_filter_block(boost::asio::ip::address_v6 first, boost::asio::ip::address_v6 last);
704        bool ip_filter_import_dat(boost::filesystem::path file, progress_callback fn, bool octalFix);
705        size_t ip_filter_size();
706        void clear_ip_filter(); 
707       
708        void set_session_half_open_limit(int halfConn);
709        void set_session_limits(int maxConn, int maxUpload);
710        void set_session_speed(float download, float upload);
711
712        queue_settings get_queue_settings();
713        void set_queue_settings(const queue_settings& s);
714       
715        timeouts get_timeouts();
716        void set_timeouts(const timeouts& t);
717
718        const cache_details get_cache_details() const;
719
720        void set_cache_settings(const cache_settings& cache);
721        cache_settings get_cache_settings() const;
722       
723        const SessionDetail get_session_details();
724
725        void set_torrent_defaults(const connections& defaults); 
726        void add_torrent(boost::filesystem::wpath file, boost::filesystem::wpath saveDirectory, 
727                bool startPaused=false, bool managed=false, allocations alloc=hal::bit::sparse_allocation, 
728                boost::filesystem::wpath moveToDirectory=L"");
729       
730        void get_all_peer_details(const std::string& filename, peer_details_vec& peerContainer);
731        void get_all_peer_details(const std::wstring& filename, peer_details_vec& peerContainer);
732        void get_all_file_details(const std::string& filename, file_details_vec& file_details);
733        void get_all_file_details(const std::wstring& filename, file_details_vec& file_details);
734       
735        void resume_all();
736        void close_all(boost::optional<report_num_active> fn);
737       
738        bool is_torrent(const std::string& filename);
739        bool is_torrent(const std::wstring& filename); 
740       
741        void pause_torrent(const std::string& filename);
742        void pause_torrent(const std::wstring& filename);
743        void resume_torrent(const std::string& filename);
744        void resume_torrent(const std::wstring& filename);
745        void stop_torrent(const std::string& filename);
746        void stop_torrent(const std::wstring& filename);
747        bool is_torrent_active(const std::string& filename);
748        bool is_torrent_active(const std::wstring& filename);
749        void reannounce_torrent(const std::string& filename);
750        void reannounce_torrent(const std::wstring& filename);
751        void recheck_torrent(const std::string& filename);
752        void recheck_torrent(const std::wstring& filename);
753       
754        void pause_all_torrents();
755        void unpause_all_torrents();
756        bool is_any_torrent_active();
757
758        template<typename S>
759        void remove_torrent(S filename)
760        { 
761                remove_torrent_wstr(to_wstr_shim(filename)); 
762        }       
763
764        template<typename S>
765        void remove_torrent_wipe_files(S filename, remove_files fn)
766        { 
767                remove_torrent_wipe_files_wstr(to_wstr_shim(filename), fn); 
768        }       
769
770        void start_event_receiver();
771        void stop_event_receiver();
772       
773        friend bit& bittorrent();
774       
775        int default_torrent_max_connections();
776        int default_torrent_max_uploads();
777        float default_torrent_download();
778        float default_torrent_upload(); 
779
780        const torrent_details_manager& torrentDetails();
781        const torrent_details_manager& updatetorrent_details_manager(const std::wstring& focused, const std::set<std::wstring>& selected);
782       
783private:
784        bit();
785
786        bit_impl* pimpl();
787        const bit_impl* pimpl() const;
788        boost::scoped_ptr<bit_impl> pimpl_;
789       
790        void remove_torrent_wstr(const std::wstring& filename);
791        void remove_torrent_wipe_files_wstr(const std::wstring&  filename, remove_files fn);
792       
793        torrent_details_manager torrentDetails_;
794};
795
796bit& bittorrent();
797
798};
Note: See TracBrowser for help on using the repository browser.