2 Commits bb536407e4 ... e5ede5d623

Auteur SHA1 Bericht Datum
  Nikos Atlas e5ede5d623 add Dockerfile 9 maanden geleden
  Nikos Atlas 852921ea93 fix todos, price/name/urls/availability 9 maanden geleden
5 gewijzigde bestanden met toevoegingen van 62 en 11 verwijderingen
  1. 29 0
      deploy/Dockerfile
  2. 3 1
      requirements.txt
  3. 17 10
      src/telecaster/Clients/CosmohomeClient.py
  4. 1 0
      src/telecaster/settings.py
  5. 12 0
      src/telecaster/views/CosmohomeView.py

+ 29 - 0
deploy/Dockerfile

@@ -0,0 +1,29 @@
+# Use an official Python runtime as a parent image
+FROM python:3.9
+# Set environment variables
+ENV PYTHONDONTWRITEBYTECODE 1
+ENV PYTHONUNBUFFERED 1
+ENV PYTHONPATH "src"
+
+RUN apt-get update && apt-get install -y cron
+
+# Set the working directory in the container
+WORKDIR /app
+COPY requirements.txt /app
+# Install any needed packages specified in requirements.txt
+RUN pip install --no-cache-dir -r requirements.txt
+
+# Copy the current directory contents into the container at /app
+COPY . /app
+WORKDIR /app/src
+# Collect static files
+RUN python manage.py migrate
+RUN python manage.py collectstatic --noinput
+RUN python manage.py crontab add
+RUN python manage.py crontab show
+
+WORKDIR /app
+# Make port 8000 available to the world outside this container
+EXPOSE 8000
+# Run app.py when the container launches
+CMD ["gunicorn", "--bind", "0.0.0.0:8000", "src.wsgi:application"]

+ 3 - 1
requirements.txt

@@ -41,4 +41,6 @@ typing-extensions==4.1.1
 untokenize==0.1.1
 urllib3==1.26.8
 djangorestframework-xml==2.0.0
-django-crontab==0.7.1
+django-crontab==0.7.1
+dicttoxml==1.7.16
+gunicorn==21.2.0

+ 17 - 10
src/telecaster/Clients/CosmohomeClient.py

@@ -2,6 +2,7 @@ import hashlib
 import struct
 from collections import defaultdict
 from datetime import datetime
+from functools import lru_cache
 
 from dicttoxml import dicttoxml
 
@@ -72,8 +73,7 @@ class CosmohomeClient(PrestaShopClient):
         serialized_product = {
             "productId": product.get('id'),
             "title": self.sanitize_language(product.get('name')),
-            # TODO FIX PRODUCT_URL - it has no domain + path!!
-            "productURL": product.get('link_rewrite'),
+            "productURL": self.generate_product_url(product),
             # add to the url the attributes like #/attr_id/attr_id/...
             "Category": self.get_category_tree(product.get('id_category_default'),
                                                min_depth=1),
@@ -82,11 +82,11 @@ class CosmohomeClient(PrestaShopClient):
             "Manufacturer": product.get('manufacturer_name'),
             "MPN": product.get('reference') or product.get('mpn'),
             "Barcode": product.get('ean13'),
-            "Price": self.calculate_final_price(product),
+            "price": self.calculate_final_price(product),
             "image": self.generate_image_url(product),
             "stock": "Y" if int(product.get('quantity')) > 0 else "N",
             "Availability": "Available from 1 to 3 days" if int(
-                product.get('quantity')) > 0 else "",
+                product.get('quantity')) > 0 else "Available from 1 to 3 days",
             "Quantity": product.get('quantity'),
             "Color": self.get_color(product),
             "Size": self.get_size(product),
@@ -100,14 +100,13 @@ class CosmohomeClient(PrestaShopClient):
                     combination.get('reference'), 10),
                 "Barcode": combination.get('ean13') or serialized_product.get(
                     'Barcode'),
-                # TODO: Product-URL should be overriden for combination
-                # TODO: Name is not a good idea it does not exist
-                # "Name": combination.get('name'),
+                "productURL": self.generate_combination_url(product, combination),
+
                 "weight": product.get('weight'),
                 "MPN": combination.get('reference') or combination.get(
                     'mpn') or serialized_product.get('MPN'),
 
-                "Price": self.calculate_final_price(
+                "price": self.calculate_final_price(
                     combination,
                     float(product.get('price')) + float(combination.get('price'))
                 ),
@@ -147,6 +146,14 @@ class CosmohomeClient(PrestaShopClient):
         link_rewrite = self.sanitize_language(product.get('link_rewrite'))
         return f"{CANONICAL_DOMAIN}/{image_id}-thickbox_default/{link_rewrite}.jpg"
 
+    def generate_product_url(self, product):
+        link_rewrite = self.sanitize_language(product.get('link_rewrite'))
+        return f"{CANONICAL_DOMAIN}/{product.get('id')}-{link_rewrite}.html"
+
+    def generate_combination_url(self, product, combination):
+        link_rewrite = self.sanitize_language(product.get('link_rewrite'))
+        return f"{CANONICAL_DOMAIN}/{product.get('id')}-{combination.get('id')}-{link_rewrite}.html"
+
     def get_color(self, product):
         options = product.get('associations').get('product_option_values') or []
         for option in options:
@@ -184,7 +191,7 @@ class CosmohomeClient(PrestaShopClient):
 
         price_with_tax = float(price) * (1 + TAX)
 
-        sp = self.caches['specific_prices'].get(product.get('id'))
+        sp = self.caches['specific_prices'].get(str(product.get('id')))
         if sp:
             discount = sp.get('reduction')
             type = sp.get('reduction_type')
@@ -238,7 +245,7 @@ def generate_xml():
 
     products = []
     for product in batch_products(client, params={'filter[active]': '1'},
-                                  batch_size=200):
+                                  batch_size=10, hard_limit=1):
         products += client.parse_product(product)
 
     xml = dicttoxml(

+ 1 - 0
src/telecaster/settings.py

@@ -117,6 +117,7 @@ USE_TZ = True
 # Static files (CSS, JavaScript, Images)
 # https://docs.djangoproject.com/en/4.0/howto/static-files/
 
+STATIC_ROOT = BASE_DIR / 'static'
 STATIC_URL = 'static/'
 
 # Default primary key field type

+ 12 - 0
src/telecaster/views/CosmohomeView.py

@@ -12,3 +12,15 @@ class CosmohomeView(viewsets.ViewSet):
     def generate_xml(cls, request: Request, *args, **kwargs) -> HttpResponse:
         final_xml = generate_xml_task()
         return HttpResponse('ok')
+
+    @classmethod
+    @action(methods=['get'], detail=False, url_path='xml')
+    def xml(cls, request: Request, *args, **kwargs) -> HttpResponse:
+        file = "cosmohome_products.xml"
+        try:
+            with open(file, 'rb') as f:
+                return HttpResponse(f.read(), content_type='text/xml')
+        except OSError:
+            print(f"No available {file} file. Please generate one first.")
+            pass
+        return HttpResponse('No available xml file. Please generate one first.', status=404)