Spaces:
Sleeping
Sleeping
| # app.py | |
| from flask import Flask, request, render_template, g | |
| import sqlite3 | |
| import requests | |
| from datetime import datetime | |
| import os | |
| app = Flask(__name__) | |
| app.config['DATABASE'] = 'visitors.db' | |
| app.config['IP_API_KEY'] = '' # Optional API key for ip-api.com | |
| # Database setup | |
| def get_db(): | |
| db = getattr(g, '_database', None) | |
| if db is None: | |
| db = g._database = sqlite3.connect(app.config['DATABASE']) | |
| return db | |
| def init_db(): | |
| with app.app_context(): | |
| db = get_db() | |
| cursor = db.cursor() | |
| cursor.execute(''' | |
| CREATE TABLE IF NOT EXISTS visitors ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| timestamp TEXT NOT NULL, | |
| ip TEXT NOT NULL, | |
| country TEXT, | |
| country_code TEXT, | |
| region TEXT, | |
| region_name TEXT, | |
| city TEXT, | |
| zip TEXT, | |
| lat REAL, | |
| lon REAL, | |
| timezone TEXT, | |
| isp TEXT, | |
| org TEXT, | |
| as_number TEXT, | |
| mobile BOOLEAN, | |
| proxy BOOLEAN, | |
| hosting BOOLEAN, | |
| user_agent TEXT, | |
| path TEXT | |
| ) | |
| ''') | |
| db.commit() | |
| def close_connection(exception): | |
| db = getattr(g, '_database', None) | |
| if db is not None: | |
| db.close() | |
| # Helper functions | |
| def get_client_ip(): | |
| """Get the client IP address, handling proxy headers""" | |
| if request.headers.getlist("X-Forwarded-For"): | |
| ip = request.headers.getlist("X-Forwarded-For")[0].split(',')[0] | |
| else: | |
| ip = request.remote_addr | |
| return ip | |
| def get_location_info(ip_address): | |
| """Get geolocation information for an IP address""" | |
| try: | |
| # Using ip-api.com (free tier) | |
| fields = 'status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,mobile,proxy,hosting,query' | |
| url = f'http://ip-api.com/json/{ip_address}?fields={fields}' | |
| if app.config['IP_API_KEY']: | |
| url += f'&key={app.config["IP_API_KEY"]}' | |
| response = requests.get(url, timeout=5) | |
| data = response.json() | |
| if data.get('status') == 'success': | |
| return data | |
| return {'error': data.get('message', 'Unknown error')} | |
| except Exception as e: | |
| return {'error': str(e)} | |
| def log_visitor(ip, location_info): | |
| """Store visitor information in the database""" | |
| db = get_db() | |
| cursor = db.cursor() | |
| cursor.execute(''' | |
| INSERT INTO visitors ( | |
| timestamp, ip, country, country_code, region, region_name, city, zip, | |
| lat, lon, timezone, isp, org, as_number, mobile, proxy, hosting, | |
| user_agent, path | |
| ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) | |
| ''', ( | |
| datetime.now().isoformat(), | |
| ip, | |
| location_info.get('country'), | |
| location_info.get('countryCode'), | |
| location_info.get('region'), | |
| location_info.get('regionName'), | |
| location_info.get('city'), | |
| location_info.get('zip'), | |
| location_info.get('lat'), | |
| location_info.get('lon'), | |
| location_info.get('timezone'), | |
| location_info.get('isp'), | |
| location_info.get('org'), | |
| location_info.get('as'), | |
| bool(location_info.get('mobile')), | |
| bool(location_info.get('proxy')), | |
| bool(location_info.get('hosting')), | |
| request.headers.get('User-Agent'), | |
| request.path | |
| )) | |
| db.commit() | |
| # Routes | |
| def index(): | |
| client_ip = get_client_ip() | |
| location_info = get_location_info(client_ip) | |
| if 'error' not in location_info: | |
| log_visitor(client_ip, location_info) | |
| return render_template('index.html', | |
| ip=client_ip, | |
| location=location_info, | |
| error=location_info.get('error')) | |
| def show_visitors(): | |
| """Admin view to see all recorded visitors""" | |
| db = get_db() | |
| cursor = db.cursor() | |
| cursor.execute('SELECT * FROM visitors ORDER BY timestamp DESC LIMIT 100') | |
| visitors = cursor.fetchall() | |
| # Get column names | |
| cursor.execute('PRAGMA table_info(visitors)') | |
| columns = [column[1] for column in cursor.fetchall()] | |
| return render_template('visitors.html', visitors=visitors, columns=columns) | |
| if __name__ == '__main__': | |
| if not os.path.exists(app.config['DATABASE']): | |
| init_db() | |
| app.run(host="0.0.0.0", debug=True) |