Beispiel #1
0
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(
        description='Get all issues/stories for an Epic')
    parser.add_argument('-i', help="Provide Issue Key", required=True)
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    issue_key = args.i
    jc = JiraConn(username, password, server)
    issue = Issue(jc.jira, issue_key)
    issue.descope()
Beispiel #2
0
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(
        description='Move an Issue to another Epic')
    parser.add_argument('-I', '--issues','--stories', nargs='+', \
       help="Provide Issue Keys", required=True)
    parser.add_argument('-e',
                        '--epic',
                        help="Provide Issue Key",
                        required=True)
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    issues = args.issues
    epic = args.epic
    jc = JiraConn(username, password, server)
    for issue in issues:
        i = Issue(jc.jira, issue)
        i.set_epic(epic)
Beispiel #3
0
def main():
	username = password = server = None
	parser = argparse.ArgumentParser(description='Pull data into csv file for all Epic')
	parser.add_argument('-E', '--epics', nargs='+', help="List of Epics", required=True)
	parser.add_argument('-P', help="Planned Iteration")
	cfg = None
	try:
		cf = ConfigFile('config.yaml')
		cfg = cf.config
		username = cfg['username']
		password = cfg['password']
		server = cfg['server']
	except FileNotFoundError as e:
		print("Config File does not exist, falling back to argument parsing")
		parser.add_argument('-u', help="Provide User Name")
		parser.add_argument('-p', help="Provide Password")
		parser.add_argument('-s', help="Provide Server URL")
	args = parser.parse_args()
	if (cfg is None):
		username = args.u
		password = args.p
		server = args.s
	issue_keys = args.epics
	pi_string = args.P
	jc = JiraConn(username, password, server)
	if(pi_string):
		get_data_for_epics_pi(jc.jira, pi_string, issue_keys)
	else:
		get_data_for_epics(jc.jira, issue_keys)
Beispiel #4
0
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(
        description='Scope and Descope Issues (Stories, Epics etc.)')
    parser.add_argument("action", choices=("scope", "descope", "show"))
    parser.add_argument('-i', help="Provide Issue Key", required=True)
    parser.add_argument(
        '-R', help="Release String - uses the Jira Planned Iteration field")
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    issue_key = args.i
    pi_string = args.R
    jc = JiraConn(username, password, server)
    issue = Issue(jc.jira, issue_key)
    if (args.action == "scope"):
        issue.scope(pi_string)
    elif (args.action == "descope"):
        issue.descope()
    else:
        print(issue.get_release())
Beispiel #5
0
def main():
    username = password = server = None
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist." + e.strerror)
        exit(1)
    parser = argparse.ArgumentParser(prog='listissues',
                                     description="Will list issues from jira")
    parser.add_argument('--project',
                        help="Provide Project Name",
                        required=True)
    parser.add_argument('--output', help="Output file")
    parser.add_argument("--query", help='Query string to filter your fetch')
    args = parser.parse_args()
    project_string = args.project
    output_file = args.output
    query_string = args.query
    if (project_string is None):
        parser.print_help()
        raise Exception("Project is None, check command line")

    if (output_file is not None):
        try:
            of = open(output_file, "w")
        except OSError as oe:
            print(f'Error opening file for writing, {oe.errno} {oe.strerror}')
            sys.exit(oe.errno)

    # Connect to jira
    jc = JiraConn(username, password, server)
    assert (jc != None)
    p = Project(jc.jira, project_string)
    issues = p.get_issues_for_query(max_rows=50, query=query_string)
    for i in issues:
        issue = Issue(jc.jira, i.key)
        print(issue.i.key,
              issue.i.fields.issuetype,
              issue.i.fields.status,
              issue.i.fields.priority,
              issue.i.fields.created,
              issue.i.fields.updated,
              issue.i.fields.customfield_13000,
              sep='|')
        if (output_file is not None):
            print(issue.i.key,
                  issue.i.fields.issuetype,
                  issue.i.fields.status,
                  issue.i.fields.priority,
                  issue.i.fields.created,
                  issue.i.fields.updated,
                  issue.i.fields.customfield_13000,
                  sep='|',
                  file=of)
