Skip to content

Instantly share code, notes, and snippets.

@rice2007
Created September 26, 2014 06:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rice2007/b68c6631bfa64a3ceee8 to your computer and use it in GitHub Desktop.
Save rice2007/b68c6631bfa64a3ceee8 to your computer and use it in GitHub Desktop.
import base64
import hmac
import json
import requests
import time
import urllib
import os
from hashlib import sha1
from hashlib import md5
def parse_time(timestr):
format = "%Y-%m-%d %H:%M:%S"
return time.mktime(time.strptime(timestr, format))
class Location:
def __init__(self, latitude, longitude, delta=None):
self.latitude = latitude
self.longitude = longitude
if delta is None:
delta = "0.030000"
self.delta = delta
def __str__(self):
return "Location(%s, %s)" % (self.latitude, self.longitude)
class PeekLocation:
def __init__(self, raw):
self.id = raw['peekID']
self.can_submit = bool(raw['canSubmit'])
self.name = raw['location']
lat = raw['latitude']
lon = raw['longitude']
d = raw['delta']
self.location = Location(lat, lon, d)
class Comment:
def __init__(self, raw, message_id, client):
self.client = client
self.message_id = message_id
self.comment_id = raw["commentID"]
self.comment = raw["comment"]
self.time = parse_time(raw["time"])
self.likes = int(raw["numberOfLikes"])
self.poster_id = raw["posterID"]
self.liked = int(raw["liked"])
self.message_id = self.message_id.replace('\\', '')
def upvote(self):
if self.liked == 0:
self.likes += 1
self.liked += 1
return self.client.upvote_comment(self.comment_id)
def downvote(self):
if self.liked == 0:
self.likes -= 1
self.liked -= 1
return self.client.downvote_comment(self.comment_id)
def report(self):
return self.client.report_comment(self.comment_id, self.message_id)
def delete(self):
if self.poster_id == self.client.id:
return self.client.delete_comment(self.comment_id, self.message_id)
def reply(self, comment):
return self.client.post_comment(self.message_id, comment)
def print_comment(self):
my_action = ""
if self.liked > 0:
my_action = "^"
elif self.liked < 0:
my_action = "v"
print "%s(%s) %s" % (my_action, self.likes, self.comment)
class Yak:
def __init__(self, raw, client):
self.client = client
self.poster_id = raw["posterID"]
self.hide_pin = bool(int(raw["hidePin"]))
self.message_id = raw["messageID"]
self.delivery_id = raw["deliveryID"]
self.longitude = raw["longitude"]
self.comments = int(raw["comments"])
self.time = parse_time(raw["time"])
self.latitude = raw["latitude"]
self.likes = int(raw["numberOfLikes"])
self.message = raw["message"]
self.type = raw["type"]
self.liked = int(raw["liked"])
self.reyaked = raw["reyaked"]
#Yaks don't always have a handle
try:
self.handle = raw["handle"]
except KeyError:
self.handle = None
#For some reason this seems necessary
self.message_id = self.message_id.replace('\\', '')
def upvote(self):
if self.liked == 0:
self.liked += 1
self.likes += 1
return self.client.upvote_yak(self.message_id)
def downvote(self):
if self.liked == 0:
self.liked -= 1
self.likes -= 1
return self.client.downvote_yak(self.message_id)
def report(self):
return self.client.report_yak(self.message_id)
def delete(self):
if self.poster_id == self.client.id:
return self.client.delete_yak(self.message_id)
def add_comment(self, comment):
return self.client.post_comment(self.message_id, comment)
def get_comments(self):
return self.client.get_comments(self.message_id)
def print_yak(self):
if self.handle is not None:
print "%s:" % self.handle
print self.message
print "%s likes, %s comments. posted %s at %s %s" % (self.likes, self.comments, self.time, self.latitude, self.longitude)
class Yakker:
base_url = "http://yikyakapp.com/api/"
user_agent = "android-async-http/1.4.4 (http://loopj.com/android-async-http)"
def __init__(self, user_id=None, location=None, force_register=False):
if location is None:
location = Location('0', '0')
self.update_location(location)
if user_id is None:
user_id = self.gen_id()
self.register_id_new(user_id)
elif force_register:
self.register_id_new(user_id)
self.id = user_id
self.handle = None
#self.update_stats()
def gen_id(self):
return md5(os.urandom(128)).hexdigest().upper()
def register_id_new(self, id):
params = {
"userID": id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
result = self.get("registerUser", params)
return result
def sign_request(self, page, params):
key = "35FD04E8-B7B1-45C4-9886-94A75F4A2BB4"
#The salt is just the current time in seconds since epoch
salt = str(int(time.time()))
#The message to be signed is essentially the request, with parameters sorted
msg = "/api/" + page
sorted_params = params.keys()
sorted_params.sort()
if len(params) > 0:
msg += "?"
for param in sorted_params:
msg += "%s=%s&" % (param, params[param])
#Chop off last "&"
if len(params) > 0:
msg = msg[:-1]
#the salt is just appended directly
msg += salt
#Calculate the signature
h = hmac.new(key, msg, sha1)
hash = base64.b64encode(h.digest())
return hash, salt
def get(self, page, params):
url = self.base_url + page
hash, salt = self.sign_request(page, params)
params['hash'] = hash
params['salt'] = salt
headers = {
"User-Agent": self.user_agent,
"Accept-Encoding": "gzip",
}
return requests.get(url, params=params, headers=headers)
def post(self, page, params):
url = self.base_url + page
hash, salt = self.sign_request(page, params)
getparams = {'hash': hash, 'salt': salt}
headers = {
"User-Agent": self.user_agent,
"Accept-Encoding": "gzip",
}
return requests.post(url, data=params, params=getparams, headers=headers)
def get_yak_list(self, page, params):
return self.parse_yaks(self.get(page, params).text)
def parse_yaks(self, text):
try:
raw_yaks = json.loads(text)["messages"]
except:
raw_yaks = []
yaks = []
for raw_yak in raw_yaks:
yaks.append(Yak(raw_yak, self))
return yaks
def parse_comments(self, text, message_id):
try:
raw_comments = json.loads(text)["comments"]
except:
raw_comments = []
comments = []
for raw_comment in raw_comments:
comments.append(Comment(raw_comment, message_id, self))
return comments
def contact(self, message):
params = {
"userID": self.id,
"message": message
}
return self.get("contactUs", params)
def upvote_yak(self, message_id):
params = {
"userID": self.id,
"messageID": message_id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get("likeMessage", params)
def downvote_yak(self, message_id):
params = {
"userID": self.id,
"messageID": message_id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get("downvoteMessage", params)
def upvote_comment(self, comment_id):
params = {
"userID": self.id,
"commentID": comment_id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get("likeComment", params)
def downvote_comment(self, comment_id):
params = {
"userID": self.id,
"commentID": comment_id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get("downvoteComment", params)
def report_yak(self, message_id):
params = params = {
"userID": self.id,
"messageID": message_id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get("reportMessage", params)
def delete_yak(self, message_id):
params = params = {
"userID": self.id,
"messageID": message_id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get("deleteMessage2", params)
def report_comment(self, comment_id, message_id):
params = {
"userID": self.id,
"commentID": comment_id,
"messageID": message_id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get("reportMessage", params)
def delete_comment(self, comment_id, message_id):
params = {
"userID": self.id,
"commentID": comment_id,
"messageID": message_id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get("deleteComment", params)
def get_greatest(self):
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get_yak_list("getGreatest", params)
def get_my_tops(self):
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get_yak_list("getMyTops", params)
def get_recent_replied(self):
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get_yak_list("getMyRecentReplies", params)
def update_location(self, location):
self.location = location
def get_my_recent_yaks(self):
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get_yak_list("getMyRecentYaks", params)
def get_area_tops(self):
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get_yak_list("getAreaTops", params)
def get_yaks(self):
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.get_yak_list("getMessages", params)
def post_yak(self, message, showloc=False, handle=False):
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
"message": message,
}
if not showloc:
params["hidePin"] = "1"
if handle and (self.handle is not None):
params["hndl"] = self.handle
return self.post("sendMessage", params)
def get_comments(self, message_id):
params = {
"userID": self.id,
"messageID": message_id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.parse_comments(self.get("getComments", params).text, message_id)
def post_comment(self, message_id, comment):
params = {
"userID": self.id,
"messageID": message_id,
"comment": comment,
"lat": self.location.latitude,
"long": self.location.longitude,
}
return self.post("postComment", params)
def get_peek_locations(self):
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
data = self.get("getMessages", params).json()
peeks = []
for peek_json in data['otherLocations']:
peeks.append(PeekLocation(peek_json))
return peeks
def get_featured_locations(self):
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
data = self.get("getMessages", params).json()
peeks = []
for peek_json in data['featuredLocations']:
peeks.append(PeekLocation(peek_json))
return peeks
def get_yakarma(self):
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
}
data = self.get("getMessages", params).json()
return int(data['yakarma'])
def peek(self, peek_id):
if isinstance(peek_id, PeekLocation):
peek_id = peek_id.id
params = {
"userID": self.id,
"lat": self.location.latitude,
"long": self.location.longitude,
'peekID': peek_id,
}
return self.get_yak_list("getPeekMessages", params)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment