pbio-site/app.py
snfsx 9e9be8f3bd Update app.py
deleted unnecessary route
2025-04-24 22:37:47 +00:00

165 lines
No EOL
4.9 KiB
Python

# app.py
# Copyright (c) 2025 snfsx.xyz
# Licensed under the MIT License. See https://opensource.org/licenses/MIT
import os
import datetime
import requests
from flask import Flask, render_template, jsonify, request, send_from_directory
from dotenv import load_dotenv
from werkzeug.middleware.proxy_fix import ProxyFix
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
# Load environment variables from .env file
load_dotenv()
app = Flask(__name__)
app.wsgi_app = ProxyFix(
app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1
)
limiter = Limiter(
get_remote_address,
app=app,
default_limits=["300 per day", "50 per hour"],
storage_uri="memory://",
)
# --- Configuration from .env ---
lastfm_apik = os.getenv('LASTFM_API_KEY')
lastfm_usrname = os.getenv('LASTFM_USERNAME')
usrname = os.getenv('USER_NAME', 'User')
age = os.getenv('USER_AGE', '')
bio = os.getenv('USER_BIO', '#')
tg = os.getenv('USER_TELEGRAM_TAG')
bd = os.getenv('USER_BIRTHDAY', '')
github_usrn = os.getenv('GITHUB_USERNAME')
email = os.getenv('EMAIL_ADDRESS')
jabber = os.getenv('JABBER_ADDRESS')
ton = os.getenv('TON_ADDRESS')
ton_v = os.getenv('TON_VERSION')
favicon = os.getenv('FAVICON_TEXT')
# ---------------------------------
# ----------- Functions --------------
def get_lastfm_now_playing():
"""Fetches the currently playing track from Last.fm API."""
if not lastfm_apik or not lastfm_usrname:
return {'error': 'Last.fm API key or username not configured.'}
api_url = f"http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user={lastfm_usrname}&api_key={lastfm_apik}&format=json&limit=1"
try:
response = requests.get(api_url, timeout=10) # Added timeout
response.raise_for_status() # Raise an exception for bad status codes
data = response.json()
if 'recenttracks' in data and 'track' in data['recenttracks'] and data['recenttracks']['track']:
track_data = data['recenttracks']['track'][0]
is_now_playing = track_data.get('@attr', {}).get('nowplaying') == 'true'
if is_now_playing:
artist = track_data['artist']['#text']
name = track_data['name']
# Get the largest available image URL
image_url = next((img['#text'] for img in reversed(track_data.get('image', [])) if img['#text']), None)
# Construct a plausible song.link URL (accuracy may vary)
song_link = f"https://song.link/s/{requests.utils.quote(f'{name} {artist}')}"
return {
'playing': True,
'artist': artist,
'name': name,
'image_url': image_url,
'song_link': song_link
}
else:
return {'playing': False, 'message': 'Not listening anything right now.'}
else:
# Handle cases where user has no tracks or invalid response structure
return {'playing': False, 'message': 'No recent tracks found.'}
except requests.exceptions.RequestException as e:
print(f"Error fetching Last.fm data: {e}")
return {'error': f'Could not connect to Last.fm API: {e}'}
except Exception as e:
print(f"An unexpected error occurred: {e}")
return {'error': 'An unexpected error occurred while fetching Last.fm data.'}
# ------- end functions ------------
# ----------- Routes ----------------
@app.route('/')
def index():
"""Renders the main page."""
personal_info = {
'name': usrname,
'age': age,
'bio': bio,
'telegram': tg,
'birthday': bd,
'github_username': github_usrn,
'email': email,
'jabber': jabber,
'ton_version': ton_v,
'ton_address': ton,
'favicon': favicon,
'nickname': usrname.lower(),
'year': datetime.datetime.now().year
}
return render_template('index.html', info=personal_info)
@app.route('/api/v1/ip')
def ip_return():
ip = request.headers.get('X-Forwarded-For', request.remote_addr)
return jsonify({"ip": ip})
@app.route('/api/v1/now_playing')
@limiter.limit("1 per 5 second")
def api_now_playing():
"""API endpoint to get current Last.fm track."""
track_info = get_lastfm_now_playing()
return jsonify(track_info)
# -------------- End routes --------------
# ------------ Error handlers -----------
@app.errorhandler(429)
def ratelimit_error(e):
""" 429 handler """
return jsonify(
error="ratelimit_exceeded",
message="Too many requests",
), 429
@app.errorhandler(404)
def handle_not_found(error):
"""404 handler"""
app.logger.warning(f"404 Not Found: {request.path}")
return render_template('404.html'), 404
# ------------ End error handlers -------------
# Start
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False)