Compare commits

...

3 Commits

Author SHA1 Message Date
Henrik Genssen 389a8f62c0 Add ProductInformation() class and examples/products.py
This allows the user to re-generate (update) the price list in
products.json using 1C4A without ProdWS access.
2019-07-11 23:45:58 +08:00
Henrik Genssen b3efdef965 make gen_1c4a_hdr() and get_product_price_by_id() class methods 2019-07-11 23:34:39 +08:00
Henrik Genssen fd0920d0bc Add coding/utf8 annotations to fix special characters for python 2.7 2019-07-11 23:23:45 +08:00
4 changed files with 98 additions and 37 deletions

View File

@ -1,4 +1,5 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import logging
from inema import Internetmarke

39
examples/products.py Executable file
View File

@ -0,0 +1,39 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import logging
from inema import ProductInformation
import json
# you have to fill the below with your login details for the ProdWS Service
USER = "xxx"
PASS = "yyyyyy"
MANDANTID = "zzzzz"
#logging.basicConfig(level=logging.INFO)
im = ProductInformation(USER, PASS, MANDANTID)
data = im.getProductList()
# print data
if data['success']:
products = {}
for ele in data['Response']['salesProductList']['SalesProduct']:
international = True if ele['extendedIdentifier']['destination'] == 'international' else False
id = ele['extendedIdentifier']['externIdentifier'][0]['id']
name = ele['extendedIdentifier']['externIdentifier'][0]['name']
cost_price = ele['priceDefinition']['price']['commercialGrossPrice']['value']
weight = ele['weight']
if weight:
products[id] = {
'international': international,
'cost_price': unicode(cost_price),
'name': name,
'max_weight': unicode(weight['maxValue'])
}
print json.dumps(products)
else:
print 'ERROR: %s' % data['Exception']

View File

@ -1,2 +1,4 @@
# -*- coding: utf-8 -*-
from .inema import Internetmarke
from .inema import ProductInformation
from .inema import __version__

View File

