Преглед на файлове

ported afc_report to wikitools and cleaned it up massively; added creator() method to Page; safety check in functions._get_site_object_from_dict()

tags/v0.1^2
Ben Kurtovic преди 13 години
родител
ревизия
d207baaee2
променени са 3 файла, в които са добавени 104 реда и са изтрити 79 реда
  1. +66
    -71
      bot/commands/afc_report.py
  2. +5
    -1
      bot/wiki/functions.py
  3. +33
    -7
      bot/wiki/page.py

+ 66
- 71
bot/commands/afc_report.py Целия файл

@@ -1,92 +1,87 @@
# -*- coding: utf-8 -*-

import json
import re
import urllib

from classes import BaseCommand
import wiki

class Command(BaseCommand):
"""Get information about an AFC submission by name."""
name = "report"

def process(self, data):
self.site = wiki.get_site()
self.data = data

if not data.args:
self.connection.reply(data, "what submission do you want me to give information about?")
msg = "what submission do you want me to give information about?"
self.connection.reply(data, msg)
return

pagename = ' '.join(data.args)
pagename = pagename.replace("http://en.wikipedia.org/wiki/", "").replace("http://enwp.org/", "").replace("_", " ")
pagename = pagename.strip()

if self.page_exists(pagename): # given '!report Foo', first try [[Foo]]
self.report(pagename)
else: # if that doesn't work, try [[Wikipedia:Articles for creation/Foo]]
if self.page_exists("Wikipedia:Articles for creation/" + pagename):
self.report("Wikipedia:Articles for creation/" + pagename)
else: # if that doesn't work, try [[Wikipedia talk:Articles for creation/Foo]]
if self.page_exists("Wikipedia talk:Articles for creation/" + pagename):
self.report("Wikipedia talk:Articles for creation/" + pagename)
else:
self.connection.reply(data, "submission \x0302{0}\x0301 not found.".format(pagename))

def report(self, pagename):
title = ' '.join(data.args)
title = title.replace("http://en.wikipedia.org/wiki/", "")
title = title.replace("http://enwp.org/", "").strip()

# Given '!report Foo', first try [[Foo]]:
if self.report(title):
return

# Then try [[Wikipedia:Articles for creation/Foo]]:
title2 = "".join(("Wikipedia:Articles for creation/", title))
if self.report(title2):
return

# Then try [[Wikipedia talk:Articles for creation/Foo]]:
title3 = "".join(("Wikipedia talk:Articles for creation/", title))
if self.report(title3):
return

msg = "submission \x0302{0}\x0301 not found.".format(title)
self.connection.reply(data, msg)

def report(self, title):
data = self.data
shortname = pagename.replace("Wikipedia:Articles for creation/", "").replace("Wikipedia talk:Articles for creation/", "")
url = "http://enwp.org/" + urllib.quote(pagename.replace(" ", "_"))
status = self.get_status(pagename)
user, user_url = self.get_creator(pagename)

self.connection.reply(data, "AfC submission report for \x0302{0}\x0301 ({1}):".format(shortname, url))
self.connection.say(data.chan, "Status: \x0303{0}\x0301".format(status))
if status == "accepted": # the first edit will be the redirect [[WT:AFC/Foo]] -> [[Foo]], NOT the creation of the submission
self.connection.say(data.chan, "Reviewed by \x0302{0}\x0301 ({1})".format(user, user_url))
else:
self.connection.say(data.chan, "Submitted by \x0302{0}\x0301 ({1})".format(user, user_url))
def page_exists(self, pagename):
params = {'action': 'query', 'format': 'json', 'titles': pagename}
data = urllib.urlencode(params)
raw = urllib.urlopen("http://en.wikipedia.org/w/api.php", data).read()
res = json.loads(raw)
try:
res['query']['pages'].values()[0]['missing'] # this key will appear if the page does not exist
return False
except KeyError: # if it's not there, the page exists
return True
def get_status(self, pagename):
params = {'action': 'query', 'prop': 'revisions', 'rvprop':'content', 'rvlimit':'1', 'format': 'json'}
params['titles'] = pagename
data = urllib.urlencode(params)
raw = urllib.urlopen("http://en.wikipedia.org/w/api.php", data).read()
res = json.loads(raw)
pageid = res['query']['pages'].keys()[0]
content = res['query']['pages'][pageid]['revisions'][0]['*']
lcontent = content.lower()
if re.search("\{\{afc submission\|r\|(.*?)\}\}", lcontent):
page = self.site.get_page(title, follow_redirects=False)
if not page.exists()[0]:
return
url = page.url().replace("en.wikipedia.org/wiki", "enwp.org")
short = re.sub(r"wikipedia( talk)?:articles for creation/", "", title,
re.IGNORECASE)
status = self.get_status(page)
user = self.site.get_user(page.creator())
user_name = user.name()
user_url = user.get_userpage().url()
msg1 = "AfC submission report for \x0302{0}\x0301 ({1}):"
msg2 = "Status: \x0303{0}\x0301"
msg3 = "Submitted by \x0302{0}\x0301 ({1})"
if status == "accepted"
msg3 = "Reviewed by \x0302{0}\x0301 ({1})"
self.connection.reply(data, msg1.format(short, url))
self.connection.say(data.chan, msg2.format(status))
self.connection.say(data.chan, msg3.format(user_name, user_url))
return True
def get_status(self, page):
content = page.get()
if page.is_redirect():
target = page.get_redirect_target()
if self.site.get_page(target).namespace() == 0:
return "accepted"
return "redirect"
if re.search("\{\{afc submission\|r\|(.*?)\}\}", content, re.I):
return "being reviewed"
elif re.search("\{\{afc submission\|\|(.*?)\}\}", lcontent):
if re.search("\{\{afc submission\|\|(.*?)\}\}", content, re.I):
return "pending"
elif re.search("\{\{afc submission\|d\|(.*?)\}\}", lcontent):
if re.search("\{\{afc submission\|d\|(.*?)\}\}", content, re.I):
regex = "\{\{afc submission\|d\|(.*?)(\||\}\})"
try:
reason = re.findall("\{\{afc submission\|d\|(.*?)(\||\}\})", lcontent)[0][0]
return "declined with reason \"{0}\"".format(reason)
reason = re.findall(regex, content, re.I)[0][0]
except IndexError:
return "declined"
else:
if "#redirect" in content:
return "accepted"
else:
return "unkown"

