Revision: 6191
Author:   russblau
Date:     2008-12-23 19:37:49 +0000 (Tue, 23 Dec 2008)

Log Message:
-----------


Modified Paths:
--------------
    branches/rewrite/pywikibot/README-conversion.txt
    branches/rewrite/pywikibot/__init__.py
    branches/rewrite/pywikibot/bot.py
    branches/rewrite/pywikibot/comms/http.py
    branches/rewrite/pywikibot/data/api.py
    branches/rewrite/pywikibot/login.py
    branches/rewrite/pywikibot/page.py
    branches/rewrite/pywikibot/site.py
    branches/rewrite/pywikibot/throttle.py
    branches/rewrite/pywikibot/userinterfaces/terminal_interface.py

Added Paths:
-----------
    branches/rewrite/pywikibot/userinterfaces/__init__.py

Modified: branches/rewrite/pywikibot/README-conversion.txt
===================================================================
--- branches/rewrite/pywikibot/README-conversion.txt    2008-12-23 17:13:12 UTC 
(rev 6190)
+++ branches/rewrite/pywikibot/README-conversion.txt    2008-12-23 19:37:49 UTC 
(rev 6191)
@@ -31,6 +31,9 @@
     change "import catlib" to "from pywikibot import catlib"
     change "wikipedia." to "pywikibot."
 
+wikipedia.setAction() no longer works; you must revise the script to pass an
+explicit edit summary message on each put() or put_async() call.
+
 == Python librairies ==
 
 [Note: the goal will be to package pywikibot with setuptools easy_install,
@@ -68,7 +71,7 @@
 Category, as long as the page is in the category namespace.
 
 The following methods of the Page object have been deprecated (deprecated
-methods will still work, but print a warning message in debug mode):
+methods still work, but print a warning message in debug mode):
 
 - urlname(): replaced by Page.title(asUrl=True)
 - titleWithoutNamespace(): replaced by Page.title(withNamespace=False)
@@ -94,8 +97,8 @@
 === Category objects ===
 
 The Category object has been moved from the catlib module to the pywikibot
-namespace.  Any references to "catlib.Category" need to be replaced by
-"pywikibot.Category".
+namespace.  Any references to "catlib.Category" can be replaced by
+"pywikibot.Category", but the old form is retained for backwards-compatibility.
 
 For Category objects, the following methods are deprecated:
 

Modified: branches/rewrite/pywikibot/__init__.py
===================================================================
--- branches/rewrite/pywikibot/__init__.py      2008-12-23 17:13:12 UTC (rev 
6190)
+++ branches/rewrite/pywikibot/__init__.py      2008-12-23 19:37:49 UTC (rev 
6191)
@@ -9,14 +9,15 @@
 #
 __version__ = '$Id$'
 
-import sys
+import difflib
 import logging
 import re
+import sys
 
-from exceptions import *
 import config2 as config
-import textlib
 from bot import *
+from exceptions import *
+from textlib import *
 
 logging.basicConfig(fmt="%(message)s")
 
@@ -30,18 +31,18 @@
             if old_arg in __kw:
                 if new_arg:
                     if new_arg in __kw:
-                        logger.warn(
+                        pywikibot.output(
 "%(new_arg)s argument of %(meth_name)s replaces %(old_arg)s; cannot use both."
-                            % locals())
+                            % locals(), level=WARNING)
                     else:
-                        logger.debug(
+                        pywikibot.output(
 "%(old_arg)s argument of %(meth_name)s is deprecated; use %(new_arg)s instead."
-                            % locals())
+                            % locals(), level=DEBUG)
                         __kw[new_arg] = __kw[old_arg]
                 else:
-                    logger.debug(
+                    pywikibot.output(
                         "%(old_arg)s argument of %(meth_name)s is deprecated."
-                        % locals())
+                        % locals(), level=DEBUG)
                 del __kw[old_arg]
             return method(*__args, **__kw)
         wrapper.__doc__ = method.__doc__
@@ -91,8 +92,8 @@
     key = '%s:%s:%s' % (fam, code, user)
     if not _sites.has_key(key):
         _sites[key] = __Site(code=code, fam=fam, user=user, sysop=sysop)