Beispiel #6
0
 def connect2jira(self):
     username = password = server = None
     cfg = {}
     try:
         cf = ConfigFile('config.yaml')
         cfg = cf.config
         username = cfg['username']
         password = cfg['password']
         server = cfg['server']
     except FileNotFoundError as e:
         print("Config File does not exist" + e.strerror)
         raise
     self.jc = JiraConn(username, password, server)
Beispiel #7
0
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(
        description='Tagging and Untagging of Jira issues')
    parser.add_argument('action',
                        choices=("tag", "detag", "print"),
                        help="Provide action")
    parser.add_argument('-i',
                        nargs='+',
                        help="Provide Issue Key",
                        required=True)
    parser.add_argument('-T',
                        '--tags',
                        nargs='+',
                        help="List of Tags",
                        required=False)
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    issues = args.i
    try:
        assert (username != None and password != None and server != None)
    except AssertionError as a:
        print("None username, password, issue, release and/or server")
        exit(1)
    jc = JiraConn(username, password, server)
    for issue_key in issues:
        issue = Issue(jc.jira, issue_key)
        tags = args.tags
        if (args.action == "tag"):
            issue.tag(tags)
        elif (args.action == "detag"):
            issue.detag(tags)
        else:
            issue.show_tags()
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(description='Get Story Point Estimates')
    parser.add_argument('-u', help="Provide User Name")
    parser.add_argument('-p', help="Provide Password")
    parser.add_argument('-s', help="Provide Server URL")
    parser.add_argument('-i', help="Provide Issue Key")
    parser.add_argument('-E', help="Provide new storypoint Estimate")
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    issue_key = args.i
    try:
        assert (username != None and password != None and server != None
                and issue_key != None)
    except AssertionError as a:
        print("None username, password and/or server or issue_key")
        print(
            'Usage: {:s} [-u <user> -p <password> -s <server>] -i <issue key> [-E <estimate>]'
        )
        exit(1)
    jc = JiraConn(username, password, server)
    issue = Issue(jc.jira, issue_key)
    print("Current Estimate for Issue is ",
          issue.get_estimate_in_story_points())
    if (args.E):
        try:
            print("New Estimate Provided, Updating.")
            estimate = float(args.E)
            issue.set_estimate_in_story_points(estimate)
        except JIRAError as e:
            print("New Estimate update failed. {} {}".format(
                e.status_code, e.text))
            exit(2)
        print("Updated.")
Beispiel #9
0
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(description='Get and Set \
			Estimates for Issues (Epics and Stories)')
    parser.add_argument("action", choices=("alter", "show"))
    parser.add_argument('-i',
                        '--issues',
                        nargs='+',
                        help="List of Issues",
                        required=True)
    parser.add_argument('--factor',
                        '-f',
                        help="Provide Normalization Factor",
                        required=True)
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    issues = args.issues
    factor = float(args.factor)
    jc = JiraConn(username, password, server)
    for issue_key in issues:
        issue = Issue(jc.jira, issue_key)
        estimate = issue.get_estimate_in_story_points()
        new_estimate = estimate * factor
        if (args.action == "show"):
            print("{:10s} ({:2.2f} -->> {:2.2f})".format(issue.i.key, \
              estimate, new_estimate))
        elif (args.action == "alter"):
            issue.set_estimate_in_story_points(new_estimate)
        else:
            print("invalid action, exiting.")
            exit(121)
