summaryrefslogtreecommitdiff
path: root/omegle/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'omegle/__init__.py')
-rw-r--r--omegle/__init__.py269
1 files changed, 269 insertions, 0 deletions
diff --git a/omegle/__init__.py b/omegle/__init__.py
new file mode 100644
index 0000000..528b629
--- /dev/null
+++ b/omegle/__init__.py
@@ -0,0 +1,269 @@
+import sys
+import httplib
+import socket
+import urllib
+import time
+import json
+import logging
+from threading import Thread, Lock, Event
+
+__all__ = ['OmegleChat', 'get_count']
+
+class Timer(Thread):
+ """
+ This class defines a object that calls the function object
+ given as func every given interval in a Thread and stops immedietly after
+ stop() has been called
+ """
+ def __init__(self,func,interval=0.50):
+ Thread.__init__(self)
+ self.logger = logging.getLogger(__name__ + "." + self.__class__.__name__)
+ self.func = func
+ self.interval = interval
+
+ self.running = False
+
+ self.event = Event()
+
+ def run(self):
+ self.running = True
+ while self.running:
+ self.func()
+ self.event.wait(self.interval)
+ self.event.clear()
+ self.logger.debug("self.running == False")
+
+ def stop(self):
+ """ XXX break func() ? """
+ self.running = False
+ self.event.set()
+
+class RESTClient(object):
+ """Some routines used for calling the webservice"""
+ headers = {
+ "Content-type": "application/x-www-form-urlencoded; charset=utf-8",
+ "Accept": "application/json"
+ }
+ def __init__(self,host,http_debuglevel=0):
+ self.host=host
+ self.conn_lock = Lock()
+ self.conn = httplib.HTTPConnection(host)
+ self.conn.set_debuglevel(http_debuglevel)
+
+ def request(self,method,path,params):
+ self.conn_lock.acquire()
+ try:
+ headers = RESTClient.headers.copy()
+ headers['Host'] = self.host
+ headers['Content-Length'] = str(len(params))
+ self.conn.request(method,path,params,headers)
+ resp = self.conn.getresponse()
+ finally:
+ self.conn_lock.release()
+ return resp
+
+
+class OmegleChat(RESTClient):
+ def __init__(self,poll_interval=0.5,name="",host="omegle.com"):
+ self.name = name
+ self.poll_interval=poll_interval
+ RESTClient.__init__(self,host)
+
+ self.timer = Timer(self._events, poll_interval)
+ self.logger = logging.getLogger(__name__ + "." + self.__class__.__name__ + name)
+ self.is_confirmed = False #after getting a connection confirm
+ self.is_connected = False #after having self.id
+
+ def start(self):
+ """Starts a chat session. You have to wait until
+ is_confirmed is set (or use on_connect)"""
+ self.logger.debug("/start host=%s" % self.host)
+ if self.is_connected:
+ self.logger.error("Already connected")
+ raise Exception("Already connected")
+ resp = RESTClient.request(self, "POST", "/start", {})
+ body=resp.read()
+ id=body.split("\"")
+ if id.__len__() == 3:
+ self.id = id[1]
+ self.logger.info("Connected id=%s" % self.id)
+ #start /events polling
+ self.is_connected = True
+ self.timer = Timer(self._events, self.poll_interval)
+ self.timer.start()
+ else:
+ self.logger.error("Bad response: %s" % body)
+ raise Exception("Bad response: %s" % body)
+
+ def disconnect(self):
+ """Close a chat session."""
+ self.logger.debug("disconnect()")
+ self.is_confirmed = False
+ self.timer.stop()
+ if self.is_connected:
+ r = RESTClient.request(self,"POST", "/disconnect", urllib.urlencode({'id': self.id}))
+ body = r.read()
+ self.logger.debug("/disconnect sent. Read: %s" % body)
+ if body == "win":
+ self.is_connected = False
+ self.id = None
+ self.conn.close()
+ else:
+ raise Exception("/disconnect; Bad response: %s" % body)
+
+ def _events(self):
+ """does use its own "HTTPConnection" because its called async from a thread"""
+ conn = httplib.HTTPConnection(self.host)
+ params = urllib.urlencode({'id' : self.id})
+ headers = OmegleChat.headers.copy()
+ headers['Host'] = "omegle.com"
+ headers['Content-Length'] = str(len(params))
+ conn.request("POST",
+ "/events",
+ params,
+ OmegleChat.headers)
+ r=conn.getresponse()
+ body=r.read()
+ self._dispatch_event(conn,body)
+ conn.close()
+
+ def send(self,msg):
+ """Send a message to the Stranger
+ Arguments:
+ msg -- the message - in utf8
+ """
+ #if a raw string given, assume its utf8
+ if msg.__class__ == str:
+ try:
+ msg = msg.decode("utf8")
+ except UnicodeDecodeError:
+ pass
+ #convert utf8 to RAW-utf8
+ try:
+ msg = msg.encode("utf8")
+ except UnicodeEncodeError,e:
+ self.logger.critical(e)
+
+ if not self.is_confirmed:
+ self.logger.error("Cant send message if not is_confirmed")
+ return ###XXX raise??
+
+ params = {'id':self.id,'msg':msg}
+ params = urllib.urlencode(params)
+ try:
+ r = RESTClient.request(self,"POST","/send",params)
+ except Exception,e:
+ self.logger.error("Error by /send request: %s" % e)
+ raise e
+ return
+
+ body = r.read()
+ if body != "win":
+ self.logger.error("/send; Bad response %s" % body)
+ raise Exception("/send; Bad response %s" % body)
+
+ def typing(self):
+ """Notify the Stranger that youre typing a message"""
+ r = RESTClient.request(self, "POST", "/typing", urllib.urlencode({'id':self.id}))
+ body = r.read()
+ if body != "win":
+ self.logger.error("/typing; Bad response %s" % body)
+ raise Exception("/typing; Bad response %s" % body)
+
+ def stopped_typing(self):
+ """Notify the Stranger that youre stopped typing"""
+ r = RESTClient.request(self, "POST", "/stoppedtyping", urllib.urlencode({'id':self.id}))
+ body = r.read()
+ if body != "win":
+ self.logger.error("/stoppedtyping; Bad response %s" % body)
+ raise Exception("/stoppedtyping; Bad response %s" % body)
+
+ def _dispatch_event(self,conn,body):
+ try:
+ data_set=json.read(body.decode("utf8"))
+ if not data_set:
+ self.on_idle()
+ return
+ for data in data_set:
+ if not self.is_connected: #in case of disconnect
+ break #stop dispatching messages
+ if data[0] == "typing":
+ self.on_typing()
+ elif data[0] == "gotMessage" and data.__len__() == 2:
+ self.on_message(data[1])
+ elif data[0] == "connected":
+ self.is_confirmed = True
+ self.on_connect()
+ elif data[0] == "strangerDisconnected":
+ self.is_confirmed = False
+ self.is_connected = False
+ self.timer.stop()
+ self.on_disconnect()
+ elif data[0] == "stoppedTyping":
+ self.on_stopped_typing()
+ elif data[0] == "waiting":
+ self.on_wait()
+ else:
+ self.logger.error("Unknown JSON Data: %s" % body)
+ except json.ReadException:
+ self.logger.error("Json ReadException. Body: %s" % body)
+
+ def on_idle(self):
+ self.logger.debug("event: no data received")
+ def on_message(self,message):
+ """To be overwritten"""
+ self.logger.info("<<< %s" % message)
+ def on_connect(self):
+ """To be overwritten"""
+ self.logger.info("Connection confirmed")
+ def on_typing(self):
+ """To be overwritten"""
+ self.logger.info("Stranger is typing")
+ def on_stopped_typing(self):
+ """To be overwritten"""
+ self.logger.info("Stranger stopped typing")
+ def on_disconnect(self):
+ """To be overwritten"""
+ self.logger.info("Stranger Disconnectet")
+ def on_wait(self):
+ """To be overwritten"""
+ self.logger.info("Server sent [\"waiting\"]")
+
+def get_count(host="omegle.com"):
+ """Return the number of current online omegle users"""
+ headers = {
+ "Host" : host,
+ "Content-type": "application/x-www-form-urlencoded; charset=utf-8",
+ "Accept": "application/json"}
+ conn = httplib.HTTPConnection(host)
+ conn.request("GET",
+ "/count",
+ urllib.urlencode({}),
+ headers)
+ body = conn.getresponse().read()
+ conn.close()
+ return body
+
+if __name__ == "__main__":
+ """Extrem einfacher Chat-Client"""
+ logging.basicConfig(level=logging.INFO)
+ print "Lets chat. Type \"quit\" to disconnect"
+ chat = OmegleChat()
+ def exit():
+ OmegleChat.on_disconnect(chat)
+ sys.exit(0)
+ chat.on_disconnect = exit
+ chat.start()
+ while 1==1:
+ try:
+ cmd=sys.stdin.readline().strip()
+ except KeyboardInterrupt:
+ chat.disconnect()
+ break
+ if cmd=="quit":
+ chat.disconnect()
+ break
+ else:
+ print ">>> %s" % cmd
+ chat.send(cmd)
+