mirror of
				https://github.com/StuffAnThings/qbit_manage.git
				synced 2025-10-31 08:26:29 +08:00 
			
		
		
		
	# Requirements Updated - "GitPython==3.1.45" - "retrying==1.4.1", # New Features - **Remove Orphaned**: Adds new `min_file_age_minutes` flag to prevent files newer than a certain time from being deleted (Thanks to @H2OKing89 #859) - Adds new standalone script `ban_peers.py` for banning selected peers (Thanks to @tboy1337 #888) # Improvements - Adds timeout detectiono for stuck runs for web API rqeeusts # Bug Fixes - Fix bug in webUI deleting nohardlink section (Fixes #884) **Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.5.1...v4.5.2 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: cat-of-wisdom <217637421+cat-of-wisdom@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Quentin <qking.dev@gmail.com> Co-authored-by: ineednewpajamas <73252768+ineednewpajamas@users.noreply.github.com> Co-authored-by: tboy1337 <30571311+tboy1337@users.noreply.github.com> Co-authored-by: tboy1337 <tboy1337.unchanged733@aleeas.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
		
			
				
	
	
		
			85 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import argparse
 | |
| import logging
 | |
| import re
 | |
| import sys
 | |
| 
 | |
| from qbittorrentapi import Client
 | |
| from qbittorrentapi.exceptions import APIError
 | |
| 
 | |
| logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
 | |
| logger = logging.getLogger(__name__)
 | |
| 
 | |
| 
 | |
| def validate_peers(peers_str):
 | |
|     if not isinstance(peers_str, str):
 | |
|         raise ValueError("Peers must be a string")
 | |
|     peer_addresses = [peer.strip() for peer in peers_str.split("|") if peer.strip()]
 | |
|     valid_peers = []
 | |
|     peer_pattern = re.compile(
 | |
|         r"^(?:"
 | |
|         r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}|"  # IPv4
 | |
|         r"\[[0-9a-fA-F:]+\]|"  # IPv6
 | |
|         r"[a-zA-Z0-9.-]+"  # Hostname
 | |
|         r"):[0-9]{1,5}$"
 | |
|     )
 | |
|     for peer in peer_addresses:
 | |
|         if peer_pattern.match(peer):
 | |
|             try:
 | |
|                 port = int(peer.split(":")[-1])
 | |
|                 if 1 <= port <= 65535:
 | |
|                     valid_peers.append(peer)
 | |
|                 else:
 | |
|                     logger.warning(f"Invalid port range for peer: {peer}")
 | |
|             except ValueError:
 | |
|                 logger.warning(f"Invalid port for peer: {peer}")
 | |
|         else:
 | |
|             logger.warning(f"Invalid peer format: {peer}")
 | |
|     return valid_peers
 | |
| 
 | |
| 
 | |
| def ban_peers(client, peer_list, dry_run):
 | |
|     if not peer_list:
 | |
|         logger.info("No valid peers to ban")
 | |
|         return 0
 | |
|     logger.info(f"Attempting to ban {len(peer_list)} peer(s): {', '.join(peer_list)}")
 | |
|     if dry_run:
 | |
|         for peer in peer_list:
 | |
|             logger.info(f"[DRY-RUN] - {peer}")
 | |
|         return len(peer_list)
 | |
|     try:
 | |
|         peers_string = "|".join(peer_list)
 | |
|         client.transfer.ban_peers(peers=peers_string)
 | |
|         logger.info(f"Successfully banned {len(peer_list)} peer(s)")
 | |
|         return len(peer_list)
 | |
|     except APIError as e:
 | |
|         logger.error(f"Error banning peers: {str(e)}")
 | |
|         return 0
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     parser = argparse.ArgumentParser(description="Ban peers in qBittorrent.")
 | |
|     parser.add_argument("--host", default="localhost", help="qBittorrent host")
 | |
|     parser.add_argument("--port", type=int, default=8080, help="qBittorrent port")
 | |
|     parser.add_argument("--user", help="Username")
 | |
|     parser.add_argument("--pass", dest="password", help="Password")
 | |
|     parser.add_argument("--peers", required=True, help="Peers to ban, separated by |")
 | |
|     parser.add_argument("--dry-run", action="store_true", help="Dry run mode")
 | |
|     args = parser.parse_args()
 | |
|     try:
 | |
|         client = Client(
 | |
|             host=args.host,
 | |
|             port=args.port,
 | |
|             username=args.user,
 | |
|             password=args.password,
 | |
|         )
 | |
|         client.auth_log_in()
 | |
|     except Exception as e:
 | |
|         logger.error(f"Failed to connect: {e}")
 | |
|         sys.exit(1)
 | |
|     valid_peers = validate_peers(args.peers)
 | |
|     stats = ban_peers(client, valid_peers, args.dry_run)
 | |
|     logger.info(f"Banned {stats} peers")
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     main()
 |