# Path: roulier/transport.py
# class RequestsTransport(ABC):
#     def __init__(self, config_object):
#     def before_ws_call_prepare_request_kwargs(self, payload):
#     def before_ws_call_transform_payload(self, payload):
#     def send(self, payload):
#     def _get_requests_headers(self, payload=None):
#     def _get_requests_auth(self, payload=None):
#     def _get_requests_url(self, payload=None):
#     def send_request(self, body, url, auth=None, headers=None, method="post", **kwargs):
#     def handle_200(self, response):
#     def handle_500(self, response):
#     def handle_response(self, response):
# 
# Path: roulier/ws_tools.py
# def remove_empty_tags(xml, ouput_as_string=True):
#     """Remove empty tags with xslt transformation.
# 
#     param: xml a string or a etree type
#     return: unicode string or lxml.etree._XSLTResultTree
#     """
#     # use Jinja env for getting the path of template file
#     # pkg_resouces may be an alternative, but we already
#     # have Jinja
#     env = Environment(
#         loader=PackageLoader("roulier", "templates"), extensions=["jinja2.ext.with_"]
#     )
#     template = env.get_template("remove_empty_tags.xsl")
#     xsl = etree.parse(open(template.filename))
#     transform = etree.XSLT(xsl)
# 
#     if isinstance(xml, str):
#         xml = etree.fromstring(xml)
#     # else we asume xml is an lxml.etree
#     if ouput_as_string:
#         return str(transform(xml))
#     else:
#         return transform(xml)
# 
# def get_parts(response):
#     """Extract parts from headers.
# 
#     Params:
#         response: a request object
#     Returns:
#         an array of content-ids
#     """
#     head_lines = ""
#     for k, v in response.raw.getheaders().items():
#         head_lines += str(k) + ":" + str(v) + "\n"
#     full = head_lines.encode() + response.content
#     parser = email.parser.BytesParser()
#     decoded_reply = parser.parsebytes(full)
#     parts = {}
#     start = decoded_reply.get_param("start").lstrip("<").rstrip(">")
#     i = 0
#     for part in decoded_reply.get_payload():
#         cid = part.get("content-Id", "").lstrip("<").rstrip(">")
#         if (not start or start == cid) and "start" not in parts:
#             parts["start"] = part.get_payload(decode=True)
#         else:
#             parts[cid or "Attachment%d" % i] = part.get_payload(decode=True)
#         i += 1
#     return parts
# 
# Path: roulier/exception.py
# class CarrierError(Exception):
#     """Error from WS.
# 
#     Use this class in your application to manage
#     exception with the carrier WS
#     """
# 
#     def __init__(self, response, msg=None):
#         if msg is None:
#             msg = "An error occured with WS"
#         super(CarrierError, self).__init__(msg)
#         self.response = response
#         if self.response:
#             if hasattr(self.response, "text"):
#                 log.debug(response.text)
#             else:
#                 log.debug(response)


import requests
import logging
from lxml import objectify
from jinja2 import Environment, PackageLoader
from roulier.transport import Transport
from roulier.ws_tools import remove_empty_tags, get_parts
from roulier.exception import CarrierError
        """Handle response type 200."""
        parts = get_parts(response)
        xml = parts["start"]

        def extract_soap(response_xml):
            obj = objectify.fromstring(response_xml)
            return obj.Body.getchildren()[0]

        payload = extract_soap(xml)
        try:
            # TODO : may be extract this elsewere
            # rechercheLocalite has no attachment
            attachement_cid = payload.codeAttachement.text[len("cid:") :]
            attachement = parts[attachement_cid]
        except AttributeError:
            attachement = None

        return {
            "body": payload,
            "parts": attachement,
            "response": response,
        }

    def handle_response(self, response):
        """Handle response of webservice."""
        if response.status_code == 500:
            return self.handle_500(response)
        elif response.status_code == 200:
            return self.handle_200(response)
        else:

