~ubuntu-branches/ubuntu/trusty/debtags/trusty-proposed

« back to all changes in this revision

Viewing changes to debtags-submit-patch

  • Committer: Package Import Robot
  • Author(s): Enrico Zini
  • Date: 2012-01-07 13:20:34 UTC
  • Revision ID: package-import@ubuntu.com-20120107132034-v4m9d2fpinpuc0df
Tags: 1.8.0
* Removed obsolete/unused command selfcheck
* Removed obsolete/unused command stats
* Removed obsolete/unused command todo
* Removed obsolete/unused command score
* Removed broken command smartsearch. Closes: #644011.
* Removed broken command install.
* Removed obsolete/unused command maintainers
* Removed obsolete/unused command related. Closes: 403137.
* Removed obsolete debtags-updatecontrol
* Send patches via HTTP using external script debtags-submit-patch
  (included). Closes: #641968.
  Added python dependency because of this.
* Manpage updated. Closes: #641379, #542525, 516098.
* Documented tax expression syntax in grep. Closes: #589953.
* Complain about unneeded arguments. Closes: #355634.
* Fix tagcat to also show tags. Closes: #625456.
* Homepage moved to the Debian wiki
* Rewritten fetcher script. Closes: #478590, #481634, #617254.
* apt-index-watcher is not in stable anymore: dropping conflict.
* Removed obsolete 'rm's in postinst

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
# debtags-submit-patch: submit a tag patch to the debtags website
 
4
#
 
5
# Copyright (C) 2007--2012  Enrico Zini <enrico@debian.org>
 
6
#
 
7
# This program is free software; you can redistribute it and/or modify
 
8
# it under the terms of the GNU General Public License as published by
 
9
# the Free Software Foundation; either version 2 of the License, or
 
10
# (at your option) any later version.
 
11
#
 
12
# This program is distributed in the hope that it will be useful,
 
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
# GNU General Public License for more details.
 
16
#
 
17
# You should have received a copy of the GNU General Public License
 
18
# along with this program; if not, write to the Free Software
 
19
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 
 
21
import pwd
 
22
import os
 
23
import sys
 
24
import hashlib
 
25
import urllib
 
26
import urllib2
 
27
import json
 
28
import logging
 
29
 
 
30
log = logging.getLogger(sys.argv[0])
 
31
 
 
32
SUBMIT_URL = "http://debtags.debian.net/api/patch"
 
33
 
 
34
def make_default_tag():
 
35
    "Autogenerate a mostly persistant, non-trackable tag"
 
36
    m = hashlib.md5()
 
37
    m.update(":".join(str(x) for x in pwd.getpwuid(os.getuid())))
 
38
    return m.hexdigest()[:20]
 
39
 
 
40
def submit(opts, patch, fname="[stdin]"):
 
41
    log.info("Submitting patch %s to %s...", fname, opts.url)
 
42
    try:
 
43
        conn = urllib2.urlopen(opts.url,
 
44
                               urllib.urlencode((
 
45
                                  ("tag", opts.tag),
 
46
                                  ("patch", patch),
 
47
                               )))
 
48
        res = json.load(conn)
 
49
        for note in res.get("notes", ()):
 
50
            log.warn("%s: %s", fname, note)
 
51
 
 
52
        for pkg, tags in sorted(res.get("pkgs", {}).iteritems()):
 
53
            log.info("%s: %s: %s", fname, pkg, ", ".join(tags))
 
54
 
 
55
        if opts.dump_http_error:
 
56
            try:
 
57
                os.unlink(opts.dump_http_error)
 
58
            except OSError:
 
59
                pass
 
60
    except urllib2.HTTPError, e:
 
61
        log.error("%s", str(e))
 
62
        if opts.dump_http_error:
 
63
            with open(opts.dump_http_error, "w") as fd:
 
64
                fd.write(e.read())
 
65
 
 
66
 
 
67
if __name__ == "__main__":
 
68
    from optparse import OptionParser
 
69
    import sys
 
70
 
 
71
    VERSION="1.8"
 
72
 
 
73
    class Parser(OptionParser):
 
74
        def print_help(self, out=None):
 
75
            if out is None: out = sys.stdout
 
76
            OptionParser.print_help(self, out)
 
77
            print >>out, """Patch files can be generated with 'debtags diff' or 'tagcoll diff'.
 
78
 
 
79
Patch submissions are marked with a tag of your choice. It does not need to
 
80
identify yourself (but feel free to use your email address), but reusing your
 
81
tag allows to handle all your edits as if they were a single one. This helps
 
82
greatly when tags are reviewed.
 
83
 
 
84
By default, a mostly persistent but anonymous tag is generated by hashing your
 
85
passwd entry.
 
86
"""
 
87
        def error(self, msg):
 
88
            sys.stderr.write("%s: error: %s\n\n" % (self.get_prog_name(), msg))
 
89
            self.print_help(sys.stderr)
 
90
            sys.exit(2)
 
91
 
 
92
    parser = Parser(usage="usage: %prog [-t TAG] [options] [patchfile [patchfile...]]",
 
93
                    version="%prog "+ VERSION,
 
94
                    description="Submits a tag patch to the Debtags website."
 
95
                    " Each patch file is submitted in a different query.")
 
96
    parser.add_option("-t", "--tag", action="store", metavar="tag", default=make_default_tag(),
 
97
                      help="tag the patch with the given string (default: %default).")
 
98
    parser.add_option("-q", "--quiet", action="store_true",
 
99
                      help="quiet mode: only output errors.")
 
100
    parser.add_option("-v", "--verbose", action="store_true",
 
101
                      help="verbose mode: output progress and non-essential information.")
 
102
    parser.add_option("--stdin", action="store_true",
 
103
                      help="read patch from standard input.")
 
104
    parser.add_option("--url", action="store", metavar="url", default=SUBMIT_URL,
 
105
                      help="URL to submit to (default: %default).")
 
106
    parser.add_option("--dump-http-error", action="store", metavar="file",
 
107
                      help="if the server returns an error, dump the contents"
 
108
                           "of the error page to the given file (default:"
 
109
                           "discard the error page).")
 
110
    (opts, args) = parser.parse_args()
 
111
 
 
112
    #FORMAT = "%(asctime)-15s %(levelname)s %(message)s"
 
113
    FORMAT = "%(message)s"
 
114
    if opts.quiet:
 
115
        logging.basicConfig(level=logging.ERROR, stream=sys.stderr, format=FORMAT)
 
116
    elif not opts.verbose:
 
117
        logging.basicConfig(level=logging.WARNING, stream=sys.stderr, format=FORMAT)
 
118
    else:
 
119
        logging.basicConfig(level=logging.INFO, stream=sys.stderr, format=FORMAT)
 
120
 
 
121
    if opts.stdin:
 
122
        patch = sys.stdin.read()
 
123
        submit(opts, patch)
 
124
    elif args:
 
125
        for fname in args:
 
126
            with open(fname, "r") as fd:
 
127
                patch = fd.read()
 
128
            submit(opts, patch, fname)
 
129
    else:
 
130
        parser.error("please invoke with a patch file name or use --stdin.")