-        logger.debug("Instantiating Site object '%(site)s'"
-                      % {'site': _sites[key]})
+        pywikibot.output("Instantiating Site object '%(site)s'"
+                         % {'site': _sites[key]}, level=DEBUG)
     return _sites[key]
 
 getSite = Site # alias for backwards-compability
@@ -125,6 +126,69 @@
     logging.getLogger(layer).setLevel(DEBUG)
 
 
+def showDiff(oldtext, newtext):
+    """
+    Output a string showing the differences between oldtext and newtext.
+    The differences are highlighted (only on compatible systems) to show which
+    changes were made.
+    
+    """
+    # This is probably not portable to non-terminal interfaces....
+    # For information on difflib, see http://pydoc.org/2.3/difflib.html
+    color = {
+        '+': 'lightgreen',
+        '-': 'lightred',
+    }
+    diff = u''
+    colors = []
+    # This will store the last line beginning with + or -.
+    lastline = None
+    # For testing purposes only: show original, uncolored diff
+    #     for line in difflib.ndiff(oldtext.splitlines(), 
newtext.splitlines()):
+    #         print line
+    for line in difflib.ndiff(oldtext.splitlines(), newtext.splitlines()):
+        if line.startswith('?'):
+            # initialize color vector with None, which means default color
+            lastcolors = [None for c in lastline]
+            # colorize the + or - sign
+            lastcolors[0] = color[lastline[0]]
+            # colorize changed parts in red or green
+            for i in range(min(len(line), len(lastline))):
+                if line[i] != ' ':
+                    lastcolors[i] = color[lastline[0]]
+            diff += lastline + '\n'
+            # append one None (default color) for the newline character
+            colors += lastcolors + [None]
+        elif lastline:
+            diff += lastline + '\n'
+            # colorize the + or - sign only
+            lastcolors = [None for c in lastline]
+            lastcolors[0] = color[lastline[0]]
+            colors += lastcolors + [None]
+        lastline = None
+        if line[0] in ('+', '-'):
+            lastline = line
+    # there might be one + or - line left that wasn't followed by a ? line.
+    if lastline:
+        diff += lastline + '\n'
+        # colorize the + or - sign only
+        lastcolors = [None for c in lastline]
+        lastcolors[0] = color[lastline[0]]
+        colors += lastcolors + [None]
+
+    result = u''
+    lastcolor = None
+    for i in range(len(diff)):
+        if colors[i] != lastcolor:
+            if lastcolor is None:
+                result += '\03{%s}' % colors[i]
+            else:
+                result += '\03{default}'
+        lastcolor = colors[i]
+        result += diff[i]
+    output(result)
+
+
 # Throttle and thread handling
 
 threadpool = []   # add page-putting threads to this list as they are created
@@ -141,11 +205,11 @@
     logger = logging.getLogger("wiki")
 
     if not stopped:
-        logger.debug("stopme() called")
+        pywikibot.output("stopme() called", level=DEBUG)
         count = sum(1 for thd in threadpool if thd.isAlive())
         if count:
-            logger.info("Waiting for about %(count)s pages to be saved."
-                         % locals())
+            pywikibot.output("Waiting for about %(count)s pages to be saved."
+                             % locals())
             for thd in threadpool:
                 if thd.isAlive():
                     thd.join()
@@ -153,7 +217,7 @@
     # only need one drop() call because all throttles use the same global pid
     try:
         _sites[_sites.keys()[0]].throttle.drop()
-        logger.log(VERBOSE, "Dropped throttle(s).")
+        pywikibot.output("Dropped throttle(s).", level=VERBOSE)
     except IndexError:
         pass
 

Modified: branches/rewrite/pywikibot/bot.py
===================================================================
--- branches/rewrite/pywikibot/bot.py   2008-12-23 17:13:12 UTC (rev 6190)
+++ branches/rewrite/pywikibot/bot.py   2008-12-23 19:37:49 UTC (rev 6191)
@@ -18,7 +18,7 @@
 import os.path
 import sys
 import pywikibot
-from pywikibot import config2 as config
+from pywikibot import config
 
 
 # logging levels
@@ -29,20 +29,164 @@
 INPUT = 25
 
 