def get_creator(self, pagename):
params = {'action': 'query', 'prop': 'revisions', 'rvprop': 'user', 'rvdir': 'newer', 'rvlimit': '1', 'format': 'json'}
params['titles'] = pagename
data = urllib.urlencode(params)
raw = urllib.urlopen("http://en.wikipedia.org/w/api.php", data).read()
res = json.loads(raw)
user = res['query']['pages'].values()[0]['revisions'][0]['user']
user_url = "http://enwp.org/User_talk:" + urllib.quote(user.replace(" ", "_"))
return user, user_url
return "declined with reason \"{0}\"".format(reason)
return "unkown"

+ 5
- 1
bot/wiki/functions.py Целия файл

@@ -90,7 +90,11 @@ def _get_site_object_from_dict(name, d):

for key, value in namespaces.items(): # Convert string keys to integers
del namespaces[key]
namespaces[int(key)] = value
try:
namespaces[int(key)] = value
except ValueError: # Data is broken, ignore it
namespaces = None
break

return Site(name=name, project=project, lang=lang, base_url=base_url,
article_path=article_path, script_path=script_path, sql=sql,


+ 33
- 7
bot/wiki/page.py Целия файл

@@ -20,6 +20,7 @@ class Page(object):
url -- returns the page's URL
namespace -- returns the page's namespace as an integer
protection -- returns the page's current protection status
creator -- returns the page's creator (first user to edit)
is_talkpage -- returns True if the page is a talkpage, else False
is_redirect -- returns True if the page is a redirect, else False
toggle_talk -- returns a content page's talk page, or vice versa
@@ -51,6 +52,7 @@ class Page(object):
self._protection = None
self._fullurl = None
self._content = None
self._creator = None

# Try to determine the page's namespace using our site's namespace
# converter:
@@ -122,15 +124,17 @@ class Page(object):
"""Loads various data from the API in a single query.

Loads self._title, ._exists, ._is_redirect, ._pageid, ._fullurl,
._protection, ._namespace, ._is_talkpage, and ._lastrevid using the
API. It will do a query of its own unless `result` is provided, in
which case we'll pretend `result` is what the query returned.
._protection, ._namespace, ._is_talkpage, ._creator, and ._lastrevid
using the API. It will do a query of its own unless `result` is
provided, in which case we'll pretend `result` is what the query
returned.

Assuming the API is sound, this should not raise any exceptions.
"""
if result is None:
params = {"action": "query", "prop": "info", "titles": self._title,
"inprop": "protection|url"}
params = {"action": "query", "rvprop": "user", "rvdir": "newer",
"prop": "info|revisions", "rvlimit": 1,
"titles": self._title, "inprop": "protection|url"}
result = self._site._api_query(params)

res = result["query"]["pages"].values()[0]
@@ -169,9 +173,10 @@ class Page(object):
self._namespace = res["ns"]
self._is_talkpage = self._namespace % 2 == 1 # talkpages have odd IDs

# This last field will only be specified if the page exists:
# These last two fields will only be specified if the page exists:
self._lastrevid = res.get("lastrevid")
try:
self._lastrevid = res["lastrevid"]
self._creator = res['revisions'][0]['user']
except KeyError:
pass

@@ -287,6 +292,27 @@ class Page(object):
self._force_validity() # invalid pages cannot be protected
return self._protection

def creator(self, force=False):
"""Returns the page's creator (i.e., the first user to edit the page).

Makes an API query if force is True or if we haven't already made one.
Normally, we can get the creator along with everything else (except
content) in self._load_attributes(). However, due to a limitation in
the API (can't get the editor of one revision and the content of
another at both ends of the history), if our other attributes were only
loaded from get(), we'll have to do another API query. This is done
by calling ourselves again with force=True.

Raises InvalidPageError or PageNotFoundError if the page name is
invalid or the page does not exist, respectively.
"""
if self._exists == 0 or force:
self._load_wrapper()
self._force_existence()
if not self._creator and not force:
self.creator(force=True)
return self._creator

def is_talkpage(self, force=False):
"""Returns True if the page is a talkpage, else False.



Зареждане…
Отказ
Запис