http://www.mediawiki.org/wiki/Special:Code/MediaWiki/96672

Revision: 96672
Author:   awjrichards
Date:     2011-09-09 17:31:59 +0000 (Fri, 09 Sep 2011)
Log Message:
-----------
Adding better identica support including statusnet library; added support for 
multiple channels, fancy author and title maps, and more useful exception 
output with sys.exc_info in bot; updated documented dependencies to include 
simplejson; Most of this work was done by someone else (werdna?) - I just did 
some cleanup and am adding changes to svn

Modified Paths:
--------------
    trunk/tools/adminlogbot/README
    trunk/tools/adminlogbot/adminlog.py
    trunk/tools/adminlogbot/adminlogbot.py

Added Paths:
-----------
    trunk/tools/adminlogbot/statusnet.py

Modified: trunk/tools/adminlogbot/README
===================================================================
--- trunk/tools/adminlogbot/README      2011-09-09 17:31:37 UTC (rev 96671)
+++ trunk/tools/adminlogbot/README      2011-09-09 17:31:59 UTC (rev 96672)
@@ -1,5 +1,5 @@
 Dependencies: 
        mwclient: svn co 
http://mwclient.svn.sourceforge.net/viewvc/mwclient/trunk/mwclient/
        irclib: 
http://downloads.sourceforge.net/python-irclib/python-irclib-0.4.6.tar.gz?modtime=1135442433&big_mirror=0
+       simplejson: http://pypi.python.org/pypi/simplejson/
 
-

Modified: trunk/tools/adminlogbot/adminlog.py
===================================================================
--- trunk/tools/adminlogbot/adminlog.py 2011-09-09 17:31:37 UTC (rev 96671)
+++ trunk/tools/adminlogbot/adminlog.py 2011-09-09 17:31:59 UTC (rev 96672)
@@ -3,9 +3,12 @@
 user="More Bots"
 password="..."
 logname="Server admin log"
+identica_username="wikimediatech"
+identica_password="..."
 
 import mwclient
 import datetime
+import statusnet
 import re
 
 
months=["January","February","March","April","May","June","July","August","September","October","November","December"]
@@ -38,3 +41,9 @@
        else:
                lines.insert(position,logline)
        page.save('\n'.join(lines),"%s (%s)"%(message,author))
+
+       ## IDENTICA :D
+       snapi = statusnet.StatusNet( { 'user': identica_username, 'passwd': 
identica_password, 'api': 'https://identi.ca/api' } )
+       snupdate = "%s: %s" % (author, message)
+       snupdate = snupdate[:140] # Trim message
+       snapi.update(snupdate)

Modified: trunk/tools/adminlogbot/adminlogbot.py
===================================================================
--- trunk/tools/adminlogbot/adminlogbot.py      2011-09-09 17:31:37 UTC (rev 
96671)
+++ trunk/tools/adminlogbot/adminlogbot.py      2011-09-09 17:31:59 UTC (rev 
96672)
@@ -1,30 +1,44 @@
 import irclib
 import time
 import adminlog
+import sys
 
-target="#wikimedia-tech"
+targets=("#wikimedia-tech", "#wikimedia-operations")
 nickserv="nickserv"
-nickpassword="..."
+nick="nick"
+nickpassword="password"
+network="irc.freenode.net"
+port=6667
 