Beispiel #10
0
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(
        description='Get all issues/stories for an Epic')
    parser.add_argument('-i', help="Provide Issue Key", required=True)
    parser.add_argument('-a',
                        action='store_true',
                        help="Provide all issues flag")
    parser.add_argument('-R', help="Planned Iteration")
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    issue_key = args.i
    pi_string = args.R
    jc = JiraConn(username, password, server)
    e = Epic(jc.jira, issue_key)
    if (args.a):
        e.print_issues()
    else:
        e.print_stories()
    print('-' * 70)
    print('{:2.1f} completed out of {:2.1f} (Original Est : {}) - {:2.2f}% Complete'.\
     format(e.closed_story_point_aggregate,\
            e.story_point_aggregate,\
            e.estimate_in_story_points, \
            e.percentage_complete))
    if (args.R != None):
        pi_estimate_for_epic = e.get_bottom_up_estimate_for_planned_iteration(
            pi_string)
        print('Points Scoped for PI {:s} is {:2.1f} Story Points'.format(
            pi_string, pi_estimate_for_epic))
Beispiel #11
0
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(
        description='Fix data in a Epic for both Epic and Stories')
    parser.add_argument("action", choices=('change', 'show'))
    parser.add_argument('-i',
                        '--issues',
                        nargs='+',
                        help="Provide Issue Key/s",
                        required=True)
    parser.add_argument('-P', '--planned_iteration', help="Planned Iteration")
    parser.add_argument('-T', '--teams', help="Teams")
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    issues = args.issues
    pi_string = args.P
    jc = JiraConn(username, password, server)
    action = args.action
    for issue_key in issues:
        e = Epic(jc.jira, issue_key)
        if (args.action == "change"):
            e.fix_estimate(pi_string)
            if (args.planned_iteration):
                e.scope(args.planned_iteration)
            if (args.teams):
                for team in arg.teams:
                    e.assign_team(args.team)
        else:
            e.print_issues()
Beispiel #12
0
def main():
	username = password = server = None
	parser = argparse.ArgumentParser(description='Get Story Point Estimates')
	parser.add_argument('-u', help="Provide User Name")
	parser.add_argument('-p', help="Provide Password")
	parser.add_argument('-s', help="Provide Server URL")
	parser.add_argument('-i', help="Provide Issue Key")
	args = parser.parse_args()
	username = args.u
	password = args.p
	server = args.s
	issue_key = args.i
	try:
		assert(username != None and password != None and server != None)
	except AssertionError as a:
		print("None username, password and/or server")
		exit(1)
	jc = JiraConn(username, password, server)
	issue = Epic(jc.jira, issue_key)
	print("Bottom Up Estimate is {:f}".format(issue.get_bottom_up_estimate()))
Beispiel #13
0
def main():
	username = password = server = None
	parser = argparse.ArgumentParser(description='Get Story Point Estimates')
	parser.add_argument('-u', help="Provide User Name")
	parser.add_argument('-p', help="Provide Password")
	parser.add_argument('-s', help="Provide Server URL")
	parser.add_argument('-b', help="Provide Board ID (Numerical)")
	args = parser.parse_args()
	username = args.u
	password = args.p
	server = args.s
	board_id = args.b
	try:
		assert(username != None and password != None and server != None)
	except AssertionError as a:
		print("None username, password and/or server")
		exit(1)
	jc = JiraConn(username, password, server)
	sb = SprintBoard(jc.jira, board_id)
	sb.list_sprints()
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(description='Batch Get and Set \
			Estimates for Issues (Epics and Stories)')
    parser.add_argument("action", choices=("alter", "show"))
    parser.add_argument('--estimates',
                        '-E',
                        nargs='+',
                        help="Provide key, \
		estimate pairs in the format key:estimate",
                        required=False)
    parser.add_argument('--keys',
                        '-K',
                        nargs='+',
                        help="Provide keys, \
		to show current estimates",
                        required=False)
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    jc = JiraConn(username, password, server)
    be = BatchEstimate(jc, args.estimates, args.keys)
    if (args.action == "show"):
        total_estimate = be.show_estimates()
    elif (args.action == "alter"):
        total_estimate = be.batch_alter()
    print("Total Story Points = {}".format(total_estimate))
