# HG changeset patch # User Paul Boddie # Date 1374168286 -7200 # Node ID db03adb5f2e3c4066606a1da5c0e0a81f5d8c681 # Parent e425db7daf2380bb73cc35735bd55278dd1b6d84 Added tools to acquire user details from Confluence and to add users to MoinMoin. diff -r e425db7daf23 -r db03adb5f2e3 README.txt --- a/README.txt Wed Jul 17 18:07:43 2013 +0200 +++ b/README.txt Thu Jul 18 19:24:46 2013 +0200 @@ -136,6 +136,31 @@ or it should be placed in a different location and the MAPPING_ID_TO_PAGE variable changed in the script to refer to this different location. +Identifying and Migrating Users +------------------------------- + +Confluence export archives do not contain user profile information, but page +versions are marked with user identifiers. Therefore, a list of user +identifiers can be obtained by running a script extracting these identifiers. +The following command writes to standard output the users involved with +editing the wiki in four different spaces (exported to four directories): + +tools/users.sh COM DEV DOC SEC + +This output can be edited and then passed to a special user administration +program as follows: + +tools/users.sh COM DEV DOC SEC > users.txt # for editing +cat users.txt | tools/addusers.py wiki http://wiki.list.org/ + +If no users are to be removed in migration, the following command could be +issued: + +tools/users.sh COM DEV DOC SEC | tools/addusers.py wiki http://wiki.list.org/ + +The addusers.py program needs to be told the directory containing the wiki +configuration as well as the URL of the original Confluence site. + Output Structure ---------------- diff -r e425db7daf23 -r db03adb5f2e3 tools/addusers.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/addusers.py Thu Jul 18 19:24:46 2013 +0200 @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +""" +Add users to a MoinMoin wiki, fetching the profile of each user from a +Confluence site in order to obtain name and e-mail details. + +User details are written to standard output in a tab-separated sequence using +the following format: + +USERNAME FULLNAME EMAIL IMAGE-URL PASSWORD +""" + +from time import sleep +from os.path import split +from subprocess import call +import random, string +import sys + +this_dir = split(sys.argv[0])[0] +sys.path.append(this_dir) + +from get_profile import get_profile + +def randompass(): + return "".join(random.sample(string.ascii_letters, 10)) + +def add_user(wiki, username, fullname, email, password): + cmd = ["moin", "--config-dir=%s" % wiki, "account", "create", + "--name=%s" % username, + "--email=%s" % email, + "--password=%s" % password] + \ + (fullname and ["--alias=%s" % fullname] or []) + call(cmd) + +def main(): + progname = split(sys.argv[0])[-1] + + try: + wiki = sys.argv[1] + url = sys.argv[2] + delay = int((sys.argv[3:4] or ["1"])[0]) + except (IndexError, ValueError): + print >>sys.stderr, "%s [ ]" % progname + print >>sys.stderr + print >>sys.stderr, "Example: %s wiki http://wiki.list.org/" % progname + sys.exit(1) + + line = sys.stdin.readline() + while line: + username = line.strip() + username, fullname, email, image = get_profile(url, username) + password = randompass() + add_user(wiki, username, fullname, email, password) + print "\t".join([username, fullname, email, image, password]) + + sleep(delay) + line = sys.stdin.readline() + +if __name__ == "__main__": + main() + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r e425db7daf23 -r db03adb5f2e3 tools/get_profile.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/get_profile.py Thu Jul 18 19:24:46 2013 +0200 @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +""" +Fetch the profile of a user from a Confluence site, printing their profile +details in a tab-separated sequence using the following format: + +USERNAME FULLNAME EMAIL IMAGE-URL +""" + +from os.path import split +from urllib import basejoin +import libxml2dom, sys + +def get_profile(url, username): + try: + d = libxml2dom.parseURI("%s/display/~%s" % (url.rstrip("/"), username), html=True) + + fullname = d.xpath("//span[@id='fullName']") + fullname = fullname and fullname[0].textContent or "" + email = d.xpath("//span[@id='email']") + email = email and email[0].textContent.replace(" at ", "@").replace(" dot ", ".") or "" + image = d.xpath("//img[contains(@class, 'userLogo')]/@src") + image = image and image[0].textContent or "" + + return [username, fullname, email, image and basejoin(url, image) or ""] + + except libxml2dom.LSException: + return [username, "", username, ""] + +def main(): + progname = split(sys.argv[0])[-1] + + try: + url = sys.argv[1] + username = sys.argv[2] + except IndexError: + print >>sys.stderr, "%s " % progname + print >>sys.stderr + print >>sys.stderr, "Example: %s http://wiki.list.org/ " % progname + sys.exit(1) + + details = get_profile(url, username) + print "\t".join(details) + +if __name__ == "__main__": + main() + +# vim: tabstop=4 expandtab shiftwidth=4