Browse Source

More fixes and tweaks; cleanup; etc.

tags/v0.1^2
Ben Kurtovic 12 years ago
parent
commit
8d8703358c
3 changed files with 43 additions and 24 deletions
  1. +1
    -1
      earwigbot/config/ordered_yaml.py
  2. +36
    -19
      earwigbot/config/script.py
  3. +6
    -4
      earwigbot/wiki/copyvios/__init__.py

+ 1
- 1
earwigbot/config/ordered_yaml.py View File

@@ -74,7 +74,7 @@ class OrderedLoader(yaml.Loader):
return mapping return mapping




class OrderedDumper(yaml.Dumper):
class OrderedDumper(yaml.SafeDumper):
"""A YAML dumper that dumps ordered dictionaries into mappings.""" """A YAML dumper that dumps ordered dictionaries into mappings."""


def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):


+ 36
- 19
earwigbot/config/script.py View File

@@ -118,8 +118,13 @@ class ConfigScript(object):
if answer.startswith("n"): if answer.startswith("n"):
return False return False


def _ask_pass(self, text):
def _ask_pass(self, text, encrypt=True):
password = getpass(self.PROMPT + text + " ") password = getpass(self.PROMPT + text + " ")
if encrypt:
return self._encrypt(password)
return password

def _encrypt(self, password):
if self._cipher: if self._cipher:
mod = len(password) % 8 mod = len(password) % 8
if mod: if mod:
@@ -213,14 +218,17 @@ class ConfigScript(object):
question = "Would you like to re-enter your login information?" question = "Would you like to re-enter your login information?"
if self._ask_bool(question): if self._ask_bool(question):
self.data["wiki"]["username"] = self._ask("Bot username:") self.data["wiki"]["username"] = self._ask("Bot username:")
self.data["wiki"]["password"] = self._ask_pass("Bot password:")
password = self._ask_pass("Bot password:", encrypt=False)
self.data["wiki"]["password"] = password
return self._login(kwargs) return self._login(kwargs)
else:
password = self.data["wiki"]["password"]
question = "Would you like to re-enter the site information?" question = "Would you like to re-enter the site information?"
if self._ask_bool(question): if self._ask_bool(question):
return self._set_wiki() return self._set_wiki()
print
self._print("""Moving on. You can modify the login information self._print("""Moving on. You can modify the login information
stored in the bot's config in the future.""") stored in the bot's config in the future.""")
password = self.data["wiki"]["password"]
self.data["wiki"]["password"] = None # Clear so we don't login self.data["wiki"]["password"] = None # Clear so we don't login
self.config.wiki._load(self.data["wiki"]) self.config.wiki._load(self.data["wiki"])
self._print_no_nl("Trying to connect to the site...") self._print_no_nl("Trying to connect to the site...")
@@ -229,6 +237,10 @@ class ConfigScript(object):
self.data["wiki"]["password"] = password # Reset original value self.data["wiki"]["password"] = password # Reset original value
else: else:
print " success." print " success."

# Remember to store the encrypted password:
password = self._encrypt(self.data["wiki"]["password"])
self.data["wiki"]["password"] = password
return site return site


def _set_wiki(self): def _set_wiki(self):
@@ -249,7 +261,8 @@ class ConfigScript(object):
kwargs = {"base_url": url, "script_path": script} kwargs = {"base_url": url, "script_path": script}


self.data["wiki"]["username"] = self._ask("Bot username:") self.data["wiki"]["username"] = self._ask("Bot username:")
self.data["wiki"]["password"] = self._ask_pass("Bot password:")
password = self._ask_pass("Bot password:", encrypt=False)
self.data["wiki"]["password"] = password
self.data["wiki"]["userAgent"] = "EarwigBot/$1 (Python/$2; https://github.com/earwig/earwigbot)" self.data["wiki"]["userAgent"] = "EarwigBot/$1 (Python/$2; https://github.com/earwig/earwigbot)"
self.data["wiki"]["summary"] = "([[WP:BOT|Bot]]): $2" self.data["wiki"]["summary"] = "([[WP:BOT|Bot]]): $2"
self.data["wiki"]["useHTTPS"] = True self.data["wiki"]["useHTTPS"] = True
@@ -275,7 +288,8 @@ class ConfigScript(object):
current task number. This can be used to implement a current task number. This can be used to implement a
separate shutoff page for each task.""") separate shutoff page for each task.""")
page = self._ask("Page title:", default="User:$1/Shutoff") page = self._ask("Page title:", default="User:$1/Shutoff")
disabled = self._ask("Page content when *not* shut off:", "run")
msg = "Page content to indicate the bot is *not* shut off:"
disabled = self._ask(msg, "run")
args = [("page", page), ("disabled", disabled)] args = [("page", page), ("disabled", disabled)]
self.data["wiki"]["shutoff"] = OrderedDict(args) self.data["wiki"]["shutoff"] = OrderedDict(args)


@@ -305,9 +319,9 @@ class ConfigScript(object):
can use certain sensitive commands) and owners can use certain sensitive commands) and owners
(users who can quit the bot and modify its access (users who can quit the bot and modify its access
list), identified by nick, ident, and/or hostname. list), identified by nick, ident, and/or hostname.
Hostname is most secure since it cannot be easily
spoofed. If you have a cloak, it will probably look
like 'wikipedia/Username' or
Hostname is the most secure option since it cannot
be easily spoofed. If you have a cloak, this will
probably look like 'wikipedia/Username' or
'unaffiliated/nickname'.""") 'unaffiliated/nickname'.""")
host = self._ask("Your hostname on the IRC frontend:") host = self._ask("Your hostname on the IRC frontend:")
if host: if host:
@@ -329,7 +343,7 @@ class ConfigScript(object):
watcher["host"] = self._ask(msg) watcher["host"] = self._ask(msg)
watcher["port"] = self._ask("Watcher port:", 6667) watcher["port"] = self._ask("Watcher port:", 6667)
nick = self._ask("Watcher bot's nickname:", frontend.get("nick")) nick = self._ask("Watcher bot's nickname:", frontend.get("nick"))
ident = self._ask("Watcher bot's ident:", watcher["nick"].lower())
ident = self._ask("Watcher bot's ident:", nick.lower())
watcher["nick"] = nick watcher["nick"] = nick
watcher["ident"] = ident watcher["ident"] = ident
question = "Watcher bot's real name (gecos):" question = "Watcher bot's real name (gecos):"
@@ -350,9 +364,9 @@ class ConfigScript(object):
self._print("""I am now creating a blank 'rules.py' file, which self._print("""I am now creating a blank 'rules.py' file, which
will determine how the bot handles messages received will determine how the bot handles messages received
from the IRC watcher. It contains a process() from the IRC watcher. It contains a process()
function that takes a Bot object allowing you to
start tasks and an RC object that holds the message
from the watcher. See the documentation for
function that takes a Bot object (allowing you to
start tasks) and an RC object (storing the message
from the watcher). See the documentation for
details.""") details.""")
with open(path.join(self.config.root_dir, "rules.py"), "w") as fp: with open(path.join(self.config.root_dir, "rules.py"), "w") as fp:
fp.write(RULES_TEMPLATE) fp.write(RULES_TEMPLATE)
@@ -367,6 +381,7 @@ class ConfigScript(object):
if (not self.data["components"]["irc_frontend"] or if (not self.data["components"]["irc_frontend"] or
self._ask_bool(msg, default=False)): self._ask_bool(msg, default=False)):
self.data["commands"]["disable"] = True self.data["commands"]["disable"] = True
print
self._print("""I am now creating the 'commands/' directory, where you self._print("""I am now creating the 'commands/' directory, where you
can place custom IRC commands and plugins. Creating your can place custom IRC commands and plugins. Creating your
own commands is described in the documentation.""") own commands is described in the documentation.""")
@@ -382,29 +397,31 @@ class ConfigScript(object):
self._pause() self._pause()


def _set_schedule(self): def _set_schedule(self):
print
self._print("""The final section of your config file, 'schedule', is a self._print("""The final section of your config file, 'schedule', is a
list of bot tasks to be started by the wiki scheduler. list of bot tasks to be started by the wiki scheduler.
Each entry contains cron-like time quantifiers and a Each entry contains cron-like time quantifiers and a
list of tasks. For example, the following starts the list of tasks. For example, the following starts the
'foobot' task every hour on the half-hour:""") 'foobot' task every hour on the half-hour:""")
print "schedule:"
print "\x1b[33mschedule:"
print " - minute: 30" print " - minute: 30"
print " tasks:" print " tasks:"
print " - foobot"
print " - foobot\x1b[0m"
self._print("""The following starts the 'barbot' task with the keyword self._print("""The following starts the 'barbot' task with the keyword
arguments 'action="baz"' every Monday at 05:00 UTC:""") arguments 'action="baz"' every Monday at 05:00 UTC:""")
print " - week_day: 1"
print "\x1b[33m - week_day: 1"
print " hour: 5" print " hour: 5"
print " tasks:" print " tasks:"
print ' - ["barbot", {"action": "baz"}]'
print ' - ["barbot", {"action": "baz"}]\x1b[0m'
self._print("""The full list of quantifiers is minute, hour, month_day, self._print("""The full list of quantifiers is minute, hour, month_day,
month, and week_day. See the documentation for more month, and week_day. See the documentation for more
details.""")
information.""")
self._pause() self._pause()


def _save(self): def _save(self):
with open(self.config.path, "w") as strm:
yaml.dump(self.data, strm, OrderedDumper, default_flow_style=False)
with open(self.config.path, "w") as stream:
yaml.dump(self.data, stream, OrderedDumper, indent=4,
allow_unicode=True, default_flow_style=False)


def make_new(self): def make_new(self):
"""Make a new config file based on the user's input.""" """Make a new config file based on the user's input."""


+ 6
- 4
earwigbot/wiki/copyvios/__init__.py View File

@@ -52,7 +52,7 @@ class CopyvioMixIn(object):


def __init__(self, site): def __init__(self, site):
self._search_config = site._search_config self._search_config = site._search_config
self._exclusions_db = self._search_config["exclusions_db"]
self._exclusions_db = self._search_config.get("exclusions_db")
self._opener = build_opener() self._opener = build_opener()
self._opener.addheaders = site._opener.addheaders self._opener.addheaders = site._opener.addheaders


@@ -137,7 +137,8 @@ class CopyvioMixIn(object):
:py:exc:`~earwigbot.exceptions.SearchQueryError`, ...) on errors. :py:exc:`~earwigbot.exceptions.SearchQueryError`, ...) on errors.
""" """
searcher = self._select_search_engine() searcher = self._select_search_engine()
self._exclusions_db.sync(self.site.name)
if self._exclusions_db:
self._exclusions_db.sync(self.site.name)
handled_urls = [] handled_urls = []
best_confidence = 0 best_confidence = 0
best_match = None best_match = None
@@ -163,8 +164,9 @@ class CopyvioMixIn(object):
urls = [url for url in urls if url not in handled_urls] urls = [url for url in urls if url not in handled_urls]
for url in urls: for url in urls:
handled_urls.append(url) handled_urls.append(url)
if self._exclusions_db.check(self.site.name, url):
continue
if self._exclusions_db:
if self._exclusions_db.check(self.site.name, url):
continue
conf, chains = self._copyvio_compare_content(article_chain, url) conf, chains = self._copyvio_compare_content(article_chain, url)
if conf > best_confidence: if conf > best_confidence:
best_confidence = conf best_confidence = conf


Loading…
Cancel
Save