artemis/artemis.py
author Dmitriy Morozov <dmitriy@mrzv.org>
Mon, 18 Apr 2011 22:51:20 -0700
changeset 66 4129876c8b86
parent 63 c384fa42f8a2
child 67 30bd40ef9165
permissions -rw-r--r--
Fixed #af5 (summary formats provided in the config file)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
     1
# Author: Dmitriy Morozov <hg@foxcub.org>, 2007 -- 2009
38
83910efdbb54 remove trailing whitespaces
Alexander Solovyov <piranha@piranha.org.ua>
parents: 33
diff changeset
     2
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
     3
"""A very simple and lightweight issue tracker for Mercurial."""
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
     4
54
bd974d9e58a2 Fixed an issue that would raise an exception when using hg 1.7
Jason <jason@zzq.org>
parents: 50
diff changeset
     5
from mercurial import hg, util, commands
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
     6
from mercurial.i18n import _
7
74cbd53bf7d8 Implemented basic filters functionality in ilist (fixing 8e4)
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 6
diff changeset
     7
import os, time, random, mailbox, glob, socket, ConfigParser
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
     8
import mimetypes
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
     9
from email import encoders
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
    10
from email.generator import Generator
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
    11
from email.mime.audio import MIMEAudio
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
    12
from email.mime.base import MIMEBase
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
    13
from email.mime.image import MIMEImage
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
    14
from email.mime.multipart import MIMEMultipart
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
    15
from email.mime.text import MIMEText
66
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
    16
from itertools import izip
60
f44b6f1f2115 Added termcolor.py and started working on #edb (colorize output)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 59
diff changeset
    17
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
    18
