- Base de datos SQLite con información de vehículos - Dashboard web con Flask y Bootstrap - Scripts de web scraping para RockAuto - Interfaz CLI para consultas - Documentación completa del proyecto Incluye: - 12 marcas de vehículos - 10,923 modelos - 10,919 especificaciones de motores - 12,075 combinaciones modelo-año-motor
248 lines
7.0 KiB
Python
248 lines
7.0 KiB
Python
from flask import Flask, render_template, jsonify, request, send_from_directory
|
|
import sqlite3
|
|
import os
|
|
|
|
app = Flask(__name__, static_folder='.')
|
|
|
|
# Database path - adjust as needed
|
|
DATABASE_PATH = '../vehicle_database/vehicle_database.db'
|
|
|
|
def get_db_connection():
|
|
"""Get a connection to the vehicle database"""
|
|
conn = sqlite3.connect(DATABASE_PATH)
|
|
conn.row_factory = sqlite3.Row # This enables column access by name
|
|
return conn
|
|
|
|
def get_all_brands():
|
|
"""Get all unique brands from the database"""
|
|
conn = get_db_connection()
|
|
cursor = conn.cursor()
|
|
cursor.execute("SELECT DISTINCT name FROM brands ORDER BY name")
|
|
brands = [row['name'] for row in cursor.fetchall()]
|
|
conn.close()
|
|
return brands
|
|
|
|
def get_all_years():
|
|
"""Get all unique years from the database"""
|
|
conn = get_db_connection()
|
|
cursor = conn.cursor()
|
|
cursor.execute("SELECT DISTINCT year FROM years ORDER BY year DESC")
|
|
years = [row['year'] for row in cursor.fetchall()]
|
|
conn.close()
|
|
return years
|
|
|
|
def get_all_engines():
|
|
"""Get all unique engines from the database"""
|
|
conn = get_db_connection()
|
|
cursor = conn.cursor()
|
|
cursor.execute("SELECT DISTINCT name FROM engines ORDER BY name")
|
|
engines = [row['name'] for row in cursor.fetchall()]
|
|
conn.close()
|
|
return engines
|
|
|
|
def get_models_by_brand(brand_name=None):
|
|
"""Get all models, optionally filtered by brand"""
|
|
conn = get_db_connection()
|
|
cursor = conn.cursor()
|
|
|
|
if brand_name:
|
|
cursor.execute("""
|
|
SELECT DISTINCT m.name
|
|
FROM models m
|
|
JOIN brands b ON m.brand_id = b.id
|
|
WHERE b.name = ?
|
|
ORDER BY m.name
|
|
""", (brand_name,))
|
|
else:
|
|
cursor.execute("SELECT DISTINCT name FROM models ORDER BY name")
|
|
|
|
models = [row['name'] for row in cursor.fetchall()]
|
|
conn.close()
|
|
return models
|
|
|
|
def search_vehicles(brand=None, model=None, year=None, engine=None):
|
|
"""Search for vehicles based on filters"""
|
|
conn = get_db_connection()
|
|
cursor = conn.cursor()
|
|
|
|
query = """
|
|
SELECT
|
|
b.name AS brand,
|
|
m.name AS model,
|
|
y.year,
|
|
e.name AS engine,
|
|
e.power_hp,
|
|
e.displacement_cc,
|
|
e.cylinders,
|
|
e.fuel_type,
|
|
mye.trim_level,
|
|
mye.drivetrain,
|
|
mye.transmission
|
|
FROM model_year_engine mye
|
|
JOIN models m ON mye.model_id = m.id
|
|
JOIN brands b ON m.brand_id = b.id
|
|
JOIN years y ON mye.year_id = y.id
|
|
JOIN engines e ON mye.engine_id = e.id
|
|
WHERE 1=1
|
|
"""
|
|
|
|
params = []
|
|
if brand:
|
|
query += " AND b.name = ?"
|
|
params.append(brand)
|
|
if model:
|
|
query += " AND m.name = ?"
|
|
params.append(model)
|
|
if year:
|
|
query += " AND y.year = ?"
|
|
params.append(int(year))
|
|
if engine:
|
|
query += " AND e.name = ?"
|
|
params.append(engine)
|
|
|
|
query += " ORDER BY b.name, m.name, y.year"
|
|
|
|
cursor.execute(query, params)
|
|
results = cursor.fetchall()
|
|
conn.close()
|
|
|
|
# Convert to list of dictionaries
|
|
vehicles = []
|
|
for row in results:
|
|
vehicle = {
|
|
'brand': row['brand'],
|
|
'model': row['model'],
|
|
'year': row['year'],
|
|
'engine': row['engine'],
|
|
'power_hp': row['power_hp'] or 0,
|
|
'displacement_cc': row['displacement_cc'] or 0,
|
|
'cylinders': row['cylinders'] or 0,
|
|
'fuel_type': row['fuel_type'] or 'unknown',
|
|
'trim_level': row['trim_level'] or 'unknown',
|
|
'drivetrain': row['drivetrain'] or 'unknown',
|
|
'transmission': row['transmission'] or 'unknown'
|
|
}
|
|
vehicles.append(vehicle)
|
|
|
|
return vehicles
|
|
|
|
@app.route('/')
|
|
def index():
|
|
"""Serve the main dashboard page"""
|
|
return send_from_directory('.', 'index.html')
|
|
|
|
@app.route('/<path:path>')
|
|
def static_files(path):
|
|
"""Serve static files"""
|
|
return send_from_directory('.', path)
|
|
|
|
@app.route('/api/brands')
|
|
def api_brands():
|
|
"""API endpoint to get all brands"""
|
|
brands = get_all_brands()
|
|
return jsonify(brands)
|
|
|
|
@app.route('/api/years')
|
|
def api_years():
|
|
"""API endpoint to get years, optionally filtered by brand and/or model"""
|
|
brand = request.args.get('brand')
|
|
model = request.args.get('model')
|
|
|
|
conn = get_db_connection()
|
|
cursor = conn.cursor()
|
|
|
|
query = """
|
|
SELECT DISTINCT y.year
|
|
FROM years y
|
|
JOIN model_year_engine mye ON y.id = mye.year_id
|
|
JOIN models m ON mye.model_id = m.id
|
|
JOIN brands b ON m.brand_id = b.id
|
|
WHERE 1=1
|
|
"""
|
|
|
|
params = []
|
|
if brand:
|
|
query += " AND b.name = ?"
|
|
params.append(brand)
|
|
if model:
|
|
query += " AND m.name = ?"
|
|
params.append(model)
|
|
|
|
query += " ORDER BY y.year DESC"
|
|
|
|
cursor.execute(query, params)
|
|
results = cursor.fetchall()
|
|
conn.close()
|
|
|
|
years = [row['year'] for row in results]
|
|
return jsonify(years)
|
|
|
|
@app.route('/api/engines')
|
|
def api_engines():
|
|
"""API endpoint to get engines, optionally filtered by brand, model, and/or year"""
|
|
brand = request.args.get('brand')
|
|
model = request.args.get('model')
|
|
year = request.args.get('year')
|
|
|
|
conn = get_db_connection()
|
|
cursor = conn.cursor()
|
|
|
|
query = """
|
|
SELECT DISTINCT e.name
|
|
FROM engines e
|
|
JOIN model_year_engine mye ON e.id = mye.engine_id
|
|
JOIN models m ON mye.model_id = m.id
|
|
JOIN brands b ON m.brand_id = b.id
|
|
JOIN years y ON mye.year_id = y.id
|
|
WHERE 1=1
|
|
"""
|
|
|
|
params = []
|
|
if brand:
|
|
query += " AND b.name = ?"
|
|
params.append(brand)
|
|
if model:
|
|
query += " AND m.name = ?"
|
|
params.append(model)
|
|
if year:
|
|
query += " AND y.year = ?"
|
|
params.append(int(year))
|
|
|
|
query += " ORDER BY e.name"
|
|
|
|
cursor.execute(query, params)
|
|
results = cursor.fetchall()
|
|
conn.close()
|
|
|
|
engines = [row['name'] for row in results]
|
|
return jsonify(engines)
|
|
|
|
@app.route('/api/models')
|
|
def api_models():
|
|
"""API endpoint to get models, optionally filtered by brand"""
|
|
brand = request.args.get('brand')
|
|
models = get_models_by_brand(brand)
|
|
return jsonify(models)
|
|
|
|
@app.route('/api/vehicles')
|
|
def api_vehicles():
|
|
"""API endpoint to search for vehicles"""
|
|
brand = request.args.get('brand')
|
|
model = request.args.get('model')
|
|
year = request.args.get('year')
|
|
engine = request.args.get('engine')
|
|
|
|
vehicles = search_vehicles(brand, model, year, engine)
|
|
return jsonify(vehicles)
|
|
|
|
if __name__ == '__main__':
|
|
# Check if database exists
|
|
if not os.path.exists(DATABASE_PATH):
|
|
print(f"Database not found at {DATABASE_PATH}")
|
|
print("Please make sure the vehicle database is created first.")
|
|
exit(1)
|
|
|
|
print("Starting Vehicle Dashboard Server...")
|
|
print("Visit http://localhost:5000 to access the dashboard locally")
|
|
print("Visit http://192.168.10.198:5000 to access the dashboard from other computers on the network")
|
|
app.run(debug=True, host='0.0.0.0', port=5000) |