+class MaxLevelFilter(logging.Filter):
+    """Filter that only passes records at or below a specific level.
+
+    (setting handler level only passes records at or *above* a specified level,
+    so this provides the opposite functionality)
+
+    """
+    def __init__(self, level=None):
+        self.level = level
+
+    def filter(self, record):
+        if self.level:
+            return record.levelno <= self.level
+        else:
+            return True
+
+
+class TerminalHandler(logging.Handler):
+    """
+    A handler class that writes logging records, appropriately formatted,
+    to a stream. Note that this class does not close the stream, as
+    sys.stdout or sys.stderr may be used.
+
+    Slightly modified version of the StreamHandler class that ships with
+    logging module.
+    
+    """
+    def __init__(self, strm=None):
+        """
+        Initialize the handler.
+
+        If strm is not specified, sys.stderr is used.
+        """
+        logging.Handler.__init__(self)
+        if strm is None:
+            strm = sys.stderr
+        self.stream = strm
+        self.formatter = None
+
+    def flush(self):
+        """
+        Flush the stream.
+        """
+        self.stream.flush()
+
+    def emit(self, record):
+        """
+        Emit a record.
+
+        If a formatter is specified, it is used to format the record. The
+        record is then written to the stream. If exception information is
+        present, it is formatted using traceback.print_exception and
+        appended to the stream.
+        """
+        try:
+            msg = self.format(record)
+            fs = "%s"
+            try:
+                self.stream.write(fs % msg.encode(config.console_encoding,
+                                                  "xmlcharrefreplace"))
+            except UnicodeError:
+                self.stream.write(fs % msg.encode("ascii",
+                                                  "xmlcharrefreplace"))
+            self.flush()
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            self.handleError(record)
+
+
+
+# User interface initialization
+# search for user interface module in the 'userinterfaces' subdirectory
+exec ("import pywikibot.userinterfaces.%s_interface as uiModule"
+      % config.userinterface)
+ui = uiModule.UI()
+
 def output(text, decoder=None, newline=True, toStdout=False, level=INFO):
+    """Output a message to the user via the userinterface.
+
+    Works like print, but uses the encoding used by the user's console
+    (console_encoding in the configuration file) instead of ASCII.
+    If decoder is None, text should be a unicode string. Otherwise it
+    should be encoded in the given encoding.
+
+    If newline is True, a linebreak will be added after printing the text.
+
+    If toStdout is True, the text will be sent to standard output,
+    so that it can be piped to another process. All other text will
+    be sent to stderr. See: http://en.wikipedia.org/wiki/Pipeline_%28Unix%29
+
+    text can contain special sequences to create colored output. These
+    consist of the escape character \03 and the color name in curly braces,
+    e. g. \03{lightpurple}. \03{default} resets the color.
+
+    @param level: output level for logging module; use VERBOSE for optional
+        messages, INPUT for prompts requiring user reponse (not yet fully
+        implemented)
+
+    """
+    if decoder:
+        text = unicode(text, decoder)
+    elif type(text) is not unicode:
+        import traceback
+        pywikibot.output(
+            u"Non-unicode (%s) passed to wikipedia.output without decoder!\n"
+             % type(text),
+            level=VERBOSE
+        )
+        try:
+            text = unicode(text, 'utf-8')
+        except UnicodeDecodeError:
+            text = unicode(text, 'iso8859-1')
+    if newline:
+        text += u'\n'
     if toStdout:
         level = STDOUT
-    logging.getLogger().log(level, text)
+    ui.output(text, level=level)
 
