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