From 0a6f580856d2fa7eb259a3cd8d4ee99c68f7800a Mon Sep 17 00:00:00 2001
From: Julianus Larson <julianus.larson@linaro.org>
Date: Tue, 8 Nov 2022 12:08:23 +0100
Subject: [PATCH] add script jipsearch

This script makes it easy to pull out all issues created by person X,
that reported issues on project Y.

Co-developed-by: Anders Roxell <anders.roxell@linaro.org>
Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
Signed-off-by: Julianus Larson <julianus.larson@linaro.org>
---
Vi behöver lägga till ett sätt att kunna filtrera på issuetype också.
dvs. --reporter anders.roxell@linaro.org --project STG --issue-type Ticket

Hur vi nu kan göra detta i jql =)

 jipdate/jipsearch.py | 186 +++++++++++++++++++++++++++++++++++++++++++
 pyproject.toml       |   1 +
 2 files changed, 187 insertions(+)
 create mode 100644 jipdate/jipsearch.py

diff --git a/jipdate/jipsearch.py b/jipdate/jipsearch.py
new file mode 100644
index 000000000000..c663845c0e43
--- /dev/null
+++ b/jipdate/jipsearch.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python3
+from argparse import ArgumentParser
+import logging as log
+import os
+import sys
+import yaml
+from dateutil import parser
+
+# Local files
+from jipdate import cfg
+from jipdate import jiralogin
+
+################################################################################
+# Argument parser
+################################################################################
+def get_parser():
+    """ Takes care of script argument parsing. """
+    parser = ArgumentParser(description='Script used to create tickets in Jira')
+
+    parser.add_argument('-u', '--user', required=False, action="store",
+            default=None,
+            help='''Query Jira with another Jira username
+            (first.last or first.last@linaro.org)''')
+
+    parser.add_argument('-j', '--jql', required=False, action="append",
+            default=None,
+            help='''JQL string to query Jira. Can be specified several
+            times to allow several searches being displayed in the search result.''')
+
+    parser.add_argument('-p', '--project', required=False, action="store",
+            default=None,
+            help='''Define which project to search in.
+            Separate with comma to search in several projects''')
+
+    parser.add_argument('-r', '--reporter', required=False, action="store",
+            default=None,
+            help='''Search for issues with the specified reporters.
+            Use comma to separate multiple reporters.''')
+
+    parser.add_argument('-a', '--assignee', required=False, action="store",
+            default=None,
+            help='''Search for issues with the specified assignees.
+            Use comma to separate multiple reporters.''')
+
+    parser.add_argument('-ca', '--created-after', required=False, action="store",
+            default=None,
+            help='''Search for issues created after this date and time.
+            Valid formats include: "yyyy/MM/dd HH:mm", "yyyy-MM-dd HH:mm",
+            "yyyy/MM/dd", "yyyy-MM-dd", or a period format e.g. "-5d", "4w 2d".''')
+
+    parser.add_argument('-cb', '--created-before', required=False, action="store",
+            default=None,
+            help='''Search for issues created before this date and time.
+            Valid formats include: "yyyy/MM/dd HH:mm", "yyyy-MM-dd HH:mm",
+            "yyyy/MM/dd", "yyyy-MM-dd", or a period format e.g. "-5d", "4w 2d".''')
+
+    parser.add_argument('-ua', '--updated-after', required=False, action="store",
+            default=None,
+            help='''Search for issues updated after this date and time.
+            Valid formats include: "yyyy/MM/dd HH:mm", "yyyy-MM-dd HH:mm",
+            "yyyy/MM/dd", "yyyy-MM-dd", or a period format e.g. "-5d", "4w 2d".''')
+
+    parser.add_argument('-ub', '--updated-before', required=False, action="store",
+            default=None,
+            help='''Search for issues updated before this date and time.
+            Valid formats include: "yyyy/MM/dd HH:mm", "yyyy-MM-dd HH:mm",
+            "yyyy/MM/dd", "yyyy-MM-dd", or a period format e.g. "-5d", "4w 2d".''')
+
+    parser.add_argument('-v', required=False, action="store_true",
+            default=False,
+            help='''Output some verbose debugging info''')
+
+    parser.add_argument('--dry-run', required=False, action="store_true",
+            default=False,
+            help='''Do not make any changes to JIRA''')
+
+    return parser
+
+
+def initialize_logger(args):
+    LOG_FMT = ("[%(levelname)s] %(funcName)s():%(lineno)d   %(message)s")
+    lvl = log.ERROR
+    if args.v:
+        lvl = log.DEBUG
+
+    log.basicConfig(
+        # filename="core.log",
+        level=lvl,
+        format=LOG_FMT,
+        filemode='w')
+
+def create_jql(jira, initial_jql):
+    jql_parts = []
+    if cfg.args.project:
+        jql_parts.append('project in (%s)' % cfg.args.project)
+
+    if cfg.args.reporter:
+        reporter_ids = []
+        reporters = cfg.args.reporter.split(',')
+        for r in reporters:
+            reporter_ids += jira.search_users(query=r)
+        if len(reporter_ids) > 0:
+            account_ids = []
+            for ri in reporter_ids:
+                account_ids.append(ri.accountId)
+            jql_parts.append('reporter in (%s)' % ','.join(account_ids))
+
+    if cfg.args.assignee:
+        assignee_ids = []
+        assignees = cfg.args.assignee.split(',')
+        for r in assignees:
+            assignee_ids += jira.search_users(query=r)
+        if len(assignee_ids) > 0:
+            account_ids = []
+            for ai in assignee_ids:
+                account_ids.append(ai.accountId)
+            jql_parts.append('assignee in (%s)' % ','.join(account_ids))
+
+    if cfg.args.created_after:
+        jql_parts.append('created >= %s' % cfg.args.created_after)
+
+    if cfg.args.created_before:
+        jql_parts.append('created <= %s' % cfg.args.created_before)
+
+    if cfg.args.updated_after:
+        jql_parts.append('updated >= %s' % cfg.args.updated_after)
+
+    if cfg.args.updated_before:
+        jql_parts.append('updated <= %s' % cfg.args.updated_before)
+
+    jql_string = initial_jql
+    jql_string = ' AND '.join(jql_parts)
+    print(jql_string)
+    return jql_string
+
+def search_issues(jira, jql):
+    issues = []
+    result = { 'startAt' : 0, 'total' : 1}
+    max_results = 50
+
+    while result['startAt'] < result['total']:
+        result = jira.search_issues(jql, startAt = result['startAt'], maxResults=max_results, fields=['summary','created'], json_result=True)
+        issues += result['issues']
+        result['startAt'] += max_results
+
+    return issues
+
+def print_issues(issues):
+    for i in issues:
+        print(f"https://linaro.atlassian.net/browse/{i['key']}, created: {str(parser.parse(i['fields']['created'])).split(' ')[0]},  Summary: {i['fields']['summary']}")
+        #print(f"{i['key']}, created: {str(parser.parse(i['fields']['created'])).split(' ')[0]}\n\t   Summary: {i['fields']['summary']}\n\t   https://linaro.atlassian.net/browse/{i['key']}")
+
+################################################################################
+# Main function
+################################################################################
+def main():
+    argv = sys.argv
+    parser = get_parser()
+    if len(sys.argv)==1:
+        parser.print_help(sys.stderr)
+        sys.exit(1)
+
+    # The parser arguments (cfg.args) are accessible everywhere after this call.
+    cfg.args = parser.parse_args()
+
+    initialize_logger(cfg.args)
+
+    # This initiates the global yml configuration instance so it will be
+    # accessible everywhere after this call.
+    cfg.initiate_config()
+
+    jira, username = jiralogin.get_jira_instance(False)
+    issues = []
+    if cfg.args.jql:
+        jql = cfg.args.jql
+        log.debug(f"JQL: "+jql[0])
+        for j in jql:
+            issues += create_jql(jira, j)
+    else:
+        jql_str = create_jql(jira, "")
+        issues += search_issues(jira,jql_str)
+
+    print_issues(issues)
+
+if __name__ == "__main__":
+    main()
diff --git a/pyproject.toml b/pyproject.toml
index 403b12dee1fd..80625ee7f036 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -22,4 +22,5 @@ Documentation = "https://jipdate.readthedocs.io/en/latest/"
 jipcreate="jipdate.jipcreate:main"
 jipdate="jipdate.jipdate:main"
 jipfp="jipdate.jipfp:main"
+jipsearch="jipdate.jipsearch:main"
 jipstatus="jipdate.jipstatus:main"
-- 
2.35.1

