torrent-downloader-react 1.0.19__py3-none-any.whl → 1.0.21__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -75,17 +75,6 @@ DOWNLOAD_PATH = get_downloads_dir()
75
75
  session = lt.session()
76
76
  settings = session.get_settings()
77
77
  settings['listen_interfaces'] = '0.0.0.0:6881'
78
- settings['active_downloads'] = -1 # No limit
79
- settings['active_seeds'] = -1 # No limit
80
- settings['active_limit'] = -1 # No limit
81
- settings['auto_manage_interval'] = 1 # Check every second
82
- settings['active_tracker_limit'] = -1 # No limit
83
- settings['enable_outgoing_utp'] = True
84
- settings['enable_incoming_utp'] = True
85
- settings['announce_to_all_tiers'] = True
86
- settings['announce_to_all_trackers'] = True
87
- settings['aio_threads'] = 8 # Number of async I/O threads
88
- settings['checking_mem_usage'] = 128 # Memory usage for checking (in MB)
89
78
  session.apply_settings(settings)
90
79
 
91
80
  # Store active torrents
@@ -103,6 +92,7 @@ class TorrentInfo(BaseModel):
103
92
  state: str
104
93
  total_size: int
105
94
  downloaded: int
95
+ eta_seconds: Optional[int] = None
106
96
 
107
97
  @app.post("/api/torrent/add")
108
98
  async def add_torrent(request: TorrentRequest):
@@ -143,8 +133,27 @@ async def list_torrents() -> List[TorrentInfo]:
143
133
  state_str = "finished"
144
134
  elif status.state == lt.torrent_status.checking_files:
145
135
  state_str = "checking"
146
- elif status.state == lt.torrent_status.paused:
147
- state_str = "paused"
136
+
137
+ logging.debug(f"Torrent {torrent_id} state: {state_str} (raw state: {status.state})")
138
+
139
+ # Calculate ETA
140
+ eta = None
141
+ try:
142
+ if state_str == "downloading":
143
+ remaining_bytes = status.total_wanted - status.total_wanted_done
144
+ if remaining_bytes <= 0:
145
+ eta = 0 # Download complete
146
+ elif status.download_rate > 0:
147
+ eta = int(remaining_bytes / status.download_rate)
148
+ else:
149
+ eta = None # Can't calculate ETA with zero download rate
150
+ elif state_str in ["finished", "seeding"]:
151
+ eta = 0 # Already complete
152
+ elif state_str == "checking":
153
+ eta = None # Can't estimate during checking
154
+ except Exception as e:
155
+ logging.error(f"Error calculating ETA for torrent {torrent_id}: {e}")
156
+ eta = None
148
157
 
149
158
  info = TorrentInfo(
150
159
  id=torrent_id,
@@ -154,7 +163,8 @@ async def list_torrents() -> List[TorrentInfo]:
154
163
  upload_speed=status.upload_rate / 1024, # Convert to KB/s
155
164
  state=state_str,
156
165
  total_size=status.total_wanted,
157
- downloaded=status.total_wanted_done
166
+ downloaded=status.total_wanted_done,
167
+ eta_seconds=eta
158
168
  )
159
169
  result.append(info)
160
170
 
@@ -182,42 +192,6 @@ async def open_downloads():
182
192
  raise HTTPException(status_code=500, detail="Failed to open downloads folder")
183
193
  return {"message": "Downloads folder opened successfully"}
184
194
 
185
- @app.post("/api/torrent/{torrent_id}/pause")
186
- async def pause_torrent(torrent_id: str):
187
- """Pause a specific torrent."""
188
- if torrent_id not in active_torrents:
189
- raise HTTPException(status_code=404, detail="Torrent not found")
190
-
191
- handle = active_torrents[torrent_id]
192
- handle.pause()
193
- # Force an immediate pause
194
- handle.flush_cache()
195
- return {"message": "Torrent paused successfully"}
196
-
197
- @app.post("/api/torrent/{torrent_id}/resume")
198
- async def resume_torrent(torrent_id: str):
199
- """Resume a specific torrent."""
200
- if torrent_id not in active_torrents:
201
- raise HTTPException(status_code=404, detail="Torrent not found")
202
-
203
- handle = active_torrents[torrent_id]
204
- handle.resume()
205
- return {"message": "Torrent resumed successfully"}
206
-
207
- @app.post("/api/torrent/pause-all")
208
- async def pause_all_torrents():
209
- """Pause all active torrents."""
210
- for handle in active_torrents.values():
211
- handle.pause()
212
- return {"message": "All torrents paused successfully"}
213
-
214
- @app.post("/api/torrent/resume-all")
215
- async def resume_all_torrents():
216
- """Resume all active torrents."""
217
- for handle in active_torrents.values():
218
- handle.resume()
219
- return {"message": "All torrents resumed successfully"}
220
-
221
195
  def main():
222
196
  """Entry point for the application."""
223
197
  import uvicorn