<commit_before>import re
from urllib2 import Request, urlopen, URLError, quote
import base64
import xml.etree.ElementTree as etree

class Customs(object):
    def __init__(self, description, quantity, weight, value, country):
        self._description = description
        self._quantity = quantity
        self._weight = weight
        self._value = value
        self._country = country
    
    @property
    def description(self):
        return self._description
    
    @property
    def quantity(self):
        return self._quantity
    
    @property
    def weight(self):
        return self._weight
    
    @property
    def value(self):
        return self._value
    
    @property
    def country(self):
        return self._country
        
class Package(object):
    shipment_types = [
                'Priority',
                'Express',
                'First',
                'LibraryMail',
                'MediaMail',
                'ParcelPost',
                'ParcelSelect',
                'StandardMailClass',
                'ExpressMailInternational',
                'FirstClassMailInternational',
                'PriorityMailInternational',
            ]
    
    shapes = [
                'SmallFlatRateBox',
                'MediumFlatRateBox',
                'LargeFlatRateBox',
                'Parcel',
                'Card',
                'Letter',
                'Flat',
                'LargeParcel',
                'IrregularParcel',
                'OversizedParcel',
                'FlatRateEnvelope',
                'FlatRatePaddedEnvelope',
             ]

    def __init__(self, mail_class, weight_oz, shape, length, width, height, description='', value=0):
        self.mail_class = mail_class
        self.weight_oz = str(weight_oz)
        self.shape = shape
        self.dimensions = ( str(length), str(width), str(height) )
        self.description = description
        self.value = str(value)

class EndiciaRequest(object):
    def __init__(self, url, api, debug=False):
        self.debug = debug
        self.url = url
        self.api = api
        
    def send(self):
        root = self._get_xml()
        request_text = etree.tostring(root)

        try:
            url_base = u'https://www.envmgr.com/LabelService/EwsLabelService.asmx' if self.debug else u'https://LabelServer.Endicia.com/LabelService/EwsLabelService.asmx'
            full_url = u'%s/%s' % (url_base, self.url)
            data = '%s=%s' % (self.api, quote(request_text))
            request = Request(full_url, data)
            response_text = urlopen(request).read()
            response = self.__parse_response(response_text)
        except URLError, e:
            if hasattr(e, 'reason'):
                print 'Could not reach the server, reason: %s' % e.reason
            elif hasattr(e, 'code'):
                print 'Could not fulfill the request, code: %d' % e.code
            raise

        return response
        
    def __parse_response(self, response_text):
        """Parses the text from an Endicia web service call"""
        root = etree.fromstring(response_text)
        namespace = re.search('{(.*)}', root.tag).group(1)
        status_path = '{%s}Status' % namespace
        status = int(root.findtext(status_path))
        response = None
        if status != 0:
            response = Error(status, root, namespace)
        else:
            response = self._parse_response_body(root, namespace)
        return response

class Error(object):
    def __init__(self, status, root, namespace):
        self.status = status
        error_path = '{%s}ErrorMessage' % namespace
        self.message = root.findtext(error_path).encode('UTF-8')
        
    def __repr__(self):
        return 'Endicia error %d: %s' % (self.status, self.message)
        
