From 728289bc6965a82999388a0aa4979854296d8058 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 10:32:28 -0700 Subject: [PATCH 01/20] be gentle with __name__ == __main__ --- confluence.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/confluence.py b/confluence.py index daca23b..51d91c3 100755 --- a/confluence.py +++ b/confluence.py @@ -446,7 +446,7 @@ def Actions(token,xml_server,args,content): print(("Error: %d: %s") % (err.faultCode, err.faultString)) -def main(): +if __name__ == "__main__": args = Parser() if args.verbose: @@ -455,5 +455,3 @@ def main(): content = Content(args) server = Connect(args) Actions(server["token"],server["xml_server"],args,content) - -main() From ba2d4b2e7f9ebd9e8d37a2ad535b99c7f38cdc32 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 10:37:09 -0700 Subject: [PATCH 02/20] split into different files --- confluence/__init__.py | 5 ++++ confluence/auth.py | 9 ++++++ confluence/group.py | 14 +++++++++ confluence/page.py | 66 ++++++++++++++++++++++++++++++++++++++++++ confluence/space.py | 28 ++++++++++++++++++ confluence/user.py | 42 +++++++++++++++++++++++++++ 6 files changed, 164 insertions(+) create mode 100644 confluence/__init__.py create mode 100644 confluence/auth.py create mode 100644 confluence/group.py create mode 100644 confluence/page.py create mode 100644 confluence/space.py create mode 100644 confluence/user.py diff --git a/confluence/__init__.py b/confluence/__init__.py new file mode 100644 index 0000000..2b3d5d8 --- /dev/null +++ b/confluence/__init__.py @@ -0,0 +1,5 @@ +from .auth import ConfluenceAuth +from .group import ConfluenceGroup +from .page import ConfluencePage +from .space import ConfluenceSpace +from .user import ConfluenceUser diff --git a/confluence/auth.py b/confluence/auth.py new file mode 100644 index 0000000..3bda035 --- /dev/null +++ b/confluence/auth.py @@ -0,0 +1,9 @@ +class ConfluenceAuth(object): + def __init__(self,server,username,password): + self.server = server + self.username = username + self.password = password + + def login(self): + self.token = self.server.confluence2.login(self.username, self.password) + return self.token diff --git a/confluence/group.py b/confluence/group.py new file mode 100644 index 0000000..92ed17d --- /dev/null +++ b/confluence/group.py @@ -0,0 +1,14 @@ +class ConfluenceGroup(object): + def __init__(self,token,server,groupname): + self.server = server + self.token = token + self.groupname = groupname + + def get_all(self): + return self.server.confluence2.getGroups(self.token) + + def add(self): + self.server.confluence2.addGroup(self.token,self.groupname) + + def remove(self): + self.server.confluence2.removeGroup(self.token,self.groupname,"confluence-users") diff --git a/confluence/page.py b/confluence/page.py new file mode 100644 index 0000000..8aae0b1 --- /dev/null +++ b/confluence/page.py @@ -0,0 +1,66 @@ +class ConfluencePage(object): + def __init__(self,token,server,name,spaceKey,content,page_id="",label=""): + self.server = server + self.token = token + self.name = name + self.spaceKey = spaceKey + self.content = content + self.label = label + self.logger = logging.getLogger( + __name__ + '.'+ self.__class__.__name__ + ) + self.logger.debug('Creating a new instance (name="{}", label="{}")'.format(name, label)) + + def add(self,parent_id=0,content=""): + self.logger.debug("Add page '{}'; label = [{}]".format(self.name, self.label)) + if content: + self.content = content + self.parent_id = parent_id + self.newPost = {"title":self.name,"content":self.content,"space":self.spaceKey,"parentId":str(self.parent_id)} + self.post_to_wiki = self.server.confluence2.storePage(self.token,self.newPost) + self.created_page = self.server.confluence2.getPage(self.token, self.spaceKey, self.name) + self.page_url = self.created_page["url"] + self.page_id = self.created_page["id"] + if self.label: + self.set_label() + return {"url": self.page_url, "id": self.page_id} + + def update(self,content,parent_id=0): + self.remove() + self.parent_id = parent_id + self.add(str(parent_id),content) + + def get(self): + self.wanted_page = self.server.confluence2.getPage(self.token, self.spaceKey, self.name) + return self.wanted_page + + def get_content(self): + self.wanted_page_id = self.get_page_id + self.content_values = {"style": "clean"} + self.page_content = self.wanted_page = self.server.confluence2.renderContet(self.token, self.wanted_page_id,self.content_values) + return self.page_content + + + def get_id(self): + return self.get()['id'] + + def get_content(self): + return self.get()['content'] + + def remove(self): + self.page = self.server.confluence2.getPage(self.token, self.spaceKey, self.name) + self.server.confluence2.removePage(self.token, self.page["id"]) + + def set_label(self): + self.page_id = self.get_id() + self.logger.debug("Set label '{}' on page {}".format( + self.label, self.page_id)) + if not self.server.confluence2.addLabelByName(self.token, self.label, self.page_id): + self.logger.debug("Unable to set label '{}' on page ID {}".format( + self.label, self.page_id)) + + def get_content(self): + return self.get()['content'] + + def get_version(self): + return self.get()['version'] diff --git a/confluence/space.py b/confluence/space.py new file mode 100644 index 0000000..8f1da37 --- /dev/null +++ b/confluence/space.py @@ -0,0 +1,28 @@ +class ConfluenceSpace(object): + def __init__(self, token, server): + self.server = server + self.token = token + + def get_all(self): + self.spaces = self.server.confluence2.getSpaces(self.token) + return self.spaces + + def get_by_key(self,space_key): + self.space_key = space_key + self.space = self.server.confluence2.getSpace(self.token,self.space_key) + return self.space + + def create(self,space_key,space_name): + self.space_key = space_key + self.space_name = space_name + self.space_to_create = {"key":self.space_key,"name":self.space_name} + self.server.confluence2.addSpace(self.token,self.space_to_create) + return self.get_by_key(space_key) + + def remove(self,space_key): + self.space_key = space_key + self.server.confluence2.removeSpace(self.token,self.space_key) + + def get_all_pages(self,spaceKey): + self.spacekey = spaceKey + return self.server.confluence2.getPages(self.token, self.spacekey) diff --git a/confluence/user.py b/confluence/user.py new file mode 100644 index 0000000..4107170 --- /dev/null +++ b/confluence/user.py @@ -0,0 +1,42 @@ +class ConfluenceUser(object): + def __init__(self,token,server,username): + self.server = server + self.token = token + self.username = username + + def create(self,full_name,email,password): + self.password = password + self.email = email + self.full_name = full_name + self.user_to_create = {"name":self.username,"fullname":self.full_name,"email":self.email} + self.server.confluence2.addUser(self.token,self.user_to_create,self.password) + + def get_info(self): + return self.server.confluence2.getUser(self.token,self.username) + + def get_groups(self): + return self.server.confluence2.getUserGroups(self.token,self.username) + + def remove(self): + self.server.confluence2.removeUser(self.token,self.username) + + def deactivate(self): + self.server.confluence2.deactivateUser(self.token,self.username) + + def reactivate(self): + self.server.confluence2.reactivateUser(self.token,self.username) + + def add_to_group(self,group): + self.group = group + self.server.confluence2.addUserToGroup(self.token,self.username,self.group) + + def remove_from_group(self,group): + self.group = group + self.server.confluence2.removeUserFromGroup(self.token,self.username,self.group) + + def change_password(self,password): + self.password = password + self.server.confluence2.changeUserPassword(self.token,self.username,self.password) + + def get_all(self): + return self.server.confluence2.getActiveUsers(self.token, True) From c20c3468118bf0af263bdd2db889a0976161119a Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 10:45:57 -0700 Subject: [PATCH 03/20] let's simplify things --- confluence.py => confluence-cli | 177 +------------------------------- confluence/__init__.py | 1 + confluence/api.py | 10 ++ confluence/page.py | 3 + 4 files changed, 19 insertions(+), 172 deletions(-) rename confluence.py => confluence-cli (69%) create mode 100644 confluence/api.py diff --git a/confluence.py b/confluence-cli similarity index 69% rename from confluence.py rename to confluence-cli index 51d91c3..8e34aa2 100755 --- a/confluence.py +++ b/confluence-cli @@ -16,6 +16,8 @@ import sys, xmlrpclib, argparse, string, logging +from confluence import connect, ConfluenceGroup, ConfluencePage, ConfluenceSpace, ConfluenceUser + # # Logging # @@ -29,173 +31,6 @@ logger.addHandler(console_handler) -class ConfluenceSpace(object): - def __init__(self, token, server): - self.server = server - self.token = token - - def get_all(self): - self.spaces = self.server.confluence2.getSpaces(self.token) - return self.spaces - - def get_by_key(self,space_key): - self.space_key = space_key - self.space = self.server.confluence2.getSpace(self.token,self.space_key) - return self.space - - def create(self,space_key,space_name): - self.space_key = space_key - self.space_name = space_name - self.space_to_create = {"key":self.space_key,"name":self.space_name} - self.server.confluence2.addSpace(self.token,self.space_to_create) - return self.get_by_key(space_key) - - def remove(self,space_key): - self.space_key = space_key - self.server.confluence2.removeSpace(self.token,self.space_key) - - def get_all_pages(self,spaceKey): - self.spacekey = spaceKey - return self.server.confluence2.getPages(self.token, self.spacekey) - -class ConfluenceGroup(object): - def __init__(self,token,server,groupname): - self.server = server - self.token = token - self.groupname = groupname - - def get_all(self): - return self.server.confluence2.getGroups(self.token) - - def add(self): - self.server.confluence2.addGroup(self.token,self.groupname) - - def remove(self): - self.server.confluence2.removeGroup(self.token,self.groupname,"confluence-users") - - -class ConfluenceUser(object): - def __init__(self,token,server,username): - self.server = server - self.token = token - self.username = username - - def create(self,full_name,email,password): - self.password = password - self.email = email - self.full_name = full_name - self.user_to_create = {"name":self.username,"fullname":self.full_name,"email":self.email} - self.server.confluence2.addUser(self.token,self.user_to_create,self.password) - - def get_info(self): - return self.server.confluence2.getUser(self.token,self.username) - - def get_groups(self): - return self.server.confluence2.getUserGroups(self.token,self.username) - - def remove(self): - self.server.confluence2.removeUser(self.token,self.username) - - def deactivate(self): - self.server.confluence2.deactivateUser(self.token,self.username) - - def reactivate(self): - self.server.confluence2.reactivateUser(self.token,self.username) - - def add_to_group(self,group): - self.group = group - self.server.confluence2.addUserToGroup(self.token,self.username,self.group) - - def remove_from_group(self,group): - self.group = group - self.server.confluence2.removeUserFromGroup(self.token,self.username,self.group) - - def change_password(self,password): - self.password = password - self.server.confluence2.changeUserPassword(self.token,self.username,self.password) - - def get_all(self): - return self.server.confluence2.getActiveUsers(self.token, True) - - - -class ConfluencePage(object): - def __init__(self,token,server,name,spaceKey,content,page_id="",label=""): - self.server = server - self.token = token - self.name = name - self.spaceKey = spaceKey - self.content = content - self.label = label - self.logger = logging.getLogger( - __name__ + '.'+ self.__class__.__name__ - ) - self.logger.debug('Creating a new instance (name="{}", label="{}")'.format(name, label)) - - def add(self,parent_id=0,content=""): - self.logger.debug("Add page '{}'; label = [{}]".format(self.name, self.label)) - if content: - self.content = content - self.parent_id = parent_id - self.newPost = {"title":self.name,"content":self.content,"space":self.spaceKey,"parentId":str(self.parent_id)} - self.post_to_wiki = self.server.confluence2.storePage(self.token,self.newPost) - self.created_page = self.server.confluence2.getPage(self.token, self.spaceKey, self.name) - self.page_url = self.created_page["url"] - self.page_id = self.created_page["id"] - if self.label: - self.set_label() - return {"url": self.page_url, "id": self.page_id} - - def update(self,content,parent_id=0): - self.remove() - self.parent_id = parent_id - self.add(str(parent_id),content) - - def get(self): - self.wanted_page = self.server.confluence2.getPage(self.token, self.spaceKey, self.name) - return self.wanted_page - - def get_content(self): - self.wanted_page_id = self.get_page_id - self.content_values = {"style": "clean"} - self.page_content = self.wanted_page = self.server.confluence2.renderContet(self.token, self.wanted_page_id,self.content_values) - return self.page_content - - - def get_id(self): - return self.get()['id'] - - def get_content(self): - return self.get()['content'] - - def remove(self): - self.page = self.server.confluence2.getPage(self.token, self.spaceKey, self.name) - self.server.confluence2.removePage(self.token, self.page["id"]) - - def set_label(self): - self.page_id = self.get_id() - self.logger.debug("Set label '{}' on page {}".format( - self.label, self.page_id)) - if not self.server.confluence2.addLabelByName(self.token, self.label, self.page_id): - self.logger.debug("Unable to set label '{}' on page ID {}".format( - self.label, self.page_id)) - - def get_content(self): - return self.get()['content'] - - def get_version(self): - return self.get()['version'] - -class ConfluenceAuth(object): - def __init__(self,server,username,password): - self.server = server - self.username = username - self.password = password - - def login(self): - self.token = self.server.confluence2.login(self.username, self.password) - return self.token - def error_out(error_message): print("Error: ") print(error_message) @@ -315,13 +150,11 @@ def Content(args): return content def Connect(args): - wiki_url = args.wikiurl + "/rpc/xmlrpc" - xml_server = xmlrpclib.Server(wiki_url) try: - token = ConfluenceAuth(xml_server,args.username,args.password).login() + api_resp = connect(args.wikiurl, args.username, args.password) except xmlrpclib.Fault as err: - error_out("%d: %s" % ( err.faultCode, err.faultString)) - return {"token":token,"xml_server":xml_server} + error_out("%d: %s" % (err.faultCode, err.faultString)) + return api_resp def Actions(token,xml_server,args,content): diff --git a/confluence/__init__.py b/confluence/__init__.py index 2b3d5d8..5721a8c 100644 --- a/confluence/__init__.py +++ b/confluence/__init__.py @@ -1,3 +1,4 @@ +from .api import connect from .auth import ConfluenceAuth from .group import ConfluenceGroup from .page import ConfluencePage diff --git a/confluence/api.py b/confluence/api.py new file mode 100644 index 0000000..cb8e381 --- /dev/null +++ b/confluence/api.py @@ -0,0 +1,10 @@ +import xmlrpclib + +from .auth import ConfluenceAuth + + +def connect(url, username, password): + url = "%s/rpc/xmlrpc" % url + xml_server = xmlrpclib.Server(url) + token = ConfluenceAuth(xml_server, username, password).login() + return {"token": token, "xml_server": xml_server} diff --git a/confluence/page.py b/confluence/page.py index 8aae0b1..648aff2 100644 --- a/confluence/page.py +++ b/confluence/page.py @@ -1,3 +1,6 @@ +import logging + + class ConfluencePage(object): def __init__(self,token,server,name,spaceKey,content,page_id="",label=""): self.server = server From 99a5590051b717a24c725b00a5f676d28be40187 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 10:46:06 -0700 Subject: [PATCH 04/20] gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc From faddedba0bda89bb85e9dd4db278310ce1c7af19 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 11:08:20 -0700 Subject: [PATCH 05/20] page actions in the Api --- confluence-cli | 39 +++++++++++++------------------- confluence/__init__.py | 2 +- confluence/api.py | 50 +++++++++++++++++++++++++++++++++++++----- confluence/page.py | 3 +-- 4 files changed, 62 insertions(+), 32 deletions(-) diff --git a/confluence-cli b/confluence-cli index 8e34aa2..c42f014 100755 --- a/confluence-cli +++ b/confluence-cli @@ -16,7 +16,7 @@ import sys, xmlrpclib, argparse, string, logging -from confluence import connect, ConfluenceGroup, ConfluencePage, ConfluenceSpace, ConfluenceUser +from confluence import Api, ConfluenceGroup, ConfluencePage, ConfluenceSpace, ConfluenceUser # # Logging @@ -151,51 +151,42 @@ def Content(args): def Connect(args): try: - api_resp = connect(args.wikiurl, args.username, args.password) + api = Api(args.wikiurl, args.username, args.password) except xmlrpclib.Fault as err: error_out("%d: %s" % (err.faultCode, err.faultString)) - return api_resp + return {"token": api.token, "xml_server": api.server} -def Actions(token,xml_server,args,content): +def Actions(api, args, content): try: if args.action == "addpage": logger.debug('Command: "addpage", args.name = "{}", args.label = "{}"'.format( args.name, args.label)) - new_page = ConfluencePage( - token,xml_server,args.name,args.spacekey,content,label=args.label) - new_page.add(args.parentpage) + new_page = api.addpage(ags.name, args.spacekey, content, args.label, args.parentpage) print(new_page.get()["url"]) elif args.action == "updatepage": - update_page = ConfluencePage(token,xml_server,args.name,args.spacekey,content,args.parentpage,label=args.label) - update_page.update(content,args.parentpage) - update_page.set_label() - print(update_page.get()['url']) + page = api.updatepage(args.name, args.spacekey, content, args.parentpage, args.label) + print(page.get()['url']) elif args.action == "getpagecontent": - get_page = ConfluencePage(token,xml_server,args.name,args.spacekey,content).get_content() - print(get_page) + content = api.getpagecontent(args.name, args.spacekey) + print(content) elif args.action == "getpagesummary": - page = ConfluencePage(token,xml_server,args.name,args.spacekey,content).get() + page = api.getpage(args.name, args.spacekey) print args.delimiter.join(( page['id'], page['space'], page['parentId'], page['title'], page['url'])) elif args.action == "listpages": - if args.spacekey == "": - spaces = ConfluenceSpace(token,xml_server).get_all() - else: - spaces = [ConfluenceSpace(token,xml_server).get_by_key(args.spacekey)] - for space in spaces: - all_pages = ConfluenceSpace(token,xml_server).get_all_pages(space['key']) - for page in all_pages: - print args.delimiter.join(( - page['id'], page['space'], page['parentId'], page['title'], page['url'])) + all_pages = api.listpages(args.spacekey) + for page in all_pages: + print args.delimiter.join(( + page['id'], page['space'], page['parentId'], page['title'], page['url'])) elif args.action == "removepage": - removed_page = ConfluencePage(token,xml_server,args.name,args.spacekey,"").remove() + removed_page = api.removepage(args.name, args.spacekey) elif args.action == "addspace": add_space = ConfluenceSpace(token,xml_server).create(args.spacekey,args.name) diff --git a/confluence/__init__.py b/confluence/__init__.py index 5721a8c..f132ba4 100644 --- a/confluence/__init__.py +++ b/confluence/__init__.py @@ -1,4 +1,4 @@ -from .api import connect +from .api import Api from .auth import ConfluenceAuth from .group import ConfluenceGroup from .page import ConfluencePage diff --git a/confluence/api.py b/confluence/api.py index cb8e381..55907b2 100644 --- a/confluence/api.py +++ b/confluence/api.py @@ -1,10 +1,50 @@ import xmlrpclib from .auth import ConfluenceAuth +from .page import ConfluencePage +from .space import ConfluenceSpace -def connect(url, username, password): - url = "%s/rpc/xmlrpc" % url - xml_server = xmlrpclib.Server(url) - token = ConfluenceAuth(xml_server, username, password).login() - return {"token": token, "xml_server": xml_server} +class Api(object): + + def __init__(self, url, username, password): + self.connect(url, username, password) + + def connect(self, url, username, password): + url = "%s/rpc/xmlrpc" % url + self.server = xmlrpclib.Server(url) + self.token = ConfluenceAuth(self.server, username, password).login() + + def addpage(self, name, spacekey, content, label=None, parentpage=None): + new_page = ConfluencePage( + self.token, self.server, name, + spacekey, content, label=label + ) + new_page.add(parentpage) + return new_page + + def updatepage(self, name, spacekey, content, page_id, label=None): + page = ConfluencePage(self.token, self.server, name, spacekey, page_id, label=label) + page.update(content, page_id) + page.set_label() + return page + + def getpagecontent(self, name, spacekey): + return ConfluencePage(self.token, self.server, name, spacekey).get_content() + + def getpage(self, name, spacekey): + return ConfluencePage(self.token, self.server, name, spacekey).get() + + def listpages(self, spacekey=None): + if not spacekey: + spaces = ConfluenceSpace(self.token, self.server).get_all() + else: + spaces = [ConfluenceSpace(self.token, self.server).get_by_key(spacekey)] + + for space in spaces: + all_pages = ConfluenceSpace(self.token, self.server).get_all_pages(space['key']) + for page in all_pages: + yield page + + def removepage(self, name, spacekey): + return ConfluencePage(self.token, self.server, name, spacekey).remove() diff --git a/confluence/page.py b/confluence/page.py index 648aff2..1e63463 100644 --- a/confluence/page.py +++ b/confluence/page.py @@ -2,7 +2,7 @@ class ConfluencePage(object): - def __init__(self,token,server,name,spaceKey,content,page_id="",label=""): + def __init__(self,token,server,name,spaceKey,content="",page_id="",label=""): self.server = server self.token = token self.name = name @@ -43,7 +43,6 @@ def get_content(self): self.page_content = self.wanted_page = self.server.confluence2.renderContet(self.token, self.wanted_page_id,self.content_values) return self.page_content - def get_id(self): return self.get()['id'] From a67f6aa32fcde5135f837623084016cf37c86761 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 11:15:55 -0700 Subject: [PATCH 06/20] user actions in the Api --- confluence-cli | 44 ++++++++++++++++++++------------------------ confluence/api.py | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/confluence-cli b/confluence-cli index c42f014..abcbbfd 100755 --- a/confluence-cli +++ b/confluence-cli @@ -195,47 +195,43 @@ def Actions(api, args, content): remove_space = ConfluenceSpace(token,xml_server).remove(args.spacekey) elif args.action == "listspaces": - all_spaces = ConfluenceSpace(token,xml_server).get_all() + all_spaces = api.listspaces() for space in all_spaces: print(("%s, %s, %s") % ( space['key'], space['name'], space['url'])) elif args.action == "getallpages": - all_spaces = ConfluenceSpace(token,xml_server).get_all() - for space in all_spaces: - all_pages = ConfluenceSpace(token,xml_server).get_all_pages(space['key']) - print("Saving space: %s" % space['name']) - print("------------") - for page in all_pages: - page_content = ConfluencePage(token,xml_server,page['title'],space['key'],"").get_content() - valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits) - page_filename = space['key'] + "_" + page['title'] + ".html" - page_filename = ''.join(c for c in page_filename if c in valid_chars) - with open(page_filename, "w") as page_file: - try: - page_file.write(page_content) - page_file.close() - print("Saved page: %s" % page_filename) - except IOError: - error_out('Could not write file: %s' % page['title']) + all_pages = api.listpages() + for page in all_pages: + page_content = ConfluencePage(token,xml_server,page['title'],space['key'],"").get_content() + valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits) + page_filename = space['key'] + "_" + page['title'] + ".html" + page_filename = ''.join(c for c in page_filename if c in valid_chars) + with open(page_filename, "w") as page_file: + try: + page_file.write(page_content) + page_file.close() + print("Saved page: %s" % page_filename) + except IOError: + error_out('Could not write file: %s' % page['title']) elif args.action == "adduser": - add_user = ConfluenceUser(token,xml_server,args.newusername).create(args.fullname,args.email,args.userpassword) + add_user = api.adduser(args.newusername, args.fullname, args.email, args.userpassword) elif args.action == "removeuser": - remove_user = ConfluenceUser(token,xml_server,args.newusername).remove() + remove_user = api.removeuser(args.newusername) elif args.action == "deactivateuser": - deactivate_user = ConfluenceUser(token,xml_server,args.newusername).deactivate() + deactivate_user = api.deactivateuser(args.newusername) elif args.action == "reactivateuser": - reactivate_user = ConfluenceUser(token,xml_server,args.newusername).reactivate() + reactivate_user = api.reactivateuser(args.newusername) elif args.action == "changeuserpassword": - change_pass = ConfluenceUser(token,xml_server,args.newusername).change_password(args.userpassword) + change_pass = api.changeuserpassword(args.newusername, args.userpassword) elif args.action == "listuserinfo": - user_info = ConfluenceUser(token,xml_server,args.newusername).get_info() + user_info = api.getuserinfo(args.newusername) for key,value in user_info.items(): print(("%s: %s") % (key,value)) diff --git a/confluence/api.py b/confluence/api.py index 55907b2..efad603 100644 --- a/confluence/api.py +++ b/confluence/api.py @@ -3,6 +3,7 @@ from .auth import ConfluenceAuth from .page import ConfluencePage from .space import ConfluenceSpace +from .user import ConfluenceUser class Api(object): @@ -48,3 +49,24 @@ def listpages(self, spacekey=None): def removepage(self, name, spacekey): return ConfluencePage(self.token, self.server, name, spacekey).remove() + + def listspaces(self): + return ConfluenceSpace(self.token, self.server).get_all() + + def adduser(self, newusername, fullname, email, userpassword): + return ConfluenceUser(self.token, self.server, newusername).create(fullname, email, userpassword) + + def removeuser(self, username): + return ConfluenceUser(self.token, self.server, username).remove() + + def deactivateuser(self, username): + return ConfluenceUser(self.token, self.server, username).deactivate() + + def reactivateuser(self, username): + return ConfluenceUser(self.token, self.server, username).reactivate() + + def changeuserpassword(self, username, newpassword): + return ConfluenceUser(self.token, self.server, username).change_password(newpassword) + + def getuserinfo(self, username): + return ConfluenceUser(self.token, self.server, username).get_info() From 6cbc8afed892a5f890e28c98413c13011fb631fe Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 11:20:37 -0700 Subject: [PATCH 07/20] group actions in the Api --- confluence-cli | 14 +++++++------- confluence/api.py | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/confluence-cli b/confluence-cli index abcbbfd..b8e26fd 100755 --- a/confluence-cli +++ b/confluence-cli @@ -236,29 +236,29 @@ def Actions(api, args, content): print(("%s: %s") % (key,value)) elif args.action == "addgroup": - add_group = ConfluenceGroup(token,xml_server,args.groupname).add() + add_group = api.addgroup(args.groupname) elif args.action == "removegroup": - remove_group = ConfluenceGroup(token,xml_server,args.groupname).remove() + remove_group = api.removegroup(args.groupname) elif args.action == "addusertogroup": - add_user_to_group = ConfluenceUser(token,xml_server,args.newusername).add_to_group(args.groupname) + add_user_to_group = api.addusertogroup(args.newusername, args.groupname) elif args.action == "removeuserfromgroup": - remove_user_from_group = ConfluenceUser(token,xml_server,args.newusername).remove_from_group(args.groupname) + remove_user_from_group = api.removeuserfromgroup(args.newusername, args.groupname) elif args.action == "listgroups": - allgroups = ConfluenceGroup(token,xml_server,"users").get_all() + allgroups = api.getgroups() for group in allgroups: print(group) elif args.action == "listusers": - allusers = ConfluenceUser(token,xml_server,"users").get_all() + allusers = api.getusers() for user in allusers: print(user) elif args.action == "listusergroups": - user_groups = ConfluenceUser(token,xml_server,args.newusername).get_groups() + user_groups = api.getusergroups(args.newusername) for group in user_groups: print(group) diff --git a/confluence/api.py b/confluence/api.py index efad603..1e21d99 100644 --- a/confluence/api.py +++ b/confluence/api.py @@ -1,6 +1,7 @@ import xmlrpclib from .auth import ConfluenceAuth +from .group import ConfluenceGroup from .page import ConfluencePage from .space import ConfluenceSpace from .user import ConfluenceUser @@ -70,3 +71,24 @@ def changeuserpassword(self, username, newpassword): def getuserinfo(self, username): return ConfluenceUser(self.token, self.server, username).get_info() + + def addgroup(self, groupname): + return ConfluenceGroup(self.token, self.server, groupname).add() + + def removegroup(self, groupname): + return ConfluenceGroup(self.token, self.server, groupname).remove() + + def addusertogroup(self, username, groupname): + return ConfluenceUser(self.token, self.server, username).add_to_group(groupname) + + def removeuserfromgroup(self, username, groupname): + return ConfluenceUser(self.token, self.server, username).remove_from_group(groupname) + + def getgroups(self): + return ConfluenceGroup(self.token, self.server, "users").get_all() + + def getusers(self): + return ConfluenceUser(self.token, self.server, "users").get_all() + + def getusergroups(self, username): + return ConfluenceUser(self.token, self.server, username).get_groups() From 5d2fd078d145739aa6156ed6fd1eccfd7d31fe98 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 11:23:50 -0700 Subject: [PATCH 08/20] Api.getallpages --- confluence-cli | 11 +++++------ confluence/api.py | 8 +++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/confluence-cli b/confluence-cli index b8e26fd..0e73bd6 100755 --- a/confluence-cli +++ b/confluence-cli @@ -16,7 +16,7 @@ import sys, xmlrpclib, argparse, string, logging -from confluence import Api, ConfluenceGroup, ConfluencePage, ConfluenceSpace, ConfluenceUser +from confluence import Api, ConfluenceSpace, ConfluenceUser # # Logging @@ -181,7 +181,7 @@ def Actions(api, args, content): elif args.action == "listpages": all_pages = api.listpages(args.spacekey) - for page in all_pages: + for page, _ in all_pages: print args.delimiter.join(( page['id'], page['space'], page['parentId'], page['title'], page['url'])) @@ -201,11 +201,10 @@ def Actions(api, args, content): space['key'], space['name'], space['url'])) elif args.action == "getallpages": - all_pages = api.listpages() - for page in all_pages: - page_content = ConfluencePage(token,xml_server,page['title'],space['key'],"").get_content() + all_pages = api.getallpages() + for page, page_content in all_pages: valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits) - page_filename = space['key'] + "_" + page['title'] + ".html" + page_filename = page['space'] + "_" + page['title'] + ".html" page_filename = ''.join(c for c in page_filename if c in valid_chars) with open(page_filename, "w") as page_file: try: diff --git a/confluence/api.py b/confluence/api.py index 1e21d99..4d25b6d 100644 --- a/confluence/api.py +++ b/confluence/api.py @@ -46,7 +46,13 @@ def listpages(self, spacekey=None): for space in spaces: all_pages = ConfluenceSpace(self.token, self.server).get_all_pages(space['key']) for page in all_pages: - yield page + yield page, space + + def getallpages(self, spacekey=None): + all_pages = api.listpages() + for page, space in all_pages: + page_content = ConfluencePage(self.token, self.server, page['title'],space['key']).get_content() + yield page, page_content def removepage(self, name, spacekey): return ConfluencePage(self.token, self.server, name, spacekey).remove() From 39ab7181af4b2936aac1e4b70cc1555ccd25dd76 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 11:25:51 -0700 Subject: [PATCH 09/20] Api.addspace & Api.removespace --- confluence-cli | 6 +++--- confluence/api.py | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/confluence-cli b/confluence-cli index 0e73bd6..0832288 100755 --- a/confluence-cli +++ b/confluence-cli @@ -16,7 +16,7 @@ import sys, xmlrpclib, argparse, string, logging -from confluence import Api, ConfluenceSpace, ConfluenceUser +from confluence import Api # # Logging @@ -189,10 +189,10 @@ def Actions(api, args, content): removed_page = api.removepage(args.name, args.spacekey) elif args.action == "addspace": - add_space = ConfluenceSpace(token,xml_server).create(args.spacekey,args.name) + add_space = api.addspace(args.spacekey, args.name) elif args.action == "removespace": - remove_space = ConfluenceSpace(token,xml_server).remove(args.spacekey) + remove_space = api.removespace(args.spacekey) elif args.action == "listspaces": all_spaces = api.listspaces() diff --git a/confluence/api.py b/confluence/api.py index 4d25b6d..ff3eb44 100644 --- a/confluence/api.py +++ b/confluence/api.py @@ -57,6 +57,12 @@ def getallpages(self, spacekey=None): def removepage(self, name, spacekey): return ConfluencePage(self.token, self.server, name, spacekey).remove() + def addspace(self, spacekey, name): + return ConfluenceSpace(self.token, self.server).create(spacekey, name) + + def removespace(self, spacekey): + return ConfluenceSpace(self.token, self.server).remove(spacekey) + def listspaces(self): return ConfluenceSpace(self.token, self.server).get_all() From 869f197fb2c92601ff45de6058fe80b82dcc5631 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 11:27:30 -0700 Subject: [PATCH 10/20] final cleanup of confluence-cli --- confluence-cli | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/confluence-cli b/confluence-cli index 0832288..c20d8e9 100755 --- a/confluence-cli +++ b/confluence-cli @@ -154,7 +154,7 @@ def Connect(args): api = Api(args.wikiurl, args.username, args.password) except xmlrpclib.Fault as err: error_out("%d: %s" % (err.faultCode, err.faultString)) - return {"token": api.token, "xml_server": api.server} + return api def Actions(api, args, content): @@ -163,7 +163,7 @@ def Actions(api, args, content): if args.action == "addpage": logger.debug('Command: "addpage", args.name = "{}", args.label = "{}"'.format( args.name, args.label)) - new_page = api.addpage(ags.name, args.spacekey, content, args.label, args.parentpage) + new_page = api.addpage(args.name, args.spacekey, content, args.label, args.parentpage) print(new_page.get()["url"]) elif args.action == "updatepage": @@ -272,5 +272,5 @@ if __name__ == "__main__": console_handler.setLevel(logging.DEBUG) content = Content(args) - server = Connect(args) - Actions(server["token"],server["xml_server"],args,content) + api = Connect(args) + Actions(api, args, content) From 546411c4ab0a9a7d892e55e1a8ac0efb2a588a68 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 11:30:17 -0700 Subject: [PATCH 11/20] bin/ folder --- confluence-cli => bin/confluence-cli | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename confluence-cli => bin/confluence-cli (100%) diff --git a/confluence-cli b/bin/confluence-cli similarity index 100% rename from confluence-cli rename to bin/confluence-cli From 7a954a19b02990161e5924c1132092d0bf7847d2 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 11:34:03 -0700 Subject: [PATCH 12/20] first draft setup.py --- setup.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 setup.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..b4eaefb --- /dev/null +++ b/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +from distutils.core import setup + +setup( + name='Confluence-py', + version='1.0', + description='Python Confluence module and command line', + author='Raymii / Mvdb', + author_email='mvdb@work4labs.com', + url='https://github.com/m-vdb/confluence-python', + packages=['confluence'], + scripts=["bin/confluence-cli"] +) From 39c50be7a059829ae9a8b89ee029562cc5f188ee Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 12:01:29 -0700 Subject: [PATCH 13/20] add classifiers --- setup.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b4eaefb..d15c95b 100644 --- a/setup.py +++ b/setup.py @@ -10,5 +10,18 @@ author_email='mvdb@work4labs.com', url='https://github.com/m-vdb/confluence-python', packages=['confluence'], - scripts=["bin/confluence-cli"] + scripts=["bin/confluence-cli"], + classifiers=[ + 'Intended Audience :: Developers', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Topic :: Software Development :: Libraries :: Application Frameworks', + 'Topic :: Software Development :: Libraries :: Python Modules', + ], ) From a8e5ae2994dbf3ed8338d6bd9b6916ba3ef885a8 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 14:34:24 -0700 Subject: [PATCH 14/20] default should be empty string, not None --- confluence/api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/confluence/api.py b/confluence/api.py index ff3eb44..0d7c121 100644 --- a/confluence/api.py +++ b/confluence/api.py @@ -17,7 +17,7 @@ def connect(self, url, username, password): self.server = xmlrpclib.Server(url) self.token = ConfluenceAuth(self.server, username, password).login() - def addpage(self, name, spacekey, content, label=None, parentpage=None): + def addpage(self, name, spacekey, content, label="", parentpage=""): new_page = ConfluencePage( self.token, self.server, name, spacekey, content, label=label @@ -25,7 +25,7 @@ def addpage(self, name, spacekey, content, label=None, parentpage=None): new_page.add(parentpage) return new_page - def updatepage(self, name, spacekey, content, page_id, label=None): + def updatepage(self, name, spacekey, content, page_id, label=""): page = ConfluencePage(self.token, self.server, name, spacekey, page_id, label=label) page.update(content, page_id) page.set_label() @@ -37,7 +37,7 @@ def getpagecontent(self, name, spacekey): def getpage(self, name, spacekey): return ConfluencePage(self.token, self.server, name, spacekey).get() - def listpages(self, spacekey=None): + def listpages(self, spacekey=""): if not spacekey: spaces = ConfluenceSpace(self.token, self.server).get_all() else: @@ -48,7 +48,7 @@ def listpages(self, spacekey=None): for page in all_pages: yield page, space - def getallpages(self, spacekey=None): + def getallpages(self, spacekey=""): all_pages = api.listpages() for page, space in all_pages: page_content = ConfluencePage(self.token, self.server, page['title'],space['key']).get_content() From 70f3a3872dd79ffbedbcbcfc1dce595494a1eeea Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 14:48:46 -0700 Subject: [PATCH 15/20] update readme --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c20180..9f52be8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,12 @@ # Confluence.py -Simple python script to use a Atlassian Confluence Wiki via the CLI. +Simple python module to use a Atlassian Confluence Wiki. CLI available. + +## Installation + +Via pip: + + pip install confluence-py ## Usage From 0eab53b254fb27708296fccaefc93ae96ecbc8b9 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 14:52:18 -0700 Subject: [PATCH 16/20] more info in readme --- README.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9f52be8..74991a3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Confluence.py +# confluence-py Simple python module to use a Atlassian Confluence Wiki. CLI available. @@ -8,7 +8,25 @@ Via pip: pip install confluence-py -## Usage +## Module usage + +Initialise the Api: + + from confluence import Api + wiki_url = "" # your wiki url + user, pw = "", "" # your credentials + api = Api(wiki_url, user, pw) + +Create a page: + + api.addpage("My new page", "SPACE_KEY", "This is my new page, yay!") + +Create a page with a parent: + + api.addpage(..., parentpage="xxxx") # with parent id + + +## CLI Usage $ python confluence.py --help usage: confluence.py [-h] -w WIKIURL -u USERNAME -p PASSWORD From 00a3ec8a8d70215c9b7fb7e2c6f1b6d99b0a0028 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 14:53:47 -0700 Subject: [PATCH 17/20] update CLI usage doc --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 74991a3..3710ed6 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ Create a page with a parent: ## CLI Usage - $ python confluence.py --help - usage: confluence.py [-h] -w WIKIURL -u USERNAME -p PASSWORD + $ confluence-cli --help + usage: confluence-cli [-h] -w WIKIURL -u USERNAME -p PASSWORD {addpage,updatepage,listpages,removepage,getpagecontent,getpagesummary,listspaces,addspace,removespace,adduser,removeuser,deactivateuser,reactivateuser,changeuserpassword,addgroup,removegroup,listgroups,listusers,getallpages,addusertogroup,removeusergromgroup,listusergroups} ... @@ -76,60 +76,60 @@ Create a page with a parent: Add page: - $ ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" addpage -f ./content.txt -n "CLI New Page" -s "RAY" + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" addpage -f ./content.txt -n "CLI New Page" -s "RAY" http://wiki.raymii.org/display/RAY/CLI+New+Page Remove Page: - $ ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" removepage -n "CLI New Page" -s "RAY" + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" removepage -n "CLI New Page" -s "RAY" Update Page: - $ ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" updatepage -f ./content.txt -n "CLI New Page" -s "RAY" + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" updatepage -f ./content.txt -n "CLI New Page" -s "RAY" http://wiki.raymii.org/display/RAY/CLI+New+Page Get page content (HTML): - $ ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" getpagecontent -n "CLI New Page" -s "RAY" + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" getpagecontent -n "CLI New Page" -s "RAY"

