blob: 151c4b57380062cf2035a8b17f4be9cc26bd5173 [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001# Copyright 2023 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""Utils for redirect."""
5import urllib
6from werkzeug.datastructures import MultiDict
7from redirect import redirect_project_template
8
9from tracker import tracker_constants
10from tracker import tracker_bizobj
11from redirect import redirect_custom_value
12
13PROJECT_REDIRECT_MAP = {
14 'pigweed': 'https://issues.pigweed.dev',
15 'git': 'https://git.issues.gerritcodereview.com',
16 'gerrit': 'https://issues.gerritcodereview.com',
17 'skia': 'http://issues.skia.org',
18 'fuchsia': 'https://issues.fuchsia.dev',
19}
20
21MAX_MONORAIL_ISSUE_ID = 10000000
22
23TRACKER_SEARCH_KEY_MAP = {
24 'cc': 'cc',
25 'owner': 'assignee',
26 'commentby': 'commenter',
27 'reporter': 'reporter',
28 'is': 'is',
29}
30
31VALID_IS_SEARCH_VALUE = ['open', 'starred']
32
33
34def GetRedirectURL(project_name):
35 return PROJECT_REDIRECT_MAP.get(project_name, None)
36
37
38def GetNewIssueParams(params: MultiDict, project_name: str):
39 new_issue_params = {}
40
41 # Get component and template id.
42 template_name = params.get('template', type=str, default='default')
43 redirect_component_id, redirect_template_id = (
44 redirect_project_template.RedirectProjectTemplate.Get(
45 project_name, template_name))
46 if redirect_component_id:
47 new_issue_params['component'] = redirect_component_id
48 if redirect_template_id:
49 new_issue_params['template'] = redirect_template_id
50
51 if params.get('summary', type=str):
52 new_issue_params['title'] = params.get('summary', type=str)
53
54 if (params.get('description', type=str) or params.get('comment', type=str)):
55 new_issue_params['description'] = (
56 params.get('description', type=str) or params.get('comment', type=str))
57
58 if params.get('cc', type=str):
59 new_issue_params['cc'] = params.get('cc', type=str)
60
61 if params.get('owner', type=str):
62 new_issue_params['assignee'] = params.get('owner', type=str).split('@')[0]
63
64 # TODO(b/283983843): redirect when custom field settled. (components)
65 return urllib.parse.urlencode(new_issue_params)
66
67
68def GetSearchQuery(project_name, params):
69 search_conds = []
70
71 # can param is the default search query used in monorail.
72 # Each project can customize the canned queries.
73 # (eg.can=41013401 in Monorail is the Triage Queue.)
74 # For redirect we will just support the build in can query as the first step.
75 # TODO(b/283983843): support customized can query as needed.
76 can_param = params.get(
77 'can', type=int, default=tracker_constants.OPEN_ISSUES_CAN)
78 # TODO(b/283983843): move the BuiltInQuery to redirect folder.
79 default_search_string = tracker_bizobj.GetBuiltInQuery(can_param)
80 for cond in default_search_string.split(' '):
81 search_conds.append(cond)
82
83 # q param is the user defined search query.
84 if params.get('q', type=str):
85 search_string = urllib.parse.unquote(params.get('q', type=str))
86 for cond in search_string.split(' '):
87 search_conds.append(cond)
88
89 query_string = ''
90 for cond in search_conds:
91 condition_pair = _ConvertSearchCondition(project_name, cond)
92 if condition_pair:
93 (k, v) = condition_pair
94 query_string += ' {0}:{1}'.format(k, v)
95 return urllib.parse.urlencode({'q': query_string.strip()})
96
97
98# Convert monorail search conditions to tracker search conditions.
99def _ConvertSearchCondition(project_name, cond):
100 cond_pair = []
101 # In monorail the search condition can be either ':' or '='.
102 if ':' in cond:
103 cond_pair = cond.split(':')
104 if '=' in cond:
105 cond_pair = cond.split('=')
106
107 if len(cond_pair) != 2:
108 return None
109 # '-' stand for NOT.
110 pre = '-' if cond_pair[0].startswith('-') else ''
111 key_val = cond_pair[0][1:] if cond_pair[0].startswith('-') else cond_pair[0]
112
113 k, v = _GenerateTrackerSearchKeyValuePair(project_name, key_val, cond_pair[1])
114 if not k or not v:
115 return None
116
117 return pre + k, v
118
119
120# Convert the search value to tracker search format.
121def _GenerateTrackerSearchKeyValuePair(project_name, key, value):
122 if len(value) == 0:
123 return None, None
124 # Find the related search filter from datastore.
125 new_key, new_value = redirect_custom_value.RedirectCustomValue.Get(
126 project_name, key, value)
127 if new_key and new_value:
128 return new_key, new_value
129
130 # If the value is not store in datastore check the general filter set.
131 new_key = TRACKER_SEARCH_KEY_MAP.get(key, None)
132 if not new_key:
133 return None, None
134
135 if new_key == 'is':
136 return new_key, value if value in VALID_IS_SEARCH_VALUE else None
137
138 new_value = value.replace(',', '|')
139 return new_key, '({})'.format(new_value)