Beispiel #15
0
def main():
	username = password = server = None
	parser = argparse.ArgumentParser(description='Jira issues Team Assignment')
	parser.add_argument('action', \
			choices=("assign","unassign","print"), help="Provide action")
	parser.add_argument('-i','--issues', help="Provide Issue Keys", nargs='+', required=True)
	parser.add_argument('-T', '--team', help="Team Code String", required=False)
	cfg = None
	try:
		cf = ConfigFile('config.yaml')
		cfg = cf.config
		username = cfg['username']
		password = cfg['password']
		server = cfg['server']
	except FileNotFoundError as e:
		print("Config File does not exist, falling back to argument parsing")
		parser.add_argument('-u', help="Provide User Name")
		parser.add_argument('-p', help="Provide Password")
		parser.add_argument('-s', help="Provide Server URL")
	args = parser.parse_args()
	if (cfg is None):
		username = args.u
		password = args.p
		server = args.s
	issues = args.issues
	try:
		assert(username != None and password != None and server != None)
	except AssertionError as a:
		print("None username, password, issue, release and/or server")
		exit(1)
	jc = JiraConn(username, password, server)
	action = args.action
	team = args.team
	for issue_key in issues:
		issue = Issue(jc.jira, issue_key)
		if (action == "assign"):
			issue.assign_team(team)
		elif(action == "print"):
			issue.show_teams()
		elif(action == "unassign"):
			issue.unassign_all_teams()
Beispiel #16
0
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(
        description='Scope and Descope Issues (Stories, Epics etc.)')
    parser.add_argument('--issues',
                        '-I',
                        nargs='+',
                        help="Provide Issue Key or list thereof",
                        required=True)
    parser.add_argument('--planned_iteration',
                        '-P',
                        help="PI - uses the Planned iteration field")
    #parser.add_argument('--release', '-R', help="Release String - uses the Jira Planned Iteration field")
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    issues = args.issues
    pi_string = args.planned_iteration
    #release_string = args.release
    jc = JiraConn(username, password, server)
    for issue in issues:
        print("Scoping issue {} for {}".format(issue, pi_string))
        issue = Issue(jc.jira, issue)
        issue.scope(pi_string)
Beispiel #17
0
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(description='Show all boards in JIRA')
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    jc = JiraConn(username, password, server)
    m = Metrics(jc.jira)
    m.list_boards()
Beispiel #18
0
def main():
    username = password = server = None
    parser = argparse.ArgumentParser(description='Get and Set \
			Estimates for Issues (Epics and Stories)')
    parser.add_argument("action", choices=("alter", "show"))
    parser.add_argument('-i', help="Provide Issue Key", required=True)
    parser.add_argument('--estimate',
                        '-E',
                        help="Provide Issue Key",
                        required=False)
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError:
        print("Config File does not exist, falling back to argument parsing")
        parser.add_argument('-u', help="Provide User Name")
        parser.add_argument('-p', help="Provide Password")
        parser.add_argument('-s', help="Provide Server URL")
    args = parser.parse_args()
    if (cfg is None):
        username = args.u
        password = args.p
        server = args.s
    issue_key = args.i
    jc = JiraConn(username, password, server)
    issue = Issue(jc.jira, issue_key)
    if (args.action == "show"):
        if (args.estimate):
            print("Ignoring script argument --estimate, none required")
        print(issue.get_estimate_in_story_points())
    elif (args.action == "alter"):
        estimate = float(args.estimate)
        issue.set_estimate_in_story_points(estimate)
