Skip to content

Instantly share code, notes, and snippets.

@ericmoritz
Created May 24, 2011 19:02
Show Gist options
  • Save ericmoritz/989401 to your computer and use it in GitHub Desktop.
Save ericmoritz/989401 to your computer and use it in GitHub Desktop.
Simple Redis powered chat server for hyper-local chat.
import redis
import simplejson as json
import logging
import settings
import math
log = logging.getLogger(__name__)
#
# The following formulas are adapted from the Aviation Formulary
# http://williams.best.vwh.net/avform.htm
#
nauticalMilePerLat = 60.00721
nauticalMilePerLongitude = 60.10793
rad = math.pi / 180.0
milesPerNauticalMile = 1.15078
def calcDistance(lat1, lon1, lat2, lon2):
"""
Caclulate distance between two lat lons in NM
"""
yDistance = (lat2 - lat1) * nauticalMilePerLat
xDistance = (math.cos(lat1 * rad) + math.cos(lat2 * rad)) * (lon2 - lon1) * (nauticalMilePerLongitude / 2)
distance = math.sqrt( yDistance**2 + xDistance**2 )
return distance * milesPerNauticalMile
def broadcast(channel, latitude, longitude, message):
"""Broadcasts a message"""
r = redis.Redis()
message = {"latitude": latitude,
"longitude": longitude,
"message": message}
r.publish(channel, json.dumps(message))
def listener(channel, latitude, longitude, radius):
"""Listens for incoming messages
channel
The Redis channel to listen on
lat
The latitude of the listener
long
The longitude of the listener
radius
The listening radius"""
r = redis.Redis()
r.subscribe(channel)
for packet in r.listen():
log.debug("Got: %s" % (packet, ))
if packet.get("type") == "message":
data = packet.get('data')
try:
# decode the message
message = json.loads(data)
# Check the lat/long of the message against the listener
# yield the message if it is within the radius
distance = calcDistance(latitude, longitude,
message['latitude'],
message['longitude'])
if distance <= radius:
log.debug("Message is within %s mi of listener" \
% (distance, ))
yield message
else:
log.debug("Message is outside %s mi of listener" \
% (distance, ))
except Exception, e:
log.exception(e)
yield ("error", e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment