30 show_all = opts['all'] |
30 show_all = opts['all'] |
31 properties = [] |
31 properties = [] |
32 match_date, date_match = False, lambda x: True |
32 match_date, date_match = False, lambda x: True |
33 if opts['date']: |
33 if opts['date']: |
34 match_date, date_match = True, util.matchdate(opts['date']) |
34 match_date, date_match = True, util.matchdate(opts['date']) |
|
35 order = 'new' |
|
36 if opts['order']: |
|
37 order = opts['order'] |
|
38 |
35 |
39 |
36 # Find issues |
40 # Find issues |
37 issues_dir = ui.config('artemis', 'issues', default = default_issues_dir) |
41 issues_dir = ui.config('artemis', 'issues', default = default_issues_dir) |
38 issues_path = os.path.join(repo.root, issues_dir) |
42 issues_path = os.path.join(repo.root, issues_dir) |
39 if not os.path.exists(issues_path): return |
43 if not os.path.exists(issues_path): return |
55 cmd_properties = _get_properties(opts['property']) |
59 cmd_properties = _get_properties(opts['property']) |
56 list_properties = [p[0] for p in cmd_properties if len(p) == 1] |
60 list_properties = [p[0] for p in cmd_properties if len(p) == 1] |
57 list_properties_dict = {} |
61 list_properties_dict = {} |
58 properties += filter(lambda p: len(p) > 1, cmd_properties) |
62 properties += filter(lambda p: len(p) > 1, cmd_properties) |
59 |
63 |
|
64 subjects = [] |
60 for issue in issues: |
65 for issue in issues: |
61 mbox = mailbox.Maildir(issue, factory=mailbox.MaildirMessage) |
66 mbox = mailbox.Maildir(issue, factory=mailbox.MaildirMessage) |
62 root = _find_root_key(mbox) |
67 root = _find_root_key(mbox) |
63 if not root: continue |
68 if not root: continue |
64 property_match = True |
69 property_match = True |
70 |
75 |
71 if not show_all and (not properties or not property_match) and (properties or mbox[root]['State'].upper() in [f.upper() for f in state['fixed']]): continue |
76 if not show_all and (not properties or not property_match) and (properties or mbox[root]['State'].upper() in [f.upper() for f in state['fixed']]): continue |
72 if match_date and not date_match(util.parsedate(mbox[root]['date'])[0]): continue |
77 if match_date and not date_match(util.parsedate(mbox[root]['date'])[0]): continue |
73 |
78 |
74 if not list_properties: |
79 if not list_properties: |
75 ui.write("%s (%3d) [%s]: %s\n" % (issue[len(issues_path)+1:], # +1 for trailing / |
80 subjects.append(("%s (%3d) [%s]: %s\n" % (issue[len(issues_path)+1:], # +1 for trailing / |
76 len(mbox)-1, # number of replies (-1 for self) |
81 len(mbox)-1, # number of replies (-1 for self) |
77 _status_msg(mbox[root]), |
82 _status_msg(mbox[root]), |
78 mbox[root]['Subject'])) |
83 mbox[root]['Subject']), |
|
84 _find_mbox_date(mbox, root, order))) |
79 else: |
85 else: |
80 for lp in list_properties: |
86 for lp in list_properties: |
81 if lp in mbox[root]: list_properties_dict.setdefault(lp, set()).add(mbox[root][lp]) |
87 if lp in mbox[root]: list_properties_dict.setdefault(lp, set()).add(mbox[root][lp]) |
82 |
88 |
83 if list_properties: |
89 if not list_properties: |
|
90 subjects.sort(lambda (s1,d1),(s2,d2): cmp(d2,d1)) |
|
91 for s,d in subjects: |
|
92 ui.write(s) |
|
93 else: |
84 for lp in list_properties_dict.keys(): |
94 for lp in list_properties_dict.keys(): |
85 ui.write("%s:\n" % lp) |
95 ui.write("%s:\n" % lp) |
86 for value in sorted(list_properties_dict[lp]): |
96 for value in sorted(list_properties_dict[lp]): |
87 ui.write(" %s\n" % value) |
97 ui.write(" %s\n" % value) |
88 |
98 |
200 |
210 |
201 comment = int(comment) |
211 comment = int(comment) |
202 issue, id = _find_issue(ui, repo, id) |
212 issue, id = _find_issue(ui, repo, id) |
203 if not issue: |
213 if not issue: |
204 return ui.warn('No such issue\n') |
214 return ui.warn('No such issue\n') |
205 |
215 |
206 issues_dir = ui.config('artemis', 'issues', default = default_issues_dir) |
216 issues_dir = ui.config('artemis', 'issues', default = default_issues_dir) |
207 _create_missing_dirs(os.path.join(repo.root, issues_dir), issue) |
217 _create_missing_dirs(os.path.join(repo.root, issues_dir), issue) |
208 |
218 |
209 if opts.get('mutt'): |
219 if opts.get('mutt'): |
210 return util.system('mutt -R -f %s' % issue) |
220 return util.system('mutt -R -f %s' % issue) |
337 def _order_keys_date(mbox): |
347 def _order_keys_date(mbox): |
338 keys = mbox.keys() |
348 keys = mbox.keys() |
339 root = _find_root_key(mbox) |
349 root = _find_root_key(mbox) |
340 keys.sort(lambda k1,k2: -(k1 == root) or cmp(util.parsedate(mbox[k1]['date']), util.parsedate(mbox[k2]['date']))) |
350 keys.sort(lambda k1,k2: -(k1 == root) or cmp(util.parsedate(mbox[k1]['date']), util.parsedate(mbox[k2]['date']))) |
341 return keys |
351 return keys |
|
352 |
|
353 def _find_mbox_date(mbox, root, order): |
|
354 if order == 'latest': |
|
355 keys = _order_keys_date(mbox) |
|
356 msg = mbox[keys[-1]] |
|
357 else: # new |
|
358 msg = mbox[root] |
|
359 return util.parsedate(msg['date']) |
342 |
360 |
343 def _random_id(): |
361 def _random_id(): |
344 return "%x" % random.randint(2**63, 2**64-1) |
362 return "%x" % random.randint(2**63, 2**64-1) |
345 |
363 |
346 def _create_missing_dirs(issues_path, issue): |
364 def _create_missing_dirs(issues_path, issue): |
407 'ilist': (ilist, |
425 'ilist': (ilist, |
408 [('a', 'all', False, |
426 [('a', 'all', False, |
409 'list all issues (by default only those with state new)'), |
427 'list all issues (by default only those with state new)'), |
410 ('p', 'property', [], |
428 ('p', 'property', [], |
411 'list issues with specific field values (e.g., -p state=fixed); lists all possible values of a property if no = sign'), |
429 'list issues with specific field values (e.g., -p state=fixed); lists all possible values of a property if no = sign'), |
|
430 ('o', 'order', 'new', 'order of the issues; choices: "new" (date submitted), "latest" (date of the last message)'), |
412 ('d', 'date', '', 'restrict to issues matching the date (e.g., -d ">12/28/2007)"'), |
431 ('d', 'date', '', 'restrict to issues matching the date (e.g., -d ">12/28/2007)"'), |
413 ('f', 'filter', '', 'restrict to pre-defined filter (in %s/%s*)' % (default_issues_dir, filter_prefix))], |
432 ('f', 'filter', '', 'restrict to pre-defined filter (in %s/%s*)' % (default_issues_dir, filter_prefix))], |
414 _('hg ilist [OPTIONS]')), |
433 _('hg ilist [OPTIONS]')), |
415 'iadd': (iadd, |
434 'iadd': (iadd, |
416 [('a', 'attach', [], |
435 [('a', 'attach', [], |