Beispiel #19
0
def main():
	username = password = server = None
	parser = argparse.ArgumentParser(description='Get and Set \
			Estimates for Issues (Epics and Stories)')
	parser.add_argument("action", choices=("what","alter"))
	parser.add_argument('-i', help="Provide Issue Key", required=True)
	parser.add_argument('-T','--tid', help="Provide the Transition ID", required=False)
	parser.add_argument('-C','--comment',help="Comment for the transition", required=False)

	cfg = None
	try:
		cf = ConfigFile('config.yaml')
		cfg = cf.config
		username = cfg['username']
		password = cfg['password']
		server = cfg['server']
	except FileNotFoundError as e:
		print("Config File does not exist, falling back to argument parsing")
		parser.add_argument('-u', help="Provide User Name")
		parser.add_argument('-p', help="Provide Password")
		parser.add_argument('-s', help="Provide Server URL")
	args = parser.parse_args()
	if (cfg is None):
		username = args.u
		password = args.p
		server = args.s
	issue_key = args.i
	jc = JiraConn(username, password, server)
	issue = Issue(jc.jira, issue_key)
	if(args.action == "what"):
		issue.available_transitions()
	elif (args.action == "alter"):
		try:
			jc.jira.transition_issue(issue.i, str(args.tid))
		except JIRAError as e:
			print("Exception: error is {}-{}".format(e.status_code, e.text))
Beispiel #20
0
def main():
    username = password = server = None
    cfg = None
    try:
        cf = ConfigFile('config.yaml')
        cfg = cf.config
        username = cfg['username']
        password = cfg['password']
        server = cfg['server']
    except FileNotFoundError as e:
        logging.error("Config File does not exist." + e.strerror)
        exit(1)

    parser = argparse.ArgumentParser(
        prog='fetchdataset',
        description="Assembling a dataset for delivery insights")
    parser.add_argument("--batch-size",
                        help='Batch size for Jira fetch',
                        required=False,
                        default=100)
    parser.add_argument("--max-rows",
                        help='Arrest the number of rows processed',
                        required=False,
                        default=3000)
    parser.add_argument("--config",
                        help='Config file (default: fetchdataset.yaml)',
                        required=False,
                        default="fetchdataset.yaml")
    parser.add_argument("--log-level",
                        help="Set your log level.",
                        required=False,
                        default="INFO")
    args = parser.parse_args()
    max_rows = int(args.max_rows)
    batch_size = int(args.batch_size)
    run_config_file = args.config

    # Set up logging
    loglevel = args.log_level
    numeric_log_level = getattr(logging, loglevel.upper())
    if (not isinstance(numeric_log_level, int)):
        raise ValueError("Invalid numeric_log_level : %s" % numeric_log_level)
    logging.basicConfig(filename="fetchdataset.log",
                        level=numeric_log_level,
                        filemode='a',
                        format="%(asctime)s %(message)s",
                        datefmt="%Y:%m:%d %H:%M:%S")

    # Connect
    con = JiraConn(username, password, server).jira  # jira conection
    assert (con != None)

    try:
        print(
            "YAML configurator not provided,  defaulting to fetchdataset.yaml."
        )
        with open(run_config_file, 'r') as file:
            dsconfig = yaml.safe_load(file)
        print(dsconfig)
    except FileNotFoundError as e:
        print("Error, yaml configurator absent, does file exist?", e)
        exit(200)
    except Exception as e:
        print("Exception occured ", e)
        exit(201)

    for project in dsconfig:
        p = Project(con, project)
        for query in dsconfig[project].keys():
            querystr = construct_query_string(dsconfig, project, query)
            print(f'Executing {querystr} for {project}')
            issues = p.get_issues_for_query(max_rows=max_rows,
                                            query=querystr,
                                            block_size=batch_size)
            logging.info("Collected # " + str(len(issues)) + " issues.")

            # Check if output file can be successfully opened
            # Opening output file
            output_file = dsconfig[project][query]['outputfile']
            if (output_file is not None):
                try:
                    print(f'Opening {output_file} for writing')
                    with open(output_file, "w") as of:
                        print_issues_to_file(issues, of)
                    logging.info("Wrote data file.")
                except Exception as e:
                    logging.info("Exception while opening file")
                    sys.exit(1)