Table of Contents

Information

Add Space: - ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" addspace -n "New Space" -s "NS" + confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" addspace -n "New Space" -s "NS" Remove Space: - ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" removespace -s "NS" + confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" removespace -s "NS" List all spaces: - $ ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" listspaces + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" listspaces NS, New Space, http://wiki.raymii.org/display/NS ITS, IT Staff, http://wiki.raymii.org/display/ITS Add user: - $ ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" adduser -U "newuser" -N "New user" -E "newuser@raymii.org" -X "password" + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" adduser -U "newuser" -N "New user" -E "newuser@raymii.org" -X "password" Remove user: - $ ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" removeuser -U newuser + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" removeuser -U newuser Deactivate user: - $ ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" deactivateuser -U newuser + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" deactivateuser -U newuser Reactivate user: - $ ./confluence.py --wikiurl="http://wiki.raymii.org" -u "api" -p "" reactivateuser -U newuser + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" reactivateuser -U newuser -For more actions, run `./confluence.py -h` or see the usage section above. +For more actions, run `confluence-cli -h` or see the usage section above. ## More info From 3a6b04012c713a4719f798044017c8eecf943ccd Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 14:54:20 -0700 Subject: [PATCH 18/20] coherence in doc --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3710ed6..d962186 100644 --- a/README.md +++ b/README.md @@ -99,11 +99,11 @@ Get page content (HTML): Add Space: - confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" addspace -n "New Space" -s "NS" + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" addspace -n "New Space" -s "NS" Remove Space: - confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" removespace -s "NS" + $ confluence-cli --wikiurl="http://wiki.raymii.org" -u "api" -p "" removespace -s "NS" List all spaces: From bbc759742f22c1a27a8b36dc736bc6b7716f0776 Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 16:27:46 -0700 Subject: [PATCH 19/20] update_or_add_page yay --- confluence/api.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/confluence/api.py b/confluence/api.py index 0d7c121..0917919 100644 --- a/confluence/api.py +++ b/confluence/api.py @@ -37,6 +37,12 @@ def getpagecontent(self, name, spacekey): def getpage(self, name, spacekey): return ConfluencePage(self.token, self.server, name, spacekey).get() + def update_or_add_page(self, *args, **kwargs): + try: + return self.updatepage(*args, **kwargs) + except xmlrpclib.Fault: + return self.addpage(*args, **kwargs) + def listpages(self, spacekey=""): if not spacekey: spaces = ConfluenceSpace(self.token, self.server).get_all() From 77a782a9e837b6b2c303b070c4aa398b251b57ca Mon Sep 17 00:00:00 2001 From: mvergerdelbove Date: Fri, 10 Apr 2015 16:28:05 -0700 Subject: [PATCH 20/20] version bump --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d15c95b..2a06720 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ setup( name='Confluence-py', - version='1.0', + version='1.0.1', description='Python Confluence module and command line', author='Raymii / Mvdb', author_email='mvdb@work4labs.com',