diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index e69de29bb..000000000 diff --git a/PKG-INFO b/PKG-INFO index 4c6bca4d3..1643c04b4 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: atlassian-python-api -Version: 0.7.1 +Version: 0.7.10 Author: Matt Harasymczuk Author-email: code at mattagile com Maintainer: Matt Harasymczuk diff --git a/atlassian/__init__.py b/atlassian/__init__.py index c402d9aa5..68e2857c4 100644 --- a/atlassian/__init__.py +++ b/atlassian/__init__.py @@ -2,7 +2,6 @@ import logging import requests - log = logging.getLogger("atlassian") @@ -23,7 +22,8 @@ def log_curl_debug(self, method, path, headers={}, data=None, level=logging.DEBU url='{0}{1}'.format(self.url, path)) log.log(level=level, msg=message) - def request(self, method='GET', path='/', headers={'Content-Type': 'application/json', 'Accept': 'application/json'}, data=None): + def request(self, method='GET', path='/', + headers={'Content-Type': 'application/json', 'Accept': 'application/json'}, data=None): self.log_curl_debug(method, path, headers, data) response = requests.request( method=method, @@ -35,8 +35,9 @@ def request(self, method='GET', path='/', headers={'Content-Type': 'application/ if response.status_code != 200: self.log_curl_debug(method, path, headers, data, level=logging.WARNING) log.warning(response.json()) - response.raise_for_status() - log.debug('Received: {0}'.format(response.json())) + response.raise_for_status() + else: + log.debug('Received: {0}'.format(response.json())) return response def get(self, path, headers={'Content-Type': 'application/json', 'Accept': 'application/json'}): @@ -56,3 +57,5 @@ def delete(self, path, headers={'Content-Type': 'application/json', 'Accept': 'a from .jira import Jira from .stash import Stash from .portfolio import Portfolio + +__all__ = ['Confluence', 'Jira', 'Stash', 'Portfolio'] diff --git a/atlassian/confluence.py b/atlassian/confluence.py index 8e34080ed..78e616fd4 100644 --- a/atlassian/confluence.py +++ b/atlassian/confluence.py @@ -2,32 +2,32 @@ from atlassian import AtlassianRestAPI -log = logging.getLogger("atlassian.confluence") +log = logging.getLogger('atlassian.confluence') class Confluence(AtlassianRestAPI): def create_page(self, space, parent_id, title, body): - return self.post("/rest/api/content/", data={ - "type": "page", - "ancestors": [{"type": "page", "id": parent_id}], - "title": title, - "space": {"key": space}, - "body": {"storage": { - "value": body, - "representation": "storage"}}}) + return self.post('/rest/api/content/', data={ + 'type': 'page', + 'ancestors': [{'type': 'page', 'id': parent_id}], + 'title': title, + 'space': {'key': space}, + 'body': {'storage': { + 'value': body, + 'representation': 'storage'}}}) def history(self, page_id): - return self.get("/rest/api/content/{0}/history".format(page_id)) + return self.get('/rest/api/content/{0}/history'.format(page_id)) - def update_page(self, parent_id, page_id, title, body, type="page",): - version = self.history(page_id)["lastUpdated"]["number"] + 1 - return self.put("/rest/api/content/{0}".format(page_id), data={ - "id": page_id, - "type": type, - "ancestors": [{"type": "page", "id": parent_id}], - "title": title, - "body": {"storage": { - "value": body, - "representation": "storage"}}, - "version": {"number": version}}) \ No newline at end of file + def update_page(self, parent_id, page_id, title, body, type='page',): + version = self.history(page_id)['lastUpdated']['number'] + 1 + return self.put('/rest/api/content/{0}'.format(page_id), data={ + 'id': page_id, + 'type': type, + 'ancestors': [{'type': 'page', 'id': parent_id}], + 'title': title, + 'body': {'storage': { + 'value': body, + 'representation': 'storage'}}, + 'version': {'number': version}}) diff --git a/atlassian/jira.py b/atlassian/jira.py index d4e2e7694..d8c3f6134 100644 --- a/atlassian/jira.py +++ b/atlassian/jira.py @@ -2,49 +2,49 @@ from atlassian import AtlassianRestAPI -log = logging.getLogger("atlassian.jira") +log = logging.getLogger('atlassian.jira') class Jira(AtlassianRestAPI): def reindex_status(self): - return self.get("/rest/api/2/reindex") + return self.get('/rest/api/2/reindex') def reindex(self): - return self.post("/rest/api/2/reindex") + return self.post('/rest/api/2/reindex') - def jql(self, jql): - return self.get("/rest/api/2/search?jql={0}&maxResults=999999".format(jql)) + def jql(self, jql, maxresults=999999): + return self.get('/rest/api/2/search?jql={0}&maxResults={1}'.format(jql, maxresults)) def projects(self): - return self.get("/rest/api/2/project") + return self.get('/rest/api/2/project') def user(self, username): - return self.get("/rest/api/2/user?username=%s" % username) + return self.get('/rest/api/2/user?username={0}'.format(username)) def project(self, key): - return self.get("/rest/api/2/project/{0}".format(key)) + return self.get('/rest/api/2/project/{0}'.format(key)) def issue(self, key): - return self.get("/rest/api/2/issue/{0}".format(key)) + return self.get('/rest/api/2/issue/{0}'.format(key)) def update_issue_field(self, key, fields): - return self.put("/rest/api/2/issue/{0}".format(key), data={"fields": fields}) + return self.put('/rest/api/2/issue/{0}'.format(key), data={'fields': fields}) def project_leaders(self): for project in self.projects(): - key = project["key"] + key = project['key'] project_data = self.project(key) - lead = self.user(project_data["lead"]["key"]) + lead = self.user(project_data['lead']['key']) yield { - "project_key": key, - "project_name": project["name"], - "lead_name": lead["displayName"], - "lead_key": lead["key"], - "lead_email": lead["emailAddress"]} + 'project_key': key, + 'project_name': project['name'], + 'lead_name': lead['displayName'], + 'lead_key': lead['key'], + 'lead_email': lead['emailAddress']} def rename_sprint(self, sprint_id, name, start_date, end_date): - return self.put("/rest/greenhopper/1.0/sprint/{0}".format(sprint_id), data={ - "name": name, - "startDate": start_date, - "endDate": end_date}) + return self.put('/rest/greenhopper/1.0/sprint/{0}'.format(sprint_id), data={ + 'name': name, + 'startDate': start_date, + 'endDate': end_date}) diff --git a/atlassian/portfolio.py b/atlassian/portfolio.py index 2f9ecb4db..8274f98e0 100644 --- a/atlassian/portfolio.py +++ b/atlassian/portfolio.py @@ -2,43 +2,48 @@ from atlassian import AtlassianRestAPI -log = logging.getLogger("atlassian.portfolio") +log = logging.getLogger('atlassian.portfolio') class Portfolio(AtlassianRestAPI): - - def plan(self, portfolio_id): - return self.get('/rest/roadmap/1.0/plans/{0}.json'.format(portfolio_id)) - def stages(self, portfolio_id): - return self.get('/rest/roadmap/1.0/plans/{0}/stages.json'.format(portfolio_id)) + def plan(self, plan_id): + return self.get('/rest/roadmap/1.0/plans/{0}.json'.format(plan_id)) - def teams(self, portfolio_id): - return self.get('/rest/roadmap/1.0/plans/{0}/teams.json'.format(portfolio_id)) + def stages(self, plan_id): + return self.get('/rest/roadmap/1.0/plans/{0}/stages.json'.format(plan_id)) - def config(self, portfolio_id): - return self.get('/rest/roadmap/1.0/plans/{0}/config.json'.format(portfolio_id)) + def teams(self, plan_id): + return self.get('/rest/roadmap/1.0/plans/{0}/teams.json'.format(plan_id)) - def persons(self, portfolio_id): - return self.get('/rest/roadmap/1.0/plans/{0}/persons.json'.format(portfolio_id)) + def config(self, plan_id): + return self.get('/rest/roadmap/1.0/plans/{0}/config.json'.format(plan_id)) - def streams(self, portfolio_id): - return self.get('/rest/roadmap/1.0/plans/{0}/streams.json'.format(portfolio_id)) + def persons(self, plan_id): + return self.get('/rest/roadmap/1.0/plans/{0}/persons.json'.format(plan_id)) - def releases(self, portfolio_id): - return self.streams(portfolio_id) + def streams(self, plan_id): + return self.get('/rest/roadmap/1.0/plans/{0}/streams.json'.format(plan_id)) - def themes(self, portfolio_id): - return self.get('/rest/roadmap/1.0/plans/{0}/themes.json'.format(portfolio_id)) + def releases(self, plan_id): + return self.streams(plan_id) - def state(self, portfolio_id, plan_version): - return self.get('/rest/roadmap/1.0/scheduling/{0}/state.json?planVersion={1}'.format(portfolio_id, plan_version)) + def themes(self, plan_id): + return self.get('/rest/roadmap/1.0/plans/{0}/themes.json'.format(plan_id)) - def filter(self, portfolio_id, plan_version): - return self.get('/rest/roadmap/1.0/plans/{0}/workitems/filter.json?planVersion={1}'.format(portfolio_id, plan_version)) + def state(self, plan_id, plan_version): + return self.get('/rest/roadmap/1.0/scheduling/{0}/state.json?planVersion={1}'.format(plan_id, plan_version)) - def stage_name(self, portfolio_id, stage_id): - return [stage['title'] for stage in self.stages(portfolio_id)['collection'] if stage['id'] == str(stage_id)][0] + def filter(self, plan_id, plan_version, limit=500): + url = '/rest/roadmap/1.0/plans/{0}/workitems/filter.json?planVersion={1}'.format(plan_id, plan_version) + return self.post(url, data={'limit': limit}) - def estimates_dict(self, portfolio_id, estimates): - return {self.stage_name(portfolio_id, stage['targetId']): stage['value'] for stage in estimates['stages']} + def dependencies(self, workitem_id, plan_version): + url = '/rest/roadmap/1.0/workitems/{0}/dependencies.json?planVersion={1}'.format(workitem_id, plan_version) + return self.get(url) + + def stage_name(self, plan_id, stage_id): + return [stage['title'] for stage in self.stages(plan_id)['collection'] if stage['id'] == str(stage_id)][0] + + def estimates_dict(self, plan_id, estimates): + return {self.stage_name(plan_id, stage['targetId']): stage['value'] for stage in estimates['stages']} diff --git a/atlassian/stash.py b/atlassian/stash.py index bc101612d..5ce78c9dc 100644 --- a/atlassian/stash.py +++ b/atlassian/stash.py @@ -2,7 +2,7 @@ from atlassian import AtlassianRestAPI -log = logging.getLogger("atlassian.stash") +log = logging.getLogger('atlassian.stash') class Stash(AtlassianRestAPI): @@ -11,20 +11,21 @@ def project_list(self): return self.get('/rest/api/1.0/projects')['values'] def project(self, key): - return self.get('/rest/api/1.0/projects/{}'.format(key))['values'] + return self.get('/rest/api/1.0/projects/{0}'.format(key))['values'] - def project_users(self, key): - return self.get('/rest/api/1.0/projects/{}/permissions/users?limit=99999'.format(key))['values'] + def project_users(self, key, limit=99999): + return self.get('/rest/api/1.0/projects/{0}/permissions/users?limit={1}'.format(key, limit))['values'] def project_users_with_administrator_permissions(self, key): - project_administrators = [user['user'] for user in self.project_users(key) if user['permission'] == 'PROJECT_ADMIN'] + project_administrators = [user['user'] for user in self.project_users(key) + if user['permission'] == 'PROJECT_ADMIN'] for group in self.project_groups_with_administrator_permissions(key): for user in self.group_members(group): project_administrators.append(user) return project_administrators - def project_groups(self, key): - return self.get('/rest/api/1.0/projects/{}/permissions/groups?limit=99999'.format(key))['values'] + def project_groups(self, key, limit=99999): + return self.get('/rest/api/1.0/projects/{0}/permissions/groups?limit={1}'.format(key, limit))['values'] def project_groups_with_administrator_permissions(self, key): return [group['group']['name'] for group in self.project_groups(key) if group['permission'] == 'PROJECT_ADMIN'] @@ -36,13 +37,14 @@ def project_summary(self, key): 'users': self.project_users(key), 'groups': self.project_groups(key)} - def group_members(self, group): - return self.get('/rest/api/1.0/admin/groups/more-members?context={}&limit=99999'.format(group))['values'] + def group_members(self, group, limit=99999): + return self.get('/rest/api/1.0/admin/groups/more-members?context={0}&limit={1}'.format(group, limit))['values'] def all_project_administrators(self): for project in self.project_list(): - log.info("Processing project: {0} - {1}".format(project['key'], project['name'])) + log.info('Processing project: {0} - {1}'.format(project['key'], project['name'])) yield { 'project_key': project['key'], 'project_name': project['name'], - 'project_administrators': [{'email': x['emailAddress'], 'name': x['displayName']} for x in self.project_users_with_administrator_permissions(project['key'])]} + 'project_administrators': [{'email': x['emailAddress'], 'name': x['displayName']} + for x in self.project_users_with_administrator_permissions(project['key'])]} diff --git a/examples/confluence-create-page.py b/examples/confluence-create-page.py index 97ea4a922..b4d76ed20 100644 --- a/examples/confluence-create-page.py +++ b/examples/confluence-create-page.py @@ -3,13 +3,13 @@ confluence = Confluence( - url="http://localhost:8090", - username="admin", - password="admin") + url='http://localhost:8090', + username='admin', + password='admin') status = confluence.create_page( - space="DEMO", - title="This is the title", - body="This is the body") + space='DEMO', + title='This is the title', + body='This is the body') pprint(status) \ No newline at end of file diff --git a/examples/confluence-update-page.py b/examples/confluence-update-page.py index 5fe796ca0..efc220ced 100644 --- a/examples/confluence-update-page.py +++ b/examples/confluence-update-page.py @@ -3,13 +3,13 @@ confluence = Confluence( - url="http://localhost:8090", - username="admin", - password="admin") + url='http://localhost:8090', + username='admin', + password='admin') status = confluence.update_page( page_id=123456, - title="This is the new title", - body="This is the new body") + title='This is the new title', + body='This is the new body') pprint(status) \ No newline at end of file diff --git a/examples/jira-jql-query.py b/examples/jira-jql-query.py index c40f4725d..6b92eaa04 100644 --- a/examples/jira-jql-query.py +++ b/examples/jira-jql-query.py @@ -2,12 +2,12 @@ from atlassian import Jira -JQL = "project = DEMO AND status NOT IN (Closed, Resolved) ORDER BY issuekey" +JQL = 'project = DEMO AND status NOT IN (Closed, Resolved) ORDER BY issuekey' jira = Jira( - url="http://localhost:8080", - username="admin", - password="admin") + url='http://localhost:8080', + username='admin', + password='admin') data = jira.jql(JQL) pprint(data) diff --git a/examples/jira-project-administrators.py b/examples/jira-project-administrators.py index 2d4391ce9..883478f24 100644 --- a/examples/jira-project-administrators.py +++ b/examples/jira-project-administrators.py @@ -3,22 +3,22 @@ from atlassian import Jira -logging.basicConfig(level=logging.DEBUG, format="[%(asctime).19s] [%(levelname)s] %(message)s") -logging.getLogger("requests").setLevel(logging.WARNING) -log = logging.getLogger("jira-projects-administrators") +logging.basicConfig(level=logging.DEBUG, format='[%(asctime).19s] [%(levelname)s] %(message)s') +logging.getLogger('requests').setLevel(logging.WARNING) +log = logging.getLogger('jira-projects-administrators') jira = Jira( - url="http://localhost:8080", - username="admin", - password="admin") + url='http://localhost:8080', + username='admin', + password='admin') -html = "" +html = '
Project KeyProject NameLeaderEmail
' for data in jira.project_leaders(): - log.info("{project_key} leader is {lead_name} <{lead_email}>".format(**data)) - html += "{lead_name}{lead_email}".format(**data) + log.info('{project_key} leader is {lead_name} <{lead_email}>'.format(**data)) + html += '{lead_name}{lead_email}'.format(**data) -html += "
Project KeyProject NameLeaderEmail
{project_key}{project_name}
{project_key}{project_name}

