ソースを参照

I can has page edit support?

tags/v0.1^2
Ben Kurtovic 12年前
コミット
ff9f6323eb
1個のファイルの変更89行の追加12行の削除
  1. +89
    -12
      bot/wiki/page.py

+ 89
- 12
bot/wiki/page.py ファイルの表示

@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-

from hashlib import md5
import re
from time import strftime
from urllib import quote

from wiki.exceptions import *
@@ -25,7 +27,9 @@ class Page(object):
is_redirect -- returns True if the page is a redirect, else False
toggle_talk -- returns a content page's talk page, or vice versa
get -- returns page content
get_redirect_target -- if the page is a redirect, returns its destination
get_redirect_target -- if the page is a redirect, returns its destination
edit -- replaces the page's content or creates a new page
add_section -- add a new section at the bottom of the page
"""

def __init__(self, site, title, follow_redirects=False):
@@ -54,6 +58,11 @@ class Page(object):
self._content = None
self._creator = None

# Attributes used for editing/deleting/protecting/etc:
self._token = None
self._basetimestamp = None
self._starttimestamp = None

# Try to determine the page's namespace using our site's namespace
# converter:
prefix = self._title.split(":", 1)[0]
@@ -124,16 +133,16 @@ 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, ._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.
._protection, ._namespace, ._is_talkpage, ._creator, ._lastrevid,
._token, and ._starttimestamp 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", "rvprop": "user", "rvdir": "newer",
"prop": "info|revisions", "rvlimit": 1,
params = {"action": "query", "rvprop": "user", "intoken": "edit",
"prop": "info|revisions", "rvlimit": 1, "rvdir": "newer",
"titles": self._title, "inprop": "protection|url"}
result = self._site._api_query(params)

@@ -168,6 +177,13 @@ class Page(object):
self._fullurl = res["fullurl"]
self._protection = res["protection"]

try:
self._token = res["edittoken"]
except KeyError:
pass
else:
self._starttimestamp = strftime("%Y-%m-%dT%H:%M:%SZ")

# We've determined the namespace and talkpage status in __init__()
# based on the title, but now we can be sure:
self._namespace = res["ns"]
@@ -192,13 +208,13 @@ class Page(object):
"""
if result is None:
params = {"action": "query", "prop": "revisions", "rvlimit": 1,
"rvprop": "content", "titles": self._title}
"rvprop": "content|timestamp", "titles": self._title}
result = self._site._api_query(params)

res = result["query"]["pages"].values()[0]
try:
content = res["revisions"][0]["*"]
self._content = content
self._content = res["revisions"][0]["*"]
self._basetimestamp = res["revisions"][0]["timestamp"]
except KeyError:
# This can only happen if the page was deleted since we last called
# self._load_attributes(). In that case, some of our attributes are
@@ -206,6 +222,25 @@ class Page(object):
self._load_attributes()
self._force_existence()

def _get_token(self):
"""Tries to get an edit token for the page.

This is actually the same as the delete and protect tokens, so we'll
use it for everything. Raises PermissionError if we're not allowed to
edit the page, otherwise sets self._token and self._starttimestamp.
"""
params = {"action": "query", "prop": "info", "intoken": "edit",
"titles": self._title}
result = self._site._api_query(params)

try:
self._token = result["query"]["pages"].values()[0]["edittoken"]
except KeyError:
e = "You don't have permission to edit this page."
raise PermissionsError(e)
else:
self._starttimestamp = strftime("%Y-%m-%dT%H:%M:%SZ")

def title(self, force=False):
"""Returns the Page's title, or pagename.

@@ -394,9 +429,9 @@ class Page(object):
if force or self._exists == 0:
# Kill two birds with one stone by doing an API query for both our
# attributes and our page content:
params = {"action": "query", "rvprop": "content", "rvlimit": 1,
params = {"action": "query", "rvlimit": 1, "titles": self._title,
"prop": "info|revisions", "inprop": "protection|url",
"titles": self._title}
"intoken": "edit", "rvprop": "content|timestamp"}
result = self._site._api_query(params)
self._load_attributes(result=result)
self._force_existence()
@@ -438,3 +473,45 @@ class Page(object):
except IndexError:
e = "The page does not appear to have a redirect target."
raise RedirectError(e)

def edit(self, text, summary, minor=False, bot=True, force=False):
"""Replaces the page's content or creates a new page.

`text` is the new page content, with `summary` as the edit summary.
If `minor` is True, the edit will be marked as minor. If `bot` is true,
the edit will be marked as a bot edit, but only if we actually have a
bot flag.

Use `force` to ignore edit conflicts and page deletions/recreations
that occured between getting our edit token and editing our page. Be
careful with this!
"""
if not self._token:
self._get_token()

hashed = md5(text).hexdigest()

params = {"action": "edit", "title": self._title, "text": text,
"token": self._token, "summary": summary, "md5": hashed}

if minor:
params["minor"] = "true"
else:
params["notminor"] = "true"
if bot:
params["bot"] = "true"

if not force:
params["starttimestamp"] = self._starttimestamp
if self._basetimestamp:
params["basetimestamp"] = self._basetimestamp
else:
params["recreate"] = "true"

result = self._site._api_query(params)
print result

def add_section(self, text, title, minor=False, bot=True):
"""
"""
pass

読み込み中…
キャンセル
保存