Help Wikitravel grow by contributing to an article! Learn how.

User:Jpatokal/post.py

From Wikitravel
Jump to: navigation, search
#!/usr/bin/python
# Edit a Wikipedia article with your favourite editor. Requires Python 2.3.
# See Talk page for usage instructions
#
# (C) Jpatokal 2005-2006
# Heavily based on editarticle.py by Gerrit Holl 2004
# Distribute under the terms of the PSF license.
#
# Heavily based on 
__metaclass__ = type
__version__ = "$Id: post.py,v 1.1.1.1 2006/04/25 17:15:44 gnosis Exp $"
sig = u"Automated upload"
#sig = u"Automated import of CIA World Factbook 2002"

import sys
import os
import httplib
import urllib
import getpass
import difflib
import optparse
import tempfile
import re
import codecs

import wikipedia
import login
import config

class EditArticle:
    import string
    joinchars = string.letters + '[]' + string.digits # join lines if line starts with this ones

    def __init__(self, args):
        """Takes one argument, usually this is sys.argv[1:]"""
        self.all_args = args
        self.set_options()

    def initialise_data(self):
        """Login, set editor, page and pagelink attributes"""
        self.login()#anonymous=self.options.anonymous)
        self.editor = self.options.editor or wikipedia.input(u"Editor to use:")

    def login(self):#, anonymous):
        """Initialises site and username data"""#, or anonymous"""
        if False:#anonymous:
            self.site = wikipedia.getSite(user=None)
        else:
            self.username = self.options.username or wikipedia.input(u"Username:")
            self.site = wikipedia.getSite(user=self.username)
            #self.site._fill() # load cookies
            #if not self.site._loggedin:
            #    password = getpass.getpass("Password: ")
            #    cookie = login.login(self.site, self.username, password)
            #    if not cookie:
            #        sys.exit("Login failed")
            #    login.storecookiedata(cookie, self.site, self.username)
            #    wikipedia.output(u"Login succesful")

    def set_options(self):
        """Parse commandline and set options attribute"""
        my_args = []
        for arg in self.all_args:
            arg = wikipedia.argHandler(arg, 'editarticle')
            if arg:
                my_args.append(arg)
        parser = optparse.OptionParser()
##        parser.add_option("-a", "--anonymous", action="store_true", default=False, help="Login anonymously")
        parser.add_option("-r", "--edit_redirect", action="store_true", default=False, help="Ignore/edit redirects")
        parser.add_option("-u", "--username", help="Username to login with (ignored with -a)")
        parser.add_option("-p", "--page", help="Page to edit")
        parser.add_option("-e", "--editor", help="Editor to use")
        parser.add_option("-j", "--join_lines", action="store_true", default=False, help="Join consecutive lines if possible")
        parser.add_option("-w", "--watch", action="store_true", default=False, help="Watch article after edit")
        parser.add_option("-n", "--new_data", default="", help="Data to insert in template")
        parser.add_option("-t", "--template", default="", help="Template for article creation")
        self.options = parser.parse_args(args=my_args)[0]

    def setpage(self):
        """Sets page and pagelink"""
        self.pagelink = wikipedia.Page(self.site, self.page)
        if not self.options.edit_redirect and self.pagelink.isRedirectPage():
            self.pagelink = wikipedia.Page(site, self.pagelink.getRedirectTarget())

    def repair(self, content):
        """Removes single newlines and prepare encoding for local wiki"""
        if self.options.join_lines:
            lines = content.splitlines()
            result = []
            for i, line in enumerate(lines):
                try:
                    nextline = lines[i+1]
                except IndexError:
                    nextline = "last"
                result.append(line)
                if line.strip() == "" or line[0] not in self.joinchars or \
                   nextline.strip() == "" or nextline[0] not in self.joinchars:
                    result.append('\n')
                else:
                    result.append(" ")
            s = "".join(result)
        else:
            s = content
        return wikipedia.unicode2html(s, self.site.encoding())

    def edit(self):
        """Edit the page using the editor.
        
        It returns two strings: the old version and the new version."""

        # Parse data file to figure out article variables and sub them into template
        newcontent = codecs.open(self.options.template, 'r', 'utf8').read()
        for line in codecs.open(self.options.new_data, 'r', 'utf8').readlines():
          data = line.strip().split('=')
          newcontent = re.sub('\$' + data[0], data[1], newcontent)
          if(data[0] == 'NAME'):
            self.page = data[1]

        # Change any remaining unresolved variables into question marks
        for x in ['CAPITAL', 'LANGUAGE', 'CURRENCY', 'TEL', 'DOMAIN', 'AREA', 'POPULATION']:
          newcontent = re.sub('\$' + x, '?', newcontent)

        # Read existing article for comparison
        self.setpage()
        try:
            oldcontent = self.pagelink.get()
        except wikipedia.NoPage:
            oldcontent = ""
        except wikipedia.IsRedirectPage:
            if self.options.redirect:
                oldcontent = self.pagelink.get(force=True, get_redirect=redirect)
            else:
                raise
        return oldcontent, newcontent

    def getcomment(self):
        comment = sig
        # wikipedia.input(u"What did you change? ") + sig
        comment = wikipedia.unicode2html(comment, self.site.encoding())
        return wikipedia.unicode2html(comment, self.site.encoding())

    def handle_edit_conflict(self):
        fn = os.path.join(tempfile.gettempdir(), self.page)
        fp = open(fn, 'w')
        fp.write(new)
        fp.close()
        wikipedia.output(u"An edit conflict has arisen. Your edit has been saved to %s. Please try again." % fn)
    
    def showdiff(self,old, new):
        diff = difflib.context_diff(old.splitlines(), new.splitlines())
        wikipedia.output(u"\n".join(diff))

    def run(self):
        self.initialise_data()
 
        # check if blocked
        allowed = self.site.allowed()
        if False:
            sys.exit("Bot blocked!");

        try:
            old, new = self.edit()
        except wikipedia.LockedPage:
            sys.exit("You do not have permission to edit %s" % self.pagelink.sectionFreeTitle())

        if old != new:
            new = self.repair(new)
            self.showdiff(old, new)
            comment = self.getcomment()
            try:
                self.pagelink.put(new, comment=comment, minorEdit=False, watchArticle=self.options.watch)#, anon=self.options.anonymous)
            except wikipedia.EditConflict:
                self.handle_edit_conflict()
        else:
            wikipedia.output(u"Nothing changed")

def main():
    app = EditArticle(sys.argv[1:])
    app.run()

if __name__ == "__main__":
    try:
        main()
    except:
        wikipedia.stopme()
        raise
    wikipedia.stopme()

Variants

Actions

Destination Docents

In other languages