class LabelRequest(EndiciaRequest):
    def __init__(self, partner_id, account_id, passphrase, package, shipper, recipient,
                       stealth=True, insurance='OFF', insurance_amount=0,
                       customs_form='None', customs_info=list(),
                       debug=False):
        url = u'GetPostageLabelXML'
        api = u'labelRequestXML'
        super(LabelRequest, self).__init__(url, api, debug)
        
        self.partner_id = partner_id
        self.account_id = account_id
        self.passphrase = <PASSWORD>
        
        self.package = package
        self.shipper = shipper
        self.recipient = recipient
        self.stealth = 'TRUE' if stealth else 'FALSE'
        self.insurance = insurance
        self.insurance_amount = insurance_amount
        self.customs_form = customs_form
        self.customs_info = customs_info
        
    def _parse_response_body(self, root, namespace):
        return LabelResponse(root, namespace)
        
    def _get_xml(self):
        root = etree.Element('LabelRequest')
        root.set('LabelType', 'Default')
        root.set('LabelSize', '4X6')
        root.set('ImageFormat', 'GIF')
        if self.debug:
            root.set('Test', 'YES')
            
        etree.SubElement(root, u'RequesterID').text = self.partner_id
        etree.SubElement(root, u'AccountID').text = self.account_id
        etree.SubElement(root, u'PassPhrase').text = self.passphrase
        
        etree.SubElement(root, u'MailClass').text = self.package.mail_class
        etree.SubElement(root, u'WeightOz').text = self.package.weight_oz
        etree.SubElement(root, u'MailpieceShape').text = self.package.shape
        etree.SubElement(root, u'Stealth').text = self.stealth
        etree.SubElement(root, u'Value').text = self.package.value
        etree.SubElement(root, u'Description').text = self.package.description
        
        etree.SubElement(root, u'PartnerCustomerID').text = 'SomeCustomerID'
        etree.SubElement(root, u'PartnerTransactionID').text = 'SomeTransactionID'
        
        etree.SubElement(root, u'ResponseOptions').set('PostagePrice', 'TRUE')
        
        self.__add_address(self.shipper, 'From', root)
        self.__add_address(self.recipient, 'To', root)
        
        etree.SubElement(root, u'Stealth').text = self.stealth
        etree.SubElement(root, u'InsuredMail').text = self.insurance
        etree.SubElement(root, u'InsuredValue').text = str(self.insurance_amount)
        
        etree.SubElement(root, u'CustomsFormType').text = self.customs_form
        for i, info in enumerate(self.customs_info):
            i += 1
            etree.SubElement(root, u'CustomsDescription%d' % i).text = info.description
            etree.SubElement(root, u'CustomsQuantity%d' % i).text = str(info.quantity)
            etree.SubElement(root, u'CustomsWeight%d' % i).text = str(info.weight)
            etree.SubElement(root, u'CustomsValue%d' % i).text = str(info.value)
            etree.SubElement(root, u'CustomsCountry%d' % i).text = info.country

        return root
        
    def __add_address(self, address, type, root):
        info = dict()
        info['Name'] = address.name
        info['Address1'] = address.address1
        info['City'] = address.city
        info['State'] = address.state
        info['PostalCode'] = address.zip
        info['Country'] = address.country.upper()
        if address.phone:
            info['Phone'] = address.phone
        if address.address2:
            info['Address2'] = address.address2
        
        for key, value in info.items():
            # Endicia expects ReturnAddressX instead of FromAddressX
            if type == 'From' and 'Address' in key:
                element_key = 'Return%s' % key
            else:
                element_key = '%s%s' % (type, key)
            etree.SubElement(root, element_key).text = value
            
class LabelResponse(object):
    def __init__(self, root, namespace):
        self.root = root
        self.tracking = root.findtext('{%s}TrackingNumber' % namespace)<commit_msg>Lots more Endicia shipping configuration<commit_after>import re
from urllib2 import Request, urlopen, URLError, quote
import base64
import xml.etree.ElementTree as etree

class Customs(object):
    def __init__(self, description, quantity, weight, value, country):
        self._description = description
        self._quantity = quantity
        self._weight = weight
        self._value = value
        self._country = country
    
    @property
    def description(self):
        return self._description
    
    @property
    def quantity(self):
        return self._quantity
    
    @property
    def weight(self):
        return self._weight
    
    @property
    def value(self):
        return self._value
    
    @property
    def country(self):
        return self._country
        
class Package(object):
    shipment_types = [
                'Priority',
                'Express',
                'First',
                'LibraryMail',
                'MediaMail',
                'ParcelPost',
                'ParcelSelect',
                'StandardMailClass',
                'ExpressMailInternational',
                'FirstClassMailInternational',
                'PriorityMailInternational',
            ]
    
    shapes = [
                'SmallFlatRateBox',
                'MediumFlatRateBox',
                'LargeFlatRateBox',
                'Parcel',
                'Card',
                'Letter',
                'Flat',
                'LargeParcel',
                'IrregularParcel',
                'OversizedParcel',
                'FlatRateEnvelope',
                'FlatRatePaddedEnvelope',
             ]

    def __init__(self, mail_class, weight_oz, shape, length, width, height, description='', value=0):
        self.mail_class = mail_class
        self.weight_oz = str(weight_oz)
        self.shape = shape
        self.dimensions = ( str(length), str(width), str(height) )
        self.description = description
        self.value = str(value)

class EndiciaRequest(object):
    def __init__(self, url, api, debug=False):
        self.debug = debug
        self.url = url
        self.api = api
        
    def send(self):
        root = self._get_xml()
        request_text = etree.tostring(root)

        try:
            url_base = u'https://www.envmgr.com/LabelService/EwsLabelService.asmx' if self.debug else u'https://LabelServer.Endicia.com/LabelService/EwsLabelService.asmx'
            full_url = u'%s/%s' % (url_base, self.url)
            data = '%s=%s' % (self.api, quote(request_text))
            request = Request(full_url, data)
            response_text = urlopen(request).read()
            response = self.__parse_response(response_text)
        except URLError, e:
            if hasattr(e, 'reason'):
                print 'Could not reach the server, reason: %s' % e.reason
            elif hasattr(e, 'code'):
                print 'Could not fulfill the request, code: %d' % e.code
            raise

        return response
        
    def __parse_response(self, response_text):
        """Parses the text from an Endicia web service call"""
        root = etree.fromstring(response_text)
        namespace = re.search('{(.*)}', root.tag).group(1)
        status_path = '{%s}Status' % namespace
        status = int(root.findtext(status_path))
        response = None
        if status != 0:
            response = Error(status, root, namespace)
        else:
            response = self._parse_response_body(root, namespace)
        return response

