import logging import csv from django.shortcuts import render from django.conf import settings # Create your views here. from rest_framework import viewsets from rest_framework.response import Response from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAdminUser from rest_framework.decorators import api_view, permission_classes import requests from products.models import Product from products.serializers import ProductSerializer from companies.models import Company from back_latienda.permissions import IsCreator logging.basicConfig( filename='logs/product-load.log', filemode='w', format='%(levelname)s:%(message)s', level=logging.INFO, ) class ProductViewSet(viewsets.ModelViewSet): queryset = Product.objects.all() serializer_class = ProductSerializer permission_classes = [IsAuthenticatedOrReadOnly, IsCreator] @api_view(['POST',]) @permission_classes([IsAdminUser,]) def load_coop_products(request): """Read CSV file being received Parse it to create products for related Company """ try: csv_file = request.FILES['csv_file'] if csv_file.name.endswith('.csv') is not True: logging.error(f"File {csv_file.name} is not a CSV file") return Response({"errors":{"details": "File is not CSV type"}}) logging.info(f"Reading contents of {csv_file.name}") decoded_file = csv_file.read().decode('utf-8').splitlines() csv_reader = csv.DictReader(decoded_file, delimiter=',') counter = 0 for row in csv_reader: if '' in (row['nombre-producto'], row['descripcion'], row['precio'], row['categoria']): logging.error(f"Required data missing: {row}") continue try: # download image references in csv if row['imagen'].strip() != '': image_url = row['imagen'].strip() response = requests.get(image_url, stream=True) if response.status_code == 200: path = f"{setting.BASE_DIR}media/{row['nombre-producto'].strip()}.{image.url.split('/')[-1]}" logging.info(f"Saving product image to: {path}") new_image = open(path, 'wb') for chunk in response: new_image.write(chunk) new_image.close() else: logging.warning(f"Image URL did not work: {image_url}") new_image = None else: new_image = None # assemble instance data product_data = { 'id': None if row['id'].strip()=='' else row['id'].strip(), 'company': Company.objects.filter(creator=request.user).first(), 'name': row['nombre-producto'].strip(), 'description': row['descripcion'].strip(), 'image': new_image, 'url': row['url'].strip(), 'price': row['precio'].strip(), 'shipping_cost': row['gastos-envio'].strip(), 'shipping_terms': row['cond-envio'].strip(), 'discount': row['descuento'].strip(), 'stock': row['stock'].strip(), 'tags': row['tags'].strip(), 'category': row['categoria'].strip(), 'identifiers': row['identificadores'].strip(), } Product.objects.create(**product_data) logging.info(f"Created Product: {product_data}") counter += 1 except Exception as e: logging.error(f"Could not parse {row}") return Response() except Exception as e: return Response({"errors": {"details": str(type(e))}}) @api_view(['GET',]) # include allowed methods def product_search(request): """ Takes a string of data, return relevant products """ query_string = request.GET.get('query_string', None) if query_string is None: return Response({"errors": {"details": "No query string to parse"}}) try: chunks = query_string.split(' ') result_set = set() import ipdb; ipdb.set_trace() for chunk in chunks: import ipdb; ipdb.set_trace() # search in name products = Product.objects.filter(name__in=chunk) for item in products: result_set.add(item) # search in description products = Product.objects.filter(description__in=chunk) for item in products: result_set.add(item) # search in tags products = Product.objects.filter(tags__in=chunk) for item in products: result_set.add(item) # search in category products = Product.objects.filter(category__in=chunk) for item in products: result_set.add(item) # search in attributes products = Product.objects.filter(attributes__in=chunk) for item in products: result_set.add(item) return Response(data=result_set) except Exception as e: return Response({"errors": {"details": str(type(e))}})