63
c384fa42f8a2 Colors can be customized in the config (fixes #edb)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 62
diff changeset
    19
state = { 'new':      ['new'],
c384fa42f8a2 Colors can be customized in the config (fixes #edb)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 62
diff changeset
    20
          'resolved': ['fixed', 'resolved'] }
61
18da6a9fa7b8 Added #c25 (state annotations)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 60
diff changeset
    21
default_state = 'new'
35
2e7575352ef3 Added configuration option to provide an alternative path for the issues directory
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 33
diff changeset
    22
default_issues_dir = ".issues"
7
74cbd53bf7d8 Implemented basic filters functionality in ilist (fixing 8e4)
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 6
diff changeset
    23
filter_prefix = ".filter"
50
10fa939a4a3e Fixed #fcd (timezone)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 49
diff changeset
    24
date_format = '%a, %d %b %Y %H:%M:%S %1%2'
24
17a8293bbbbf Fixed various maildir-related bugs: missing subdirs, wrong keys, etc
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 21
diff changeset
    25
maildir_dirs = ['new','cur','tmp']
66
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
    26
default_format = '%(id)s (%(len)3d) [%(state)s]: %(Subject)s'
0
c1b34481e50a Initial commit
Dmitriy Morozov <morozov@cs.duke.edu>
parents:
diff changeset
    27
6
11cab5930258 Function rename + pretty list
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 5
diff changeset
    28
def ilist(ui, repo, **opts):
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    29
    """List issues associated with the project"""
1
0bbf290d6f07 Commit artemis before cleaning repository
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 0
diff changeset
    30
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    31
    # Process options
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    32
    show_all = opts['all']
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    33
    properties = []
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    34
    match_date, date_match = False, lambda x: True
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    35
    if opts['date']:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    36
        match_date, date_match = True, util.matchdate(opts['date'])
59
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
    37
    order = 'new'
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
    38
    if opts['order']:
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
    39
        order = opts['order']
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
    40
66
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
    41
    # Formats
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
    42
    formats = _read_formats(ui)
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
    43
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    44
    # Find issues
35
2e7575352ef3 Added configuration option to provide an alternative path for the issues directory
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 33
diff changeset
    45
    issues_dir = ui.config('artemis', 'issues', default = default_issues_dir)
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    46
    issues_path = os.path.join(repo.root, issues_dir)
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    47
    if not os.path.exists(issues_path): return
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
    48
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    49
    issues = glob.glob(os.path.join(issues_path, '*'))
17
f70d7e98eb21 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 16
diff changeset
    50
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
    51
    _create_all_missing_dirs(issues_path, issues)
24
17a8293bbbbf Fixed various maildir-related bugs: missing subdirs, wrong keys, etc
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 21
diff changeset
    52
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    53
    # Process filter
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    54
    if opts['filter']:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    55
        filters = glob.glob(os.path.join(issues_path, filter_prefix + '*'))
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    56
        config = ConfigParser.SafeConfigParser()
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    57
        config.read(filters)
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    58
        if not config.has_section(opts['filter']):
33
4b1f56527f08 Added README + fixed a bug with non-existent filters
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 32
diff changeset
    59
            ui.write('No filter %s defined\n' % opts['filter'])
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    60
        else:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    61
            properties += config.items(opts['filter'])
17
f70d7e98eb21 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 16
diff changeset
    62
31
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    63
    cmd_properties = _get_properties(opts['property'])
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    64
    list_properties = [p[0] for p in cmd_properties if len(p) == 1]
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    65
    list_properties_dict = {}
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    66
    properties += filter(lambda p: len(p) > 1, cmd_properties)
17
f70d7e98eb21 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 16
diff changeset
    67
60
f44b6f1f2115 Added termcolor.py and started working on #edb (colorize output)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 59
diff changeset
    68
    summaries = []
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    69
    for issue in issues:
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
    70
        mbox = mailbox.Maildir(issue, factory=mailbox.MaildirMessage)
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
    71
        root = _find_root_key(mbox)
56
0b2722bb35c9 Fixed cf0 (exception on empty Maildir in ilist)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 55
diff changeset
    72
        if not root: continue
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    73
        property_match = True
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
    74
        for property,value in properties:
31
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    75
            if value:
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    76
                property_match = property_match and (mbox[root][property] == value)
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    77
            else:
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    78
                property_match = property_match and (property not in mbox[root])
38
83910efdbb54 remove trailing whitespaces
Alexander Solovyov <piranha@piranha.org.ua>
parents: 33
diff changeset
    79
63
c384fa42f8a2 Colors can be customized in the config (fixes #edb)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 62
diff changeset
    80
        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['resolved']]): continue
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
    81
        if match_date and not date_match(util.parsedate(mbox[root]['date'])[0]): continue
31
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    82
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    83
        if not list_properties:
66
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
    84
            summaries.append((_summary_line(mbox, root, issue[len(issues_path)+1:], formats),     # +1 for trailing /
60
f44b6f1f2115 Added termcolor.py and started working on #edb (colorize output)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 59
diff changeset
    85
                              _find_mbox_date(mbox, root, order)))
31
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    86
        else:
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    87
            for lp in list_properties:
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    88
                if lp in mbox[root]:    list_properties_dict.setdefault(lp, set()).add(mbox[root][lp])
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    89
59
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
    90
    if not list_properties:
60
f44b6f1f2115 Added termcolor.py and started working on #edb (colorize output)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 59
diff changeset
    91
        summaries.sort(lambda (s1,d1),(s2,d2): cmp(d2,d1))
f44b6f1f2115 Added termcolor.py and started working on #edb (colorize output)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 59
diff changeset
    92
        for s,d in summaries:
66
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
    93
            ui.write(s + '\n')
59
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
    94
    else:
31
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    95
        for lp in list_properties_dict.keys():
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    96
            ui.write("%s:\n" % lp)
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    97
            for value in sorted(list_properties_dict[lp]):
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
    98
                ui.write("  %s\n" % value)
17
f70d7e98eb21 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 16
diff changeset
    99
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   100
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   101
def iadd(ui, repo, id = None, comment = 0, **opts):
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   102
    """Adds a new issue, or comment to an existing issue ID or its comment COMMENT"""
17
f70d7e98eb21 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 16
diff changeset
   103
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   104
    comment = int(comment)
4
bf71e2069dbd Basic functionality in place; added feature request for integration with commit (ef1)
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 2
diff changeset
   105
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   106
    # First, make sure issues have a directory
35
2e7575352ef3 Added configuration option to provide an alternative path for the issues directory
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 33
diff changeset
   107
    issues_dir = ui.config('artemis', 'issues', default = default_issues_dir)
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   108
    issues_path = os.path.join(repo.root, issues_dir)
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   109
    if not os.path.exists(issues_path): os.mkdir(issues_path)
4
bf71e2069dbd Basic functionality in place; added feature request for integration with commit (ef1)
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 2
diff changeset
   110
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   111
    if id:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   112
        issue_fn, issue_id = _find_issue(ui, repo, id)
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   113
        if not issue_fn:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   114
            ui.warn('No such issue\n')
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   115
            return
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   116
        _create_missing_dirs(issues_path, issue_id)
17
f70d7e98eb21 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 16
diff changeset
   117
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   118
    user = ui.username()
1
0bbf290d6f07 Commit artemis before cleaning repository
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 0
diff changeset
   119
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   120
    default_issue_text  =         "From: %s\nDate: %s\n" % (user, util.datestr(format = date_format))
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   121
    if not id:
61
18da6a9fa7b8 Added #c25 (state annotations)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 60
diff changeset
   122
        default_issue_text +=     "State: %s\n" % default_state
24
17a8293bbbbf Fixed various maildir-related bugs: missing subdirs, wrong keys, etc
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 21
diff changeset
   123
    default_issue_text +=         "Subject: brief description\n\n"
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   124
    default_issue_text +=         "Detailed description."
1
0bbf290d6f07 Commit artemis before cleaning repository
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 0
diff changeset
   125
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   126
    # Get properties, and figure out if we need an explicit comment
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   127
    properties = _get_properties(opts['property'])
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   128
    no_comment = id and properties and opts['no_property_comment']
48
7897c850150f iadd: Added --message
Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
parents: 40
diff changeset
   129
    message = opts['message']
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   130
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   131
    # Create the text
48
7897c850150f iadd: Added --message
Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
parents: 40
diff changeset
   132
    if message:
7897c850150f iadd: Added --message
Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
parents: 40
diff changeset
   133
        if not id:
61
18da6a9fa7b8 Added #c25 (state annotations)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 60
diff changeset
   134
            state_str = 'State: %s\n' % default_state
48
7897c850150f iadd: Added --message
Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
parents: 40
diff changeset
   135
        else:
7897c850150f iadd: Added --message
Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
parents: 40
diff changeset
   136
            state_str = ''
7897c850150f iadd: Added --message
Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
parents: 40
diff changeset
   137
        issue = "From: %s\nDate: %s\nSubject: %s\n%s" % \
7897c850150f iadd: Added --message
Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
parents: 40
diff changeset
   138
                (user, util.datestr(format=date_format), message, state_str)
7897c850150f iadd: Added --message
Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
parents: 40
diff changeset
   139
    elif not no_comment:
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   140
        issue = ui.edit(default_issue_text, user)
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   141
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   142
        if issue.strip() == '':
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   143
            ui.warn('Empty issue, ignoring\n')
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   144
            return
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   145
        if issue.strip() == default_issue_text:
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   146
            ui.warn('Unchanged issue text, ignoring\n')
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   147
            return
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   148
    else:
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   149
        # Write down a comment about updated properties
38
83910efdbb54 remove trailing whitespaces
Alexander Solovyov <piranha@piranha.org.ua>
parents: 33
diff changeset
   150
        properties_subject = ', '.join(['%s=%s' % (property, value) for (property, value) in properties])
83910efdbb54 remove trailing whitespaces
Alexander Solovyov <piranha@piranha.org.ua>
parents: 33
diff changeset
   151
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   152
        issue =     "From: %s\nDate: %s\nSubject: changed properties (%s)\n" % \
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   153
                     (user, util.datestr(format = date_format), properties_subject)
1
0bbf290d6f07 Commit artemis before cleaning repository
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 0
diff changeset
   154
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   155
    # Create the message
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   156
    msg = mailbox.MaildirMessage(issue)
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   157
    if opts['attach']:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   158
        outer = _attach_files(msg, opts['attach'])
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   159
    else:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   160
        outer = msg
17
f70d7e98eb21 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 16
diff changeset
   161
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   162
    # Pick random filename
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   163
    if not id:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   164
        issue_fn = issues_path
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   165
        while os.path.exists(issue_fn):
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   166
            issue_id = _random_id()
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   167
            issue_fn = os.path.join(issues_path, issue_id)
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   168
    # else: issue_fn already set
1
0bbf290d6f07 Commit artemis before cleaning repository
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 0
diff changeset
   169
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   170
    # Add message to the mailbox
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   171
    mbox = mailbox.Maildir(issue_fn, factory=mailbox.MaildirMessage)
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   172
    keys = _order_keys_date(mbox)
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   173
    mbox.lock()
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   174
    if id and comment >= len(mbox):
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   175
        ui.warn('No such comment number in mailbox, commenting on the issue itself\n')
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   176
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   177
    if not id:
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   178
        outer.add_header('Message-Id', "<%s-0-artemis@%s>" % (issue_id, socket.gethostname()))
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   179
    else:
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   180
        root = keys[0]
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   181
        outer.add_header('Message-Id', "<%s-%s-artemis@%s>" % (issue_id, _random_id(), socket.gethostname()))
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   182
        outer.add_header('References', mbox[(comment < len(mbox) and keys[comment]) or root]['Message-Id'])
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   183
        outer.add_header('In-Reply-To', mbox[(comment < len(mbox) and keys[comment]) or root]['Message-Id'])
54
bd974d9e58a2 Fixed an issue that would raise an exception when using hg 1.7
Jason <jason@zzq.org>
parents: 50
diff changeset
   184
    new_bug_path = issue_fn[(len(repo.root)+1):] + '/new/' + mbox.add(outer) # + 1 for the trailing /
bd974d9e58a2 Fixed an issue that would raise an exception when using hg 1.7
Jason <jason@zzq.org>
parents: 50
diff changeset
   185
    commands.add(ui, repo, new_bug_path)
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   186
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   187
    # Fix properties in the root message
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   188
    if properties:
30
b93ab358f2fc Fixed small iadd bug + added documentation issue (#d913)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 29
diff changeset
   189
        root = _find_root_key(mbox)
b93ab358f2fc Fixed small iadd bug + added documentation issue (#d913)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 29
diff changeset
   190
        msg = mbox[root]
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   191
        for property, value in properties:
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   192
            if property in msg:
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   193
                msg.replace_header(property, value)
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   194
            else:
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   195
                msg.add_header(property, value)
30
b93ab358f2fc Fixed small iadd bug + added documentation issue (#d913)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 29
diff changeset
   196
        mbox[root] = msg
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   197
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   198
    mbox.close()
1
0bbf290d6f07 Commit artemis before cleaning repository
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 0
diff changeset
   199
55
c379bed603c6 Fixed f09 (option to commit after iadd)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 54
diff changeset
   200
    if opts['commit']:
c379bed603c6 Fixed f09 (option to commit after iadd)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 54
diff changeset
   201
        commands.commit(ui, repo, issue_fn)
c379bed603c6 Fixed f09 (option to commit after iadd)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 54
diff changeset
   202
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   203
    # If adding issue, add the new mailbox to the repository
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   204
    if not id:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   205
        ui.status('Added new issue %s\n' % issue_id)
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   206
    else:
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   207
        _show_mbox(ui, mbox, 0)
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   208
6
11cab5930258 Function rename + pretty list
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 5
diff changeset
   209
def ishow(ui, repo, id, comment = 0, **opts):
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   210
    """Shows issue ID, or possibly its comment COMMENT"""
17
f70d7e98eb21 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 16
diff changeset
   211
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   212
    comment = int(comment)
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   213
    issue, id = _find_issue(ui, repo, id)
40
d013e9b9aba7 ishow: add --mutt option to display issue with mutt
Alexander Solovyov <piranha@piranha.org.ua>
parents: 38
diff changeset
   214
    if not issue:
d013e9b9aba7 ishow: add --mutt option to display issue with mutt
Alexander Solovyov <piranha@piranha.org.ua>
parents: 38
diff changeset
   215
        return ui.warn('No such issue\n')
59
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
   216
35
2e7575352ef3 Added configuration option to provide an alternative path for the issues directory
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 33
diff changeset
   217
    issues_dir = ui.config('artemis', 'issues', default = default_issues_dir)
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   218
    _create_missing_dirs(os.path.join(repo.root, issues_dir), issue)
24
17a8293bbbbf Fixed various maildir-related bugs: missing subdirs, wrong keys, etc
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 21
diff changeset
   219
40
d013e9b9aba7 ishow: add --mutt option to display issue with mutt
Alexander Solovyov <piranha@piranha.org.ua>
parents: 38
diff changeset
   220
    if opts.get('mutt'):
d013e9b9aba7 ishow: add --mutt option to display issue with mutt
Alexander Solovyov <piranha@piranha.org.ua>
parents: 38
diff changeset
   221
        return util.system('mutt -R -f %s' % issue)
d013e9b9aba7 ishow: add --mutt option to display issue with mutt
Alexander Solovyov <piranha@piranha.org.ua>
parents: 38
diff changeset
   222
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   223
    mbox = mailbox.Maildir(issue, factory=mailbox.MaildirMessage)
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   224
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   225
    if opts['all']:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   226
        ui.write('='*70 + '\n')
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   227
        i = 0
38
83910efdbb54 remove trailing whitespaces
Alexander Solovyov <piranha@piranha.org.ua>
parents: 33
diff changeset
   228
        keys = _order_keys_date(mbox)
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   229
        for k in keys:
32
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   230
            _write_message(ui, mbox[k], i, skip = opts['skip'])
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   231
            ui.write('-'*70 + '\n')
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   232
            i += 1
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   233
        return
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   234
32
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   235
    _show_mbox(ui, mbox, comment, skip = opts['skip'])
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   236
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   237
    if opts['extract']:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   238
        attachment_numbers = map(int, opts['extract'])
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   239
        keys = _order_keys_date(mbox)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   240
        msg = mbox[keys[comment]]
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   241
        counter = 1
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   242
        for part in msg.walk():
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   243
            ctype = part.get_content_type()
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   244
            maintype, subtype = ctype.split('/', 1)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   245
            if maintype == 'multipart' or ctype == 'text/plain': continue
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   246
            if counter in attachment_numbers:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   247
                filename = part.get_filename()
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   248
                if not filename:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   249
                    ext = mimetypes.guess_extension(part.get_content_type()) or ''
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   250
                    filename = 'attachment-%03d%s' % (counter, ext)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   251
                fp = open(filename, 'wb')
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   252
                fp.write(part.get_payload(decode = True))
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   253
                fp.close()
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   254
            counter += 1
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   255
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   256
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   257
def _find_issue(ui, repo, id):
35
2e7575352ef3 Added configuration option to provide an alternative path for the issues directory
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 33
diff changeset
   258
    issues_dir = ui.config('artemis', 'issues', default = default_issues_dir)
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   259
    issues_path = os.path.join(repo.root, issues_dir)
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   260
    if not os.path.exists(issues_path): return False
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   261
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   262
    issues = glob.glob(os.path.join(issues_path, id + '*'))
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   263
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   264
    if len(issues) == 0:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   265
        return False, 0
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   266
    elif len(issues) > 1:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   267
        ui.status("Multiple choices:\n")
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   268
        for i in issues: ui.status('  ', i[len(issues_path)+1:], '\n')
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   269
        return False, 0
17
f70d7e98eb21 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 16
diff changeset
   270
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   271
    return issues[0], issues[0][len(issues_path)+1:]
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   272
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   273
def _get_properties(property_list):
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   274
    return [p.split('=') for p in property_list]
17
f70d7e98eb21 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 16
diff changeset
   275
32
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   276
def _write_message(ui, message, index = 0, skip = None):
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   277
    if index: ui.write("Comment: %d\n" % index)
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   278
    if ui.verbose:
32
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   279
        _show_text(ui, message.as_string().strip(), skip)
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   280
    else:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   281
        if 'From' in message: ui.write('From: %s\n' % message['From'])
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   282
        if 'Date' in message: ui.write('Date: %s\n' % message['Date'])
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   283
        if 'Subject' in message: ui.write('Subject: %s\n' % message['Subject'])
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   284
        if 'State' in message: ui.write('State: %s\n' % message['State'])
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   285
        counter = 1
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   286
        for part in message.walk():
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   287
            ctype = part.get_content_type()
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   288
            maintype, subtype = ctype.split('/', 1)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   289
            if maintype == 'multipart': continue
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   290
            if ctype == 'text/plain':
32
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   291
                ui.write('\n')
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   292
                _show_text(ui, part.get_payload().strip(), skip)
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   293
            else:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   294
                filename = part.get_filename()
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   295
                ui.write('\n' + '%d: Attachment [%s, %s]: %s' % (counter, ctype, _humanreadable(len(part.get_payload())), filename) + '\n')
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   296
                counter += 1
4
bf71e2069dbd Basic functionality in place; added feature request for integration with commit (ef1)
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 2
diff changeset
   297
32
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   298
def _show_text(ui, text, skip = None):
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   299
    for line in text.splitlines():
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   300
        if not skip or not line.startswith(skip):
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   301
            ui.write(line + '\n')
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   302
    ui.write('\n')
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   303
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   304
def _show_mbox(ui, mbox, comment, **opts):
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   305
    # Output the issue (or comment)
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   306
    if comment >= len(mbox):
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   307
        comment = 0
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   308
        ui.warn('Comment out of range, showing the issue itself\n')
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   309
    keys = _order_keys_date(mbox)
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   310
    root = keys[0]
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   311
    msg = mbox[keys[comment]]
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   312
    ui.write('='*70 + '\n')
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   313
    if comment:
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   314
        ui.write('Subject: %s\n' % mbox[root]['Subject'])
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   315
        ui.write('State: %s\n' % mbox[root]['State'])
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   316
        ui.write('-'*70 + '\n')
32
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   317
    _write_message(ui, msg, comment, skip = ('skip' in opts) and opts['skip'])
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   318
    ui.write('-'*70 + '\n')
4
bf71e2069dbd Basic functionality in place; added feature request for integration with commit (ef1)
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 2
diff changeset
   319
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   320
    # Read the mailbox into the messages and children dictionaries
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   321
    messages = {}
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   322
    children = {}
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   323
    i = 0
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   324
    for k in keys:
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   325
        m = mbox[k]
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   326
        messages[m['Message-Id']] = (i,m)
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   327
        children.setdefault(m['In-Reply-To'], []).append(m['Message-Id'])
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   328
        i += 1
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   329
    children[None] = []                # Safeguard against infinte loop on empty Message-Id
4
bf71e2069dbd Basic functionality in place; added feature request for integration with commit (ef1)
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 2
diff changeset
   330
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   331
    # Iterate over children
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   332
    id = msg['Message-Id']
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   333
    id_stack = (id in children and map(lambda x: (x, 1), reversed(children[id]))) or []
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   334
    if not id_stack: return
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   335
    ui.write('Comments:\n')
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   336
    while id_stack:
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   337
        id,offset = id_stack.pop()
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   338
        id_stack += (id in children and map(lambda x: (x, offset+1), reversed(children[id]))) or []
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   339
        index, msg = messages[id]
29
0b3edabb7da2 Touched up ishow ("From" in the message thread + clarifed extract option)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 28
diff changeset
   340
        ui.write('  '*offset + '%d: [%s] %s\n' % (index, util.shortuser(msg['From']), msg['Subject']))
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   341
    ui.write('-'*70 + '\n')
2
9e804a85c82c list works well, basic show, add, and update functionality
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 1
diff changeset
   342
21
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   343
def _find_root_key(maildir):
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   344
    for k,m in maildir.iteritems():
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   345
        if 'in-reply-to' not in m:
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   346
            return k
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   347
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   348
def _order_keys_date(mbox):
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   349
    keys = mbox.keys()
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   350
    root = _find_root_key(mbox)
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   351
    keys.sort(lambda k1,k2: -(k1 == root) or cmp(util.parsedate(mbox[k1]['date']), util.parsedate(mbox[k2]['date'])))
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   352
    return keys
5b3579dc7abf Switched to maildir
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 20
diff changeset
   353
59
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
   354
def _find_mbox_date(mbox, root, order):
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
   355
    if order == 'latest':
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
   356
        keys = _order_keys_date(mbox)
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
   357
        msg = mbox[keys[-1]]
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
   358
    else:   # new
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
   359
        msg = mbox[root]
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
   360
    return util.parsedate(msg['date'])
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
   361
8
b1f268a9e4ed Message-Ids in <...> + randomized comment ids
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 7
diff changeset
   362
def _random_id():
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   363
    return "%x" % random.randint(2**63, 2**64-1)
8
b1f268a9e4ed Message-Ids in <...> + randomized comment ids
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 7
diff changeset
   364
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   365
def _create_missing_dirs(issues_path, issue):
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   366
    for d in maildir_dirs:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   367
        path = os.path.join(issues_path,issue,d)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   368
        if not os.path.exists(path): os.mkdir(path)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   369
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   370
def _create_all_missing_dirs(issues_path, issues):
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   371
    for i in issues:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   372
        _create_missing_dirs(issues_path, i)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   373
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   374
def _humanreadable(size):
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   375
    if size > 1024*1024:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   376
        return '%5.1fM' % (float(size) / (1024*1024))
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   377
    elif size > 1024:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   378
        return '%5.1fK' % (float(size) / 1024)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   379
    else:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   380
        return '%dB' % size
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   381
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   382
def _attach_files(msg, filenames):
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   383
    outer = MIMEMultipart()
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   384
    for k in msg.keys(): outer[k] = msg[k]
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   385
    outer.attach(MIMEText(msg.get_payload()))
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   386
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   387
    for filename in filenames:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   388
        ctype, encoding = mimetypes.guess_type(filename)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   389
        if ctype is None or encoding is not None:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   390
            # No guess could be made, or the file is encoded (compressed), so
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   391
            # use a generic bag-of-bits type.
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   392
            ctype = 'application/octet-stream'
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   393
        maintype, subtype = ctype.split('/', 1)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   394
        if maintype == 'text':
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   395
            fp = open(filename)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   396
            # Note: we should handle calculating the charset
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   397
            attachment = MIMEText(fp.read(), _subtype=subtype)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   398
            fp.close()
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   399
        elif maintype == 'image':
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   400
            fp = open(filename, 'rb')
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   401
            attachment = MIMEImage(fp.read(), _subtype=subtype)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   402
            fp.close()
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   403
        elif maintype == 'audio':
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   404
            fp = open(filename, 'rb')
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   405
            attachment = MIMEAudio(fp.read(), _subtype=subtype)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   406
            fp.close()
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   407
        else:
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   408
            fp = open(filename, 'rb')
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   409
            attachment = MIMEBase(maintype, subtype)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   410
            attachment.set_payload(fp.read())
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   411
            fp.close()
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   412
            # Encode the payload using Base64
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   413
            encoders.encode_base64(attachment)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   414
        # Set the filename parameter
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   415
        attachment.add_header('Content-Disposition', 'attachment', filename=filename)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   416
        outer.attach(attachment)
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   417
    return outer
0
c1b34481e50a Initial commit
Dmitriy Morozov <morozov@cs.duke.edu>
parents:
diff changeset
   418
66
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   419
def _read_formats(ui):
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   420
    formats = []
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   421
    global default_format
63
c384fa42f8a2 Colors can be customized in the config (fixes #edb)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 62
diff changeset
   422
c384fa42f8a2 Colors can be customized in the config (fixes #edb)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 62
diff changeset
   423
    for k,v in ui.configitems('artemis'):
66
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   424
        if not k.startswith('format'): continue
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   425
        if k == 'format':
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   426
            default_format = v
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   427
            continue
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   428
        formats.append((k.split(':')[1], v))
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   429
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   430
    return formats
63
c384fa42f8a2 Colors can be customized in the config (fixes #edb)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 62
diff changeset
   431
66
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   432
def _format_match(props, formats):
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   433
    for k,v in formats:
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   434
        eq = k.split('&')
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   435
        eq = [e.split('*') for e in eq]
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   436
        for e in eq:
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   437
            if props[e[0]] != e[1]:
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   438
                break
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   439
        else:
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   440
            return v
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   441
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   442
    return default_format
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   443
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   444
def _summary_line(mbox, root, issue, formats):
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   445
    props = PropertiesDictionary(mbox[root])
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   446
    props['id']  = issue
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   447
    props['len'] = len(mbox)-1              # number of replies (-1 for self)
60
f44b6f1f2115 Added termcolor.py and started working on #edb (colorize output)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 59
diff changeset
   448
66
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   449
    return _format_match(props, formats) % props
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   450
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   451
class PropertiesDictionary(dict):
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   452
    def __init__(self, msg):
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   453
        # Borrowed from termcolor
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   454
        for k,v in zip(['bold', 'dark', '', 'underline', 'blink', '', 'reverse', 'concealed'], range(1, 9)) + \
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   455
                   zip(['grey', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'], range(30, 38)):
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   456
            self[k] = '\033[' + str(v) + 'm'
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   457
        self['reset']  = '\033[0m'
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   458
        del self['']
60
f44b6f1f2115 Added termcolor.py and started working on #edb (colorize output)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 59
diff changeset
   459
66
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   460
        for k,v in msg.items():
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   461
            self[k] = v
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   462
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   463
    def __contains__(self, k):
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   464
        return super(PropertiesDictionary, self).__contains__(k.lower())
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   465
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   466
    def __getitem__(self, k):
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   467
        if k not in self: return ''
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   468
        return super(PropertiesDictionary, self).__getitem__(k.lower())
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   469
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   470
    def __setitem__(self, k, v):
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   471
        super(PropertiesDictionary, self).__setitem__(k.lower(), v)
4129876c8b86 Fixed #af5 (summary formats provided in the config file)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 63
diff changeset
   472
60
f44b6f1f2115 Added termcolor.py and started working on #edb (colorize output)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 59
diff changeset
   473
0
c1b34481e50a Initial commit
Dmitriy Morozov <morozov@cs.duke.edu>
parents:
diff changeset
   474
cmdtable = {
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   475
    'ilist':    (ilist,
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   476
                 [('a', 'all', False,
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   477
                   'list all issues (by default only those with state new)'),
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   478
                  ('p', 'property', [],
31
bffaaa5c8c9b Added ability to list all possible values for a property + list issues with an unset property
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 30
diff changeset
   479
                   'list issues with specific field values (e.g., -p state=fixed); lists all possible values of a property if no = sign'),
59
6c388fe11dcc ilist: added --order to sort by date (fixes #82a)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 56
diff changeset
   480
                  ('o', 'order', 'new', 'order of the issues; choices: "new" (date submitted), "latest" (date of the last message)'),
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   481
                  ('d', 'date', '', 'restrict to issues matching the date (e.g., -d ">12/28/2007)"'),
35
2e7575352ef3 Added configuration option to provide an alternative path for the issues directory
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 33
diff changeset
   482
                  ('f', 'filter', '', 'restrict to pre-defined filter (in %s/%s*)' % (default_issues_dir, filter_prefix))],
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   483
                 _('hg ilist [OPTIONS]')),
38
83910efdbb54 remove trailing whitespaces
Alexander Solovyov <piranha@piranha.org.ua>
parents: 33
diff changeset
   484
    'iadd':       (iadd,
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   485
                 [('a', 'attach', [],
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   486
                   'attach file(s) (e.g., -a filename1 -a filename2)'),
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   487
                  ('p', 'property', [],
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   488
                   'update properties (e.g., -p state=fixed)'),
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   489
                  ('n', 'no-property-comment', None,
48
7897c850150f iadd: Added --message
Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
parents: 40
diff changeset
   490
                   'do not add a comment about changed properties'),
7897c850150f iadd: Added --message
Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>
parents: 40
diff changeset
   491
                  ('m', 'message', '',
55
c379bed603c6 Fixed f09 (option to commit after iadd)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 54
diff changeset
   492
                   'use <text> as an issue subject'),
c379bed603c6 Fixed f09 (option to commit after iadd)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 54
diff changeset
   493
                  ('c', 'commit', False,
c379bed603c6 Fixed f09 (option to commit after iadd)
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 54
diff changeset
   494
                   'perform a commit after the addition')],
28
8b6b282d3ebd Combined iadd and iupdate (#b8ff) + added special "resolved" state
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 27
diff changeset
   495
                 _('hg iadd [OPTIONS] [ID] [COMMENT]')),
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   496
    'ishow':      (ishow,
26
4574d2d34009 Added ability to attach files
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 24
diff changeset
   497
                 [('a', 'all', None, 'list all comments'),
32
090ed3ae4c0a Added ability to skip lines starting with a string when showing a message
Dmitriy Morozov <dmitriy@mrzv.org>
parents: 31
diff changeset
   498
                  ('s', 'skip', '>', 'skip lines starting with a substring'),
40
d013e9b9aba7 ishow: add --mutt option to display issue with mutt
Alexander Solovyov <piranha@piranha.org.ua>
parents: 38
diff changeset
   499
                  ('x', 'extract', [], 'extract attachments (provide attachment number as argument)'),
d013e9b9aba7 ishow: add --mutt option to display issue with mutt
Alexander Solovyov <piranha@piranha.org.ua>
parents: 38
diff changeset
   500
                  ('', 'mutt', False, 'use mutt to show issue')],
16
49645303d045 Spaces instead of tabs
Mirko Friedenhagen <mirko.friedenhagen@1und1.de>
parents: 15
diff changeset
   501
                 _('hg ishow [OPTIONS] ID [COMMENT]')),
0
c1b34481e50a Initial commit
Dmitriy Morozov <morozov@cs.duke.edu>
parents:
diff changeset
   502
}
19
c79f89b04676 Added vim instruction to expand tabs + number of comments aligned to preset width in ilist
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 18
diff changeset
   503
c79f89b04676 Added vim instruction to expand tabs + number of comments aligned to preset width in ilist
Dmitriy Morozov <morozov@cs.duke.edu>
parents: 18
diff changeset
   504
# vim: expandtab