+authormap = { "TimStarling": "Tim", "_mary_kate_": "river", "yksinaisyyteni": 
"river", "flyingparchment": "river", "RobH": "RobH", "werdnum": "Andrew", 
"werdna": "Andrew", "werdnus": "Andrew", "aZaFred" : "Fred"  }
+titlemap = { "Andrew": "junior", "RoanKattouw": "Mr. Obvious", "RobH": "RobH", 
"notpeter": "and now dispaching a T1000 to your position to terminate you.", 
"domas": "o lord of the trolls, my master, my love. I can't live with out you; 
oh please log to me some more!" }
+
 def on_connect(con, event):
        con.privmsg(nickserv,"identify "+nickpassword)
        time.sleep(1)
-       con.join(target)
+       for target in targets:
+               con.join(target)
 
 def on_msg(con, event):
-       if event.target() != target: return
+       if event.target() not in targets: return
        author,rest=event.source().split('!')
+       if author in authormap: author=authormap[author]
        line=event.arguments()[0]
        if line.startswith("!log "):
                undef,message=line.split(" ",1);
-               try: adminlog.log(message,author)
-               except: server.privmsg(target,"I failed :(")
+               try: 
+                       adminlog.log(message,author)
+                       if author in titlemap: title = titlemap[author]
+                       else: title = "Master"
+                       server.privmsg(event.target(),"Logged the message, %s" 
% title)
+               except: print sys.exc_info()
                
 
 irc = irclib.IRC()
 server = irc.server()
-server.connect("irc.freenode.net",6667,"morebots")
+server.connect(network,port,nick)
 server.add_global_handler("welcome", on_connect)
 server.add_global_handler("pubmsg",on_msg)
 
 irc.process_forever()
+

Added: trunk/tools/adminlogbot/statusnet.py
===================================================================
--- trunk/tools/adminlogbot/statusnet.py                                (rev 0)
+++ trunk/tools/adminlogbot/statusnet.py        2011-09-09 17:31:59 UTC (rev 
96672)
@@ -0,0 +1,217 @@
+# LICENCE: GPL3
+import os.path
+import simplejson as json
+from select import select
+from subprocess import Popen, PIPE
+from sys import version_info
+
+if version_info[0] < 3:
+  from urllib import urlencode
+else:
+  from urllib.parse import urlencode
+
+def p_ready(p):
+  if p.poll() is not None or len(select([p.stdout], [], [], 0)[0]) > 0:
+    return True
+  else:
+    return False
+
+def success(data):
+  if 'error' in data:
+    return False
+  else:
+    return True
+
+def to_json(data):
+  try:
+    data = json.loads(str(data.decode('utf8')))
+    return data
+  except:
+    errstr = "<div class='error'>"
+
+    if version_info[0] == 3:
+      errstr = bytes(errstr, 'utf8')
+
+    if errstr in data:
+      error = data.replace(errstr, '')[:-6]
+      return {'error':error}
+    else:
+      return {'error':"unknown error"}
+
+class StatusNet:
+  def __init__(self, acc):
+    if type(acc) is dict:
+      self.acc = acc
+    else:
+      return None
+    self.source = 'python-statusnet'
+    self.ext = '.json'
+
+  def _request(self, path, params=None, post=None):
+    auth_str = ':'.join( (self.acc['user'], self.acc['passwd']) )
+
+    url = os.path.join(self.acc['api'], path)
+    url += self.ext
+    if params is not None:
+      url += "?"+urlencode(params)
+
+    cmd = ['curl', '-s', '-u', auth_str, url]
+
+    if post is not None and type(post) is dict:
+      cmd.append('-d')
+      cmd.append(urlencode(post))
+
+    return Popen(cmd, stdout=PIPE)
+
+  # account verification
+  def verify_creds(self):
+    return self._request("account/verify_credentials")
+
+  # notices
+  def get(self, notice_id):
+    return self._request("statuses/show/"+str(notice_id))
+
+  def update(self, status, replyid=None):
+    data = { 'status': status,
+             'in_reply_to_status_id': replyid,
+             'source': self.source }
+    if replyid is not None:
+      data['in_reply_to_status_id'] = replyid
+    return self._request("statuses/update", post=data)
+
+  def repeat(self, nid):
+    data = {'source': self.source}
+    return self._request("statuses/retweet/{0}".format(nid), post=data)
+
+  def delete(self, notice_id):
+    data = { 'id': notice_id }
+    return self._request("statuses/destroy/{0}".format(notice_id), post=data)
+
+  # direct messages
+  def direct(self, user, msg):
+    data = { 'screen_name': user 
+           , 'text': msg }
+    return self._request("direct_messages/new", post=data)
+
+# def delete_direct(self, acc, id):
+#   return self._request(acc, "direct_messages/destroy/"+str(id))
+
+  # timelines
+  def home(self, page=1, count=20):
+    data = { 'page': page
+           , 'count': count }
+    return self._request("statuses/friends_timeline", data)
+
+  def mentions(self, page=1, count=20, show_repeats=0):
+    data = { 'page': page
+           , 'count': count
+           , 'include_rts': show_repeats }
+    return self._request("statuses/mentions", data)
+
+  def user_tl(self, user, page=1, count=20, show_repeats=0):
+    data = { 'screen_name': user
+           , 'page': page
+           , 'count': count
+           , 'include_rts': show_repeats }
+    return self._request("statuses/user_timeline", data)
+
+  def inbox(self, page=1, count=20):
+    data = { 'page': page
+           , 'count': count }
+    return self._request("direct_messages", data)
+
+  def outbox(self, page=1, count=20):
+    data = { 'page': page
+           , 'count': count }
+    return self._request("direct_messages/sent", data)
+
+  def public(self, page=1, count=20):
+    data = { 'page': page
+           , 'count': count }
+    return self._request("statuses/public_timeline", data)
+
+  # friends + followers
+  def friends(self, user):
+    data = { 'screen_name': user }
+    return self._request("statuses/friends", data)
+
+  def followers(self, user):
+    data = { 'screen_name': user }
+    return self._request("statuses/followers", data)
+
+  # groups
+  def groups(self, user=None, page=1):
+    data = { 'page': page }
+    if user is not None:
+      data['screen_name'] = user
+    else:
+      data['screen_name'] = self.acc['user']
+    return self._request("statusnet/groups/list", data)
+
+  def group_tl(self, group, page=1, count=20):
+    data = { 'page': page
+           , 'count': count }
+    return self._request("statusnet/groups/timeline/"+group, data)
+
+  def group_join(self, group):
+    return self._request("statusnet/groups/join/"+group)
+
+  def group_leave(self, group):
+    return self._request("statusnet/groups/leave/"+group)
+
+  # subscriptions
+  def follow(self, user_id):
+    data = { 'user_id': user_id }
+    return self._request("friendships/create", post=data)
+
+  def unfollow(self, user_id):
+    data = { 'user_id': user_id }
+    return self._request("friendships/destroy", post=data)
+
+  # favorites
+  def favorites(self, user=None, page=1):
+    data = { 'page': page }
+    if user is not None:
+      return self._request("favorites/"+user, data)
+    else:
+      return self._request("favorites", data)
+
+  def favorite(self, notice_id):
+    data = { 'id': notice_id }
+    return self._request("favorites/create/"+str(notice_id), post=data)
+
+  def unfavorite(self, notice_id):
+    data = { 'id': notice_id }
+    return self._request("favorites/destroy/"+str(notice_id), post=data)
+
+  # blocks
+  def block(self, user_id):
+    data = { 'user_id': user_id }
+    return self._request("blocks/create", post=data)
+
+  def unblock(self, user_id):
+    data = { 'user_id': user_id }
+    return self._request("blocks/destroy", post=data)
+
+# def get_blocks(self, page=1):
+#   data = { "page": page }
+#   return self._request("blocks/blocking", data)
+
+  # searches
+  def search(self, query, page=1, count=20):
+    data = { 'q': query
+           , 'page': page
+           , 'count': count }
+    return self._request("search", data)
+
+  def tag_tl(self, tag, page=1, count=20):
+    data = { 'page': page
+           , 'count': count }
+    return self._request("statusnet/tags/timeline/"+tag, data)
+
+  # profile / config
+  def update_profile(self, data):
+    return self._request("account/update_profile", data)
+
+  def config(self):
+    return self._request("statusnet/config")


Property changes on: trunk/tools/adminlogbot/statusnet.py
___________________________________________________________________
Added: svn:eol-style
   + native


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to