diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/README.md b/README.md
index 5c20180..d962186 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,35 @@
-# Confluence.py
+# 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.
-## Usage
+## Installation
+
+Via pip:
+
+ pip install confluence-py
+
+## 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
+ $ 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}
...
@@ -52,60 +76,60 @@ Simple python script to use a Atlassian Confluence Wiki via the CLI.
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
diff --git a/bin/confluence-cli b/bin/confluence-cli
new file mode 100755
index 0000000..c20d8e9
--- /dev/null
+++ b/bin/confluence-cli
@@ -0,0 +1,276 @@
+#!/usr/bin/env python
+# Copyright (C) 2013 Remy van Elst
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import sys, xmlrpclib, argparse, string, logging
+
+from confluence import Api
+
+#
+# Logging
+#
+
+logger = logging.getLogger(__name__.rpartition('.')[0])
+logger.setLevel(logging.DEBUG)
+console_handler = logging.StreamHandler()
+console_handler.setLevel(logging.INFO)
+formatter = logging.Formatter('%(levelname)s: [%(name)s] %(message)s')
+console_handler.setFormatter(formatter)
+logger.addHandler(console_handler)
+
+
+def error_out(error_message):
+ print("Error: ")
+ print(error_message)
+ exit()
+
+
+def Parser():
+ parser = argparse.ArgumentParser(description="Confluence wiki API")
+ parser.add_argument("-w", "--wikiurl", help="Wiki URL (only FQDN, no / and such)", required=True)
+ parser.add_argument("-u", "--username", help="Login Username", required=True)
+ parser.add_argument("-p", "--password", help="Login Password", required=True)
+ parser.add_argument("-v", "--verbose", help="Enable debug logging", action="store_true")
+ subparsers = parser.add_subparsers(dest="action")
+
+ parser_addpage = subparsers.add_parser('addpage', help='Add a page')
+ parser_addpage.add_argument("-n", "--name", help="(New) page name", required=True)
+ parser_addpage.add_argument("-P", "--parentpage", help="Parent page ID", default="0")
+ parser_addpage.add_argument("-l", "--label", help="Page label", default="created_via_api")
+ parser_addpage.add_argument("-s", "--spacekey", help="Space Key", required=True)
+ files_addpage = parser_addpage.add_mutually_exclusive_group()
+ files_addpage.add_argument("-f", "--file", help="Read content from this file")
+ files_addpage.add_argument("-S", "--stdin", help="Read content from STDIN", action="store_true")
+
+ parser_updatepage = subparsers.add_parser('updatepage', help='Update a page')
+ parser_updatepage.add_argument("-n", "--name", help="Page name", required=True)
+ parser_updatepage.add_argument("-s", "--spacekey", help="Space Key", required=True)
+ parser_updatepage.add_argument("-P", "--parentpage", help="Parent page ID", default="0")
+ parser_updatepage.add_argument("-l", "--label", help="Page label", default="created_via_api")
+ files_updatepage = parser_updatepage.add_mutually_exclusive_group()
+ files_updatepage.add_argument("-f", "--file", help="Read content from this file")
+ files_updatepage.add_argument("-S", "--stdin", help="Read content from STDIN", action="store_true")
+
+ parser_listpages = subparsers.add_parser('listpages', help='List pages in one or all spaces')
+ parser_listpages.add_argument("-s", "--spacekey", help="Space Key", default="")
+ parser_listpages.add_argument("-d", "--delimiter", help="Field delimiter", default=", ")
+
+ parser_removepage = subparsers.add_parser('removepage', help='Remove a page')
+ parser_removepage.add_argument("-n", "--name", help="Page name", required=True)
+ parser_removepage.add_argument("-s", "--spacekey", help="Space Key", required=True)
+
+ parser_getpage = subparsers.add_parser('getpagecontent', help='Get page content')
+ parser_getpage.add_argument("-n", "--name", help="Page name", required=True)
+ parser_getpage.add_argument("-s", "--spacekey", help="Space Key", required=True)
+
+ parser_getpagesummary = subparsers.add_parser('getpagesummary', help='Get page summary')
+ parser_getpagesummary.add_argument("-s", "--spacekey", help="Space Key", required=True)
+ parser_getpagesummary.add_argument("-n", "--name", help="Page name", required=True)
+ parser_getpagesummary.add_argument("-d", "--delimiter", help="Field delimiter", default=", ")
+
+ parser_listspaces = subparsers.add_parser('listspaces', help='List all spaces')
+
+ parser_addspace = subparsers.add_parser('addspace', help='Add a space')
+ parser_addspace.add_argument("-s", "--spacekey", help="Space Key", required=True)
+ parser_addspace.add_argument("-D", "--description", help="Space description", required=True)
+
+ parser_removespace = subparsers.add_parser('removespace', help='Remove a space')
+ parser_removespace.add_argument("-s", "--spacekey", help="Space Key", required=True)
+
+ parser_adduser = subparsers.add_parser('adduser', help='Add a user')
+ parser_adduser.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
+ parser_adduser.add_argument("-N", "--fullname", help="Full name for new user", required=True)
+ parser_adduser.add_argument("-E", "--email", help="Email address for new user", required=True)
+ parser_adduser.add_argument("-X", "--userpassword", help="Password for new user", required=True)
+
+ parser_removeuser = subparsers.add_parser('removeuser', help='Remove a user')
+ parser_removeuser.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
+
+ parser_deactuser = subparsers.add_parser('deactivateuser', help='Deactivate a user')
+ parser_deactuser.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
+
+ parser_reactuser = subparsers.add_parser('reactivateuser', help='Reactivate a user')
+ parser_reactuser.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
+
+ parser_changepass = subparsers.add_parser('changeuserpassword', help='Change user password')
+ parser_changepass.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
+ parser_changepass.add_argument("-X", "--userpassword", help="Password for user", required=True)
+
+ parser_addgroup = subparsers.add_parser('addgroup', help='Add a goup')
+ parser_addgroup.add_argument("-G", "--groupname", help="Group name to perform action on.", required=True)
+
+ parser_removegroup = subparsers.add_parser('removegroup', help='Remove a goup')
+ parser_removegroup.add_argument("-G", "--groupname", help="Group name to perform action on.", required=True)
+
+ parser_listgroups = subparsers.add_parser('listgroups', help='List all goup')
+
+ parser_usersgroups = subparsers.add_parser('listusers', help='List all users')
+
+ parser_allpages = subparsers.add_parser('getallpages', help='Save all pages to local files.')
+
+ parser_addutog = subparsers.add_parser('addusertogroup', help='Add user to a group')
+ parser_addutog.add_argument("-G", "--groupname", help="Group name to perform action on.", required=True)
+ parser_addutog.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
+
+ parser_removeufromg = subparsers.add_parser('removeusergromgroup', help='Remove user from a group')
+ parser_removeufromg.add_argument("-G", "--groupname", help="Group name to perform action on.", required=True)
+ parser_removeufromg.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
+
+ parser_listusergroups = subparsers.add_parser('listusergroups', help='List groups user is in')
+ parser_listusergroups.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
+
+ args = parser.parse_args()
+ return args
+
+def Content(args):
+ if not hasattr(args, 'file') or not hasattr(args, 'stdin'):
+ content = ""
+ elif args.file:
+ try:
+ content = open(args.file, 'rb').read()
+ except:
+ error = "Cannot open file: ", args.file
+ raise
+ elif args.stdin:
+ content = sys.stdin.read()
+ else:
+ content = ""
+ return content
+
+def Connect(args):
+ try:
+ api = Api(args.wikiurl, args.username, args.password)
+ except xmlrpclib.Fault as err:
+ error_out("%d: %s" % (err.faultCode, err.faultString))
+ return api
+
+
+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 = api.addpage(args.name, args.spacekey, content, args.label, args.parentpage)
+ print(new_page.get()["url"])
+
+ elif args.action == "updatepage":
+ page = api.updatepage(args.name, args.spacekey, content, args.parentpage, args.label)
+ print(page.get()['url'])
+
+ elif args.action == "getpagecontent":
+ content = api.getpagecontent(args.name, args.spacekey)
+ print(content)
+
+ elif args.action == "getpagesummary":
+ 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":
+ 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 = api.removepage(args.name, args.spacekey)
+
+ elif args.action == "addspace":
+ add_space = api.addspace(args.spacekey, args.name)
+
+ elif args.action == "removespace":
+ remove_space = api.removespace(args.spacekey)
+
+ elif args.action == "listspaces":
+ all_spaces = api.listspaces()
+ for space in all_spaces:
+ print(("%s, %s, %s") % (
+ space['key'], space['name'], space['url']))
+
+ elif args.action == "getallpages":
+ all_pages = api.getallpages()
+ for page, page_content in all_pages:
+ valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
+ 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:
+ 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 = api.adduser(args.newusername, args.fullname, args.email, args.userpassword)
+
+ elif args.action == "removeuser":
+ remove_user = api.removeuser(args.newusername)
+
+ elif args.action == "deactivateuser":
+ deactivate_user = api.deactivateuser(args.newusername)
+
+ elif args.action == "reactivateuser":
+ reactivate_user = api.reactivateuser(args.newusername)
+
+ elif args.action == "changeuserpassword":
+ change_pass = api.changeuserpassword(args.newusername, args.userpassword)
+
+ elif args.action == "listuserinfo":
+ user_info = api.getuserinfo(args.newusername)
+ for key,value in user_info.items():
+ print(("%s: %s") % (key,value))
+
+ elif args.action == "addgroup":
+ add_group = api.addgroup(args.groupname)
+
+ elif args.action == "removegroup":
+ remove_group = api.removegroup(args.groupname)
+
+ elif args.action == "addusertogroup":
+ add_user_to_group = api.addusertogroup(args.newusername, args.groupname)
+
+ elif args.action == "removeuserfromgroup":
+ remove_user_from_group = api.removeuserfromgroup(args.newusername, args.groupname)
+
+ elif args.action == "listgroups":
+ allgroups = api.getgroups()
+ for group in allgroups:
+ print(group)
+
+ elif args.action == "listusers":
+ allusers = api.getusers()
+ for user in allusers:
+ print(user)
+
+ elif args.action == "listusergroups":
+ user_groups = api.getusergroups(args.newusername)
+ for group in user_groups:
+ print(group)
+
+ except xmlrpclib.Fault as err:
+ print(("Error: %d: %s") % (err.faultCode, err.faultString))
+
+
+if __name__ == "__main__":
+ args = Parser()
+
+ if args.verbose:
+ console_handler.setLevel(logging.DEBUG)
+
+ content = Content(args)
+ api = Connect(args)
+ Actions(api, args, content)
diff --git a/confluence.py b/confluence.py
deleted file mode 100755
index daca23b..0000000
--- a/confluence.py
+++ /dev/null
@@ -1,459 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2013 Remy van Elst
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-import sys, xmlrpclib, argparse, string, logging
-
-#
-# Logging
-#
-
-logger = logging.getLogger(__name__.rpartition('.')[0])
-logger.setLevel(logging.DEBUG)
-console_handler = logging.StreamHandler()
-console_handler.setLevel(logging.INFO)
-formatter = logging.Formatter('%(levelname)s: [%(name)s] %(message)s')
-console_handler.setFormatter(formatter)
-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)
- exit()
-
-
-def Parser():
- parser = argparse.ArgumentParser(description="Confluence wiki API")
- parser.add_argument("-w", "--wikiurl", help="Wiki URL (only FQDN, no / and such)", required=True)
- parser.add_argument("-u", "--username", help="Login Username", required=True)
- parser.add_argument("-p", "--password", help="Login Password", required=True)
- parser.add_argument("-v", "--verbose", help="Enable debug logging", action="store_true")
- subparsers = parser.add_subparsers(dest="action")
-
- parser_addpage = subparsers.add_parser('addpage', help='Add a page')
- parser_addpage.add_argument("-n", "--name", help="(New) page name", required=True)
- parser_addpage.add_argument("-P", "--parentpage", help="Parent page ID", default="0")
- parser_addpage.add_argument("-l", "--label", help="Page label", default="created_via_api")
- parser_addpage.add_argument("-s", "--spacekey", help="Space Key", required=True)
- files_addpage = parser_addpage.add_mutually_exclusive_group()
- files_addpage.add_argument("-f", "--file", help="Read content from this file")
- files_addpage.add_argument("-S", "--stdin", help="Read content from STDIN", action="store_true")
-
- parser_updatepage = subparsers.add_parser('updatepage', help='Update a page')
- parser_updatepage.add_argument("-n", "--name", help="Page name", required=True)
- parser_updatepage.add_argument("-s", "--spacekey", help="Space Key", required=True)
- parser_updatepage.add_argument("-P", "--parentpage", help="Parent page ID", default="0")
- parser_updatepage.add_argument("-l", "--label", help="Page label", default="created_via_api")
- files_updatepage = parser_updatepage.add_mutually_exclusive_group()
- files_updatepage.add_argument("-f", "--file", help="Read content from this file")
- files_updatepage.add_argument("-S", "--stdin", help="Read content from STDIN", action="store_true")
-
- parser_listpages = subparsers.add_parser('listpages', help='List pages in one or all spaces')
- parser_listpages.add_argument("-s", "--spacekey", help="Space Key", default="")
- parser_listpages.add_argument("-d", "--delimiter", help="Field delimiter", default=", ")
-
- parser_removepage = subparsers.add_parser('removepage', help='Remove a page')
- parser_removepage.add_argument("-n", "--name", help="Page name", required=True)
- parser_removepage.add_argument("-s", "--spacekey", help="Space Key", required=True)
-
- parser_getpage = subparsers.add_parser('getpagecontent', help='Get page content')
- parser_getpage.add_argument("-n", "--name", help="Page name", required=True)
- parser_getpage.add_argument("-s", "--spacekey", help="Space Key", required=True)
-
- parser_getpagesummary = subparsers.add_parser('getpagesummary', help='Get page summary')
- parser_getpagesummary.add_argument("-s", "--spacekey", help="Space Key", required=True)
- parser_getpagesummary.add_argument("-n", "--name", help="Page name", required=True)
- parser_getpagesummary.add_argument("-d", "--delimiter", help="Field delimiter", default=", ")
-
- parser_listspaces = subparsers.add_parser('listspaces', help='List all spaces')
-
- parser_addspace = subparsers.add_parser('addspace', help='Add a space')
- parser_addspace.add_argument("-s", "--spacekey", help="Space Key", required=True)
- parser_addspace.add_argument("-D", "--description", help="Space description", required=True)
-
- parser_removespace = subparsers.add_parser('removespace', help='Remove a space')
- parser_removespace.add_argument("-s", "--spacekey", help="Space Key", required=True)
-
- parser_adduser = subparsers.add_parser('adduser', help='Add a user')
- parser_adduser.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
- parser_adduser.add_argument("-N", "--fullname", help="Full name for new user", required=True)
- parser_adduser.add_argument("-E", "--email", help="Email address for new user", required=True)
- parser_adduser.add_argument("-X", "--userpassword", help="Password for new user", required=True)
-
- parser_removeuser = subparsers.add_parser('removeuser', help='Remove a user')
- parser_removeuser.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
-
- parser_deactuser = subparsers.add_parser('deactivateuser', help='Deactivate a user')
- parser_deactuser.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
-
- parser_reactuser = subparsers.add_parser('reactivateuser', help='Reactivate a user')
- parser_reactuser.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
-
- parser_changepass = subparsers.add_parser('changeuserpassword', help='Change user password')
- parser_changepass.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
- parser_changepass.add_argument("-X", "--userpassword", help="Password for user", required=True)
-
- parser_addgroup = subparsers.add_parser('addgroup', help='Add a goup')
- parser_addgroup.add_argument("-G", "--groupname", help="Group name to perform action on.", required=True)
-
- parser_removegroup = subparsers.add_parser('removegroup', help='Remove a goup')
- parser_removegroup.add_argument("-G", "--groupname", help="Group name to perform action on.", required=True)
-
- parser_listgroups = subparsers.add_parser('listgroups', help='List all goup')
-
- parser_usersgroups = subparsers.add_parser('listusers', help='List all users')
-
- parser_allpages = subparsers.add_parser('getallpages', help='Save all pages to local files.')
-
- parser_addutog = subparsers.add_parser('addusertogroup', help='Add user to a group')
- parser_addutog.add_argument("-G", "--groupname", help="Group name to perform action on.", required=True)
- parser_addutog.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
-
- parser_removeufromg = subparsers.add_parser('removeusergromgroup', help='Remove user from a group')
- parser_removeufromg.add_argument("-G", "--groupname", help="Group name to perform action on.", required=True)
- parser_removeufromg.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
-
- parser_listusergroups = subparsers.add_parser('listusergroups', help='List groups user is in')
- parser_listusergroups.add_argument("-U", "--newusername", help="Username to perform action on.", required=True)
-
- args = parser.parse_args()
- return args
-
-def Content(args):
- if not hasattr(args, 'file') or not hasattr(args, 'stdin'):
- content = ""
- elif args.file:
- try:
- content = open(args.file, 'rb').read()
- except:
- error = "Cannot open file: ", args.file
- raise
- elif args.stdin:
- content = sys.stdin.read()
- else:
- content = ""
- 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()
- except xmlrpclib.Fault as err:
- error_out("%d: %s" % ( err.faultCode, err.faultString))
- return {"token":token,"xml_server":xml_server}
-
-
-def Actions(token,xml_server,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)
- 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'])
-
- elif args.action == "getpagecontent":
- get_page = ConfluencePage(token,xml_server,args.name,args.spacekey,content).get_content()
- print(get_page)
-
- elif args.action == "getpagesummary":
- page = ConfluencePage(token,xml_server,args.name,args.spacekey,content).get()
- 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']))
-
- elif args.action == "removepage":
- removed_page = ConfluencePage(token,xml_server,args.name,args.spacekey,"").remove()
-
- elif args.action == "addspace":
- add_space = ConfluenceSpace(token,xml_server).create(args.spacekey,args.name)
-
- elif args.action == "removespace":
- remove_space = ConfluenceSpace(token,xml_server).remove(args.spacekey)
-
- elif args.action == "listspaces":
- all_spaces = ConfluenceSpace(token,xml_server).get_all()
- 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'])
-
- elif args.action == "adduser":
- add_user = ConfluenceUser(token,xml_server,args.newusername).create(args.fullname,args.email,args.userpassword)
-
- elif args.action == "removeuser":
- remove_user = ConfluenceUser(token,xml_server,args.newusername).remove()
-
- elif args.action == "deactivateuser":
- deactivate_user = ConfluenceUser(token,xml_server,args.newusername).deactivate()
-
- elif args.action == "reactivateuser":
- reactivate_user = ConfluenceUser(token,xml_server,args.newusername).reactivate()
-
- elif args.action == "changeuserpassword":
- change_pass = ConfluenceUser(token,xml_server,args.newusername).change_password(args.userpassword)
-
- elif args.action == "listuserinfo":
- user_info = ConfluenceUser(token,xml_server,args.newusername).get_info()
- for key,value in user_info.items():
- print(("%s: %s") % (key,value))
-
- elif args.action == "addgroup":
- add_group = ConfluenceGroup(token,xml_server,args.groupname).add()
-
- elif args.action == "removegroup":
- remove_group = ConfluenceGroup(token,xml_server,args.groupname).remove()
-
- elif args.action == "addusertogroup":
- add_user_to_group = ConfluenceUser(token,xml_server,args.newusername).add_to_group(args.groupname)
-
- elif args.action == "removeuserfromgroup":
- remove_user_from_group = ConfluenceUser(token,xml_server,args.newusername).remove_from_group(args.groupname)
-
- elif args.action == "listgroups":
- allgroups = ConfluenceGroup(token,xml_server,"users").get_all()
- for group in allgroups:
- print(group)
-
- elif args.action == "listusers":
- allusers = ConfluenceUser(token,xml_server,"users").get_all()
- for user in allusers:
- print(user)
-
- elif args.action == "listusergroups":
- user_groups = ConfluenceUser(token,xml_server,args.newusername).get_groups()
- for group in user_groups:
- print(group)
-
- except xmlrpclib.Fault as err:
- print(("Error: %d: %s") % (err.faultCode, err.faultString))
-
-
-def main():
- args = Parser()
-
- if args.verbose:
- console_handler.setLevel(logging.DEBUG)
-
- content = Content(args)
- server = Connect(args)
- Actions(server["token"],server["xml_server"],args,content)
-
-main()
diff --git a/confluence/__init__.py b/confluence/__init__.py
new file mode 100644
index 0000000..f132ba4
--- /dev/null
+++ b/confluence/__init__.py
@@ -0,0 +1,6 @@
+from .api import Api
+from .auth import ConfluenceAuth
+from .group import ConfluenceGroup
+from .page import ConfluencePage
+from .space import ConfluenceSpace
+from .user import ConfluenceUser
diff --git a/confluence/api.py b/confluence/api.py
new file mode 100644
index 0000000..0917919
--- /dev/null
+++ b/confluence/api.py
@@ -0,0 +1,112 @@
+import xmlrpclib
+
+from .auth import ConfluenceAuth
+from .group import ConfluenceGroup
+from .page import ConfluencePage
+from .space import ConfluenceSpace
+from .user import ConfluenceUser
+
+
+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="", parentpage=""):
+ 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=""):
+ 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 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()
+ 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, space
+
+ 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()
+ yield page, page_content
+
+ 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()
+
+ 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()
+
+ 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()
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..1e63463
--- /dev/null
+++ b/confluence/page.py
@@ -0,0 +1,68 @@
+import logging
+
+
+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)
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..2a06720
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+
+from distutils.core import setup
+
+setup(
+ name='Confluence-py',
+ version='1.0.1',
+ 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"],
+ 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',
+ ],
+)