Attention!
After reading the article, you might get the impression that I love BDSM or something like that, but it only seems to you.
Store problems
I work in a regular bike shop in the center of Warsaw. We trade both stationary and on the Internet. Average number of bought bicycles per day ~ 2 for the whole year. At the same time, the peak of sales falls on the summer, and then we can have ~ 17 online orders a day and the same in the store, and in winter we can not sell anything at all.
In 2020. In connection with the COVID pandemic, the demand for bicycles has grown to incredible rates, and we, as a decent office, have begun to expand.
This led to the fact that at the end of last season, orders for only non-existent bicycles increased on average up to 4 times a week during the 4 most productive months. And this is ~ 16 inconsistencies on the site per month (not counting the failures in the store).
This year, with the appearance of another large warehouse, the situation has worsened and now, in addition to non-existent bicycles, those that were not there were added and it was often impossible to bring them to customers on time.
, - EXEL, , . , . 2 2-3 .
. , , , – , . .
, , - . . , . :
, .
:
Python API PrestaShop;
, -, . ;
Chrome . , Chrome.
middle-, . .
API PrestaShop
API PrestaShop Python , , PS 5% ( 1.6 ). — prestapyt, . , , .
, , API, PS. , , .
, , ! , .
- , .
, , .
:
reference ;
— ;
, , stock_availables. ;
associations .
, , > 0 — . – , .
XML stock_availables, .
.
, - , .
API
https://domain.com/api. , . id – , «products» . , .
API XML, :
<prestashop>
<api shopName="myshop">
<addresses xlink:href="https://domain.com/api/addresses" get="true" put="false" post="false" delete="false" head="false"></addresses>
</api>
</prestashop>
- . https://domain.com/api/products:
<prestashop>
<products>
<product id="22" xlink:href="https://domain.com/api/products/22"/>
<product id="24" xlink:href="https://domain.com/api/products/24"/>
<product id="265" xlink:href="https://domain.com/api/products/265"/>
<product id="294" xlink:href="https://domain.com/api/products/294"/>
<products />
<prestashop />
.
requests. , Requests — , .
API PS Basic ( ). . requests:
request_url = «https://domain.com/api»
get_combination_xml = requests.get(request_url, auth=(self.api_secret_key, ''))
200, , XML. .
XML
– xml.etree. , , ( ), , Python.
:
# 2
from xml.etree import ElementTree as ET
from xml.etree.ElementTree import ElementTree
# xml.etree
def xml_data_extractor(data, tag):
# data – XML
# tag = products–
try:
xml_content = ET.fromstring(data.content) # ElementTree. . .
general_tag = xml_content[0] # –
tag = general_tag.find(tag) #
tag_inner_link = tag.get('{http://www.w3.org/1999/xlink}href') #
# href
#
product_meta = {'product_link': tag_inner_link}
return product_meta
except:
return None
: https://domain.com/api/products. , .
None except Try. , , , , .
PS
PS . , – SQL . XML , — , .
:
https://domain.com/api/combinations/?filter[reference]=reference
, reference — .
- -, : KRHE1Z26X14M200034.
, . ! Git:
«»
( , ). base64 , , , :
def __init__(self, api_secret_key, request_url=None, **kwargs):
try:
self.api_secret_key = str(api_secret_key) #!API key is necessary!
self.api_secret_key_64 = base64.b64encode((self.api_secret_key + ':').encode())
except:
raise TypeError('The secret_key must be a string!')
# Main path to working directory
self.base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
self.request_url = request_url
self.kwargs = kwargs.items()
#product meta to return
self.name = None
self.total_quantity = None
self.w_from = None
self.w_to = None
self.date = str(datetime.datetime.now().strftime("%d-%m-%Y, %H:%M"))
: _xml_data_extractor(), _wd() _logging(), . -.
— . 11. . , , .
middle-
c Python. , - . WSGI- , !
, , .
, . , Django, — middle-, .
, , - .
! https://palachintosh.com/xxx/xxx/
? ( ) , , . .
/?code=1122334455&token=IUFJ44KPQE342M3M109DNWI
( ):
success – , , , , - . .
, , , , . Django Django REST. Java Retrofit, .
– – . – - :
token = None
with open(‘token.txt’) as file_t:
token = file_t[0]
if token == str(request.GET.get(‘token’)):
//
return JsonResponse({‘Error’: ‘Invalid token’})
, , .
Chrome
, , ..
, . . XMLHttpRequest.
CORS. , Access-Control-Allow-Origin. , OPTIONS.
views.py def options(self, request). GET .
100 , .
- , . . :
, . «Kod roweru» , .
– PrestaRequest . , .
«sku» , ajax . , ajax . .
var interval;
function main_interval() {
clearInterval(interval);
interval = setInterval(function () {
href = window.location.href
if (href.indexOf('https://24.kross.pl/warranty/new') >= 0 ||
href.indexOf('id_product=') >= 0) {
if (href.indexOf('id_product=') >= 0) {
prestaCheck();
clearInterval(interval);
}
if (href.indexOf('https://24.kross.pl/warranty/new') >= 0) {
location.reload();
get_buttons();
}
}
if (href.indexOf('https://24.kross.pl/bike-overview/new') >= 0) {
clearInterval(interval);
check_all();
}
}, 1000);
}
:
// onclick or enter events
function getFormData() {
var getForm = document.forms[0];
if (getForm != null) {
if (getForm.hasChildNodes("sku") && getForm.sku != null){
var code = String(getForm.sku.value);
}
if (getForm.hasChildNodes("bike_model") && getForm.bike_model != null) {
edit_msg = document.querySelector(".message-container > span > h1");
edit_msg.innerText = "Rower " + String(getForm.bike_model.value) + " zostanie usunięty ze stanów!";
}
if (code != null && getForm.serial_number != null) {
sendRequest(code);
}
}
}
bike_model , , . :
var getBodyBlock = document.querySelector('body');
var alert_div = document.createElement('div');
alert_div.innerHTML = '<div class="alert-message"><div class="message-container">\
<span><h1></h1></span>\
<div class="inner-buttons">\
<button id="btnYes" class="ant-btn ant-btn-danger">Potwierdzam!</button>\
<button id="btnReserve" class="ant-btn ant-btn-danger">Zdjąć rezerwację</button>\
<button id="btnNo" class="ant-btn ant-btn-success">Nie teraz</button>\
</div></div></div>';
loader = document.createElement('div');
getBodyBlock.appendChild(alert_div);
: https://github.com/palachintosh/shop_extension
– Android-
, , . . , , , 50 ., .
. , . , .
( )
3 . , :
, .
, , , - , .
, . - . , - . Java .
Retrofit 2. , Python. , , , , , .
Main Activity 3 – onCreate, scanCode, enterCode , :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner fromSpinner = (Spinner) findViewById(R.id.fromSpinner);
Spinner toSpinner = (Spinner) findViewById(R.id.toSpinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String> (
this, android.R.layout.simple_spinner_item, warehouses);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
fromSpinner.setAdapter(adapter);
toSpinner.setAdapter(adapter);
}
public void scanCode(View view) {
Intent intent = new Intent(MainActivity.this, Scan.class);
Spinner get_w_from = (Spinner) findViewById(R.id.fromSpinner);
Spinner get_w_to = (Spinner) findViewById(R.id.toSpinner);
EditText editText = (EditText) findViewById(R.id.prodctQuantity);
String quantity_tt = editText.getText().toString();
RequestData requestData = new RequestData(
get_w_from.getSelectedItem().toString(),
get_w_to.getSelectedItem().toString(),
quantity_tt);
intent.putExtra(RequestData.class.getSimpleName(), requestData);
startActivity(intent);
}
“Enter Code” . , . – .
Scan Code Activity co , Barcode Scanner Google.
Send Code – . , . Retrofit . , , – Java Android , .
github: https://github.com/palachintosh/product_control.git
:
– ;
– , , ;
- , .
:
– - , ;
– ;
– .
, 2- -.
, , 5:
.
( , PrestaShop).
"Enter code" .
"Scan code".
– "Send Code".
, , , .
, , , . - - .
: , , , .
, , , .
People who have looked at the repositories or generally read this will be grateful for constructive comments and criticism.