P5-4896 remove esales
This commit is contained in:
@@ -34,8 +34,6 @@ List of available configuration options:
|
||||
| `SQLALCHEMY_DATABASE_URI` | Database connection string. e.g: `postgresql://user:password@localhost/photowall` |
|
||||
| `DEBUG` | Enable/disable debug mode |
|
||||
| `API_KEYS` | A list of api keys that are used to authenticate to the API. If this list is empty authentication will be disabled. |
|
||||
| `ESALES_URL` | URL to the eSales server. If its a cloud cluster it has the format `username:password` |
|
||||
| `ESALES_IMPORT_DIR` | XML-files that should be imported to eSales are temporarily stored in this directory. e.g: `/tmp/esales`
|
||||
| `BERNARD_QUEUE_URL` | URL to Bernard queue (used for running Photowall background tasks)
|
||||
|
||||
## Getting started
|
||||
@@ -44,10 +42,6 @@ Starting the application:
|
||||
|
||||
`$ python manage.py runserver`
|
||||
|
||||
Running the eSales import
|
||||
|
||||
`$ python manage.py run_esales_import`
|
||||
|
||||
## Testing
|
||||
|
||||
To run unit tests:
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
from flask import Flask, jsonify, Response, request
|
||||
from api.extensions import db, esales, bernard
|
||||
from api.extensions import db, bernard
|
||||
from api.validators import ValidationError
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ def create_app(config_name="config"):
|
||||
app.config.from_object(config_name)
|
||||
|
||||
db.init_app(app)
|
||||
esales.init_app(app)
|
||||
bernard.init_app(app)
|
||||
|
||||
# register errors handlers
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from esales.flask_esales import Esales
|
||||
from api.lib.bernard import Bernard
|
||||
|
||||
|
||||
db = SQLAlchemy()
|
||||
esales = Esales()
|
||||
bernard = Bernard()
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import json
|
||||
|
||||
class Bernard(object):
|
||||
def __init__(self, app=None):
|
||||
self.sqs = boto3.client("sqs", region_name='eu-west-1')
|
||||
self.sqs = boto3.client("sqs", region_name="eu-west-1")
|
||||
if app:
|
||||
self.init_app(app)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from flask import Blueprint, request, jsonify
|
||||
from api import db, tasks
|
||||
from api import db
|
||||
from api.models import Designer
|
||||
from api.helpers import pagination_to_dict, check_api_key
|
||||
from api.validators import validate_jsonschema
|
||||
@@ -58,5 +58,5 @@ def update(id):
|
||||
setattr(designer, k, v)
|
||||
db.session.add(designer)
|
||||
db.session.commit()
|
||||
tasks.esales.update_designer(designer)
|
||||
|
||||
return jsonify(designer.to_json())
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
from . import esales
|
||||
@@ -1,29 +0,0 @@
|
||||
# coding=utf-8
|
||||
from flask import current_app
|
||||
from api.models.locale import Locale
|
||||
from esales.models import Category, CategoryTree
|
||||
from esales.utils import ImportFile
|
||||
|
||||
|
||||
def update_designer(designer):
|
||||
category = Category(
|
||||
"root/designers/{}".format(designer.path),
|
||||
display_name=designer.name,
|
||||
visible_search=designer.visible_search,
|
||||
visible_list=designer.visible_list,
|
||||
visible_productpage=designer.visible_productpage,
|
||||
visible_designerpage=designer.visible_designerpage,
|
||||
exclude_from_overview=designer.exclude_from_overview,
|
||||
send_to_bottom=designer.send_to_bottom,
|
||||
no_follow=designer.no_follow,
|
||||
hidden=1,
|
||||
path="/designers/{}".format(designer.path),
|
||||
)
|
||||
importfile = ImportFile()
|
||||
for locale in Locale.query.all():
|
||||
tree = CategoryTree("categories_{}".format(locale.value))
|
||||
tree.add_category(category)
|
||||
importfile.add_operation("update", tree)
|
||||
|
||||
directory = current_app.config.get("ESALES_IMPORT_DIR")
|
||||
importfile.write(directory)
|
||||
@@ -2,6 +2,4 @@ SQLALCHEMY_DATABASE_URI = 'postgresql://user:password@host/db_name'
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = True
|
||||
DEBUG = True
|
||||
API_KEYS = ['secretkey']
|
||||
ESALES_URL = 'username:password'
|
||||
ESALES_IMPORT_DIR = '/tmp/esales'
|
||||
BERNARD_QUEUE_URL = 'https://sqs.eu-west-1.amazonaws.com/<queue_id>/<queue_name>'
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
from .cluster import Cluster
|
||||
@@ -1,52 +0,0 @@
|
||||
# coding=utf-8
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger("esales")
|
||||
|
||||
|
||||
class CommandException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Cluster(object):
|
||||
|
||||
def __init__(self, url=None):
|
||||
self.url = url
|
||||
|
||||
def run_command(self, command):
|
||||
""" execute a command against the esales cluster """
|
||||
try:
|
||||
# find the location of the jar file (provided by apptus) that is
|
||||
# used to execute the commands
|
||||
jar = os.path.abspath(os.path.dirname(
|
||||
__file__) + "/command/command.jar")
|
||||
subprocess.check_output(
|
||||
"java -jar {0} {1}".format(jar, command).split(), stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
message = "Could not execute command {0}. Error: {1}".format(
|
||||
command, e.output)
|
||||
logger.error(message)
|
||||
raise CommandException(message)
|
||||
except OSError:
|
||||
sys.exit("Java not found on this system")
|
||||
|
||||
def import_products_and_categories(self, pattern):
|
||||
""" imports products and categories into the eSales cluster """
|
||||
i = 0
|
||||
for f in sorted(glob.iglob(pattern)):
|
||||
if os.path.isfile(f):
|
||||
logger.info("Importing {}".format(f))
|
||||
try:
|
||||
self.run_command("import -p {0} {1}".format(self.url, f))
|
||||
i += 1
|
||||
except CommandException as e:
|
||||
logger.error("Failed to import {}".format(f))
|
||||
finally:
|
||||
os.remove(f)
|
||||
|
||||
logger.info("Imported {} file(s)".format(i))
|
||||
return i
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,15 +0,0 @@
|
||||
from .cluster import Cluster
|
||||
|
||||
|
||||
class Esales(object):
|
||||
|
||||
def __init__(self, app=None):
|
||||
self.cluster = Cluster()
|
||||
|
||||
if app:
|
||||
self.init_app(app)
|
||||
|
||||
def init_app(self, app):
|
||||
if not 'ESALES_URL' in app.config:
|
||||
raise Exception('ESALES_URL missing in config')
|
||||
self.cluster.url = app.config.get('ESALES_URL')
|
||||
@@ -1,45 +0,0 @@
|
||||
# coding=utf-8
|
||||
from xml.etree.cElementTree import Element, SubElement
|
||||
|
||||
|
||||
class Category(object):
|
||||
""" represents an eSales category """
|
||||
|
||||
def __init__(self, key, display_name=None, **kwargs):
|
||||
self.key = key
|
||||
self.display_name = display_name
|
||||
self.attributes = {}
|
||||
for k, v in kwargs.items():
|
||||
self.attributes[k] = v
|
||||
|
||||
@property
|
||||
def etree(self):
|
||||
root = Element("category", key=self.key)
|
||||
if self.display_name:
|
||||
SubElement(root, "display_name").text = self.display_name
|
||||
if self.attributes:
|
||||
attributes = SubElement(root, "attributes")
|
||||
for k, v in self.attributes.items():
|
||||
SubElement(attributes, k).text = str(v)
|
||||
|
||||
return root
|
||||
|
||||
|
||||
class CategoryTree(object):
|
||||
"""represents an eSales CategoryTree"""
|
||||
|
||||
def __init__(self, product_attribute):
|
||||
self.categories = []
|
||||
self.product_attribute = product_attribute
|
||||
|
||||
def add_category(self, category):
|
||||
self.categories.append(category)
|
||||
|
||||
@property
|
||||
def etree(self):
|
||||
root = Element("category_tree",
|
||||
product_attribute=self.product_attribute)
|
||||
for category in self.categories:
|
||||
root.append(category.etree)
|
||||
|
||||
return root
|
||||
@@ -1,35 +0,0 @@
|
||||
# coding=utf-8
|
||||
import os
|
||||
import uuid
|
||||
import time
|
||||
from xml.etree.cElementTree import ElementTree, Element, SubElement, dump
|
||||
|
||||
|
||||
class ImportFile(object):
|
||||
|
||||
def __init__(self):
|
||||
self.operations = []
|
||||
|
||||
def add_operation(self, operation, model):
|
||||
assert operation in ["create", "update", "delete"]
|
||||
self.operations.append((operation, model))
|
||||
|
||||
@property
|
||||
def etree(self):
|
||||
root = Element("operations")
|
||||
for name, model in self.operations:
|
||||
operation = SubElement(root, name)
|
||||
operation.append(model.etree)
|
||||
return root
|
||||
|
||||
def dump_xml(self):
|
||||
return dump(self.etree)
|
||||
|
||||
def write(self, directory, filename=None):
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
if not filename:
|
||||
filename = "{}.xml".format(time.time())
|
||||
xml = ElementTree(self.etree)
|
||||
xml.write("{}/{}".format(directory, filename),
|
||||
encoding="UTF-8", xml_declaration=True)
|
||||
@@ -1,5 +1,5 @@
|
||||
from flask.ext.script import Manager, prompt_bool
|
||||
from api import create_app, db, esales
|
||||
from api import create_app, db
|
||||
from api.models import Designer
|
||||
|
||||
app = create_app()
|
||||
@@ -27,11 +27,5 @@ def seed_db():
|
||||
db.session.commit()
|
||||
|
||||
|
||||
@manager.command
|
||||
def run_esales_import():
|
||||
print("Importing products and categories into eSales")
|
||||
pattern = "{}/*.xml".format(app.config.get("ESALES_IMPORT_DIR"))
|
||||
esales.cluster.import_products_and_categories(pattern)
|
||||
|
||||
if __name__ == '__main__':
|
||||
manager.run()
|
||||
|
||||
@@ -2,7 +2,6 @@ SERVER_NAME = "localhost"
|
||||
SQLALCHEMY_DATABASE_URI = "sqlite://"
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = True
|
||||
PRESERVE_CONTEXT_ON_EXCEPTION = False
|
||||
ESALES_URL = ""
|
||||
TESTING = True
|
||||
DEBUG = True
|
||||
SQLALCHEMY_ECHO = False
|
||||
|
||||
@@ -56,14 +56,3 @@ class TestEndpoints(flask_testing.TestCase):
|
||||
"/designers/", data=json.dumps(data), content_type="application/json"
|
||||
)
|
||||
self.assert400(response)
|
||||
|
||||
@patch("api.tasks.esales.update_designer")
|
||||
def test_update_designer(self, esales_update_designer):
|
||||
designer = self._add_designer("designer1")
|
||||
data = {"name": "test"}
|
||||
response = self.client.put(
|
||||
"/designers/1", data=json.dumps(data), content_type="application/json"
|
||||
)
|
||||
self.assertTrue(esales_update_designer.called)
|
||||
self.assertEqual("test", response.json["name"])
|
||||
self.assertEqual("test", Designer.query.get(1).name)
|
||||
|
||||
Reference in New Issue
Block a user