def flatten_conditions(filters): for key, val in filters.items(): if isinstance(val, (list, tuple)): for v in val: yield (port.to_b(key), port.to_b(v)) else: yield (port.to_b(key), port.to_b(val))
def urlencode_any(d): """ Encode a dictionary consisting of a mixture of bytes, text and integers into a str object that only uses ASCII characters. """ as_bytes = dict((port.to_b(key), port.to_b(value)) for key, value in d.items()) return port.urlencode(as_bytes)
def urlencode_any(d): """ Encode a dictionary consisting of a mixture of bytes, text and integers into a str object that only uses ASCII characters. """ as_bytes = dict( (port.to_b(key), port.to_b(value)) for key, value in d.items()) return port.urlencode(as_bytes)
def sign_request(self, request): if getattr(request, 'nosign', False): return expires = str(calendar.timegm(self.timesource()) + self.EXPIRES) to_sign = port.to_b(self.access_id + '\n' + expires) signature = hmac.new(port.to_b(self.secret_key), to_sign, hashlib.sha1).digest() request.params['AccessID'] = self.access_id request.params['Expires'] = expires request.params['Signature'] = port.to_u(base64.b64encode(signature))
def urlencode_any(d): """ Encode a dictionary or a sequence of two-element tuples consisting of a mixture of bytes, text and integers into a str object that only uses ASCII characters. """ try: d = d.items() except AttributeError: pass as_bytes = tuple((port.to_b(key), port.to_b(value)) for key, value in d) return port.urlencode(as_bytes)
def engage(self, distinct_id, data): """ Store people properties Upstream documentation: {0} :var properties: The user properties, your access token will be inserted into it automatically. :vartype properties: dict :return: A boolean that tells if the event has been logged. """ if not self.token: raise InsufficientSettings('token is required for this method') data['$token'] = self.token data['$distinct_id'] = distinct_id params = {'data': base64.b64encode(port.to_b(json.dumps(data)))} request = http.Request('GET', 'http://api.mixpanel.com/engage/', params) request.nosign = True return request, resources.parse_boolean
def encode_data(request): if not request.params: return b'' if not isinstance(request.params, dict): return port.to_b(request.params) return http.urlencode_any(request.params)
def encode_data(request): if not request.params: return b'' if isinstance(request.params, (port.text_type, port.binary_type)): return port.to_b(request.params) return http.urlencode_any(request.params)
def __call__(self, request): nonce = self.generate_nonce() timestamp = self.generate_timestamp() base = self.get_base_string(request, nonce, timestamp) key = (self.encode(self.secret) + '&' + self.encode(self.oauth_token_secret)) digest = hmac.new(port.to_b(key), port.to_b(base), sha1).digest() signature = self.encode(base64.b64encode(digest)) params = self.oauth_params(nonce, timestamp, signature) auth = ','.join('{0}="{1}"'.format(key, val) for key, val in sorted(params)) header = 'OAuth ' + auth if request.headers is None: request.headers = {} request.headers['Authorization'] = header
def sign_request(self, request): if getattr(request, "nosign", False): return if not self.api_key or not self.api_secret: raise InsufficientSettings("api_key and api_secret are required " "for this method") request.params["api_key"] = self.api_key if self.USE_EXPIRE: request.params["expire"] = calendar.timegm(time.gmtime()) + 600 to_hash = "".join( "{0}={1}".format(key, port.to_u(request.params[key])) for key in sorted(request.params.keys()) ) md5 = hashlib.md5() md5.update(port.to_b(to_hash)) md5.update(port.to_b(self.api_secret)) request.params["sig"] = md5.hexdigest()
def sign_request(self, request): if getattr(request, 'nosign', False): return if not self.api_key or not self.api_secret: raise InsufficientSettings('api_key and api_secret are required ' 'for this method') request.params['api_key'] = self.api_key if self.USE_EXPIRE: request.params['expire'] = calendar.timegm(time.gmtime()) + 600 to_hash = ''.join('{0}={1}'.format(key, port.to_u(request.params[key])) for key in sorted(request.params.keys())) md5 = hashlib.md5() md5.update(port.to_b(to_hash)) md5.update(port.to_b(self.api_secret)) request.params['sig'] = md5.hexdigest()
def __call__(self, request): auth = '{0}:{1}'.format(self.username, self.password) # According to RFC2617 the username and password are *TEXT, which # RFC2616 says may contain characters from outside of ISO-8859-1 if # they are MIME-encoded. Our first approach was to assume latin-1 in # username and password, but practice has proved us wrong (services # like Zendesk allow non-latin-1 characters in both, which are used # in basic auth for their API). To be as compatible as possible, # allow unicode in username and password, but keep resulting base64 # in latin-1. encoded = port.to_u(base64.b64encode(port.to_b(auth)), 'latin-1') header = 'Basic {0}'.format(encoded) request.headers['Authorization'] = header
def __call__(self, request): # According to RFC2617 the username and password are *TEXT, which # RFC2616 says may contain characters from outside of ISO-8859-1 if # they are MIME-encoded. Our first approach was to assume latin-1 in # username and password, but practice has proved us wrong (services # like Zendesk allow non-latin-1 characters in both, which are used # in basic auth for their API). To be as compatible as possible, # allow unicode in username and password, but keep resulting base64 # in latin-1. auth = port.to_u('{0}:{1}').format(port.to_u(self.username), port.to_u(self.password)) encoded = port.to_u(base64.b64encode(port.to_b(auth)), 'latin-1') header = 'Basic {0}'.format(encoded) request.headers['Authorization'] = header
def _make_track_import_params(self, event, properties, ip, test): if not self.token: raise InsufficientSettings('token is required for this method') if properties is None: properties = {} properties['token'] = self.token properties = dict((port.to_u(key), self.serialize_property(value)) for key, value in properties.items()) params = base.get_params(('ip', 'test'), locals(), resources.serialize_param) data = {'event': port.to_u(event), 'properties': properties} params['data'] = base64.b64encode(port.to_b(json.dumps(data))) return params
def track(self, event, properties=None, ip=False, test=False): """ Track an event. Upstream documentation: {0} :var event: The name of the event. :vartype event: str :var properties: The event's properties, your access token will be inserted into it automatically. :vartype properties: dict :var ip: Should Mixpanel automatically use the incoming request IP. :vartype ip: bool :var test: Use a high priority rate limited queue for testing. :vartype test: bool :return: A boolean that tells if the event has been logged. """ if not self.token: raise InsufficientSettings('token is required for this method') if properties is None: properties = {} properties['token'] = self.token properites = dict((port.to_u(key), port.to_u(value))for key, value in properties.items()) params = base.get_params(('ip', 'test'), locals(), resources.serialize_param) data = {'event': port.to_u(event), 'properties': properties} params['data'] = base64.b64encode(port.to_b(json.dumps(data))) request = http.Request('GET', 'http://api.mixpanel.com/track/', params) request.nosign = True return request, resources.parse_boolean
def track(self, event, properties=None, ip=False, test=False): """ Track an event. Upstream documentation: {0} :var event: The name of the event. :vartype event: str :var properties: The event's properties, your access token will be inserted into it automatically. :vartype properties: dict :var ip: Should Mixpanel automatically use the incoming request IP. :vartype ip: bool :var test: Use a high priority rate limited queue for testing. :vartype test: bool :return: A boolean that tells if the event has been logged. """ if not self.token: raise InsufficientSettings('token is required for this method') if properties is None: properties = {} properties['token'] = self.token properites = dict((port.to_u(key), port.to_u(value)) for key, value in properties.items()) params = base.get_params(('ip', 'test'), locals(), resources.serialize_param) data = {'event': port.to_u(event), 'properties': properties} params['data'] = base64.b64encode(port.to_b(json.dumps(data))) request = http.Request('GET', 'http://api.mixpanel.com/track/', params) request.nosign = True return request, resources.parse_boolean
def serializer(val): if isinstance(val, (list, tuple)): return port.to_b(',').join(map(port.to_b, val)) return base.serialize_param(val)
def quote_any(val): """ Percent quote any value, be it binary, text or integer. """ return port.quote(port.to_b(val))
def encode(self, val): # RFC5849 says that ~ should not be quoted, but / should return port.quote(port.to_b(val), safe='~')
def quote_any(val): """ Percent quite any value, be it binary, text or integer. """ return port.quote(port.to_b(val))