- Posts+Posts
- Date: {{ page.date | date: "%b %d, %Y" }}
+
+ Date: {{ page.date | date: "%b %d, %Y" }}
+
{{ content }}
diff --git a/_posts/2011-08-05-earwigbot-progress-wiki-toolset.md b/_posts/2011-08-05-earwigbot-progress-wiki-toolset.md
new file mode 100644
index 0000000..e52dd94
--- /dev/null
+++ b/_posts/2011-08-05-earwigbot-progress-wiki-toolset.md
@@ -0,0 +1,134 @@
+---
+layout: post
+title: EarwigBot Progress: Wiki Toolset
+description: YAWTF (Yet Another Wiki Tools Framework, or Yet Another... WTF?)
+---
+
+So I've been spending the past week and a half working on EarwigBot's new
+wikitools framework thing (to avoid confusion with Mr.Z-man's
+`python-wikitools` package, I'm referring to it as "EarwigBot's Wiki Toolset"
+in the docs, even though it's `wiki.tools` internally). Basically, it's the
+interface between EarwigBot and the MediaWiki API.
+
+As Josh put it, this is "the thing that actually makes it work".
+
+So, now you can do this (from within Python's interpreter, a wiki bot task, or
+an IRC command):
+
+{% highlight pycon %}
+
+>>> from wiki import tools
+>>> site = tools.get_site()
+>>> print site.name()
+enwiki
+>>> print site.project()
+wikipedia
+>>> print site.lang()
+en
+>>> print site.domain()
+en.wikipedia.org
+
+{% endhighlight %}
+
+Our `config.json` file stores site information, along with our chosen "default
+site". Pretty neat, huh? "But what can it actually do?" I hear you ask? Well,
+for example, we can get information about users:
+
+{% highlight pycon %}
+
+>>> user = site.get_user("The Earwig")
+>>> print user.editcount()
+11079
+>>> print user.groups()
+[u'*', u'user', u'autoconfirmed', u'abusefilter', u'sysop']
+>>> reg = user.registration()
+>>> import time
+>>> print time.strftime("%a, %d %b %Y %H:%M:%S", reg)
+Thu, 03 Jul 2008 21:51:34
+
+{% endhighlight %}
+
+and pages as well, with intelligent namespace logic:
+
+{% highlight pycon %}
+
+>>> page = site.get_page("Wikipedia:Articles for creation")
+>>> print page.url()
+http://en.wikipedia.org/wiki/Wikipedia:Articles_for_creation
+>>> print page.namespace()
+4
+>>> print site.namespace_id_to_name(4)
+Wikipedia
+>>> print site.namespace_id_to_name(4, all=True)
+[u'Wikipedia', u'Project', u'WP']
+>>> print page.is_talkpage()
+False
+
+>>> talkpage = page.toggle_talk()
+>>> print talkpage.title()
+Wikipedia talk:Articles for creation
+>>> print talkpage.is_talkpage()
+True
+
+{% endhighlight %}
+
+and with support for redirect following:
+
+{% highlight pycon %}
+
+>>> page = site.get_page("Main page")
+>>> print page.is_redirect()
+True
+>>> print page.get()
+#REDIRECT [[Main Page]]
+[[Category:Protected redirects]]
+[[Category:Main Page| ]]
+>>> print page.get_redirect_target()
+Main Page
+
+>>> page = site.get_page("Main page", follow_redirects=True)
+>>> print page.is_redirect()
+False # would only be True if "Main page" is a double redirect
+>>> print page.get()
+
+{| id="mp-topbanner" style="width:100%; background:#f9f9f9; margin:1.2em 0 6px 0; border:1px solid #ddd;"
+| style="width:61%; color:#000;" |
+...
+
+{% endhighlight %}
+
+Of course, a Wiki Toolset would be nothing without login! Our username and
+password are stored (encrypted with Blowfish) in the bot's `config.json` file,
+and we login automatically whenever we create a new Site object – unless
+we're already logged in, of course, and we know that based on whether we have
+valid login cookies.
+
+{% highlight pycon %}
+
+>>> user = site.get_user() # gets the logged-in user
+>>> print user.name()
+EarwigBot
+
+{% endhighlight %}
+
+Cookies are stored in a special `.cookies` file in the project root (with no
+access given to other users, of course). We support both per-project login and
+CentralAuth, meaning I can do...
+
+{% highlight pycon %}
+
+>>> es = tools.get_site("eswiki")
+>>> print es.get_user().name()
+EarwigBot
+
+{% endhighlight %}
+
+without making additional logins. One thing I strove for when designing the
+toolset was as minimal API usage as possible – we accept gzipped data, we
+don't make API queries unless they're actually requested, and we combine
+queries whenever possible. Of course, I'm probably doing it all wrong, but
+it seems to be working so far.
+
+So... yeah. Carry on then!
+
+:—earwig
diff --git a/css/main.css b/css/main.css
index f8a07ba..942df36 100644
--- a/css/main.css
+++ b/css/main.css
@@ -5,30 +5,31 @@ body {
background-color: #E0E0E0;
}
-.text-highlight {
+.color-highlight {
color: #040;
}
-.description {
- font-size: 12px;
-}
-
-.topless {
- margin-top: 0px;
- padding-top: 0px;
+.highlight { /* syntax highlighter */
+ background: #f2f2f2;
+ border: 1px solid #e8e8e8;
+ border-radius: 10px;
+ padding-left: 16px;
+ line-height: 1.35em;
+ font-size: 13px;
}
-.naked {
- margin-top: 0px;
- padding-top: 0px;
- margin-bottom: 0px;
- padding-bottom: 0px;
+.description {
+ font-size: 12px;
}
h1, h2 {
text-align: center;
}
+pre {
+ white-space: pre-wrap;
+}
+
div.project {
border: 1px solid #CCC;
border-radius: 5px;
@@ -47,12 +48,12 @@ div.project-body {
}
td.about-l {
- padding: 3px 6px 3px 6px;
+ padding: 4px 12px 4px 12px;
border-left: 1px solid #CCC;
}
td.about-r {
- padding: 3px 6px 3px 6px;
+ padding: 4px 12px 4px 12px;
border-right: 1px solid #CCC;
}
@@ -65,17 +66,29 @@ td.dark-l { background-color: #DADADA; }
td.light-r { background-color: #F7F7F7; }
td.dark-r { background-color: #E5E5E5; }
+h1#header {
+ margin-top: 0px;
+ padding-top: 0px;
+ margin-bottom: 0px;
+ padding-bottom: 0px;
+}
+
+h2#posts {
+ margin-top: 0px;
+ padding-top: 0px;
+}
+
div#container {
width: 800px;
- margin: 16px auto 16px auto;
+ margin: 20px auto 32px auto;
border: 1px solid #999;
border-radius: 10px;
background-color: #FFF;
}
div#header {
- margin: 12px 12px 20px 12px;
- padding: 15px 0px 15px 0px;
+ margin: 16px 16px 20px 16px;
+ padding: 30px 0px 30px 0px;
border: 1px solid #999;
border-radius: 10px 10px 0px 0px;
background-color: #DED;
@@ -88,10 +101,14 @@ div#content {
div#footer {
font-size: 11px;
text-align: center;
- padding: 6px 2px 6px 2px;
+ padding: 9px 4px 12px 4px;
color: #222;
}
+div#post-info {
+ margin-left: 24px;
+}
+
div#post {
line-height: 1.5em;
}
diff --git a/css/syntax.css b/css/syntax.css
index fe22f94..f699fff 100644
--- a/css/syntax.css
+++ b/css/syntax.css
@@ -1,10 +1,9 @@
/*
-This file has been shamelessly stolen from:
+This file has been shamelessly stolen from (with modifications):
https://github.com/mojombo/tpw/blob/master/css/syntax.css
...which is released under the MIT license.
*/
-.highlight { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
@@ -20,7 +19,7 @@ This file has been shamelessly stolen from:
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
-.highlight .go { color: #888888 } /* Generic.Output */
+.highlight .go { color: #666666 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
|