+def input(question, password=False):
+    """Ask the user a question, return the user's answer.
 
-def input(prompt, password=False):
-    logging.getLogger().log(INPUT, prompt)
-    if password:
-        import getpass
-        return getpass.getpass("")
-    return raw_input()
+    Parameters:
+    * question - a unicode string that will be shown to the user. Don't add a
+                 space after the question mark/colon, this method will do this
+                 for you.
+    * password - if True, hides the user's input (for password entry).
 
+    Returns a unicode string.
 
+    """
+    data = ui.input(question, password)
+    return data
+
+def inputChoice(question, answers, hotkeys, default=None):
+    """Ask the user a question with several options, return the user's choice.
+
+    The user's input will be case-insensitive, so the hotkeys should be
+    distinctive case-insensitively.
+
+    Parameters:
+    * question - a unicode string that will be shown to the user. Don't add a
+                 space after the question mark, this method will do this
+                 for you.
+    * answers  - a list of strings that represent the options.
+    * hotkeys  - a list of one-letter strings, one for each answer.
+    * default  - an element of hotkeys, or None. The default choice that will
+                 be returned when the user just presses Enter.
+
+    Returns a one-letter string in lowercase.
+
+    """
+    data = ui.inputChoice(question, answers, hotkeys, default).lower()
+    return data
+
+
+# Command line parsing and help
+
 def calledModuleName():
     """Return the name of the module calling this function.
 
@@ -56,24 +200,6 @@
         called = called[ : called.rindex(".py")]
     return os.path.basename(called)
 
-
-class MaxLevelFilter(logging.Filter):
-    """Filter that only passes records at or below a specific level.
-
-    (setting handler level only passes records at or *above* a specified level,
-    so this provides the opposite functionality)
-
-    """
-    def __init__(self, level=None):
-        self.level = level
-
-    def filter(self, record):
-        if self.level:
-            return record.levelno <= self.level
-        else:
-            return True
-
-
 def _decodeArg(arg):
     if sys.platform=='win32':
         if config.console_encoding == 'cp850':
@@ -91,7 +217,6 @@
         # I don't know how non-Western Windows versions behave.
         return unicode(arg, config.console_encoding)
 
-
 def handleArgs(*args):
     """Handle standard command line arguments, return the rest as a list.
 
@@ -176,10 +301,7 @@
     #    ERROR - user error messages
     #    CRITICAL - fatal error messages
     # Accordingly, do ''not'' use print statements in bot code; instead,
-    # send output to logging.log(level, text) or one of its equivalents.
-    # For backwards-compatibility, pywikibot.output is supported, which
-    # directs output to logging.info() or other levels as appropriate, but
-    # its use in new code is deprecated.
+    # use pywikibot.output function.
 
     logging.addLevelName(VERBOSE, "VERBOSE")
         # for messages to be displayed on terminal at "verbose" setting
@@ -190,17 +312,18 @@
         # for prompts requiring user response
 
     root_logger = logging.getLogger()
-    # default handler for VERBOSE and INFO levels
-    default_handler = root_logger.handlers[0]
+    root_logger.handlers = [] # get rid of default handler
     root_logger.setLevel(DEBUG) # all records go to logger
 
-    # configure default handler for VERBOSE, INFO, and INPUT levels
+    # configure default handler for VERBOSE and INFO levels
+    default_handler = TerminalHandler(strm=sys.stderr)
     if config.verbose_output:
         default_handler.setLevel(VERBOSE)
     else:
         default_handler.setLevel(INFO)
     default_handler.addFilter(MaxLevelFilter(INPUT))
     default_handler.setFormatter(logging.Formatter(fmt="%(message)s"))
+    root_logger.addHandler(default_handler)
 
     # if user has enabled file logging, configure file handler
     if moduleName in config.log or '*' in config.log:
@@ -223,13 +346,13 @@
         root_logger.addHandler(file_handler)
 
     # handler for level STDOUT
-    output_handler = logging.StreamHandler(strm=sys.stdout)
+    output_handler = TerminalHandler(strm=sys.stdout)
     output_handler.setLevel(STDOUT)
     output_handler.addFilter(MaxLevelFilter(STDOUT))
     root_logger.addHandler(output_handler)
 
     # handler for levels WARNING and higher
-    warning_handler = logging.StreamHandler() # uses sys.stderr
+    warning_handler = TerminalHandler(strm=sys.stderr)
     warning_handler.setLevel(logging.WARNING)
     warning_handler.setFormatter(
             logging.Formatter(fmt="%(levelname)s: %(message)s"))
@@ -242,7 +365,7 @@
         pywikibot.output(u'Pywikipediabot r%s' % m.group(1))
         pywikibot.output(u'Python %s' % sys.version)
 
-    root_logger.debug("handleArgs() completed.")
+    pywikibot.output("handleArgs() completed.", level=DEBUG)
     return nonGlobalArgs
 
 

