====== Picalike Customer Interface ======
Host: **pci01.picalike.corpex-kunden.de**
Port: **8090**
===== Dependencies =====
passlib==1.6.5
===== git =====
Im git zu finden als:
$ git clone git@git.picalike.corpex-kunden.de:picalike/pci.git
===== Operations =====
check [[upci|upci]]
===== Allgemeines =====
Anfragen mit json als post
Antworten:
* als json
* immer “message” und “result”
* negativer “result” bedeutet Error
* positiver “result” ist Grund zur Hoffnung
* in “response” steht die Antwort auf die Frage
Test User:
"email" : "unittest@picalike.com",
"password_for_testing" : "picalike",
"userid" : "f6622021aae19fd282df4945a3a47aa8",
"username" : "unittest",
"uid" : [905]
===== Image Cache Server =====
Host: **sg02.picalike.copex-kunden.de**
Port: **8095**
Aufrufbeispiel:
http://sg02.picalike.corpex-kunden.de:8095/
http://sg02.picalike.corpex-kunden.de:8095/http%3A%2F%2Fwww.picalike.com%2Fdesign%2Fpicalike%2Flogo.png
Der Server gibt die Datei zurück. Wenn nötig wird sie heruntergeladen, wenn möglich wird die gespeicherte Version aus dem Cache ausgespielt.
Zusätzlich gibt es die Möglichkeit die Bilder direkt resized zu bestellen, es wird grundsätzlich die Aspectratio beibehalten (wenn width zu height nicht passt gewinnt der größere Wert, der andere wird ignoriert):
http://sg02.picalike.corpex-kunden.de:8095//width/height
Es braucht nur width oder height angegeben werden, der andere kann auf -1 gesetzt werden.
===== Apis =====
http://:/
Testing with curl:
curl --data-binary @style_count.json -H "Content-type: application/json" "http://pci01.picalike.corpex-kunden.de:8090/style_count"
where style_count.json is a file containing the message that you want to send
==== /login ====
**in:**
{"email": , "pwd": }
**out:**
{
"result": 2,
"message": ,
"response": {
"userid": ,
"username": ,
"sid": , # new session id
"lang": , # default: 'en', if not set
"fav_shop": # only if it is set
"shop_info": [{"shop_name": , "apikey": }],
"privileges": [, ...],
"role": ,
"create_date":
}
}
==== /delete_user ====
**in:**
{"userid": }
**out:**
{"result": 1, "message": , "response": {}}
==== /get_available_permissions ====
**in:**
{}
**out:**
{"result": , "message": , "response": {"permissions": [, ...]}}
==== /user_by_shop ====
**in:**
{"shop_apikey": , "include_all": }
**include_all** is optional and by default **False**, if **True** all users that include “all” in “uid” will be returned
**out:**
{"result": , "message": , "response": {"user_list": [{"username": , "userid": , "role": }, ...]}}
==== /change_role ====
**in:**
{"userid": , "role": }
**out:**
{"result": , "message": , "response": {}}
==== /change_pwd ====
**in:**
{"userid": , "pwd": }
**out:**
{"result": , "message": , "response": {}}
==== /change_permissions ====
**in:**
{"userid": , "permissions": [, ...]}
**out:**
{"result": , "message": , "response": {}}
==== /user_data_by_sessionid ====
**in:**
{"sid": } # sessionid
**out:**
{"result": 1, "message": "OK", "response": {
"userid": ,
"username": ,
"email". ,
"shop_info": [{"shop_name": , "apikey": }],
"fav_shop": # only if it is set
"privileges": [, ...],
"role": ,
"lang": ,
"create_date":
}}
==== /get_user ====
**in:**
{"userid": }
**out:**
{"result": 1, "message": "OK", "response": {
"userid": ,
"username": ,
"shop_info": [{"shop_name": , "apikey": }],
"fav_shop": # only if it is set
"privileges": [, ...],
"role": ,
"lang": ,
"create_date":
}}
==== /set_language ====
**in:**
{"userid": , "lang": }
**out:**
{"result": 1, "message": "OK", "response": {}}
//lang// is a two letter string, e.g.: 'de', 'en', …
==== /set_favorite_shop ====
**in:**
{"userid": , "shop_id": }
**out:**
{"result": 1, "message": "OK", "response": {}}
==== /check_session ====
**in:**
{
"userid": ,
"sid": ,
"action": ,
"shop_id":
# optional
"data": # not used right now
}
**out:**
{"result": 1, "message": "OK", "response": {"match": }}
==== /admin_user_stats ====
**in:**
{
"sid": , # authorization
"userid": , # stats for this user
"shop_id": # and this shop
}
**out:**
{"result": 1, "message": "OK", "response": [
{
"date": # e.g. "2019-02-01"
"first": # first activity of the day in UTC, e.g. "2019-02-01T08:01:11Z"
"last": # last activity of the day in UTC, e.g. "2019-02-01T18:03:51Z"
"count": # total number of actions (calls to check_session)
"details": # ->
}
]}
==== /stats_ ====
**in:**
{"from_time": , "to_time": , "resolution": , "userid": , "shop_apikey": }
Zeiten als String in der Form: 2015-12-06 11:55
“resolution”: “hour” nicht möglich bei stats_color
**out:**
{"result": 1, "message": "OK", "response": {"sum_list": {: {"time": , "sum": }, ... }}}
Anmerkung:
Der Zeitstempel (z.B. “2015-11-30 10:00:00.000”) meint den Beginn der Zeitspanne (Beisp. endet hier bei “2015-11-30 10:59:59.999)
==== /stats_color ====
**in:**
{"from_time": , "to_time": , "resolution": , "userid": , "shop_apikey": }
Zeiten als String in der Form: 2015-12-06 11:55
“resolution”: “hour” nicht möglich bei stats_color
**out:**
{"result": 1, "message": "OK", "response": {"sum_list": [{"time": , "sum": }, ... ]}}
Anmerkung:
Der Zeitstempel (z.B. “2015-11-30 10:00:00.000”) meint den Beginn der Zeitspanne (Beisp. endet hier bei “2015-11-30 10:59:59.999)
==== /categories (deprecated use get_field_values instead) ====
**in:**
{"userid": , "shop_apikey": }
**out:**
{"result": 1, "message": "OK", "response": {"categories":[{"name": , "count": , "gender": , "f_value": , "available":
==== /get_field_values ====
Alle Werte im Feed (unified) anzeigen:
**in:**
{"userid": , "shop_apikey": , "field_name": (categories, brands, colors, shops, season)}
**out:**
{"result": 1, "message": "OK", "response": {"field_values":[...]}}
categories:
{"name": , "count": , "gender": , "f_value": , "available": , "size": }
Nur die Werte innerhalb einer Kategorie (unified) anzeigen:
**in:**
{"userid": , "shop_apikey": , "field_name": (brands, colors, shops, gender, season), "category": }
**out:**
{"result": 1, "message": "OK", "response": {"field_values":[]}}
==== /get_categories_translation ====
**in:**
{"shop_apikey": }
**out:**
{"result": 1, "message": "OK", "response": {"translation":{: , ...}}}
==== /update_categories_cache ====
(for internal use only)
**in:**
{"shop_apikey": }
**out:**
{"result": 1, "message": "OK", "response": {}}
==== /save_f_value ====
**in:**
{"userid": , "shop_apikey": , "category": , "f_value": , "gender": }
**out:**
{"result": 1, "message": "OK", "response": {}}
==== /get_f_values ====
**in:**
{"userid": , "shop_apikey": , "categories": []}
{"userid": , "shop_apikey": , "categories": [], "gender": }
**out:**
{"result": 1, "message": "OK", "response": {"f_values": {"category": , "f_value": , "gender": }}}
{{/dokuwiki/lib/images/smileys/icon_question.gif|:?:}} Bitte categories auf encoding Probleme testen.
==== /save_mapping ====
**in:**
{"userid": , "shop_apikey": , "customer_cat": , "picalike_cat": , "visual": , "gender": }
**out:**
{"result": 1, "message": "OK", "response": {}}
==== /get_mapping ====
**in:**
{"userid": , "shop_apikey": }
**out:**
{"result": 1, "message": "OK", "response": {"mapping": [{"customer_cat": , "picalike_cat": , "suggested_cat": , "gender": , "visual": }]}}
==== /picalike_categories ====
**in:**
{"userid": }
**out:**
{"result": 1, "message": "OK", "response": {"categories": []}}
==== /picalike_fashion_categories ====
**in:**
{"userid": }
**out:**
{"result": 1, "message": "OK", "response": {"categories": [[, ], ...]}}
==== /products ====
**in:**
{"userid": , "shop_apikey": , "page": , "limit": , "sort_key_direction": }
{"userid": , "shop_apikey": , "cat_name": , "page": , "limit": }
{"userid": , "shop_apikey": , "gender": , "page": , "limit": }
{"userid": , "shop_apikey": , "available": , "page": , "limit": }
{"userid": , "shop_apikey": , "season": , "page": , "limit": }
{"userid": , "shop_apikey": , "type": , "page": , "limit": }
{"userid": , "shop_apikey": , "color": , "pColor": , "page": , "limit": }
{"userid": , "shop_apikey": , "page": , "limit": , "filter_price": {"lower": , "upper": }}
{"userid": , "shop_apikey": , "cat_name": , "page": , "limit": , "filter_price": {"lower": , "upper": }}
filter_price ist nachgelagern, Anzahl der Produkte kann kleiner sein als limit. Filterung auf gesammten Daten möglich aber teurer.
gender, available, cat_name, season, type und color können kombiniert werden
wenn "color" ein picalikeColor ist, muss "pColor": true ("pColor": false für "color" aus dem Feed)
mittels "unify": true können die Bilder-Urls auf Einmaligkeit gefiltert werden (möglichst nur mit cat_name, ist bei großen Datenmengen sehr langsam)
**out:**
{"result": 1, "message": "OK", "response": {"products":[{"name": , "price": , "url": , "imgid": , "deeplink": , "gender": , "season": , "type": , "color": }]}}
==== /products_by_random ====
**in:**
{"userid": , "shop_apikey": , "limit": }
**out:**
{"result": 1, "message": "OK", "response": {"products":[{"name": , "price": , "url": , "imgid": , "deeplink": , "gender": }]}}
==== /product_by_views ====
**in:**
{"userid": , "shop_apikey": , "from_time": , "to_time": , "productid": }
{"userid": , "shop_apikey": , "from_time": , "to_time": , "productid": , "resolution": }
Zeiten als String in der Form: 2015-12-06 11:55
**out:**
{"result": 1, "message": "OK", "response": {"product_count": }}
{"result": 1, "message": "OK", "response": {"product_count": , "sum_list": {: {"time": , "sum": }, ... }}}
==== /product_by_views_30 ====
**in:**
{"userid": , "shop_apikey": , "productid": }
**out:**
{"result": 1, "message": "OK", "response": {"product_count": , "sum_list": {: {"time": , "sum": }, ... }}}
==== /top_views ====
**in:**
{"userid": , "shop_apikey": , "from_time": , "to_time": , "limit": }
Zeiten als String in der Form: 2015-12-06 11:55
mittels "update_cache": kann der cache in der mongo neu geschrieben werden
**out:**
{"result": 1, "message": "OK", "response": {"top_views": [{"productid": , "amount": }]}}
Bei gleicher Häufigkeit ist die Sortierung undefiniert.
==== /get_products_metaData ====
**in:**
{"userid": , "shop_apikey": , "productids": [], "cat_name": , "image_id_delimiter": , "n_image_id_chunks": , "extra_fields": }
Optional:
cat_name - filter by cat,
image_id_delimiter - split image_id at delimiter,
n_image_id_chunks - number of chunks to keep,
extra_fields
**out:**
{"result": 1, "message": "OK", "response": {"products":[{"name": , "price": , "url": , "imgid": , "deeplink": , "available": , "cat": , "season": , "type": , "color": , "pColor": }]}}
**out_with_extra_field(s):**
The ouput is exactly the same as for a request without any option, but the query from the pci app to MongoDB pcistyles collection will only respond with items containing the field extra_image_filter with the value extra_image_exists.
==== /colors ====
**in:**
{"userid": , "shop_apikey": }
{"userid": , "shop_apikey": , "category": [], "gender": }
category und gender optional und frei kombinierbar
**out:**
{"result": 1, "message": "OK", "response": {"related_products": , "color_statistic":[{"color_name": , "avg_amount": , "found_count": , "found_percent": }]}}
related_products: Anzahl der gefundenen Produkte
avg_amount: Durchschnittlicher Anteil dieser Farbe in allen Bildern die diese Farbe haben
found_count: Anzahl der Bilder die diese Farbe haben
found_percent: (found_count / related_products)
==== /get_colors ====
**in:**
{"userid": , "shop_apikey": }
**out:**
{"result": 1, "message": "OK", "response": {"color_names":[]}}
==== /search_by_color ====
**in:**
{"userid": , "shop_apikey": , "color_name": , "limit": , "page": }
{"userid": , "shop_apikey": , "color_name": , "limit": , "page": , "cat_name": , "gender": }
cat_name und gender optional und frei kombinierbar
**out:**
{"result": 1, "message": "OK", "response": {"products":[{"productid": , "amount": }]}}
products sind absteigend sortiert nach Anteil der Farbe am Produkt
==== /colors_by_views ====
**in:**
{"userid": , "shop_apikey": , "from_time": , "to_time": }
Zeiten als String in der Form: 2015-12-06 11:55
**out:**
{"result": 1, "message": "OK", "response": {"related_products": , "color_statistic":[{"color_name": , "amount": ]}}
==== /color_filter ====
Returns a list of all colors in a feed or a list of all picalike colors if the former is not available.
**in:**
{"userid": , "shop_apikey": ,"pColor": }
"pColor": true forces use of picalike colors
**out:**
{"result": 1, "message": "OK", "response": {"colors": [], "pColor": }}
"pColor": true if picalike colors are returned
==== /replace_product ====
**in:**
{"userid": , "shop_apikey": , "ref_pid": , "new_prod": }
* : dict mit allem, was man sich für das Produkt merken muss (same as save_style/update_style)
* “ref_pid”: product id of the product that has to be replaced
**out:**
{"result": 1, "message": "OK", "response": {"num_updated_styles": }}
* num_updated_styles: number of updated styles where ref_pid was found
==== /save_style ====
**in:**
{"userid": , "shop_apikey": , "name": , "type": , "order_by": , "products": }
* : dict mit allem, was man sich für das Produkt merken muss (“img (imgId)(str)”, “f”(str of an float), “dist” (str of float), “cat”(str), “gender”, “season”)
* optional: “tags” (format is not specified, has to be JSON/mongo compatible)
* optional: “visibility” (default: “preview”)
* hidden option: “build_cache”: (default: True)
* Dict Template: {“p1” : {} .., p2:{}}
**out:**
{"result": 1, "message": "OK", "response": {"styleid": , "userid": , "name": , "type": , "modified": double, "created": double, "visibility": , "products": }}
* modified: timestamp
* created: timestamp
* visibility: [“public”, “preview” (default), “delete”]
==== /copy_style_to_shop ====
this will replace some SKUs for Atelier Goldner Schnitt if the following settings are present in the feed settings:
* visualytics.image_id_delimiter
* visualytics.n_image_id_chunks
* style_updater.in_stock_value
**in:**
{"userid": , "from_shop_apikey": , "to_shop_apikey": [], "styleid": []}
* to_shop_apikey and styleid should always be lists
* optional: *copy_on_error*: (default: False) - if True, style will be copied even if product ids are missing
**out:**
{"result": 1, "message": "OK", "response":
{:
{"copied": [],
"errors": [{styleid: , "msg": }],
"missing": [{styleid: , "prod_ids": []}]
}
}
}
* response is a dictionary with the to_shop_apikeys as key
* copied contains a list of styleids that were copied
* errors contains a list of styleids that were not copied (reasons/msg: [“name in use”, “missing product ids”, “unknown error”])
* missing contains a list of styleids and the product ids that are missing in the destination shop
==== /check_style_name ====
**in:**
{"shop_apikey": , "name": }
**out:**
{"result": 1, "message": "OK", "response": {"exists": }}
==== /update_style ====
**in:**
{"styleid": , "shop_apikey": , ...}
* Jedes Feld aus der Antwort von “save_style” kann angegeben werden.
* Die Liste der Produkte muss entweder komplett oder gar nicht angegeben werden.
* “modified” wird immer auf die Zeit des API-Aufrufs gesetzt
* Felder die nicht “save_style” definiert sind, werden ignoriert
* hidden option: “build_cache”: (default: True)
**out:**
{"result": 1, "message": "OK", "response": {...}}
* …: gibt den geupdatete Style zurück (siehe “save_style”)
==== /get_style ====
**in:**
{"styleid": , "shop_apikey": }
**out:**
{"result": 1, "message": "OK", "response": {...}}
* …: Rückgabe wie bei “save_style”
* Es werden an dieser Stelle keine Empfehlungen mit zurückgegeben, um die API sauber und minimal zu halten.
==== /style_count ====
**in:**
{"shop_apikey": }
**out:**
{"result": 1, "message": "OK", "response": {"style_count": }}
==== /style_cover ====
**in:**
{"shop_apikey": }
{"shop_apikey": , "renew": }
**out:**
{"result": 1, "message": "OK", "response": {"all": , : , ...}}
==== /list_styles ====
**in:**
{"shop_apikey": , "limit": , "page": }
**out:**
{"result": 1, "message": "OK", "response": [...]}
* response: Eine Liste mit Styles. Felder sind so benannt wie auch schon bei “save_style”
==== /list_all_styles ====
**in:**
{"shop_apikey": }
**out:**
{"result": 1, "message": "OK", "response": [...]}
* response: Eine Liste mit Styles. Felder sind so benannt wie auch schon bei “save_style”
==== /update_styles_cache ====
**in:**
{"shop_apikey": }
**out:**
{"result": 1, "message": "OK", "response": {}}
* response: ein leeres Dictionary
==== /delete_style ====
**in:**
{"styleid": , "shop_apikey": , "userid": }
* hidden option: “build_cache”: (default: True)
**out:**
{"result": 1, "message": "OK", "response": {}}
==== /all_recoboxes ====
**in:**
{"userid": , "shop_apikey": ,}
**out:**
{"result": 1, "message": "OK", "response": [{"userid": , "shop_apikey": , "box_id": , "reco_type": (look|sim), "mode": (live|preview), "referrer": , "only_if_unavailable": , "box_name": , "creation_time": , "status": (active|deleted), "template": }]}
Falls keine Recobox gespeichert ist, ist der Wert von response eine leerer Array. Der Wert von creation_time ist im Format “seconds since epoch”.
==== /read_recobox ====
**in:**
{"userid": , "shop_apikey": , "box_id": }
**out:**
{"result": 1, "message": "OK", "response": [{"userid": , "shop_apikey": , "box_id": , "reco_type": (look|sim), "mode": (live|preview), "referrer": , "only_if_unavailable": , "box_name": , "creation_time": , "status": (active|deleted), "template": , "regex": }]}
Falls keine Recobox vorhanden ist, ist der Wert von response eine leerer Array. Der Wert von creation_time ist im Format “seconds since epoch”.
==== /delete_recobox ====
**in:**
{"userid": , "shop_apikey": , "box_id": }
**out:**
{"result": 1, "message": "OK", "response": {"matched_count": }}
Der Wert von matched_count ist die Anzahl der auf status=deleted gesetzten Einträge.
==== /save_recobox ====
**in:**
{"userid": , "shop_apikey": , "box_id": ,
"reco_type": , "mode": (live|preview), "box_name": , "template": , "regex": ,
"referrer": , "only_if_unavailable": }
Alle Parameter außer “userid”, “shop_apikey”, “box_id” sind optional. Boolean wird hier wie folgt interpretiert: ein leerer String ist false und ein nicht-leerer String true.
**out:**
{"result": 1, "message": "OK", "response": {}}
==== /edit_recobox ====
**in:**
{"userid": , "shop_apikey": , "box_id": ,
"reco_type": (sim|look), "mode": (live|preview), "box_name": , "template": , "regex": ,
"referrer": , "only_if_unavailable": }
Alle Parameter außer “userid”, “shop_apikey”, “box_id” sind optional. Boolean wird hier wie folgt interpretiert: ein leerer String ist false und ein nicht-leerer String true.
**out:**
{"result": 1, "message": "OK", "response": {}}
==== /stats_clicks ====
**in:**
{"userid": , "shop_apikey": , "from_time": , "to_time": }
oder:
{"userid": , "shop_apikey": , "from_time": , "to_time": , "testid": , "test_class": }
Zeiten als String in der Form: 2015-12-06 11:55 “test_class” ist z.B. “A”
**out:**
{"result": 1, "message": "OK", "response": {"click_stats": {: { : }}, "todays_prediction": {: }}}
in der Form “sim_*” oder “look_*”
als String in der Form: 2015-12-06
“todays_prediction” ist nicht leer nur wenn “to_time” == heute
==== /stats_checkouts ====
**in:**
{"userid": , "shop_apikey": , "from_time": , "to_time": }
oder
{"userid": , "shop_apikey": , "from_time": , "to_time": , "testid": , "test_class": }
Zeiten als String in der Form: 2015-12-06 11:55 “test_class” ist z.B. “A”
**out:**
{"result": 1, "message": "OK", "response": {"checkout_stats": [{"date": , "not_found": , "products": , "value": , "checkouts": , "sessions": }], "todays_prediction": {"sessions": , "checkouts": }}}
“date” in der Form: 2015-12-06
“value” als Cents
“todays_prediction” ist nicht leer nur wenn “to_time” == heute
==== /top_clicked ====
**in:**
{"userid": , "shop_apikey": , "from_time": , "to_time": , "limit": }
Zeiten als String in der Form: 2015-12-06 11:55
**out:**
{"result": 1, "message": "OK", "response": {"top_clicked": [[imgId, n_clicks], ...]}}
“top_clicked” ist eine high-to-low sortierte Liste.
==== /ab_config/create ====
**in:**
{"userid": , "shop_apikey": , "from_time": , "to_time": , "status": , "prob_a": , "name": , "testid": , "description": }
from_time und to_time als String im Format: “2015-11-30 10:00”.
status (activity status)
prob_a (probability parameter in real-valued range [0, 1], i.e. 0.856)
**out:**
{"result": 1, "message": "OK", "response": {"status": , "testid": }}
==== /ab_config/get_ab_tests ====
**in**
{"userid": , "shop_apikey": }
**out:**
{"result": 1, "message": "OK", "response": {"ab_tests": [{"shop_apikey": , "from_time": , "to_time": , "status": , "prob_a": , "name": , "testid": , "description": }]}}
==== /trend_create ====
Parameters and files are passed as form fields (content-type=multipart/form-data)
**in:**
userid=, name=, sources=, gender=, age=, weather=, segment=, categories=, country=, status=, hashtags=, description=, image_i=new, file_i=, style_i=, cpc_i=
* mandatory: ''%%userid%%'' and ''%%name%%''
* to add image i set ''%%image_i=new%%'', where i is from the set {1, …, 9} and provide ''%%file_i%%''
* ''%%status%%'' is a string from the set {“preview”, “active, “deleted”}
* ''%%%%'' is a string where items are separated by ''%%;%%''
**out:**
{"result": 1, "message": "OK", "response": {"trendid": }}
==== /trend_info ====
**in:**
{"userid": , "trendid": }
**out:**
{"result": 1, "message": "OK", "response": {"trend_info": {"userid": , "name": , "trendid": , "created": , "edited": , "sources" [, ...], "gender": , "age": [, ...], "weather": [, ...], "segment": [, ...], "categories": [, ...], "country": [, ...], "status": {"preview", "active, "deleted"}, "hashtags": , "description": , "images": {"image_1": {"file_id": , "style": , "cpc": }, "image_2": {"file_id": , "style": , "cpc": }, ...}}}}
* ''%%images%%'': dictionary with keys ''%%image_i%%'', where i is from the set {1, …, 9}
* ''%%image_i%%'' contains ''%%file_id%%'', ''%%style%%'' and ''%%cpc%%'' (central product category) for image i
==== /trend_edit ====
Parameters and files are passed as form fields (content-type=multipart/form-data)
**in:**
userid=, name=, sources=, gender=, age=, weather=, segment=, categories=, country=, status=, hashtags=, description=, image_i=, file_i=, style_i=, cpc_i=
* mandatory: ''%%userid%%'', ''%%trendid%%''
* ''%%status%%'' is a string from the set {“preview”, “active, “deleted”}
* ''%%%%'' is a string where items are separated by ''%%;%%''
* ''%%%%'' is a string from the set {“new”, “edit”, “del”}
* add or replace image (and attributes): ''%%image_i=new%%'' and provide ''%%file_i%%''
* delete image and its attributes: ''%%image_i=del%%''
* edit image attributes: ''%%image_i=edit%%''
**out:**
{"result": 1, "message": "OK", "response": {}}
==== /trend_delete ====
**in:**
{"userid": , "trendid": }
**out:**
{"result": 1, "message": "OK", "response": {}}
==== /trend_list ====
**in:**
{"userid": , "status": [, ...], "n_images": }
* mandatory: ''%%userid%%''
* optional:
* ''%%status%%'': list of elements from set {“preview”, “active”, “deleted”}
* ''%%n_images%%'': maximal number of images for each trend
**out:**
{"result": 1, "message": "OK", "response": {"trends": [{"trendid": , "name": , "created": , "userid": , "status": , "categories": [, ...], "images": [, ...]}, ...}}
* ''%%images%%'': list of file id's
==== /trend_image/ ====
Image with database _id = ''%%file_id%%'' is returned
==== /upload ====
Parameters and files are passed as form fields (content-type=multipart/form-data)
**in:**
{userid:, image_1: , "shop_apikey" : }
* ''%%image_1%%'' is a input with type=file.
* It stores the image in the collection 'pci_upload', than, makes the request to the tower01 prediction API, returning response Json in the end.
* The predictions are made with: big_net : true, fasterrcnn_microworker: true, free_person: true.
**out:**
{"result": 1, "message": "OK", "response": {"_id": , 'images_with_fatal_error': ,'urls_with_image_cloud_error': , 'images_without_error': { : "bits": [[bit, value], ...] , "attributes": [[name, value], ...] , "categories": [[name, value], ...] , "free_person": [[name, value], ...] , 'fasterrcnn_microworker_boxes': [{'x1': , 'x2': , 'score': , 'y2': , 'class': , 'y1': }, ... ] } } }
==== /get_image/ ====
Just a endpoint to the upload system, this endpoint serve as the http link that the tower01 needs to do the predictions. The method send the image from the collection 'pci_upload'.
==== /upload_list> ====
**in:**
{userid: , shop_apikey : }
**out:**
{"result": 1, "message": "OK", "response": [{"_id": ,"uploadDate" : , "userid" : } , {"_id": ,"uploadDate" : , "userid" : } ,... ] }
* Lists all the _id of uploaded images, by shop_apikey, in the upload system.
==== /upload_view> ====
**in:**
{userid: , shop_apikey : , file_id: }
**out:**
{"result": 1, "message": "OK", "response": {"new_prediction" : {"_id": , 'images_with_fatal_error': ,'urls_with_image_cloud_error': , 'images_without_error': { : "bits": [[bit, value], ...] , "attributes": [[name, value], ...] , "categories": [[name, value], ...] , "free_person": [[name, value], ...] , 'fasterrcnn_microworker_boxes': [{'x1': , 'x2': , 'score': , 'y2': , 'class': , 'y1': }, ... ] } } }}
==== /get_image_data> ====
**in:**
{userid: , shop_apikey : , file_id: }
**out:**
{"result": 1, "message": "OK", "response": {"_id": , 'images_with_fatal_error': ,'urls_with_image_cloud_error': , 'images_without_error': { : "bits": [[bit, value], ...] , "attributes": [[name, value], ...] , "categories": [[name, value], ...] , "free_person": [[name, value], ...] , 'fasterrcnn_microworker_boxes': [{'x1': , 'x2': , 'score': , 'y2': , 'class': , 'y1': }, ... ] } } }
==== /set_style_exact_match ====
**in:**
{userid: , shop_apikey : , styleid:, exact_match: }
**out:**
{"result": 1, "message": "OK", "response": {"exact_match":} }
===== Collections =====
* pci_categories
* wird automatisch mit dem Skript “update_categories.py” erzeugt.
* Läuft als cronjob auf sg02.
* Kann manuell ausgeführt werden.
* Läuft recht lang. (abhängig von der Anzahl und Größe der Kunden)
* pci_f_values
* in dieser Collection werden Benutzereingaben gespeichert
* pci_mapping
* wird noch nicht verwendet
* pci_user
* in dieser Collection werden Benutzer und deren Rechte in Visuallytics gespeichert
* pci_history
* stündliche Summation der Abfragen für einen Kunden (Skript “add_history_every_hour.py”)
* Cronjob auf sg02
* Index
* time
* time, uid
* pci_products_history
* tägliche Summation der Abfragen je Produkt (Skript “add_product_history_every_day.py”)
* Cronjob auf sg02
* Index
* uid, productid
* time, uid, productid
* time (ttl 2678400sec {31 Tage})
* pci_cache
* enthält zwei Sachen:
* Colors by Views
* Verteilung der Farben abhängig von den angeschauten Produkten für einen Zeitraum
* Top Views
* Welche Produkte wurden in einem bestimmten Zeitraum am häufigsten angeschaut
* Anfragen werden bei Bedarf live ausgeführt und in den Cache gelegt
* Nachts läuft ein Cronjob auf sg02, der den Cache für den gestrigen Tag/letzten Monat befüllt (Skript “update_cache_last_day.py” / Skript “update_cache_last_month.py”)
* Index
* uid, from_time, to_time
* pci_stylecover
* wird automatisch mit dem Skript “update_cache_stylecover.py” erzeugt
* Läuft als cronjob auf sg02
* kann manuell ausgeführt werden
* Läuft recht lang (abhängig von der Anzahl der Styles und Größe der Kunden)
* pci_styles
* in dieser Collection werden Styles gespeichert
* pci_brands
* pci_colors
* pci_picalike_cateogories
* pci_shops
* pci_cat_translation
* pci_speedup
* pci_trends
* trend_fs.files, trend_fs.chunks
* these collections contain images from trends
* pci_upload