" +html += '

' print(html) diff --git a/examples/jira-project-leaders.py b/examples/jira-project-leaders.py index 94f436546..3535f7c94 100644 --- a/examples/jira-project-leaders.py +++ b/examples/jira-project-leaders.py @@ -3,13 +3,13 @@ jira = Jira( - url="http://localhost:8080", - username="admin", - password="admin") + url='http://localhost:8080', + username='admin', + password='admin') -EMAIL_SUBJECT= urllib.parse.quote("Jira access to project {project_key}") -EMAIL_BODY = urllib.parse.quote("""Proszę o dostęp do projektu {project_key} w Jirze. +EMAIL_SUBJECT= urllib.parse.quote('Jira access to project {project_key}') +EMAIL_BODY = urllib.parse.quote('''Proszę o dostęp do projektu {project_key} w Jirze. Aby nadać mi odpowiednie uprawnienia przypisz mnie do roli na stronie: http://localhost:8080/plugins/servlet/project-config/{project_key}/roles @@ -17,17 +17,17 @@ Role: Users - dostęp tylko do odczytu + komentowanie Developers - praca na zadaniach, edycja itp. -Admin - Zmiana konfiguracji oraz możliwość startowania sprintów""") +Admin - Zmiana konfiguracji oraz możliwość startowania sprintów''') MAILTO = '{lead_name}' -print("|| Project Key || Project Name || Ask for Access ||") +print('|| Project Key || Project Name || Ask for Access ||') for project in jira.project_leaders(): print('| {project_key} | {project_name} | {lead_name} <{lead_email}> |'.format( - project_key=project["project_key"], - project_name=project["project_name"], + project_key=project['project_key'], + project_name=project['project_name'], email_subject=EMAIL_SUBJECT, email_body=EMAIL_BODY, - lead_name=project["lead_name"], - lead_email=project["lead_email"])) \ No newline at end of file + lead_name=project['lead_name'], + lead_email=project['lead_email'])) \ No newline at end of file diff --git a/examples/jira-sprint-rename.py b/examples/jira-sprint-rename.py index ffde4e2fa..dcc9ed58a 100644 --- a/examples/jira-sprint-rename.py +++ b/examples/jira-sprint-rename.py @@ -3,14 +3,14 @@ jira = Jira( - url="http://localhost:8080", - username="admin", - password="admin") + url='http://localhost:8080', + username='admin', + password='admin') data = jira.rename_sprint( sprint_id=10, - name="Here's the name of my new sprint", - start_date="2014-10-13 11:44", - end_date="2014-10-20 09:34") + name='Here is the name of my new sprint', + start_date='2014-10-13 11:44', + end_date='2014-10-20 09:34') pprint(data) diff --git a/examples/stash-project.py b/examples/stash-project.py index 60fe83e0e..b38fa0fb8 100644 --- a/examples/stash-project.py +++ b/examples/stash-project.py @@ -2,17 +2,16 @@ from atlassian import Stash -stash = Stash( - url='http://localhost:7990', - username='admin', - password='admin') - -data = stash.project_users("DEMO") - - def html(project): html = '{project_key}{project_name}\n' +stash = Stash( + url='http://localhost:7990', + username='admin', + password='admin') + +data = stash.project('DEMO') +pprint(html(data)) \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 000000000..538d53111 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,4 @@ +[pep8] +max-line-length = 120 +ignore = E402 + diff --git a/setup.py b/setup.py index 953f2b737..683eb9ab3 100644 --- a/setup.py +++ b/setup.py @@ -2,50 +2,50 @@ from setuptools import setup -assert sys.version_info >= (3, 0), "Python 3.0+ required." +assert sys.version_info >= (3, 0), 'Python 3.0+ required.' setup( - name="atlassian-python-api", - description="Atlassian Python API", - license="Apache License 2.0", - version="0.7.1", - download_url="https://github.com/MattAgile/atlassian-python-api", - - author="Matt Harasymczuk", - author_email="code@mattagile.com", - url="http://mattagile.com/", - - packages=["atlassian"], - package_data={"": ["LICENSE", "README"], "atlassian": ["*.py"]}, - package_dir={"atlassian": "atlassian"}, + name='atlassian-python-api', + description='Atlassian Python API', + license='Apache License 2.0', + version='0.7.10', + download_url='https://github.com/MattAgile/atlassian-python-api', + + author='Matt Harasymczuk', + author_email='code@mattagile.com', + url='http://mattagile.com/', + + packages=['atlassian'], + package_data={'': ['LICENSE', 'README'], 'atlassian': ['*.py']}, + package_dir={'atlassian': 'atlassian'}, include_package_data=True, zip_safe=False, - install_requires=["requests==2.5.3"], + install_requires=['requests==2.5.3'], classifiers=[ - "Development Status :: 4 - Beta", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Intended Audience :: System Administrators", - "License :: OSI Approved :: Apache Software License", - "Natural Language :: English", - "Operating System :: OS Independent", - "Operating System :: POSIX", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.0", - "Programming Language :: Python :: 3.1", - "Programming Language :: Python :: 3.2", - "Programming Language :: Python :: 3.3", - "Programming Language :: Python :: 3.4", - "Topic :: Internet", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Software Development :: Libraries :: Application Frameworks", + 'Development Status :: 4 - Beta', + 'Environment :: Web Environment', + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: OS Independent', + 'Operating System :: POSIX', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.0', + 'Programming Language :: Python :: 3.1', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Topic :: Internet', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', + 'Topic :: Software Development :: Libraries :: Python Modules', + 'Topic :: Software Development :: Libraries :: Application Frameworks', ], )