-
Notifications
You must be signed in to change notification settings - Fork 0
/
booli.py
111 lines (89 loc) · 3.42 KB
/
booli.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import random
import string
import time
import requests
import urllib.request as urllib2
from hashlib import sha1
from urllib.parse import urlencode
def html_decode(s):
return s.replace("<", "<").replace(">", ">").replace("&", "&")
def urlify_value(value):
if isinstance(value, int):
return str(int(value))
elif isinstance(value, list):
return ",".join(urlify_value(x) for x in value)
return str(value)
def smart_urlencode(params):
return urlencode(dict((key, urlify_value(value))
for key, value in params.items()))
class BooliClient(object):
base_url = "http://api.booli.se"
def __init__(self, caller_id, key):
self.caller_id = caller_id
self.key = key
def get_sold_objects(self, params):
last = False
limit = 500
offset = 0
while not last:
response = self._get_sold_object(limit, offset, params)
yield response
offset += limit
last = response.offset > response.totalCount
def _get_sold_object(self, limit, offset, params):
url = self.base_url + "/sold"
params.update(limit=limit, offset=offset)
params.update(self._get_auth_params())
response = requests.get(url, params)
return BooliResponse.from_dict(response.json())
def _get_auth_params(self):
timestamp = str(time.time()).split('.')[0]
unique = "".join(random.choice(string.ascii_letters + string.digits)
for _ in range(16))
line = (self.caller_id + timestamp + self.key + unique).encode('utf-8')
hash = sha1(line).hexdigest()
params = {}
params.update(callerId=self.caller_id, time=timestamp,
unique=unique, hash=hash, format="json")
return params
class BooliAPI(object):
base_url = "http://api.booli.se/sold"
def __init__(self, caller_id, key):
self.caller_id = caller_id
self.key = key
def search(self, area="", **params):
url = self._build_url(area, params)
print(url)
response = urllib2.urlopen(url)
data = json.load(response)
bs = BooliResponse.from_dict(data)
print(bs.totalCount)
return bs
def _build_url(self, area, params):
"""Return a complete API request URL for the given search
parameters, including the required authentication bits."""
timestamp = str(time.time()).split('.')[0]
unique = "".join(random.choice(string.ascii_letters + string.digits)
for _ in range(16))
line = (self.caller_id + timestamp + self.key + unique).encode('utf-8')
hash = sha1(line).hexdigest()
params.update(q=area, callerId=self.caller_id, time=timestamp,
unique=unique, hash=hash, format="json")
return self.base_url + "?" + smart_urlencode(params)
class BooliResponse(object):
def __init__(self, totalCount, count, limit, offset, payload):
self.totalCount = totalCount
self.count = count
self.limit = limit
self.offset = offset
self.payload = payload
def from_dict(o):
totalCount = o['totalCount']
count = o['count']
limit = o['limit']
offset = o['offset']
payload = o['sold']
return BooliResponse(totalCount, count, limit, offset, payload)