162 lines
5.6 KiB
Python
162 lines
5.6 KiB
Python
"""
|
|
Services module
|
|
"""
|
|
|
|
import requests
|
|
import json
|
|
from requests import Session
|
|
|
|
from pyvin import VIN
|
|
from django.conf import settings
|
|
from .models import CarMake
|
|
|
|
|
|
def get_make(item):
|
|
"""
|
|
Fetches a car make object from the database based on the provided item. The function
|
|
first attempts an exact case-insensitive match on the full string. If no match is found,
|
|
it splits the input string by spaces and checks for a match with each fragment, stopping
|
|
as soon as a match is found.
|
|
|
|
:param item: A string representing the name or a part of the name of the car make to search.
|
|
:type item: str
|
|
:return: The first matching CarMake object found, or None if no match is found.
|
|
:rtype: CarMake or None
|
|
"""
|
|
data = CarMake.objects.filter(name__iexact=item).first()
|
|
if not data:
|
|
r = item.split(" ")
|
|
for i in r:
|
|
if data := CarMake.objects.filter(name__iexact=i).first():
|
|
break
|
|
return data
|
|
|
|
|
|
def get_model(item, make):
|
|
"""
|
|
Searches for a car model associated with a specific make by performing an
|
|
exact case-insensitive match. If no match is found, it attempts to match
|
|
based on individual words split from the input item.
|
|
|
|
:param item: A string representing the name of the car model to search for.
|
|
:param make: An object representing the car manufacturer, which contains the
|
|
associated car models.
|
|
:return: Returns the first car model object that matches the search criteria,
|
|
or None if no match is found.
|
|
"""
|
|
data = make.carmodel_set.filter(name__iexact=item).first()
|
|
if not data:
|
|
r = item.split(" ")
|
|
for i in r:
|
|
if data := make.carmodel_set.filter(name__iexact=i).first():
|
|
break
|
|
return data
|
|
|
|
|
|
def normalize_name(name):
|
|
"""
|
|
Normalizes a given name by removing spaces and hyphens and converting it to lowercase.
|
|
|
|
This function is useful for ensuring consistent formatting of names by
|
|
removing unwanted characters and applying a uniform casing. The output
|
|
is designed to be a simple, standardized string version of the input name.
|
|
|
|
:param name: The name string to be normalized.
|
|
:type name: str
|
|
:return: A normalized string with no spaces or hyphens, all in lowercase.
|
|
:rtype: str
|
|
"""
|
|
return name.replace(" ", "").replace("-", "").lower()
|
|
|
|
|
|
def decodevin(vin):
|
|
"""
|
|
Decodes a Vehicle Identification Number (VIN) using multiple decoding functions
|
|
and returns the decoded result. This function attempts to decode the VIN using
|
|
three different functions in sequence and returns the first successful result.
|
|
If none of the decoding functions produce a valid result, the function returns None.
|
|
|
|
:param vin: The Vehicle Identification Number (VIN) to be decoded.
|
|
:type vin: str
|
|
:return: The decoded result if any decoding function is successful, or None if
|
|
all decoding attempts fail.
|
|
:rtype: dict | None
|
|
"""
|
|
if result := decode_vin(vin):
|
|
return result
|
|
elif result := elm(vin):
|
|
return result
|
|
# elif result:=decode_vin_haikalna(vin):
|
|
# return result
|
|
else:
|
|
return None
|
|
|
|
|
|
def decode_vin(vin):
|
|
"""
|
|
Decodes a given Vehicle Identification Number (VIN) to extract vehicle details such as
|
|
maker, model, and model year.
|
|
|
|
This function takes a VIN string as input, processes it using the VIN utility, and attempts
|
|
to extract essential information about the vehicle. It returns a dictionary containing the
|
|
decoded details if all required fields are successfully retrieved; otherwise, it returns None.
|
|
|
|
:param vin: The Vehicle Identification Number to be decoded.
|
|
:type vin: str
|
|
|
|
:return: A dictionary containing decoded vehicle details with keys "maker", "model", and
|
|
"modelYear", or None if any of these fields cannot be determined.
|
|
:rtype: dict | None
|
|
"""
|
|
v = VIN(vin)
|
|
data = {}
|
|
if v:
|
|
data = {
|
|
"maker": v.Make,
|
|
"model": v.Model,
|
|
"modelYear": v.ModelYear,
|
|
}
|
|
return data if all([x for x in data.values()]) else None
|
|
|
|
|
|
def elm(vin):
|
|
"""
|
|
Fetches vehicle information using the provided VIN (Vehicle Identification Number)
|
|
through the ELM API service.
|
|
|
|
This function sends a GET request to the ELM API endpoint with the VIN parameter
|
|
to retrieve details about a vehicle, including its maker, model, and model year.
|
|
The function processes the API's JSON response to extract relevant data and
|
|
returns it if all required fields are available.
|
|
|
|
:param vin: Vehicle Identification Number required to query the ELM API
|
|
service for vehicle information.
|
|
:type vin: str
|
|
|
|
:return: A dictionary containing the vehicle's `maker`, `model`, and `modelYear`
|
|
if all fields are present. Returns None if any of these fields are missing.
|
|
:rtype: dict or None
|
|
"""
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"app-id": settings.ELM_APP_ID,
|
|
"app-key": settings.ELM_APP_KEY,
|
|
"client-id": settings.ELM_CLIENT_ID,
|
|
}
|
|
url = (
|
|
"https://vehicle-maintenance.api.elm.sa/api/v1/vehicles/vehicle-info?vin=" + vin
|
|
)
|
|
|
|
payload = {}
|
|
response = requests.request("GET", url, headers=headers, data=payload)
|
|
response = json.loads(response.text)
|
|
data = {}
|
|
if response.get("data"):
|
|
data = {
|
|
"maker": response["data"]["maker"],
|
|
"model": response["data"]["model"] if response["data"]["model"] else " ",
|
|
"modelYear": response["data"]["modelYear"],
|
|
}
|
|
print([x for x in data.values()])
|
|
return data if all([x for x in data.values()]) else None
|