made car makes
This commit is contained in:
parent
66608ee633
commit
a80d2be661
52
.dockerignore
Normal file
52
.dockerignore
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# dependencies
|
||||||
|
node_modules
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# build output
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
out/
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
# environment files
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# logs
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
|
pids/
|
||||||
|
*.pid
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# runtime data
|
||||||
|
*.sock
|
||||||
|
|
||||||
|
# editor directories and files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Docker itself
|
||||||
|
Dockerfile*
|
||||||
|
docker-compose*.yml
|
||||||
|
|
||||||
|
# bundle artifacts
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# test output
|
||||||
|
test-results/
|
||||||
|
|
||||||
|
# other
|
||||||
|
coverage/
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -130,3 +130,4 @@ dist
|
|||||||
.yarn/install-state.gz
|
.yarn/install-state.gz
|
||||||
.pnp.*
|
.pnp.*
|
||||||
|
|
||||||
|
.venv
|
||||||
112
nhtsa_jp.py
Normal file
112
nhtsa_jp.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
# nhtsa_japan_domestic.py
|
||||||
|
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
from pymongo import MongoClient, ASCENDING
|
||||||
|
from typing import List, Dict, Set
|
||||||
|
|
||||||
|
BASE_URL = 'https://vpic.nhtsa.dot.gov/api/vehicles'
|
||||||
|
FMT = 'format=json'
|
||||||
|
|
||||||
|
# — MongoDB setup
|
||||||
|
MONGO_URI = os.getenv('MONGO_URI', 'mongodb+srv://goldfishjonny:Tt0BBMbzai477RIM@csc491.g36va.mongodb.net/')
|
||||||
|
MONGO_DB = os.getenv('MONGO_DB', 'RevSocial')
|
||||||
|
client = MongoClient(MONGO_URI)
|
||||||
|
db = client[MONGO_DB]
|
||||||
|
|
||||||
|
# — Collections & Indexes
|
||||||
|
makes_col = db['jdm_makes']
|
||||||
|
models_col = db['jdm_models']
|
||||||
|
|
||||||
|
makes_col .create_index('make_name', unique=True)
|
||||||
|
models_col.create_index([('make',ASCENDING),
|
||||||
|
('year',ASCENDING),
|
||||||
|
('model',ASCENDING)], unique=True)
|
||||||
|
|
||||||
|
def get_all_manufacturers(page: int=1) -> List[Dict]:
|
||||||
|
"""/vehicles/GetAllManufacturers?page={page}&format=json :contentReference[oaicite:0]{index=0}"""
|
||||||
|
r = requests.get(f'{BASE_URL}/GetAllManufacturers?{FMT}&page={page}')
|
||||||
|
r.raise_for_status()
|
||||||
|
return r.json()['Results']
|
||||||
|
|
||||||
|
def get_makes_for_manufacturer(mfr_id: int) -> List[Dict]:
|
||||||
|
"""/vehicles/GetMakeForManufacturer/{mfr_id}?format=json :contentReference[oaicite:1]{index=1}"""
|
||||||
|
r = requests.get(f'{BASE_URL}/GetMakeForManufacturer/{mfr_id}?{FMT}')
|
||||||
|
r.raise_for_status()
|
||||||
|
return r.json()['Results']
|
||||||
|
|
||||||
|
def produces_strict_passenger_car(make: str) -> bool:
|
||||||
|
"""
|
||||||
|
Only count if VehicleTypeName == "Passenger Car" exactly.
|
||||||
|
/vehicles/GetVehicleTypesForMake/{make}?format=json :contentReference[oaicite:2]{index=2}
|
||||||
|
"""
|
||||||
|
r = requests.get(
|
||||||
|
f'{BASE_URL}/GetVehicleTypesForMake/{requests.utils.quote(make)}?{FMT}'
|
||||||
|
)
|
||||||
|
r.raise_for_status()
|
||||||
|
types = [v['VehicleTypeName'].strip().lower()
|
||||||
|
for v in r.json()['Results']]
|
||||||
|
return 'passenger car' in types
|
||||||
|
|
||||||
|
def seed_jdm_makes() -> List[str]:
|
||||||
|
"""
|
||||||
|
Find all Japanese manufacturers, then their makes that
|
||||||
|
strictly produce Passenger Cars in the JDM market.
|
||||||
|
"""
|
||||||
|
jdm_makes: Set[str] = set()
|
||||||
|
page = 1
|
||||||
|
while True:
|
||||||
|
mfrs = get_all_manufacturers(page)
|
||||||
|
if not mfrs:
|
||||||
|
break
|
||||||
|
|
||||||
|
# only Japan‐based manufacturers
|
||||||
|
jap = [m for m in mfrs if m.get('Country','').lower() == 'japan']
|
||||||
|
if not jap:
|
||||||
|
# no more Japan entries further on
|
||||||
|
break
|
||||||
|
|
||||||
|
for m in jap:
|
||||||
|
for mk in get_makes_for_manufacturer(m['Mfr_ID']):
|
||||||
|
name = mk['Make_Name']
|
||||||
|
if produces_strict_passenger_car(name):
|
||||||
|
jdm_makes.add(name)
|
||||||
|
makes_col.update_one(
|
||||||
|
{'make_name': name},
|
||||||
|
{'$set': {'make_name': name}},
|
||||||
|
upsert=True
|
||||||
|
)
|
||||||
|
page += 1
|
||||||
|
|
||||||
|
return sorted(jdm_makes)
|
||||||
|
|
||||||
|
def seed_models_for_years(makes: List[str], years: List[int]):
|
||||||
|
"""
|
||||||
|
For each JDM make, seed models_by_year documents.
|
||||||
|
/vehicles/GetModelsForMakeYear/make/{make}/modelyear/{year}?format=json :contentReference[oaicite:3]{index=3}
|
||||||
|
"""
|
||||||
|
for make in makes:
|
||||||
|
for yr in years:
|
||||||
|
url = (
|
||||||
|
f'{BASE_URL}/GetModelsForMakeYear/'
|
||||||
|
f'make/{requests.utils.quote(make)}/modelyear/{yr}?{FMT}'
|
||||||
|
)
|
||||||
|
r = requests.get(url)
|
||||||
|
r.raise_for_status()
|
||||||
|
models = [m['Model_Name'] for m in r.json()['Results']]
|
||||||
|
for model in models:
|
||||||
|
models_col.update_one(
|
||||||
|
{'make': make, 'year': yr, 'model': model},
|
||||||
|
{'$set': {'make': make, 'year': yr, 'model': model}},
|
||||||
|
upsert=True
|
||||||
|
)
|
||||||
|
print(f"{yr} {make}: {len(models)} models")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print("Seeding JDM makes…")
|
||||||
|
jdm = seed_jdm_makes()
|
||||||
|
print(f"→ {len(jdm)} Japanese domestic‐market makes stored in '{MONGO_DB}.jdm_makes'")
|
||||||
|
|
||||||
|
YEARS = list(range(2015, 2026))
|
||||||
|
seed_models_for_years(jdm, YEARS)
|
||||||
|
print("Done seeding Japanese domestic cars.")
|
||||||
16
src/controllers/carsController.js
Normal file
16
src/controllers/carsController.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
const CarMake = require('../models/car_makes.js');
|
||||||
|
|
||||||
|
// Get all makes
|
||||||
|
// This function retrieves all car makes from the database and sends them as a response.
|
||||||
|
exports.getMakes = async (req, res) =>{
|
||||||
|
try {
|
||||||
|
const makes = await CarMake.find()
|
||||||
|
res.status(200).json(makes);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
message: 'Server error retrieving makes',
|
||||||
|
error: error.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,6 +1,4 @@
|
|||||||
const User = require('../models/user');
|
const User = require('../models/user');
|
||||||
const bcrypt = require('bcryptjs');
|
|
||||||
const jwt = require('jsonwebtoken');
|
|
||||||
|
|
||||||
// Get single user by ID
|
// Get single user by ID
|
||||||
exports.getUser = async (req, res) => {
|
exports.getUser = async (req, res) => {
|
||||||
|
|||||||
10
src/models/car_makes.js
Normal file
10
src/models/car_makes.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const { Schema, model } = require('mongoose');
|
||||||
|
|
||||||
|
const carMakeSchema = new Schema(
|
||||||
|
{
|
||||||
|
make_name: {
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
model.exports = model('CarMake', carMakeSchema);
|
||||||
5
src/routes/v1/carsRoutes.js
Normal file
5
src/routes/v1/carsRoutes.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
const {getMakes} = require('../../controllers/carsController');
|
||||||
|
|
||||||
|
router.get('/makes', getMakes);
|
||||||
Loading…
x
Reference in New Issue
Block a user