forked from VikParuchuri/apartment-finder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.py
135 lines (118 loc) · 4.6 KB
/
util.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import settings
import math
import simplejson
import urllib
def coord_distance(lat1, lon1, lat2, lon2):
"""
Finds the distance between two pairs of latitude and longitude.
:param lat1: Point 1 latitude.
:param lon1: Point 1 longitude.
:param lat2: Point two latitude.
:param lon2: Point two longitude.
:return: Kilometer distance.
"""
lon1, lat1, lon2, lat2 = map(math.radians, [lon1, lat1, lon2, lat2])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
c = 2 * math.asin(math.sqrt(a))
km = 6367 * c
return km
def google_transit_time(start, end, time):
"""
Get the time to travel between start and stop
:param start: List of lat and log for starting position
:param end: List of lat and log for Ending position
:param time:
:return: transit time in minutes
"""
url = "http://maps.googleapis.com/maps/api/distancematrix/json?origins={},{}&destinations={},{}&mode=driving&language=en-EN&sensor=false"\
.format(start[0], start[1], end[0], end[1])
result= simplejson.load(urllib.request.urlopen(url))
try:
driving_time = result['rows'][0]['elements'][0]['duration']['value']
except KeyError:
driving_time = 0
except IndexError:
driving_time = 0
return driving_time / 60.0
def get_walkscore(lat, lon):
url = "http://api.walkscore.com/score?format=json&lat={}&lon={}&wsapikey={}" \
.format(lat, lon, settings.WS_API_KEY)
result = simplejson.load(urllib.request.urlopen(url))
try:
score = result["walkscore"]
except KeyError:
score = 0
except IndexError:
score = 0
return score
def in_box(coords, box):
"""
Find if a coordinate tuple is inside a bounding box.
:param coords: Tuple containing latitude and longitude.
:param box: Two tuples, where first is the bottom left, and the second is the top right of the box.
:return: Boolean indicating if the coordinates are in the box.
"""
if box[0][0] < coords[0] < box[1][0] and box[0][1] < coords[1] < box[1][1]:
return True
return False
def post_listing_to_slack(sc, listing):
"""
Posts the listing to slack.
:param sc: A slack client.
:param listing: A record of the listing.
"""
desc = "*{}* - {} - {}\nTime to work: {:.2f}\n{}\n<{}>".format(listing["area"], listing["price"],
listing["walkscore"], listing["driving_time"],
listing["name"], listing["url"])
sc.api_call(
"chat.postMessage", channel=settings.SLACK_CHANNEL, text=desc,
username='Apartment Finder', icon_emoji=':robot_face:'
)
def find_points_of_interest(geotag, location):
"""
Find points of interest, like transit, near a result.
:param geotag: The geotag field of a Craigslist result.
:param location: The where field of a Craigslist result. Is a string containing a description of where
the listing was posted.
:return: A dictionary containing annotations.
"""
area_found = False
area = ""
min_dist = None
near_bart = False
bart_dist = "N/A"
bart = ""
# Look to see if the listing is in any of the neighborhood boxes we defined.
for a, coords in settings.BOXES.items():
if in_box(geotag, coords):
area = a
area_found = True
# Check to see if the listing is near any transit stations.
for station, coords in settings.TRANSIT_STATIONS.items():
dist = coord_distance(coords[0], coords[1], geotag[0], geotag[1])
if (min_dist is None or dist < min_dist) and dist < settings.MAX_TRANSIT_DIST:
bart = station
near_bart = True
if (min_dist is None or dist < min_dist):
bart_dist = dist
# If the listing isn't in any of the boxes we defined, check to see if the string description of the neighborhood
# matches anything in our list of neighborhoods.
if len(area) == 0:
for hood in settings.NEIGHBORHOODS:
if hood in location.lower():
area = hood
# Try and find travel time to work
driving_time = google_transit_time(geotag, settings.WORK_LOCATION, settings.TIME_TO_WORK)
# Try and get walkscore
walkscore = get_walkscore(geotag[0], geotag[1])
return {
"area_found": area_found,
"area": area,
"near_bart": near_bart,
"bart_dist": bart_dist,
"bart": bart,
"driving_time": driving_time,
"walkscore": walkscore
}