# Path: roulier/transport.py
# class RequestsTransport(ABC):
#     def __init__(self, config_object):
#     def before_ws_call_prepare_request_kwargs(self, payload):
#     def before_ws_call_transform_payload(self, payload):
#     def send(self, payload):
#     def _get_requests_headers(self, payload=None):
#     def _get_requests_auth(self, payload=None):
#     def _get_requests_url(self, payload=None):
#     def send_request(self, body, url, auth=None, headers=None, method="post", **kwargs):
#     def handle_200(self, response):
#     def handle_500(self, response):
#     def handle_response(self, response):
# 
# Path: roulier/ws_tools.py
# def remove_empty_tags(xml, ouput_as_string=True):
#     """Remove empty tags with xslt transformation.
# 
#     param: xml a string or a etree type
#     return: unicode string or lxml.etree._XSLTResultTree
#     """
#     # use Jinja env for getting the path of template file
#     # pkg_resouces may be an alternative, but we already
#     # have Jinja
#     env = Environment(
#         loader=PackageLoader("roulier", "templates"), extensions=["jinja2.ext.with_"]
#     )
#     template = env.get_template("remove_empty_tags.xsl")
#     xsl = etree.parse(open(template.filename))
#     transform = etree.XSLT(xsl)
# 
#     if isinstance(xml, str):
#         xml = etree.fromstring(xml)
#     # else we asume xml is an lxml.etree
#     if ouput_as_string:
#         return str(transform(xml))
#     else:
#         return transform(xml)
# 
# def get_parts(response):
#     """Extract parts from headers.
# 
#     Params:
#         response: a request object
#     Returns:
#         an array of content-ids
#     """
#     head_lines = ""
#     for k, v in response.raw.getheaders().items():
#         head_lines += str(k) + ":" + str(v) + "\n"
#     full = head_lines.encode() + response.content
#     parser = email.parser.BytesParser()
#     decoded_reply = parser.parsebytes(full)
#     parts = {}
#     start = decoded_reply.get_param("start").lstrip("<").rstrip(">")
#     i = 0
#     for part in decoded_reply.get_payload():
#         cid = part.get("content-Id", "").lstrip("<").rstrip(">")
#         if (not start or start == cid) and "start" not in parts:
#             parts["start"] = part.get_payload(decode=True)
#         else:
#             parts[cid or "Attachment%d" % i] = part.get_payload(decode=True)
#         i += 1
#     return parts
# 
# Path: roulier/exception.py
# class CarrierError(Exception):
#     """Error from WS.
# 
#     Use this class in your application to manage
#     exception with the carrier WS
#     """
# 
#     def __init__(self, response, msg=None):
#         if msg is None:
#             msg = "An error occured with WS"
#         super(CarrierError, self).__init__(msg)
#         self.response = response
#         if self.response:
#             if hasattr(self.response, "text"):
#                 log.debug(response.text)
#             else:
#                 log.debug(response)


# Path: roulier/carriers/geodis/geodis_transport_ws.py
import requests
import logging
from lxml import objectify
from jinja2 import Environment, PackageLoader
from roulier.transport import Transport
from roulier.ws_tools import remove_empty_tags, get_parts
from roulier.exception import CarrierError

        """Handle response type 200."""
        parts = get_parts(response)
        xml = parts["start"]

        def extract_soap(response_xml):
            obj = objectify.fromstring(response_xml)
            return obj.Body.getchildren()[0]

        payload = extract_soap(xml)
        try:
            # TODO : may be extract this elsewere
            # rechercheLocalite has no attachment
            attachement_cid = payload.codeAttachement.text[len("cid:") :]
            attachement = parts[attachement_cid]
        except AttributeError:
            attachement = None

        return {
            "body": payload,
            "parts": attachement,
            "response": response,
        }

    def handle_response(self, response):
        """Handle response of webservice."""
        if response.status_code == 500:
            return self.handle_500(response)
        elif response.status_code == 200:
            return self.handle_200(response)
        else:

            raise CarrierError(