class Error(object):
    def __init__(self, status, root, namespace):
        self.status = status
        error_path = '{%s}ErrorMessage' % namespace
        self.message = root.findtext(error_path).encode('UTF-8')
        
    def __repr__(self):
        return 'Endicia error %d: %s' % (self.status, self.message)
        
class LabelRequest(EndiciaRequest):
    def __init__(self, partner_id, account_id, passphrase, package, shipper, recipient,
                       stealth=True, value=0, insurance='OFF', insurance_amount=0,
                       customs_form='None', customs_info=list(),
                       contents_type='', contents_explanation='', nondelivery='Return',
                       debug=False):
        url = u'GetPostageLabelXML'
        api = u'labelRequestXML'
        super(LabelRequest, self).__init__(url, api, debug)
        
        self.partner_id = partner_id
        self.account_id = account_id
        self.passphrase = <PASSWORD>
        
        self.package = package
        self.shipper = shipper
        self.recipient = recipient
        self.stealth = 'TRUE' if stealth else 'FALSE'
        self.value = value
        self.insurance = insurance
        self.insurance_amount = insurance_amount
        self.customs_form = customs_form
        self.customs_info = customs_info
        self.contents_type = contents_type
        self.contents_explanation = contents_explanation
        self.nondelivery = nondelivery
        
    def _parse_response_body(self, root, namespace):
        return LabelResponse(root, namespace)
        
    def _get_xml(self):
        root = etree.Element('LabelRequest')
        root.set('LabelType', 'Default')
        root.set('LabelSize', '4X6')
        root.set('ImageFormat', 'GIF')
        if self.debug:
            root.set('Test', 'YES')
            
        etree.SubElement(root, u'RequesterID').text = self.partner_id
        etree.SubElement(root, u'AccountID').text = self.account_id
        etree.SubElement(root, u'PassPhrase').text = self.passphrase
        
        etree.SubElement(root, u'MailClass').text = self.package.mail_class
        etree.SubElement(root, u'WeightOz').text = self.package.weight_oz
        etree.SubElement(root, u'MailpieceShape').text = self.package.shape
        etree.SubElement(root, u'Stealth').text = self.stealth
        etree.SubElement(root, u'Value').text = self.package.value
        etree.SubElement(root, u'Description').text = self.package.description
        
        etree.SubElement(root, u'PartnerCustomerID').text = 'SomeCustomerID'
        etree.SubElement(root, u'PartnerTransactionID').text = 'SomeTransactionID'
        
        etree.SubElement(root, u'ResponseOptions').set('PostagePrice', 'TRUE')
        
        self.__add_address(self.shipper, 'From', root)
        self.__add_address(self.recipient, 'To', root)
        
        etree.SubElement(root, u'Stealth').text = self.stealth
        etree.SubElement(root, u'Value').text = str(self.value)
        etree.SubElement(root, u'InsuredMail').text = self.insurance
        etree.SubElement(root, u'InsuredValue').text = str(self.insurance_amount)
        
        etree.SubElement(root, u'CustomsFormType').text = self.customs_form
        etree.SubElement(root, u'ContentsType').text = self.contents_type
        etree.SubElement(root, u'ContentsExplanation').text = self.contents_explanation
        etree.SubElement(root, u'NonDeliveryOption').text = self.nondelivery
        for i, info in enumerate(self.customs_info):
            i += 1
            if info.description:
                etree.SubElement(root, u'CustomsDescription%d' % i).text = info.description
            if info.quantity:
                etree.SubElement(root, u'CustomsQuantity%d' % i).text = str(info.quantity)
            if info.weight:
                etree.SubElement(root, u'CustomsWeight%d' % i).text = str(info.weight)
            if info.value:
                etree.SubElement(root, u'CustomsValue%d' % i).text = str(info.value)
            if info.country:
                etree.SubElement(root, u'CustomsCountry%d' % i).text = info.country
        from shipping import debug_print_tree
        debug_print_tree(root)
        return root
        
    def __add_address(self, address, type, root):
        info = dict()
        info['Name'] = address.name
        info['Address1'] = address.address1
        info['City'] = address.city
        info['State'] = address.state
        info['PostalCode'] = address.zip
        info['Country'] = address.country.upper()
        if address.phone:
            info['Phone'] = address.phone
        if address.address2:
            info['Address2'] = address.address2
        
        for key, value in info.items():
            # Endicia expects ReturnAddressX instead of FromAddressX
            if type == 'From' and 'Address' in key:
                element_key = 'Return%s' % key
            else:
                element_key = '%s%s' % (type, key)
            etree.SubElement(root, element_key).text = value
            
class LabelResponse(object):
    def __init__(self, root, namespace):
        self.root = root
        self.tracking = root.findtext('{%s}TrackingNumber' % namespace)
{'fraction_non_alphanumeric': 0.1091671659676453, 'fraction_numerical': 0.001977231875374476, 'mean_word_length': 2.093790546802595, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '162761', 'n_tokens_mistral': 4810, 'n_tokens_neox': 4683, 'n_words': 966}