Skip to content

Commit

Permalink
Add code
Browse files Browse the repository at this point in the history
  • Loading branch information
dosaboy committed Jan 24, 2023
0 parents commit 2db4d35
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
asana_export
Empty file added asana-to-jira/__init__.py
Empty file.
124 changes: 124 additions & 0 deletions asana-to-jira/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/env python3
import argparse
import os
import asana
import json

PROJECTS_JSON = 'projects.json'
EXPORT_DIR = 'asana_export'


class Asana(object):

def __init__(self, token, workspace):
self.workspace = workspace
self.client = asana.Client.access_token(token)
if not os.path.isdir(EXPORT_DIR):
os.makedirs(EXPORT_DIR)

@property
def projects_json(self):
return os.path.join(EXPORT_DIR, PROJECTS_JSON)

@property
def projects_dir(self):
return os.path.join(EXPORT_DIR, 'projects')

@property
def tasks_dir(self):
return os.path.join(EXPORT_DIR, 'tasks')

@property
def stories_dir(self):
return os.path.join(EXPORT_DIR, 'stories')

def get_projects(self):
if os.path.exists(self.projects_json):
print("INFO: using cached projects")
with open(self.projects_json) as fd:
projects = json.loads(fd.read())
else:
print("INFO: fetching projects")
projects = []
for p in self.client.projects.find_by_workspace(self.workspace):
projects.append(p)

with open(self.projects_json, 'w') as fd:
fd.write(json.dumps(projects))

return projects

def get_project_tasks(self, project):
root_path = path = os.path.join(self.projects_dir, project['gid'])
if os.path.exists(os.path.join(root_path, 'tasks.json')):
print("INFO: using cached tasks for project '{}'".
format(project['name']))
with open(os.path.join(root_path, 'tasks.json')) as fd:
tasks = json.loads(fd.read())
else:
print("INFO: fetching tasks for project '{}'".
format(project['name']))
path = os.path.join(root_path, 'tasks')
os.makedirs(path)

tasks = []
for t in self.client.projects.tasks(project['gid']):
tasks.append(t)

for t in tasks:
if os.path.exists(os.path.join(path, t['gid'])):
continue

os.makedirs(os.path.join(path, t['gid']))

with open(os.path.join(root_path, 'tasks.json'), 'w') as fd:
fd.write(json.dumps(tasks))

return tasks

def get_task_stories(self, project, task):
root_path = os.path.join(self.projects_dir, project['gid'], 'tasks',
task['gid'])
if os.path.exists(os.path.join(root_path, 'stories.json')):
print("INFO: using cached stories for project '{}' task '{}'".
format(project['name'], task['name']))
with open(os.path.join(root_path, 'stories.json')) as fd:
stories = json.loads(fd.read())
else:
print("INFO: fetching stories for task '{}'".format(task['name']))
path = os.path.join(root_path, 'stories')
os.makedirs(path)

stories = []
for s in self.client.stories.find_by_task(task['gid']):
stories.append(s)

for s in stories:
with open(os.path.join(path, s['gid']), 'w') as fd:
fd.write(json.dumps(s))

with open(os.path.join(root_path, 'stories.json'),
'w') as fd:
fd.write(json.dumps(stories))

return stories

def load(self):
print("INFO: starting extraction")
if not os.path.isdir(EXPORT_DIR):
os.makedirs(EXPORT_DIR)

for p in self.get_projects():
if 'handover' in p['name'].lower():
for t in self.get_project_tasks(p):
self.get_task_stories(p, t)


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--token', type=str,
default=None, required=True, help="Asana api token")
parser.add_argument('--workspace', type=str,
default=None, required=True, help="Asana workspace ID")
args = parser.parse_args()
Asana(token=args.token, workspace=args.workspace).load()
57 changes: 57 additions & 0 deletions pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
[MASTER]
jobs=0

[FORMAT]
max-line-length=79

[REPORTS]
#reports=yes
score=yes

[MESSAGES CONTROL]
disable=
fixme,
invalid-name,
no-value-for-parameter,
no-member,
pointless-statement,
missing-module-docstring,
missing-class-docstring,
missing-function-docstring,
too-many-arguments,
too-many-locals,
too-many-branches,
too-many-instance-attributes,
too-many-ancestors,
too-many-public-methods,
too-many-lines,
too-many-nested-blocks,
too-many-statements,
signature-differs,
protected-access,
redefined-argument-from-local,
super-init-not-called,
undefined-loop-variable,
wrong-import-order,
duplicate-code,
useless-object-inheritance,
unidiomatic-typecheck,
unsubscriptable-object,
consider-using-set-comprehension,
use-a-generator,
useless-super-delegation,
inconsistent-return-statements,
redefined-builtin,
attribute-defined-outside-init,
too-few-public-methods,
abstract-method,
no-else-return,
no-self-use,
simplifiable-if-statement,
broad-except,
trailing-comma-tuple,
redefined-outer-name,
expression-not-assigned,
unnecessary-lambda,
pointless-string-statement,
arguments-differ,
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
asana
simplejson
19 changes: 19 additions & 0 deletions snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: hotsos
version: '1.0'
summary: Extract Asana data and import into Jira
description:
Extract Asana data and import into Jira
confinement: strict
grade: stable
base: core22

apps:
asana-to-jira:
command: bin/asana-to-jira
parts:
asana-to-jira:
plugin: python
source: .
requirements:
- requirements.txt

2 changes: 2 additions & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
flake8
pylint==2.8.3
22 changes: 22 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[tox]
skipsdist = True
envlist = pep8,pylint
sitepackages = False

[testenv]
pyfiles =
{toxinidir}/asana-to-jira
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
TERM=linux
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
basepython = python3

[testenv:pep8]
commands = flake8 -v {posargs:{[testenv]pyfiles}}

[testenv:pylint]
commands = pylint -v --rcfile={toxinidir}/pylintrc {posargs:{[testenv]pyfiles}}

0 comments on commit 2db4d35

Please sign in to comment.