from flask import Blueprint, render_template, session, redirect, url_for, jsonify, request import sqlite3 import transmission_rpc import sys import os # Import format functions sys.path.append(os.path.join(os.path.dirname(__file__), '..')) from utils.format import format_file_size, format_status transmission_bp = Blueprint('transmission', __name__) def get_db_connection(): conn = sqlite3.connect('pt_manager.db') conn.row_factory = sqlite3.Row return conn def get_transmission_client(): conn = get_db_connection() client_config = conn.execute( "SELECT * FROM clients WHERE name = 'transmission' AND enabled = 1" ).fetchone() conn.close() if not client_config: return None try: tc = transmission_rpc.Client( host=client_config['host'], port=client_config['port'], username=client_config['username'], password=client_config['password'] ) return tc except Exception as e: print(f"Failed to connect to Transmission: {e}") return None @transmission_bp.route('/transmission') def transmission_index(): if 'user_id' not in session: return redirect(url_for('auth.login')) return render_template('transmission/index.html') @transmission_bp.route('/transmission/torrents') def torrents(): if 'user_id' not in session: return redirect(url_for('auth.login')) tc = get_transmission_client() if not tc: return render_template('transmission/torrents.html', error='Transmission client not configured or unavailable') try: torrents = tc.get_torrents() # Process torrents to format file sizes and statuses processed_torrents = [] for torrent in torrents: # Create a dictionary with the torrent attributes we need processed_torrent = { 'id': torrent.id, 'name': torrent.name, 'totalSize': format_file_size(torrent.total_size), 'percentDone': torrent.progress, 'status': torrent.status, 'statusString': format_status(torrent.status), 'peersSendingToUs': getattr(torrent, 'peers_sending_to_us', 0), 'peersGettingFromUs': getattr(torrent, 'peers_getting_from_us', 0) } processed_torrents.append(processed_torrent) return render_template('transmission/torrents.html', torrents=processed_torrents) except Exception as e: return render_template('transmission/torrents.html', error=f'Failed to fetch torrents: {str(e)}') @transmission_bp.route('/transmission/torrent//stop', methods=['POST']) def stop_torrent(torrent_id): if 'user_id' not in session: return jsonify({'error': 'Authentication required'}), 401 tc = get_transmission_client() if not tc: return jsonify({'error': 'Transmission client not configured or unavailable'}), 500 try: tc.stop_torrent(ids=[torrent_id]) return jsonify({'success': True}) except Exception as e: return jsonify({'error': str(e)}), 500 @transmission_bp.route('/transmission/torrent//start', methods=['POST']) def start_torrent(torrent_id): if 'user_id' not in session: return jsonify({'error': 'Authentication required'}), 401 tc = get_transmission_client() if not tc: return jsonify({'error': 'Transmission client not configured or unavailable'}), 500 try: tc.start_torrent(ids=[torrent_id]) return jsonify({'success': True}) except Exception as e: return jsonify({'error': str(e)}), 500 @transmission_bp.route('/transmission/torrent//remove', methods=['POST']) def remove_torrent(torrent_id): if 'user_id' not in session: return jsonify({'error': 'Authentication required'}), 401 tc = get_transmission_client() if not tc: return jsonify({'error': 'Transmission client not configured or unavailable'}), 500 try: # Remove torrent and data tc.remove_torrent(ids=[torrent_id], delete_data=True) return jsonify({'success': True}) except Exception as e: return jsonify({'error': str(e)}), 500