Initial commit: Sistema Autoparts DB

- 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
This commit is contained in:
2026-01-19 08:45:03 +00:00
commit f395d67136
59 changed files with 10881 additions and 0 deletions

248
dashboard/server.py Normal file
View File

@@ -0,0 +1,248 @@
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)