chaloBEST/smsBEST/mumbai/app.py

149 lines
6.0 KiB
Python
Raw Normal View History

from rapidsms.apps.base import AppBase
2012-02-28 18:10:22 +00:00
import re
import arrest
MAX_MSG_LEN = 160
2012-02-28 18:10:22 +00:00
DIGIT = re.compile(r"\d{1,3}")
2012-02-28 20:03:35 +00:00
PUNCT = re.compile(r"[^\w\s]")
"""
2012-02-28 20:03:35 +00:00
STYLE = {
2012-02-28 20:15:32 +00:00
"start": "-* ",
"repeat": " -*- ",
"end": " *-"
2012-02-28 20:03:35 +00:00
}
"""
STYLE = {"start": "", "repeat": "; ", "end": ""}
2012-02-28 20:03:35 +00:00
ChaloBest = arrest.Client("http://chalobest.in/1.0")
def get_routes_for_matches(stops):
2012-09-11 10:58:35 +00:00
# same_stops = []
# same_stops.append(stops[0])
# if len(stops) > 1:
# for s in stops[1:]:
# if s['properties']['official_name'] == stops[0]['properties']['official_name']:
# same_stops.append(s)
routes = []
2012-09-11 10:58:35 +00:00
for stop in stops:
2012-09-06 13:49:08 +00:00
routes.extend(stop['properties']['routes'].split(", "))
return routes
2012-09-11 10:58:35 +00:00
def get_stops_for_string(s):
2012-10-05 10:02:20 +00:00
'''
Returns a dict with name and stops to associate with given search string.
First looks at areas, if string matches an area, returns area as name and all stops within that area as stops.
If search term does not match an area, returns the first / best match of stop to string. If there are multiple stops with the same name, returns all of them in the list of stops.
'''
2012-09-11 10:58:35 +00:00
stops = []
s = s.strip()
2012-09-18 11:40:20 +00:00
# areas = ChaloBest.areas(q=s)
areas = [area for area in ChaloBest.areas(q=s) if area.lower().startswith(s)]
2012-09-11 10:58:35 +00:00
if len(areas) > 0:
for a in areas:
area = ChaloBest.area[a]
for stop in area['stops']['features']:
stops.append(stop)
return {
'name': ", ".join(areas),
'stops': stops
}
else:
2012-09-11 11:07:14 +00:00
stops_results = ChaloBest.stops(q=s)['features']
2012-09-11 10:58:35 +00:00
if len(stops_results) == 0:
return None
same_stops = []
2012-09-11 11:13:22 +00:00
same_stops.append(stops_results[0])
2012-09-11 10:58:35 +00:00
if len(stops_results) > 1:
for s in stops_results[1:]:
2012-09-11 11:13:22 +00:00
if s['properties']['official_name'] == same_stops[0]['properties']['official_name']:
2012-09-11 10:58:35 +00:00
same_stops.append(s)
return {
2012-09-11 11:13:22 +00:00
'name': same_stops[0]['properties']['display_name'],
2012-09-11 10:58:35 +00:00
'stops': same_stops
}
class App(AppBase):
2012-02-28 18:10:22 +00:00
def handle(self, msg):
if DIGIT.search(msg.text):
2012-02-28 20:03:35 +00:00
routes = ChaloBest.routes(q=msg.text.replace(" ", ""))
2012-02-28 21:08:53 +00:00
if not routes:
msg.respond("Sorry, we found no route marked '%(text)s'.", text=msg.text)
2012-02-28 20:15:32 +00:00
return
2012-09-11 10:58:35 +00:00
detail = None
for route in routes:
if route.replace(" ", "").upper() == msg.text.replace(" ", "").upper():
detail = ChaloBest.route[route]
if detail == None:
detail = ChaloBest.route[routes[0]]
2012-02-28 21:08:53 +00:00
detail = ChaloBest.route[routes[0]]
stops = detail['stops']['features']
origin, dest = stops[0]['properties'], stops[-1]['properties']
origin_name, dest_name = origin['display_name'], dest['display_name']
origin_area, dest_area = PUNCT.sub('', origin['area']), PUNCT.sub('', dest['area'])
2012-09-18 12:25:39 +00:00
url = "http://chalobest.in" + detail['route']['url']
2012-10-05 14:23:15 +00:00
if detail.headway:
headway = "Frequency: " + detail.headway + " mins"
else:
headway = "Route currently not running."
response = "%s: %s (%s) to %s (%s). %s. %s" % (
",".join(routes), origin_name, origin_area, dest_name, dest_area, headway, url)
2012-10-05 10:02:20 +00:00
2012-09-06 12:53:08 +00:00
elif msg.text.find(" to ") != -1:
2012-09-11 10:58:35 +00:00
2012-09-18 11:36:27 +00:00
from_txt = msg.text.lower().split("to")[0].strip()
to_txt = msg.text.lower().split("to")[1].strip()
2012-09-11 10:58:35 +00:00
from_matches = get_stops_for_string(from_txt)
to_matches = get_stops_for_string(to_txt)
# stop1matches = ChaloBest.stops(q=stop1txt)['features']
if not from_matches:
msg.respond("Sorry, found no stop matching '%s'" % from_txt)
2012-09-06 12:53:08 +00:00
return
2012-09-11 10:58:35 +00:00
#best_match1 = stop1matches[0]
routes1 = set(get_routes_for_matches(from_matches['stops']))
#stop2matches = ChaloBest.stops(q=stop2txt)['features']
if not to_matches:
msg.respond("Sorry, found no stop matching '%s'" % to_txt)
#best_match2 = stop2matches[0]
routes2 = set(get_routes_for_matches(to_matches['stops']))
2012-09-06 13:44:02 +00:00
#routes1arr = set(routes1.split(", "))
#routes2arr = set(routes2.split(", "))
intersection = list(routes1.intersection(routes2))
2012-09-06 12:53:08 +00:00
if len(intersection) == 0:
2012-09-11 10:58:35 +00:00
msg.respond("Sorry, no direct buses found between %s and %s" % (from_matches['name'], to_matches['name'],))
2012-09-06 12:53:08 +00:00
return
routesFound = ", ".join(intersection)
2012-09-18 12:01:44 +00:00
response = "%s to %s: %s" % (from_matches['name'], to_matches['name'], routesFound,)
if len(response) > MAX_MSG_LEN:
response = response[0:MAX_MSG_LEN]
#msg.respond("%s to %s: %s" % (from_matches['name'], to_matches['name'], routesFound,))
2012-10-05 10:09:46 +00:00
2012-09-06 12:53:08 +00:00
2012-02-28 18:10:22 +00:00
else:
features = ChaloBest.stops(q=msg.text)['features']
if not features:
msg.respond("Sorry, we found no stops marked '%(text)s'.", text=msg.text)
2012-02-28 20:15:32 +00:00
return
stops = []
for feat in features:
stop = feat['properties']
if stops and stop["official_name"] == stops[-1]["official_name"]:
stops[-1]["routes"] += ", " + stop["routes"]
else:
stops.append(stop)
2012-02-28 20:03:35 +00:00
response = STYLE["start"]
for stop in stops:
match = stop["official_name"] + ": " + stop["routes"]
if len(response) > len(STYLE["repeat"]): response += STYLE["repeat"]
response += match
if len(response) > MAX_MSG_LEN: break
if len(response) > MAX_MSG_LEN:
response = response[:MAX_MSG_LEN-(len(STYLE["end"])+4)] + "..."
2012-02-28 20:03:35 +00:00
response += STYLE["end"]
2012-10-05 10:02:20 +00:00
msg.respond(response)