Skip to content

Instantly share code, notes, and snippets.

@bergie
Created April 7, 2010 15:56
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 bergie/359045 to your computer and use it in GitHub Desktop.
Save bergie/359045 to your computer and use it in GitHub Desktop.
import network, util
from util import exceptions
from gettext import lgettext as _
PROTOCOL_INFO = {
"name": "Qaiku",
"version": "1.0",
"config": [
"private:password",
"username",
"color",
"receive_enabled",
"send_enabled",
],
"authtype": "login",
"color": "#729FCF",
"features": [
"send",
"receive",
"reply",
"responses",
"thread",
"send_thread",
"user_messages",
],
"default_streams": [
"receive",
"responses",
],
}
URL_PREFIX = "http://www.qaiku.com"
class Client:
def __init__(self, acct):
self.account = acct
def _common(self, data):
m = {};
m["id"] = str(data["id"])
m["protocol"] = "qaiku"
m["account"] = self.account["_id"]
m["time"] = util.parsetime(data["created_at"])
m["text"] = data["text"]
m["to_me"] = ("@%s" % self.account["username"]) in data["text"]
m["html"] = data["html"]
# TODO: Change Qaiku's @-links to people to Gwibber-internal ones
m["content"] = data["html"]
if (data["external_url"]):
# Qaiku posts can have external links in them, display that under the message
m["content"] += "<p><a href=\"" + data["external_url"] + "\">" + data["external_url"] + "</a></p>"
# TODO: Display picture Qaikus
if "channel" in data and data["channel"]:
# Put message's Qaiku channel as "source" so it will be displayed in the UI
m["source"] = "<a href=\"http://www.qaiku.com/channels/show/" + data["channel"] + "/\">#" + data["channel"] + "</a>"
if "in_reply_to_status_id" in data and data["in_reply_to_status_id"]:
m["reply"] = {}
m["reply"]["id"] = data["in_reply_to_status_id"]
m["reply"]["nick"] = data["in_reply_to_screen_name"]
m["reply"]["url"] = data["in_reply_to_status_url"]
return m
def _message(self, data):
m = self._common(data)
user = data["user"]
img = user["profile_image_url"]
m["sender"] = {}
m["sender"]["name"] = user["name"]
m["sender"]["nick"] = user["screen_name"]
m["sender"]["id"] = user["id"]
m["sender"]["location"] = user.get("location", "")
m["sender"]["followers"] = user["followers_count"]
m["sender"]["image"] = "/".join((URL_PREFIX, img)) if img[0] == "/" else img
m["sender"]["url"] = user["url"]
m["sender"]["is_me"] = m["sender"]["nick"] == self.account["username"]
m["url"] = "/".join((m["sender"]["url"], "show", m["id"]))
return m
def _get(self, path, parse="message", post=False, single=False, **args):
url = "/".join((URL_PREFIX, "api", path))
url += ("&" if "?" in url else "?") + "apikey=%s" % self.account["password"]
data = network.Download(url, util.compact(args) or None, post).get_json()
# error we'll have to assume failed auth, qaiku returns an html page on failure
try:
if single: return [getattr(self, "_%s" % parse)(data)]
if parse: return [getattr(self, "_%s" % parse)(m) for m in data]
else: return []
except:
raise exceptions.GwibberProtocolError("auth", self.account["protocol"], self.account["username"], data)
def __call__(self, opname, **args):
return getattr(self, opname)(**args)
def receive(self):
return self._get("statuses/friends_timeline.json")
def user_messages(self, id=None):
return self._get("statuses/user_timeline.json", screen_name=id)
def responses(self):
return self._get("statuses/mentions.json")
def send(self, message):
return self._get("statuses/update.json", post=True, single=True, status=message, source='gwibbernet')
def send_thread(self, message, target):
recipient = target.get("reply_id", 0) or target.get("id", 0)
return self._get("statuses/update.json", post=True, single=True,
status=message, in_reply_to_status_id=recipient, source='gwibbernet')
"""
NICK_PARSE = re.compile("\B@([A-Za-z0-9_]+|@[A-Za-z0-9_]$)")
HASH_PARSE = re.compile("\B#([A-Za-z0-9_\-]+|@[A-Za-z0-9_\-]$)")
class Message:
def __init__(self, client, data):
self.client = client
self.account = client.account
self.protocol = client.account["protocol"]
self.username = client.account["username"]
self.id = data["id"] or ''
self.time = support.parse_time(data["created_at"])
self.is_private = False
user = data["user"]
#self.reply_nick = data["in_reply_to_user_id"]
self.reply_url = "http://qaiku.com/home/%s/show/%s" % (user["screen_name"], data["id"])
self.reply_id = data["in_reply_to_status_id"]
self.bgcolor = "comment_color" if self.reply_id else "message_color"
self.sender = user["name"]
self.sender_nick = user["screen_name"]
self.sender_id = user["id"]
self.sender_location = user["location"]
self.sender_followers_count = user["followers_count"]
self.image = "http://qaiku.com/" + user["profile_image_url"] if user["profile_image_url"].startswith("/") else user["profile_image_url"]
self.url = "http://qaiku.com/home/%s/show/%s" % (user["screen_name"], data["id"])
self.profile_url = "gwibber:user/%s/%s" % (self.account.id, user["screen_name"])
self.external_profile_url = user["url"]
self.text = data["text"]
self.html_string = '<span class="text">%s</span>' % \
HASH_PARSE.sub('#<a class="inlinehash" href="gwibber:tag/\\1">\\1</a>',
NICK_PARSE.sub('@<a class="inlinenick" href="gwibber:user/'+self.account.id+'/\\1">\\1</a>',
support.linkify(self.text)))
self.is_reply = True if re.compile("@%s[\W]+|@%s$" % (self.username, self.username)).search(self.text) else False
self.can_thread = True
class Client:
def __init__(self, acct):
self.account = acct
def send_enabled(self):
return self.account["send_enabled"] and \
self.account["username"] != None and \
self.account["private:apikey"] != None
def receive_enabled(self):
return self.account["receive_enabled"] and \
self.account["username"] != None and \
self.account["private:apikey"] != None
def connect(self, url, data = None):
url += "&" if "?" in url else "?"
url += urllib.urlencode({'apikey': self.account['private:apikey']})
return urllib2.urlopen(urllib2.Request("http://www.qaiku.com/api" + url, data))
def get_messages(self):
return simplejson.load(self.connect("/statuses/friends_timeline.json"))
def get_user_messages(self, screen_name):
return simplejson.load(self.connect("/statuses/user_timeline.json" +'?'+
urllib.urlencode({"screen_name": screen_name})))
def get_search_data(self, query):
return simplejson.load(self.connect("/search.json?" +
urllib.urlencode({"q": query})))
def get_thread_data(self, msg):
return simplejson.load(self.connect(
"/statuses/replies/%s.json" % msg["reply_id"] or msg["id"]))
def get_message_data(self, id):
return simplejson.load(self.connect(
"/statuses/show/%s.json" % id))
def thread(self, msg):
yield Message(self, self.get_message_data(msg["reply_id"] or msg["id"]))
for data in self.get_thread_data(msg):
yield Message(self, data)
def get_replies(self):
return simplejson.load(self.connect("/statuses/mentions.json"))
def responses(self):
for data in self.get_replies():
yield Message(self, data)
def search(self, query):
for data in self.get_search_data(query):
if "user" in data:
yield Message(self, data)
def receive(self):
for data in self.get_messages():
if "user" in data:
yield Message(self, data)
def user_messages(self, screen_name):
for data in self.get_user_messages(screen_name):
yield Message(self, data)
def delete(self, message):
return simplejson.load(self.connect(
"/statuses/destroy/%s.json" % message.id, ""))
def send(self, message):
data = simplejson.load(self.connect("/statuses/update.json",
urllib.urlencode({"status":message})))
return Message(self, data)
def send_thread(self, message, target):
data = simplejson.load(self.connect("/statuses/update.json",
urllib.urlencode({"status":message,
"in_reply_to_status_id": target["reply_id"] or target["id"]})))
return Message(self, data)
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment