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: