Spaces:
Paused
Paused
| from flask import Flask, request, jsonify, send_from_directory, send_file | |
| from PIL import Image, ImageDraw, ImageFont, ImageFilter | |
| from io import BytesIO | |
| import requests | |
| import random | |
| import time | |
| import os | |
| import uuid | |
| import io | |
| import textwrap | |
| import re | |
| app = Flask(__name__) | |
| # Store uptime and request count | |
| start_time = time.time() | |
| request_count = 0 | |
| TINYURL_API = "https://tinyurl.com/api-create.php" | |
| WAIFU_API = "https://api.waifu.pics" | |
| BASE_ANIME_API = "https://reikerxx-animedl.hf.space/anime/" | |
| BASE_DOWNLOAD_API = "https://reikerxx-plw.hf.space/download-links?url=" | |
| ANIME_IDS = [20, 21, 16498, 118763, 2025, 813, 153, 5114, 11757, 2747364, | |
| 12355, 123, 169, 30276, 34565, 6702, 32182, 9253, 157, 30, 1735, 52299, 44511, 34572, 269] | |
| JIKAN_API_BASE = "https://api.jikan.moe/v4/anime" | |
| NODE_API_URL = "https://reikerxx-bani.hf.space/anime" | |
| YT_API_URL = "https://reikerxx-ytm.hf.space/api/q" | |
| BASE_URL = "https://reikerxx-agi.hf.space/getDownload" | |
| IMAGE_FOLDER = "static/images" | |
| os.makedirs(IMAGE_FOLDER, exist_ok=True) # Ensure the folder exists | |
| API_TOKEN = "fe51903c8ea947498dcb16927f840670" | |
| HEADERS = {"X-Auth-Token": API_TOKEN} | |
| # List of 30 popular team IDs | |
| TEAM_IDS = [ | |
| 66, 65, 64, 61, 57, 73, # Premier League | |
| 86, 81, 78, 559, 95, # La Liga | |
| 5, 4, 721, 3, 6, # Bundesliga | |
| 109, 108, 98, 113, 100, # Serie A | |
| 524, 516, 523, 548, # Ligue 1 | |
| 678, 1903, 503, 211, 1877 # Other Leagues | |
| ] | |
| THUMBNAIL_IMAGES = [ | |
| "https://i.imgur.com/WfTUHmd.jpeg", | |
| "https://i.imgur.com/WfTUHmd.jpeg", | |
| "https://i.imgur.com/WfTUHmd.jpeg" | |
| ] | |
| def fetch_random_character(): | |
| while True: | |
| anime_id = random.choice(ANIME_IDS) | |
| url = f"{JIKAN_API_BASE}/{anime_id}/characters" | |
| response = requests.get(url) | |
| if response.status_code != 200: | |
| continue | |
| characters = response.json().get("data", []) | |
| if not characters: | |
| continue | |
| character = random.choice(characters).get("character", {}) | |
| if not character or not character.get("images", {}).get("jpg", {}).get("image_url"): | |
| continue | |
| return { | |
| "name": character.get("name"), | |
| "image": character.get("images", {}).get("jpg", {}).get("image_url"), | |
| "url": character.get("url"), | |
| "api_owner": "Reiker" | |
| } | |
| def get_uptime(): | |
| seconds = int(time.time() - start_time) | |
| days = seconds // 86400 | |
| hours = (seconds % 86400) // 3600 | |
| return f"{days} days, {hours} hours" | |
| def home(): | |
| return send_from_directory(os.getcwd(), 'index.html') # Serves the HTML file from the root directory | |
| def stats(): | |
| global request_count | |
| request_count += 1 | |
| return jsonify({ | |
| "uptime": get_uptime(), | |
| "requests": request_count | |
| }) | |
| def get_random_character(): | |
| return jsonify(fetch_random_character()) | |
| def shorturl(): | |
| long_url = request.args.get('longurl') | |
| if not long_url: | |
| return jsonify({"error": "Missing 'longurl' parameter"}), 400 | |
| response = requests.get(TINYURL_API, params={"url": long_url}) | |
| if response.status_code == 200: | |
| short_url = response.text.strip() # TinyURL returns plain text | |
| return jsonify({ | |
| "apiowner": "Reiker", | |
| "short_url": short_url | |
| }) | |
| else: | |
| return jsonify({"error": "Failed to shorten URL"}), 500 | |
| def get_waifu(): | |
| category = request.args.get('category', 'waifu') # Default to 'waifu' | |
| sfw = request.args.get('sfw', 'true').lower() # Default to SFW images | |
| # Validate category | |
| valid_categories = [ | |
| "waifu", "neko", "shinobu", "megumin", "bully", "cuddle", "cry", "hug", | |
| "awoo", "kiss", "lick", "pat", "smug", "bonk", "yeet", "blush", "smile", | |
| "wave", "highfive", "handhold", "nom", "bite", "glomp", "slap", "kill", | |
| "kick", "happy", "wink", "poke", "dance", "cringe" | |
| ] | |
| if category not in valid_categories: | |
| return jsonify({"error": "Invalid category"}), 400 | |
| # Choose SFW or NSFW | |
| type_field = "sfw" if sfw == "true" else "nsfw" | |
| # Call the waifu.pics API | |
| response = requests.get(f"{WAIFU_API}/{type_field}/{category}") | |
| if response.status_code == 200: | |
| waifu_image = response.json().get("url") | |
| return jsonify({ | |
| "apiowner": "Reiker", | |
| "category": category, | |
| "image_url": waifu_image | |
| }) | |
| else: | |
| return jsonify({"error": "Failed to fetch waifu image"}), 500 | |
| FONT_PATH = "gagalin.otf" # Ensure this font is in the same directory | |
| IMAGE_PATH = "image.png" # Background image | |
| def generate_logo(): | |
| name = request.args.get("name", "Default Name") | |
| info = request.args.get("info", "Your Motto") | |
| try: | |
| # Load the background image | |
| img = Image.open(IMAGE_PATH).convert("RGBA") | |
| draw = ImageDraw.Draw(img) | |
| # Set font sizes dynamically | |
| max_width = img.width * 0.8 # 80% of image width | |
| name_size = int(img.width * 0.12) # Dynamic name size | |
| info_size = int(img.width * 0.05) # Smaller motto size | |
| font_name = ImageFont.truetype(FONT_PATH, name_size) | |
| font_info = ImageFont.truetype(FONT_PATH, info_size) | |
| # Shrink name text if too long | |
| while draw.textbbox((0, 0), name, font=font_name)[2] > max_width: | |
| name_size -= 5 | |
| font_name = ImageFont.truetype(FONT_PATH, name_size) | |
| # **Break long info text into multiple lines** | |
| def wrap_text(text, font, max_width): | |
| lines = [] | |
| for line in textwrap.wrap(text, width=30): # Wrap text every 30 characters | |
| while draw.textbbox((0, 0), line, font=font)[2] > max_width: | |
| font = ImageFont.truetype(FONT_PATH, font.size - 2) # Reduce font size | |
| lines.append(line) | |
| return lines, font | |
| info_lines, font_info = wrap_text(info, font_info, max_width) | |
| # Calculate positions | |
| text_x = img.width // 2 | |
| text_y_name = int(img.height * 0.42) # Slightly lower | |
| text_y_info = int(img.height * 0.58) # Adjusted further down | |
| # Center name text | |
| name_bbox = draw.textbbox((0, 0), name, font=font_name) | |
| name_x = text_x - (name_bbox[2] - name_bbox[0]) // 2 | |
| # Function to draw an **outline glow** instead of blurry glow | |
| def draw_outline(draw, position, text, font, outline_color, thickness=2): | |
| x, y = position | |
| for dx in range(-thickness, thickness + 1): | |
| for dy in range(-thickness, thickness + 1): | |
| if dx != 0 or dy != 0: # Avoid double drawing the center | |
| draw.text((x + dx, y + dy), text, font=font, fill=outline_color) | |
| # **Apply dark blue outline with reduced opacity** | |
| outline_color = (0, 0, 139, 180) # RGBA (Dark Blue with lower opacity) | |
| # **Draw name text** | |
| draw_outline(draw, (name_x, text_y_name), name, font_name, outline_color, thickness=3) | |
| draw.text((name_x, text_y_name), name, font=font_name, fill="white") | |
| # **Draw multi-line info text** | |
| for i, line in enumerate(info_lines): | |
| line_bbox = draw.textbbox((0, 0), line, font=font_info) | |
| line_x = text_x - (line_bbox[2] - line_bbox[0]) // 2 | |
| line_y = text_y_info + (i * (font_info.size + 5)) # Adjust for line spacing | |
| draw_outline(draw, (line_x, line_y), line, font_info, outline_color, thickness=2) | |
| draw.text((line_x, line_y), line, font=font_info, fill="white") | |
| # Save and return as API response | |
| img_io = io.BytesIO() | |
| img.save(img_io, "PNG") | |
| img_io.seek(0) | |
| return send_file(img_io, mimetype="image/png") | |
| except Exception as e: | |
| return {"error": str(e)}, 500 | |
| def get_random_player(): | |
| attempts = 0 | |
| while attempts < 2: # Retry twice if needed | |
| team_id = random.choice(TEAM_IDS) | |
| response = requests.get(f"https://api.football-data.org/v4/teams/{team_id}", headers=HEADERS) | |
| if response.status_code == 200: | |
| team_data = response.json() | |
| squad = team_data.get("squad", []) | |
| if squad: # Ensure the squad is not empty | |
| player = random.choice(squad) | |
| return jsonify({ | |
| "player_name": player.get("name"), | |
| "position": player.get("position"), | |
| "nationality": player.get("nationality"), | |
| "team": team_data.get("name"), | |
| "apiowner": "Reiker" | |
| }) | |
| attempts += 1 | |
| return jsonify({"error": "Failed to fetch valid player data"}), 500 # Only return error after 2 failed attempts | |
| def get_anime_download_links(anime_name, episode): | |
| anime_name_formatted = anime_name.replace(" ", "%20") # URL encoding | |
| anime_api_url = f"{BASE_ANIME_API}{anime_name_formatted}/{episode}" | |
| # Fetch the download page URL | |
| anime_response = requests.get(anime_api_url) | |
| if anime_response.status_code != 200: | |
| return jsonify({"error": "Failed to fetch anime info"}), 500 | |
| anime_data = anime_response.json() | |
| download_page_url = anime_data.get("downloadPage") | |
| if not download_page_url: | |
| return jsonify({"error": "Download page URL not found"}), 404 | |
| # Fetch MP4 links | |
| download_api_url = f"{BASE_DOWNLOAD_API}{download_page_url}" | |
| download_response = requests.get(download_api_url) | |
| if download_response.status_code != 200: | |
| return jsonify({"error": "Failed to fetch download links"}), 500 | |
| download_data = download_response.json() | |
| download_links = download_data.get("downloadLinks", {}) | |
| # Well-formatted JSON response | |
| response_data = { | |
| "api_owner": "Reiker", | |
| "anime_name": anime_data.get("anime", anime_name), | |
| "episode": episode, | |
| "download_links": { | |
| "360p": download_links.get("3604p", "Not Available"), | |
| "720p": download_links.get("7204p", "Not Available") | |
| } | |
| } | |
| return jsonify(response_data), 200 | |
| def get_anime(): | |
| anime_name = request.args.get('name', '').strip() | |
| episode_number = request.args.get('episode', '').strip() | |
| if not anime_name or not episode_number: | |
| return jsonify({"error": "Missing required parameters: name and episode"}), 400 | |
| node_api_url = f"{NODE_API_URL}/{anime_name}/{episode_number}" | |
| try: | |
| response = requests.get(node_api_url) | |
| data = response.json() | |
| if not data or "error" in data: | |
| return jsonify({"error": "No results found for the given anime and episode"}), 404 | |
| formatted_response = { | |
| "Anime": data["anime"], | |
| "Episode": data["episode"], | |
| "Episode URL": data["episodeURL"], | |
| "Downloads": { | |
| "360p": data["360p"] if data["360p"] else "Not available", | |
| "720p": data["720p"] if data["720p"] else "Not available", | |
| "1080p": data["1080p"] if data["1080p"] else "Not available" | |
| } | |
| } | |
| return jsonify(formatted_response), 200 | |
| except requests.exceptions.RequestException as e: | |
| return jsonify({"error": "Failed to connect to the Node.js API", "details": str(e)}), 500 | |
| def youtube_to_mp3(): | |
| video_url = request.args.get('url', '').strip() | |
| if not video_url: | |
| return jsonify({"error": "Missing required parameter: url"}), 400 | |
| try: | |
| response = requests.get(YT_API_URL, params={"url": video_url}) | |
| data = response.json() | |
| if not data.get("success"): | |
| return jsonify({"error": "Failed to convert video"}), 500 | |
| return jsonify({ | |
| "download_link": data["file"], | |
| "api_owner": "Reikerx" | |
| }), 200 | |
| except requests.exceptions.RequestException as e: | |
| return jsonify({"error": "Failed to connect to the conversion API", "details": str(e)}), 500 | |
| def clean_movie_name(raw_name): | |
| """Extracts a clean movie name by removing extra tags like site names.""" | |
| # Remove common tags (e.g., NKIRI COM, BluRay, and unnecessary dots) | |
| clean_name = re.sub(r"(\s*NKIRI\s*COM\s*|\s*DOWNLOADED\s*FROM\s*NKIRI\s*COM|\s*\d{4}\s*BluRay)", "", raw_name, flags=re.IGNORECASE) | |
| # Remove excessive dots and underscores | |
| clean_name = re.sub(r"[\.\_]+", " ", clean_name).strip() | |
| return clean_name | |
| def fetch_download(): | |
| moviename = request.args.get('moviename') | |
| episode = request.args.get('episode') | |
| if not moviename: | |
| return jsonify({"error": "Movie name is required"}), 400 | |
| # Construct the request URL | |
| url = f"{BASE_URL}?moviename={moviename}" | |
| if episode: | |
| url += f"&episode={episode}" | |
| try: | |
| response = requests.get(url) | |
| data = response.json() | |
| except Exception as e: | |
| return jsonify({"error": "Failed to fetch download info", "details": str(e)}), 500 | |
| if "movie" not in data or "finalDownloadUrl" not in data: | |
| return jsonify({"error": "Invalid response format"}), 500 | |
| # Extract and clean movie name | |
| movie_name = clean_movie_name(data["movie"]) | |
| download_url = data["finalDownloadUrl"] | |
| # Format response | |
| formatted_response = { | |
| "Movie Name": movie_name, | |
| "Download Link": download_url | |
| } | |
| return jsonify(formatted_response) | |
| if __name__ == '__main__': | |
| app.run(debug=True, host='0.0.0.0', port=7860) |