Last active
August 29, 2015 14:16
-
-
Save danshev/de6719c1731ae3ad0430 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from TwitterAPI import TwitterAPI | |
api = TwitterAPI("QHCFXKcJeYvFMr8XBTes3eID8", | |
"Zh3JhEBL8PXnfAEAAOivlB4xrX1PAfDEIdg6DsC78qs6O2Aruk", | |
"2401578782-7P2QUySnDc8gFHQ1vCwTrckbLLSty8tOFjrizC6", | |
"WNcilnQcbd0o7xnTYf1XBylsriyBb1KkNlxyTx4u4uB1s" | |
) | |
# instantiate empty lists that will hold Event data. | |
# these would be populated by a periodic (e.g. every 1 minute) query of "active" Events. | |
event_ids = [] | |
event_upper_longitudes = [] | |
event_lower_longitudes = [] | |
event_upper_latitudes = [] | |
event_lower_latitudes = [] | |
# helper function for testing (adds an Event to the list of target Events) | |
def addEvent(boxNeLat, boxNeLon, boxSwLat, boxSwLon, eventID): | |
global event_ids | |
global event_upper_longitudes | |
global event_lower_longitudes | |
global event_upper_latitudes | |
global event_lower_latitudes | |
event_ids.append(eventID) | |
event_upper_longitudes.append(boxNeLon) | |
event_lower_longitudes.append(boxSwLon) | |
event_upper_latitudes.append(boxNeLat) | |
event_lower_latitudes.append(boxSwLat) | |
return | |
# add box around where I live | |
addEvent(32.819655, -96.802374, 32.817328, -96.807116, 2006) | |
# add box around Love Field | |
addEvent(32.861336, -96.830076, 32.829175, -96.869387, 737) | |
# add box around SMU | |
addEvent(32.847997, -96.776475, 32.834909, -96.789864, 342) | |
# add box around White Rock Lake | |
addEvent(32.852973, -96.706780, 32.814101, -96.742743, 1000) | |
# add box around Fort Worth Water Gardens | |
addEvent(32.749163, -97.324360, 32.746618, -97.328266, 420) | |
# add box around JPS Hospital in Fort Worth | |
addEvent(32.730951, -97.323065, 32.725734, -97.330017, 83) | |
# add box around NAS JRB Fort Worth | |
addEvent(32.788938, -97.413410, 32.746645, -97.463535, 1776) | |
# helper function to remove t.co link from tweets | |
def removeLink(tweetText): | |
# clean up general tweet text | |
tweetText = tweetText.replace('\n', ' ') | |
tweetText = tweetText.replace(' ', ' ') | |
link = False | |
if "http://t.co/" in tweetText: | |
target = "http://t.co/" | |
link = True | |
offset = 23 | |
elif "https://t.co/" in tweetText: | |
target = "https://t.co/" | |
link = True | |
offset = 24 | |
if link: | |
i = tweetText.index(target) | |
before = tweetText[:i] | |
after = tweetText[(i + offset):] | |
tweetText = before + after | |
return tweetText | |
# helper function to extract video or photo URL (if media is attached to the tweet) | |
def extractMedia(tweet): | |
tweetMediaURL = None | |
# attempt to get video | |
if 'extended_entities' in tweet: | |
if 'media' in tweet['extended_entities']: | |
if 'type' in tweet['extended_entities']['media'][0]: | |
if tweet['extended_entities']['media'][0]['type'] == 'video': | |
video = tweet['extended_entities']['media'][0] | |
# loop through variants (will get highest bitrate version of video) | |
for vid in video['video_info']['variants']: | |
if vid['content_type'] == 'video/mp4': | |
tweetMediaURL = vid['url'] | |
# if no video (more valuable), then attempt to get photo | |
if tweetMediaURL is None: | |
if 'entities' in tweet: | |
if 'media' in tweet['entities']: | |
tweetMediaURL = tweet['entities']['media'][0]['media_url_https'] | |
return tweetMediaURL | |
neLat = 0.0 | |
neLon = 0.0 | |
swLat = 0.0 | |
swLon = 0.0 | |
# a helper function to make it easier to work with lat/lon values copied from Google Maps | |
def quickBox(boxNeLat, boxNeLon, boxSwLat, boxSwLon): | |
global neLat | |
global neLon | |
global swLat | |
global swLon | |
neLat = boxNeLat | |
neLon = boxNeLon | |
swLat = boxSwLat | |
swLon = boxSwLon | |
return | |
# This function determines if a Tweet falls within a list of Events. | |
# Compares the coordinates of the [point-type] Tweet against pre-instantiated lists | |
# that contain the minimum and maximum latitudes & longitudes of all the target Events. | |
def eventsTweetWithin(tweetLat, tweetLon): | |
# there's likely a better way to do this (bringing in the target lists) | |
global event_ids | |
global event_upper_longitudes | |
global event_lower_longitudes | |
global event_upper_latitudes | |
global event_lower_latitudes | |
# instantiate the "pointer" lists | |
upperLonIndexes = [] | |
lowerLonIndexes = [] | |
upperLatIndexes = [] | |
lowerLatIndexes = [] | |
# Scan through the minimum & maximum lists of Event latitudes & longitudes | |
# We record each qualifying index into the respective "pointer" list | |
for (index, event_upper_lon) in enumerate(event_upper_longitudes): | |
if tweetLon < event_upper_lon: | |
upperLonIndexes.append(index) | |
for (index, event_lower_lon) in enumerate(event_lower_longitudes): | |
if tweetLon > event_lower_lon: | |
lowerLonIndexes.append(index) | |
for (index, event_upper_lat) in enumerate(event_upper_latitudes): | |
if tweetLat < event_upper_lat: | |
upperLatIndexes.append(index) | |
for (index, event_lower_lat) in enumerate(event_lower_latitudes): | |
if tweetLat > event_lower_lat: | |
lowerLatIndexes.append(index) | |
# finally, we intersect the four "pointer" lists, thus producing (if any) the index (or indexes) that fit *all* four criteria | |
s = set(upperLonIndexes).intersection(lowerLonIndexes).intersection(upperLatIndexes).intersection(lowerLatIndexes) | |
# if the resultant set > 0, then the Tweet must "fall within" at least one Event | |
# - all that's left to do is, using the index (or indexes) retrieve the Event ID(s) | |
if len(s) > 0: | |
events = [] | |
for index in list(s): | |
events.append(event_ids[index]) | |
return events | |
else: | |
return None | |
# this is where we easily paste in our NE and SW coordinates from Google Maps | |
quickBox(32.953848, -96.611259, 32.647951, -96.998527) | |
# notice the odd ordering of lat/lon values Twitter uses -- lower left *and then* upper right using lon, lat (versus lat, lon) | |
stream = api.request('statuses/filter', {'locations': str(swLon) +','+ str(swLat) +','+ str(neLon) +','+ str(neLat) }) | |
print "monitoring the box bounded by "+ str(neLat) +", "+ str(neLon) +" and "+ str(swLat) +", "+ str(swLon) +" ..." | |
for tweet in stream: | |
# verify the tweet has geo information (and a usable point-type coordinate pair) | |
if 'geo' in tweet: | |
if tweet['geo'] is not None: | |
if tweet['geo']['type'] == 'Point': | |
# get the tweet's coordinates | |
tweetLat = tweet['geo']['coordinates'][0] | |
tweetLon = tweet['geo']['coordinates'][1] | |
# sanity check to ensure the tweet is actually within our market bounding box | |
if tweetLat < neLat and tweetLat > swLat and tweetLon < neLon and tweetLon > swLon: | |
# analyze the tweet to see if it falls within any of our mock events | |
tweet_events = eventsTweetWithin(tweetLat, tweetLon) | |
if tweet_events is not None: | |
tweetText = removeLink(tweet['text']) | |
tweetUser = tweet['user']['screen_name'] | |
tweetMediaURL = extractMedia(tweet) | |
tweetProfilePicULR = tweet['user']['profile_image_url'] | |
# tweetUTC = parser.parse(tweet['created_at']) | |
print tweetUser +" is on-scene Event "+ str(tweet_events[0]) +" at "+ str(tweetLat) +", "+ str(tweetLon) + " "+ tweetText | |
if tweetMediaURL is not None: | |
print ' * '+ tweetMediaURL |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment