import os import requests from flask import Flask, Response, request from dotenv import load_dotenv from bs4 import BeautifulSoup # Load environment variables from .env file load_dotenv() app = Flask(__name__) @app.route('/metalink') def get_metalink(): # Get query parameters from the request repo = request.args.get('repo') arch = request.args.get('arch') # Check if required parameters are provided if not repo or not arch: return "Error: Missing 'repo' or 'arch' parameter", 400 # Construct the metalink URL using the provided parameters metalink_url = f'https://mirrors.fedoraproject.org/metalink?repo={repo}&arch={arch}' # Fetch the metalink file from the constructed URL response = requests.get(metalink_url) metalink_content = response.content # Parse the .env file to get the filtering criteria excluded_countries = eval(os.getenv('EXCLUDED_COUNTRIES', '[]')) preferred_protocols = eval(os.getenv('PREFERRED_PROTOCOLS', '["https", "http"]')) preferred_types = eval(os.getenv('PREFERRED_TYPES', '["https", "http"]')) min_preference = int(os.getenv('MIN_PREFERENCE', '0')) # Filter out the URLs based on the criteria filtered_content = filter_urls(metalink_content, excluded_countries, preferred_protocols, preferred_types, min_preference) # Return the filtered content as a response return Response(filtered_content, mimetype='application/xml') def filter_urls(content, excluded_countries, preferred_protocols, preferred_types, min_preference): # Parse the XML content soup = BeautifulSoup(content, 'xml') # Find all URL elements urls = soup.find_all('url') # Iterate over URLs and remove those that do not meet the criteria for url in urls: location = url.get('location') protocol = url.get('protocol') type_ = url.get('type') preference = int(url.get('preference', 0)) if (location in excluded_countries or protocol not in preferred_protocols or type_ not in preferred_types or preference < min_preference): url.decompose() # Convert the BeautifulSoup object back to a string and clean up filtered_content = str(soup) filtered_content = '\n'.join(line for line in filtered_content.splitlines() if line.strip()) return filtered_content if __name__ == '__main__': app.run(debug=True)