diff options
Diffstat (limited to 'src/Network/BitTorrent/Client/Handle.hs')
-rw-r--r-- | src/Network/BitTorrent/Client/Handle.hs | 58 |
1 files changed, 36 insertions, 22 deletions
diff --git a/src/Network/BitTorrent/Client/Handle.hs b/src/Network/BitTorrent/Client/Handle.hs index 19ad1675..fcc0adad 100644 --- a/src/Network/BitTorrent/Client/Handle.hs +++ b/src/Network/BitTorrent/Client/Handle.hs | |||
@@ -29,7 +29,7 @@ import Data.HashMap.Strict as HM | |||
29 | import Data.Torrent | 29 | import Data.Torrent |
30 | import Data.Torrent.InfoHash | 30 | import Data.Torrent.InfoHash |
31 | import Data.Torrent.Magnet | 31 | import Data.Torrent.Magnet |
32 | import Network.BitTorrent.Client.Types | 32 | import Network.BitTorrent.Client.Types as Types |
33 | import Network.BitTorrent.DHT as DHT | 33 | import Network.BitTorrent.DHT as DHT |
34 | import Network.BitTorrent.Exchange as Exchange | 34 | import Network.BitTorrent.Exchange as Exchange |
35 | import Network.BitTorrent.Tracker as Tracker | 35 | import Network.BitTorrent.Tracker as Tracker |
@@ -86,11 +86,13 @@ openTorrent :: FilePath -> Torrent -> BitTorrent Handle | |||
86 | openTorrent rootPath t @ Torrent {..} = do | 86 | openTorrent rootPath t @ Torrent {..} = do |
87 | let ih = idInfoHash tInfoDict | 87 | let ih = idInfoHash tInfoDict |
88 | allocHandle ih $ do | 88 | allocHandle ih $ do |
89 | statusVar <- newMVar Types.Stopped | ||
89 | tses <- liftIO $ Tracker.newSession ih (trackerList t) | 90 | tses <- liftIO $ Tracker.newSession ih (trackerList t) |
90 | eses <- newExchangeSession rootPath (Right tInfoDict) | 91 | eses <- newExchangeSession rootPath (Right tInfoDict) |
91 | return $ Handle | 92 | return $ Handle |
92 | { handleTopic = ih | 93 | { handleTopic = ih |
93 | , handlePrivate = idPrivate tInfoDict | 94 | , handlePrivate = idPrivate tInfoDict |
95 | , handleStatus = statusVar | ||
94 | , handleTrackers = tses | 96 | , handleTrackers = tses |
95 | , handleExchange = eses | 97 | , handleExchange = eses |
96 | } | 98 | } |
@@ -99,11 +101,13 @@ openTorrent rootPath t @ Torrent {..} = do | |||
99 | openMagnet :: FilePath -> Magnet -> BitTorrent Handle | 101 | openMagnet :: FilePath -> Magnet -> BitTorrent Handle |
100 | openMagnet rootPath Magnet {..} = do | 102 | openMagnet rootPath Magnet {..} = do |
101 | allocHandle exactTopic $ do | 103 | allocHandle exactTopic $ do |
104 | statusVar <- newMVar Types.Stopped | ||
102 | tses <- liftIO $ Tracker.newSession exactTopic def | 105 | tses <- liftIO $ Tracker.newSession exactTopic def |
103 | eses <- newExchangeSession rootPath (Left exactTopic) | 106 | eses <- newExchangeSession rootPath (Left exactTopic) |
104 | return $ Handle | 107 | return $ Handle |
105 | { handleTopic = exactTopic | 108 | { handleTopic = exactTopic |
106 | , handlePrivate = False | 109 | , handlePrivate = False |
110 | , handleStatus = statusVar | ||
107 | , handleTrackers = tses | 111 | , handleTrackers = tses |
108 | , handleExchange = eses | 112 | , handleExchange = eses |
109 | } | 113 | } |
@@ -124,21 +128,32 @@ closeHandle h @ Handle {..} = do | |||
124 | -- Control | 128 | -- Control |
125 | -----------------------------------------------------------------------} | 129 | -----------------------------------------------------------------------} |
126 | 130 | ||
131 | modifyStatus :: HandleStatus -> Handle -> (HandleStatus -> BitTorrent ()) -> BitTorrent () | ||
132 | modifyStatus targetStatus Handle {..} targetAction = do | ||
133 | modifyMVar_ handleStatus $ \ actualStatus -> do | ||
134 | unless (actualStatus == targetStatus) $ do | ||
135 | targetAction actualStatus | ||
136 | return targetStatus | ||
137 | |||
127 | -- | Start downloading, uploading and announcing this torrent. | 138 | -- | Start downloading, uploading and announcing this torrent. |
128 | -- | 139 | -- |
129 | -- This operation is blocking, use | 140 | -- This operation is blocking, use |
130 | -- 'Control.Concurrent.Async.Lifted.async' if needed. | 141 | -- 'Control.Concurrent.Async.Lifted.async' if needed. |
131 | start :: Handle -> BitTorrent () | 142 | start :: Handle -> BitTorrent () |
132 | start Handle {..} = do | 143 | start h @ Handle {..} = do |
133 | Client {..} <- getClient | 144 | modifyStatus Types.Running h $ \ status -> do |
134 | liftIO $ Tracker.notify trackerManager handleTrackers Tracker.Started | 145 | case status of |
135 | unless handlePrivate $ do | 146 | Types.Running -> return () |
136 | liftDHT $ DHT.insert handleTopic (error "start") | 147 | Types.Stopped -> do |
137 | liftIO $ do | 148 | Client {..} <- getClient |
138 | peers <- askPeers trackerManager handleTrackers | 149 | liftIO $ Tracker.notify trackerManager handleTrackers Tracker.Started |
139 | print $ "got: " ++ show (L.length peers) ++ " peers" | 150 | unless handlePrivate $ do |
140 | forM_ peers $ \ peer -> do | 151 | liftDHT $ DHT.insert handleTopic (error "start") |
141 | Exchange.connect peer handleExchange | 152 | liftIO $ do |
153 | peers <- askPeers trackerManager handleTrackers | ||
154 | print $ "got: " ++ show (L.length peers) ++ " peers" | ||
155 | forM_ peers $ \ peer -> do | ||
156 | Exchange.connect peer handleExchange | ||
142 | 157 | ||
143 | -- | Stop downloading this torrent. | 158 | -- | Stop downloading this torrent. |
144 | pause :: Handle -> BitTorrent () | 159 | pause :: Handle -> BitTorrent () |
@@ -146,21 +161,20 @@ pause _ = return () | |||
146 | 161 | ||
147 | -- | Stop downloading, uploading and announcing this torrent. | 162 | -- | Stop downloading, uploading and announcing this torrent. |
148 | stop :: Handle -> BitTorrent () | 163 | stop :: Handle -> BitTorrent () |
149 | stop Handle {..} = do | 164 | stop h @ Handle {..} = do |
150 | Client {..} <- getClient | 165 | modifyStatus Types.Stopped h $ \ status -> do |
151 | unless handlePrivate $ do | 166 | case status of |
152 | liftDHT $ DHT.delete handleTopic (error "stop") | 167 | Types.Stopped -> return () |
153 | liftIO $ Tracker.notify trackerManager handleTrackers Tracker.Stopped | 168 | Types.Running -> do |
169 | Client {..} <- getClient | ||
170 | unless handlePrivate $ do | ||
171 | liftDHT $ DHT.delete handleTopic (error "stop") | ||
172 | liftIO $ Tracker.notify trackerManager handleTrackers Tracker.Stopped | ||
154 | 173 | ||
155 | {----------------------------------------------------------------------- | 174 | {----------------------------------------------------------------------- |
156 | -- Query | 175 | -- Query |
157 | -----------------------------------------------------------------------} | 176 | -----------------------------------------------------------------------} |
158 | 177 | ||
159 | data HandleStatus | ||
160 | = Running | ||
161 | | Paused | ||
162 | | Stopped | ||
163 | |||
164 | getHandle :: InfoHash -> BitTorrent Handle | 178 | getHandle :: InfoHash -> BitTorrent Handle |
165 | getHandle ih = do | 179 | getHandle ih = do |
166 | mhandle <- lookupHandle ih | 180 | mhandle <- lookupHandle ih |
@@ -169,4 +183,4 @@ getHandle ih = do | |||
169 | Just h -> return h | 183 | Just h -> return h |
170 | 184 | ||
171 | getStatus :: Handle -> IO HandleStatus | 185 | getStatus :: Handle -> IO HandleStatus |
172 | getStatus = undefined | 186 | getStatus Handle {..} = readMVar handleStatus |