@ -1,4 +1,5 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from datetime import datetime
from pytz import timezone
@ -6,7 +7,8 @@ import hashlib
import json
from lxml import etree
from zeep import Client
from pkg_resources import resource_stream, Requirement
from zeep.wsse.username import UsernameToken
from pkg_resources import resource_stream
import requests, zipfile
import io
import logging
@ -21,53 +23,70 @@ marke_products = json.loads(products_json)
formats_json = resource_stream(__name__, "data/formats.json").read().decode()
formats = json.loads(formats_json)
def get_product_price_by_id(ext_prod_id):
price_float_str = marke_products[str(ext_prod_id)]['cost_price']
return int(round(float(price_float_str) * 100))
class ProductInformation(object):
wsdl_url = 'https://prodws.deutschepost.de:8443/ProdWSProvider_1_1/prodws?wsdl'
# generate a 1C4A SOAP header
def gen_1c4a_hdr(partner_id, key_phase, key):
# Compute 1C4A request hash accordig to Section 4 of service description
def compute_1c4a_hash(partner_id, req_ts, key_phase, key):
# trim leading and trailing spaces of each argument
partner_id = partner_id.strip()
req_ts = req_ts.strip()
key_phase = key_phase.strip()
key = key.strip()
# concatenate with "::" separator
inp = "%s::%s::%s::%s" % (partner_id, req_ts, key_phase, key)
# compute MD5 hash as 32 hex nibbles
md5_hex = hashlib.md5(inp.encode('utf8')).hexdigest()
# return the first 8 characters
return md5_hex[:8]
def __init__(self, username, password, mandantid):
self.client = Client(self.wsdl_url, wsse=UsernameToken(username, password))
self.username = username
self.password = password
self.mandantid = mandantid
def gen_timestamp():
de_zone = timezone("Europe/Berlin")
de_time = datetime.now(de_zone)
return de_time.strftime("%d%m%Y-%H%M%S")
def getProductList(self):
s = self.client.service
r = s.getProductList(mandantID=self.mandantid, dedicatedProducts=True, responseMode=0)
_logger.info("getProductList result: %s", r)
return r
nsmap={'soapenv': 'http://schemas.xmlsoap.org/soap/envelope/',
'v3':'http://oneclickforpartner.dpag.de'}
r = etree.Element("{http://schemas.xmlsoap.org/soap/envelope/}Header", nsmap = nsmap)
p = etree.SubElement(r, "{http://oneclickforpartner.dpag.de}PARTNER_ID")
p.text = partner_id
t = etree.SubElement(r, "{http://oneclickforpartner.dpag.de}REQUEST_TIMESTAMP")
t.text = gen_timestamp()
k = etree.SubElement(r, "{http://oneclickforpartner.dpag.de}KEY_PHASE")
k.text = key_phase
s = etree.SubElement(r, "{http://oneclickforpartner.dpag.de}PARTNER_SIGNATURE")
s.text = compute_1c4a_hash(partner_id, t.text, key_phase, key)
return [p, t, k, s]
class Internetmarke(object):
wsdl_url = 'https://internetmarke.deutschepost.de/OneClickForAppV3/OneClickForAppServiceV3?wsdl'
# generate a 1C4A SOAP header
def gen_1c4a_hdr(self, partner_id, key_phase, key):
# Compute 1C4A request hash accordig to Section 4 of service description
def compute_1c4a_hash(partner_id, req_ts, key_phase, key):
# trim leading and trailing spaces of each argument
partner_id = partner_id.strip()
req_ts = req_ts.strip()
key_phase = key_phase.strip()
key = key.strip()
# concatenate with "::" separator
inp = "%s::%s::%s::%s" % (partner_id, req_ts, key_phase, key)
# compute MD5 hash as 32 hex nibbles
md5_hex = hashlib.md5(inp.encode('utf8')).hexdigest()
# return the first 8 characters
return md5_hex[:8]
def gen_timestamp():
de_zone = timezone("Europe/Berlin")
de_time = datetime.now(de_zone)
return de_time.strftime("%d%m%Y-%H%M%S")
nsmap={'soapenv': 'http://schemas.xmlsoap.org/soap/envelope/',
'v3':'http://oneclickforpartner.dpag.de'}
r = etree.Element("{http://schemas.xmlsoap.org/soap/envelope/}Header", nsmap = nsmap)
p = etree.SubElement(r, "{http://oneclickforpartner.dpag.de}PARTNER_ID")
p.text = partner_id
t = etree.SubElement(r, "{http://oneclickforpartner.dpag.de}REQUEST_TIMESTAMP")
t.text = gen_timestamp()
k = etree.SubElement(r, "{http://oneclickforpartner.dpag.de}KEY_PHASE")
k.text = key_phase
s = etree.SubElement(r, "{http://oneclickforpartner.dpag.de}PARTNER_SIGNATURE")
s.text = compute_1c4a_hash(partner_id, t.text, key_phase, key)
return [p, t, k, s]
def get_product_price_by_id(self, ext_prod_id):
price_float_str = marke_products[str(ext_prod_id)]['cost_price']
return int(round(float(price_float_str) * 100))
def __init__(self, partner_id, key, key_phase="1"):
self.client = Client(self.wsdl_url)
self.partner_id = partner_id
self.key_phase = key_phase
self.key = key
self.soapheader = gen_1c4a_hdr(self.partner_id, self.key_phase, self.key)
self.soapheader = self.gen_1c4a_hdr(self.partner_id, self.key_phase, self.key)
self.positions = []
def authenticate(self, username, password):
@ -123,7 +142,7 @@ class Internetmarke(object):
def compute_total(self):
total = 0
for p in self.positions:
total += get_product_price_by_id(p.productCode)
total += self.get_product_price_by_id(p.productCode)
return total
def checkoutPDF(self, page_format):