175 lines
7.6 KiB
Python
175 lines
7.6 KiB
Python
from django.db.models import Q
|
|
|
|
from cookbook.models import Unit, SupermarketCategory, FoodProperty, FoodPropertyType, Supermarket, SupermarketCategoryRelation, Food, Automation
|
|
|
|
|
|
class OpenDataImporter:
|
|
request = None
|
|
data = {}
|
|
slug_id_cache = {}
|
|
|
|
def __init__(self, request, data):
|
|
self.request = request
|
|
self.data = data
|
|
|
|
def _update_slug_cache(self, object_class, datatype):
|
|
self.slug_id_cache[datatype] = dict(object_class.objects.filter(space=self.request.space, open_data_slug__isnull=False).values_list('open_data_slug', 'id', ))
|
|
|
|
def import_units(self):
|
|
unit_name_list = []
|
|
for u in list(self.data['unit'].keys()):
|
|
unit_name_list.append(self.data['unit'][u]['name'])
|
|
unit_name_list.append(self.data['unit'][u]['plural_name'])
|
|
|
|
existing_units = Unit.objects.filter(space=self.request.space).filter(Q(name__in=unit_name_list) | Q(plural_name__in=unit_name_list)).values_list('name', 'plural_name')
|
|
existing_units = [item for sublist in existing_units for item in sublist]
|
|
|
|
insert_list = []
|
|
for u in list(self.data['unit'].keys()):
|
|
if not (self.data['unit'][u]['name'] in existing_units or self.data['unit'][u]['plural_name'] in existing_units):
|
|
insert_list.append(Unit(
|
|
name=self.data['unit'][u]['name'],
|
|
plural_name=self.data['unit'][u]['plural_name'],
|
|
base_unit=self.data['unit'][u]['base_unit'] if self.data['unit'][u]['base_unit'] != '' else None,
|
|
open_data_slug=u,
|
|
space=self.request.space
|
|
))
|
|
|
|
Unit.objects.bulk_create(insert_list)
|
|
return len(insert_list)
|
|
|
|
def import_category(self):
|
|
identifier_list = []
|
|
datatype = 'category'
|
|
for k in list(self.data[datatype].keys()):
|
|
identifier_list.append(self.data[datatype][k]['name'])
|
|
|
|
existing_objects = SupermarketCategory.objects.filter(space=self.request.space).filter(name__in=identifier_list).values_list('name', flat=True)
|
|
|
|
insert_list = []
|
|
for k in list(self.data[datatype].keys()):
|
|
if not (self.data[datatype][k]['name'] in existing_objects):
|
|
insert_list.append(SupermarketCategory(
|
|
name=self.data[datatype][k]['name'],
|
|
open_data_slug=k,
|
|
space=self.request.space
|
|
))
|
|
|
|
SupermarketCategory.objects.bulk_create(insert_list)
|
|
return len(insert_list)
|
|
|
|
def import_property(self):
|
|
identifier_list = []
|
|
datatype = 'property'
|
|
for k in list(self.data[datatype].keys()):
|
|
identifier_list.append(self.data[datatype][k]['name'])
|
|
|
|
existing_objects = FoodPropertyType.objects.filter(space=self.request.space).filter(name__in=identifier_list).values_list('name', flat=True)
|
|
|
|
insert_list = []
|
|
for k in list(self.data[datatype].keys()):
|
|
if not (self.data[datatype][k]['name'] in existing_objects):
|
|
insert_list.append(FoodPropertyType(
|
|
name=self.data[datatype][k]['name'],
|
|
unit=self.data[datatype][k]['unit'],
|
|
open_data_slug=k,
|
|
space=self.request.space
|
|
))
|
|
|
|
FoodPropertyType.objects.bulk_create(insert_list)
|
|
return len(insert_list)
|
|
|
|
def import_supermarket(self):
|
|
identifier_list = []
|
|
datatype = 'supermarket'
|
|
for k in list(self.data[datatype].keys()):
|
|
identifier_list.append(self.data[datatype][k]['name'])
|
|
|
|
existing_objects = Supermarket.objects.filter(space=self.request.space).filter(name__in=identifier_list).values_list('name', flat=True)
|
|
|
|
self._update_slug_cache(SupermarketCategory, 'category')
|
|
|
|
insert_list = []
|
|
for k in list(self.data[datatype].keys()):
|
|
if not (self.data[datatype][k]['name'] in existing_objects): # TODO on large datasets see if bulk creating supermarkets and then relations as well is better
|
|
supermarket = Supermarket.objects.create(
|
|
name=self.data[datatype][k]['name'],
|
|
open_data_slug=k,
|
|
space=self.request.space
|
|
)
|
|
|
|
relations = []
|
|
order = 0
|
|
for c in self.data[datatype][k]['categories']:
|
|
relations.append(
|
|
SupermarketCategoryRelation(
|
|
supermarket=supermarket,
|
|
category_id=self.slug_id_cache['category'][c],
|
|
order=order,
|
|
)
|
|
)
|
|
order += 1
|
|
|
|
SupermarketCategoryRelation.objects.bulk_create(relations)
|
|
|
|
return len(insert_list)
|
|
|
|
def import_food(self, metric=True):
|
|
identifier_list = []
|
|
datatype = 'food'
|
|
for k in list(self.data[datatype].keys()):
|
|
identifier_list.append(self.data[datatype][k]['name'])
|
|
identifier_list.append(self.data[datatype][k]['plural_name'])
|
|
|
|
existing_objects = Food.objects.filter(space=self.request.space).filter(name__in=identifier_list).values_list('name', flat=True)
|
|
|
|
self._update_slug_cache(Unit, 'unit')
|
|
self._update_slug_cache(FoodPropertyType, 'property')
|
|
|
|
pref_unit_key = 'preferred_unit_metric'
|
|
pref_shopping_unit_key = 'preferred_packaging_unit_metric'
|
|
if not metric:
|
|
pref_unit_key = 'preferred_unit_imperial'
|
|
pref_shopping_unit_key = 'preferred_packaging_unit_imperial'
|
|
|
|
insert_list = []
|
|
|
|
for k in list(self.data[datatype].keys()):
|
|
if not (self.data[datatype][k]['name'] in existing_objects):
|
|
insert_list.append(Food(
|
|
name=self.data[datatype][k]['name'],
|
|
plural_name=self.data[datatype][k]['plural_name'] if self.data[datatype][k]['plural_name'] != '' else None,
|
|
preferred_unit_id=self.slug_id_cache['unit'][self.data[datatype][k][pref_unit_key]],
|
|
preferred_shopping_unit_id=self.slug_id_cache['unit'][self.data[datatype][k][pref_shopping_unit_key]],
|
|
supermarket_category_id=self.slug_id_cache['category'][self.data[datatype][k]['supermarket_category']],
|
|
fdc_id=self.data[datatype][k]['fdc_id'] if self.data[datatype][k]['fdc_id'] != '' else None,
|
|
open_data_slug=k,
|
|
space=self.request.space,
|
|
))
|
|
|
|
Food.objects.bulk_create(insert_list)
|
|
|
|
self._update_slug_cache(Food, 'food')
|
|
|
|
food_property_list = []
|
|
alias_list = []
|
|
for k in list(self.data[datatype].keys()):
|
|
for fp in self.data[datatype][k]['properties']['type_values']:
|
|
food_property_list.append(FoodProperty(
|
|
food_id=self.slug_id_cache['food'][k],
|
|
food_amount=self.data[datatype][k]['properties']['food_amount'],
|
|
food_unit_id=self.slug_id_cache['unit'][self.data[datatype][k]['properties']['food_unit']],
|
|
property_type_id=self.slug_id_cache['property'][fp['property_type']],
|
|
property_amount=fp['property_value'],
|
|
))
|
|
|
|
for a in self.data[datatype][k]['alias']:
|
|
alias_list.append(Automation(
|
|
param_1=a,
|
|
param_2=self.data[datatype][k]['name']
|
|
))
|
|
|
|
FoodProperty.objects.bulk_create(food_property_list)
|
|
Automation.objects.bulk_create(alias_list)
|
|
return len(insert_list)
|