Modified: branches/rewrite/pywikibot/comms/http.py
===================================================================
--- branches/rewrite/pywikibot/comms/http.py    2008-12-23 17:13:12 UTC (rev 
6190)
+++ branches/rewrite/pywikibot/comms/http.py    2008-12-23 19:37:49 UTC (rev 
6191)
@@ -101,7 +101,8 @@
         raise request.data
 
     if request.data[0].status != 200:
-        logger.warning("Http response status %(status)s"
-                       % {'status': request.data[0].status})
+        pywikibot.output("Http response status %(status)s"
+                         % {'status': request.data[0].status},
+                         level=pywikibot.WARNING)
 
     return request.data[1]    

Modified: branches/rewrite/pywikibot/data/api.py
===================================================================
--- branches/rewrite/pywikibot/data/api.py      2008-12-23 17:13:12 UTC (rev 
6190)
+++ branches/rewrite/pywikibot/data/api.py      2008-12-23 19:37:49 UTC (rev 
6191)
@@ -244,7 +244,7 @@
             if code == "maxlag":
                 lag = lagpattern.search(info)
                 if lag:
-                    logger.info(
+                    pywikibot.output(
                         "Pausing due to database lag: " + info)
                     self.site.throttle.lag(int(lag.group("lag")))
                     continue

Modified: branches/rewrite/pywikibot/login.py
===================================================================
--- branches/rewrite/pywikibot/login.py 2008-12-23 17:13:12 UTC (rev 6190)
+++ branches/rewrite/pywikibot/login.py 2008-12-23 19:37:49 UTC (rev 6191)
@@ -189,8 +189,8 @@
 
 #        self.password = self.password.encode(self.site.encoding())
 
-        logger.info(u"Logging in to %(site)s as %(name)s"
-                     % {'name': self.username, 'site': self.site})
+        pywikibot.output(u"Logging in to %(site)s as %(name)s"
+                         % {'name': self.username, 'site': self.site})
         try:
             cookiedata = self.getCookie()
         except pywikibot.data.api.APIError, e:
@@ -201,7 +201,7 @@
             else:
                 return False
         self.storecookiedata(cookiedata)
-        logger.info(u"Should be logged in now")
+        pywikibot.output(u"Should be logged in now")
 ##        # Show a warning according to the local bot policy
 ##   FIXME: disabled due to recursion; need to move this to the Site object 
after
 ##   login
@@ -249,9 +249,11 @@
                 try:
                     site = pywikibot.getSite(code=lang, fam=familyName)
                     if not forceLogin and site.loggedInAs(sysop = sysop) != 
None:
-                        logger.info(u'Already logged in on %(site)s' % 
locals())
+                        pywikibot.output(u'Already logged in on %(site)s'
+                                          % locals())
                     else:
-                        loginMan = LoginManager(password, sysop=sysop, 
site=site)
+                        loginMan = LoginManager(password, sysop=sysop,
+                                                site=site)
                         loginMan.login()
                 except pywikibot.NoSuchSite:
                     pywikibot.output(

Modified: branches/rewrite/pywikibot/page.py
===================================================================
--- branches/rewrite/pywikibot/page.py  2008-12-23 17:13:12 UTC (rev 6190)
+++ branches/rewrite/pywikibot/page.py  2008-12-23 19:37:49 UTC (rev 6191)
@@ -13,7 +13,6 @@
 from pywikibot import deprecate_arg
 from pywikibot import config
 import pywikibot.site
-import pywikibot.textlib
 
 import htmlentitydefs
 import logging
@@ -417,8 +416,8 @@
 
         """
         txt = self.get()
-        txt = pywikibot.textlib.removeLanguageLinks(txt, site = self.site())
-        txt = pywikibot.textlib.removeCategoryLinks(txt, site = self.site())
+        txt = pywikibot.removeLanguageLinks(txt, site = self.site())
+        txt = pywikibot.removeCategoryLinks(txt, site = self.site())
         if len(txt) < 4:
             return True
         else:
@@ -655,9 +654,10 @@
             done = self.site().editpage(self, summary=comment, minor=minor,
                                         watch=watch, unwatch=unwatch)
             if not done:
-                logger.warn("Page %s not saved" % self.title(asLink=True))
+                pywikibot.output("Page %s not saved" % self.title(asLink=True),
+                                 level=pywikibot.WARNING)
             else:
-                logger.info("Page %s saved" % self.title(asLink=True))
+                pywikibot.output("Page %s saved" % self.title(asLink=True))
         except pywikibot.Error, err:
             logger.exception("Error saving page %s" % self.title(asLink=True))
         if callback:
@@ -721,7 +721,7 @@
         else:
             text = self.text
         for linkmatch in pywikibot.link_regex.finditer(
-                            pywikibot.textlib.removeDisabledParts(text)):
+                            pywikibot.removeDisabledParts(text)):
             linktitle = linkmatch.group("title")
             link = Link(linktitle, self.site())
             # only yield links that are to a different site and that
@@ -774,7 +774,7 @@
         parameters as the second entry.
 
         """
-        templates = pywikibot.textlib.extract_templates_and_params(self.text)
+        templates = pywikibot.extract_templates_and_params(self.text)
         # backwards-compatibility: convert the dict returned as the second
         # element into a list in the format used by old scripts
         result = []
@@ -900,7 +900,7 @@
 
         """
         if reason is None:
-            logger.info(u'Moving %s to [[%s]].'
+            pywikibot.output(u'Moving %s to [[%s]].'
                              % (self.title(asLink=True), newtitle))
             reason = pywikibot.input(u'Please enter a reason for the move:')
         # TODO: implement "safe" parameter
@@ -920,7 +920,7 @@
 
         """
         if reason is None:
-            logger.info(u'Deleting %s.' % (self.title(asLink=True)))
+            pywikibot.output(u'Deleting %s.' % (self.title(asLink=True)))
             reason = pywikibot.input(u'Please enter a reason for the 
deletion:')
         answer = u'y'
         if prompt and not hasattr(self.site(), '_noDeletePrompt'):
@@ -995,7 +995,7 @@
 
         """
         if comment is None:
-            logger.info(u'Preparing to undelete %s.'
+            pywikibot.output(u'Preparing to undelete %s.'
                              % (self.title(asLink=True)))
             comment = pywikibot.input(
                         u'Please enter a reason for the undeletion:')
@@ -1022,7 +1022,7 @@
                 un = u'un'
             else:
                 un = u''
-            logger.info(u'Preparing to %sprotect %s.'
+            pywikibot.output(u'Preparing to %sprotect %s.'
                              % (un, self.title(asLink=True)))
             reason = pywikibot.input(u'Please enter a reason for the action:')
         if unprotect:
@@ -1056,8 +1056,8 @@
                               % self.title(asLink=True))
             return False
         if inPlace == True:
-            newtext = pywikibot.textlib.replaceCategoryInPlace(
-                                            self.text, oldCat, newCat)
+            newtext = pywikibot.replaceCategoryInPlace(self.text,
+                                                       oldCat, newCat)
             if newtext == self.text:
                 pywikibot.output(
                     u'No changes in made in page %s.'
@@ -1111,8 +1111,7 @@
                               % (self.title(asLink=True), oldCat.title()))
         else:
             try:
-                text = pywikibot.textlib.replaceCategoryLinks(self.text,
-                                                              newCatList)
+                text = pywikibot.replaceCategoryLinks(self.text, newCatList)
             except ValueError:
                 # Make sure that the only way replaceCategoryLinks() can return
                 # a ValueError is in the case of interwiki links to self.
@@ -1402,7 +1401,7 @@
                              % targetCat.title())
             return False
         else:
-            logger.info('Moving text from %s to %s.'
+            pywikibot.output('Moving text from %s to %s.'
                              % (self.title(), targetCat.title()))
             authors = ', '.join(self.contributingUsers())
             creationSummary = pywikibot.translate(
@@ -1438,7 +1437,7 @@
                              % targetCat.title())
             return False
         else:
-            logger.info('Moving text from %s to %s.'
+            pywikibot.output('Moving text from %s to %s.'
                              % (self.title(), targetCat.title()))
             authors = ', '.join(self.contributingUsers())
             creationSummary = pywikibot.translate(

Modified: branches/rewrite/pywikibot/site.py
===================================================================
--- branches/rewrite/pywikibot/site.py  2008-12-23 17:13:12 UTC (rev 6190)
+++ branches/rewrite/pywikibot/site.py  2008-12-23 19:37:49 UTC (rev 6191)
@@ -1014,7 +1014,7 @@
                 rvgen.request["titles"] = "|".join(cache.keys())
             rvgen.request[u"rvprop"] = \
                     u"ids|flags|timestamp|user|comment|content"
-            logger.info(u"Retrieving %s pages from %s."
+            pywikibot.output(u"Retrieving %s pages from %s."
                            % (len(cache), self)
                         )
             for pagedata in rvgen:
@@ -1052,7 +1052,7 @@
                      % (page.title(withSection=False, asLink=True),
                         item['title']))
             api.update_page(page, item)
-            logging.debug(str(item))
+            pywikibot.output(str(item), level=pywikibot.DEBUG)
             return item[tokentype + "token"]
 
     # following group of methods map more-or-less directly to API queries

Modified: branches/rewrite/pywikibot/throttle.py
===================================================================
--- branches/rewrite/pywikibot/throttle.py      2008-12-23 17:13:12 UTC (rev 
6190)
+++ branches/rewrite/pywikibot/throttle.py      2008-12-23 19:37:49 UTC (rev 
6191)
@@ -10,7 +10,7 @@
 __version__ = '$Id$'
 
 import pywikibot
-from pywikibot import config2 as config
+from pywikibot import config
 
 import logging
 import math
@@ -66,7 +66,8 @@
         global pid
         self.lock.acquire()
         mysite = self.mysite
-        logger.debug("Checking multiplicity: pid = %(pid)s" % globals())
+        pywikibot.output("Checking multiplicity: pid = %(pid)s" % globals(),
+                         level=pywikibot.DEBUG)
         try:
             processes = []
             my_pid = pid or 1  # start at 1 if global pid not yet set
@@ -117,7 +118,7 @@
             f.close()
             self.process_multiplicity = count
             if self.verbosedelay:
-                logger.info(
+                pywikibot.output(
 u"Found %(count)s %(mysite)s processes running, including this one."
                     % locals())
         finally:
@@ -233,11 +234,11 @@
             self.next_multiplicity = math.log(1+requestsize)/math.log(2.0)
             # Announce the delay if it exceeds a preset limit
             if wait > config.noisysleep:
-                logger.info(u"Sleeping for %(wait).1f seconds, %(now)s"
-                              % {'wait': wait,
-                                 'now': time.strftime("%Y-%m-%d %H:%M:%S",
-                                                      time.localtime())
-                                } )
+                pywikibot.output(u"Sleeping for %(wait).1f seconds, %(now)s"
+                                  % {'wait': wait,
+                                     'now': time.strftime("%Y-%m-%d %H:%M:%S",
+                                                          time.localtime())
+                                    } )
             time.sleep(wait)
             if write:
                 self.last_write = time.time()
@@ -262,11 +263,12 @@
             wait = delay - (time.time() - started)
             if wait > 0:
                 if wait > config.noisysleep:
-                    logger.info(u"Sleeping for %(wait).1f seconds, %(now)s"
-                                  % {'wait': wait,
-                                     'now': time.strftime("%Y-%m-%d %H:%M:%S",
-                                                          time.localtime())
-                                    } )
+                    pywikibot.output(
+                              u"Sleeping for %(wait).1f seconds, %(now)s"
+                               % {'wait': wait,
+                                  'now': time.strftime("%Y-%m-%d %H:%M:%S",
+                                                       time.localtime())
+                                 } )
                 time.sleep(wait)
         finally:
             self.lock.release()

Modified: branches/rewrite/pywikibot/userinterfaces/terminal_interface.py
===================================================================
--- branches/rewrite/pywikibot/userinterfaces/terminal_interface.py     
2008-12-23 17:13:12 UTC (rev 6190)
+++ branches/rewrite/pywikibot/userinterfaces/terminal_interface.py     
2008-12-23 19:37:49 UTC (rev 6191)
@@ -6,16 +6,21 @@
 #
 __version__ = '$Id$'
 
-import config, transliteration
+
 import traceback, re, sys
-import wikipedia
+import logging
+import pywikibot
+from pywikibot import config
+from pywikibot.userinterfaces import transliteration
 
+
 try:
     import ctypes
     ctypes_found = True
 except ImportError:
     ctypes_found = False
 
+
 def getDefaultTextColorInWindows():
     """
     This method determines the default text color and saves its color
@@ -112,16 +117,15 @@
     def __init__(self):
         pass
 
-    def printColorizedInUnix(self, text, targetStream):
+    def printColorizedInUnix(self, text, level):
         lastColor = None
         for key, value in unixColors.iteritems():
             text = text.replace('\03{%s}' % key, value)
         # just to be sure, reset the color
         text += unixColors['default']
+        logging.log(level, text)
 
-        targetStream.write(text.encode(config.console_encoding, 'replace'))
-
-    def printColorizedInWindows(self, text, targetStream):
+    def printColorizedInWindows(self, text, level):
         """
         This only works in Python 2.5 or higher.
         """
@@ -135,7 +139,7 @@
                 tagM = colorTagR.search(text)
                 if tagM:
                     # print the text up to the tag.
-                    
targetStream.write(text[:tagM.start()].encode(config.console_encoding, 
'replace'))
+                    logging.log(level, text[:tagM.start()])
                     newColor = tagM.group('name')
                     if newColor == 'default':
                         if len(colorStack) > 0:
@@ -151,7 +155,7 @@
                         
ctypes.windll.kernel32.SetConsoleTextAttribute(std_out_handle, 
windowsColors[newColor])
                     text = text[tagM.end():]
             # print the rest of the text
-            targetStream.write(text.encode(config.console_encoding, 'replace'))
+            logging.log(level, text)
             # just to be sure, reset the color
             ctypes.windll.kernel32.SetConsoleTextAttribute(std_out_handle, 
windowsColors['default'])
         else:
@@ -164,18 +168,18 @@
                 if count > 0:
                     line += '***'
                 line += '\n'
-                targetStream.write(line.encode(config.console_encoding, 
'replace'))
+                logging.log(level, line)
 
-    def printColorized(self, text, targetStream):
+    def printColorized(self, text, level):
         if config.colorized_output:
             if sys.platform == 'win32':
-                self.printColorizedInWindows(text, targetStream)
+                self.printColorizedInWindows(text, level)
             else:
-                self.printColorizedInUnix(text, targetStream)
+                self.printColorizedInUnix(text, level)
         else:
-            targetStream.write(text.encode(config.console_encoding, 'replace'))
+            logging.log(level, text)
 
-    def output(self, text, toStdout = False):
+    def output(self, text, level=logging.INFO):
         """
         If a character can't be displayed in the encoding used by the user's
         terminal, it will be replaced with a question mark or by a
@@ -212,11 +216,7 @@
                     prev = codecedText[i]
             text = transliteratedText
 
-        if toStdout:
-            targetStream = sys.stdout
-        else:
-            targetStream = sys.stderr
-        self.printColorized(text, targetStream)
+        self.printColorized(text, level)
 
     def input(self, question, password = False):
         """
@@ -229,8 +229,7 @@
         # sound the terminal bell to notify the user
         if config.ring_bell:
             sys.stdout.write('\07')
-        # TODO: make sure this is logged as well
-        self.output(question + ' ')
+        self.output(question + ' ', level=pywikibot.INPUT)
         if password:
             import getpass
             text = getpass.getpass('')
@@ -239,7 +238,7 @@
         text = unicode(text, config.console_encoding)
         return text
 
-    def inputChoice(self, question, options, hotkeys, default = None):
+    def inputChoice(self, question, options, hotkeys, default=None):
         options = options[:] # we don't want to edit the passed parameter
         for i in range(len(options)):
             option = options[i]
@@ -279,7 +278,7 @@
             print 'Could not load GUI modules: %s' % e
             return text
         editor = gui.EditBoxWindow()
-        return editor.edit(text, jumpIndex = jumpIndex, highlight = highlight)
+        return editor.edit(text, jumpIndex=jumpIndex, highlight=highlight)
 
     def askForCaptcha(self, url):
         try:



_______________________________________________
Pywikipedia-l mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikipedia-l

Reply via email to