3
# debtags-submit-patch: submit a tag patch to the debtags website
5
# Copyright (C) 2007--2012 Enrico Zini <enrico@debian.org>
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.
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.
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
30
log = logging.getLogger(sys.argv[0])
32
SUBMIT_URL = "http://debtags.debian.net/api/patch"
34
def make_default_tag():
35
"Autogenerate a mostly persistant, non-trackable tag"
37
m.update(":".join(str(x) for x in pwd.getpwuid(os.getuid())))
38
return m.hexdigest()[:20]
40
def submit(opts, patch, fname="[stdin]"):
41
log.info("Submitting patch %s to %s...", fname, opts.url)
43
conn = urllib2.urlopen(opts.url,
49
for note in res.get("notes", ()):
50
log.warn("%s: %s", fname, note)
52
for pkg, tags in sorted(res.get("pkgs", {}).iteritems()):
53
log.info("%s: %s: %s", fname, pkg, ", ".join(tags))
55
if opts.dump_http_error:
57
os.unlink(opts.dump_http_error)
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:
67
if __name__ == "__main__":
68
from optparse import OptionParser
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'.
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.
84
By default, a mostly persistent but anonymous tag is generated by hashing your
88
sys.stderr.write("%s: error: %s\n\n" % (self.get_prog_name(), msg))
89
self.print_help(sys.stderr)
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()
112
#FORMAT = "%(asctime)-15s %(levelname)s %(message)s"
113
FORMAT = "%(message)s"
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)
119
logging.basicConfig(level=logging.INFO, stream=sys.stderr, format=FORMAT)
122
patch = sys.stdin.read()
126
with open(fname, "r") as fd:
128
submit(opts, patch, fname)
130
parser.error("please invoke with a patch file name or use --stdin.")