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" @app.route('/') def home(): return send_from_directory(os.getcwd(), 'index.html') # Serves the HTML file from the root directory @app.route('/api/stats') def stats(): global request_count request_count += 1 return jsonify({ "uptime": get_uptime(), "requests": request_count }) @app.route('/reiker/random-character', methods=['GET']) def get_random_character(): return jsonify(fetch_random_character()) @app.route('/api/shorturl', methods=['GET']) 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 @app.route('/api/waifu', methods=['GET']) 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 @app.route("/api/logo") 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 @app.route('/api/soccer', methods=['GET']) 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 @app.route('/api/anime//', methods=['GET']) 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 @app.route('/api/anime2', methods=['GET']) 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 @app.route('/api/ytmp3', methods=['GET']) 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 @app.route('/fetchDownload', methods=['GET']) 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)