aboutsummaryrefslogtreecommitdiff
path: root/upload/set-changeset-tag.py
diff options
context:
space:
mode:
authorAndrew Harvey <andrew@alantgeo.com.au>2021-07-04 20:48:39 +1000
committerAndrew Harvey <andrew@alantgeo.com.au>2021-07-04 20:48:39 +1000
commitdeffe3e80b786f5782c6915e3adabf855bd54ac4 (patch)
tree23bd569e18dc64b07ce9204eb67a929776d57e2f /upload/set-changeset-tag.py
parent7f59a0a9a9a8d3a739a08bbb0336fbf9aaf8b85d (diff)
directly commit upload.py as some local changes were made
Diffstat (limited to 'upload/set-changeset-tag.py')
-rwxr-xr-xupload/set-changeset-tag.py252
1 files changed, 252 insertions, 0 deletions
diff --git a/upload/set-changeset-tag.py b/upload/set-changeset-tag.py
new file mode 100755
index 0000000..9c9787a
--- /dev/null
+++ b/upload/set-changeset-tag.py
@@ -0,0 +1,252 @@
+#! /usr/bin/python2
+# vim: fileencoding=utf-8 encoding=utf-8 et sw=4
+
+# Copyright (C) 2009 Jacek Konieczny <jajcus@jajcus.net>
+# Copyright (C) 2009 Andrzej Zaborowski <balrogg@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+"""
+Set a tag on an open changeset
+"""
+
+__version__ = "$Revision: 21 $"
+
+import os
+import subprocess
+import sys
+import traceback
+import codecs
+import locale
+
+import httplib
+
+import xml.etree.cElementTree as ElementTree
+import urlparse
+
+import locale, codecs
+try:
+ locale.setlocale(locale.LC_ALL, "en_US.UTF-8")
+ encoding = locale.getlocale()[1]
+ sys.stdout = codecs.getwriter(encoding)(sys.stdout, errors = "replace")
+ sys.stderr = codecs.getwriter(encoding)(sys.stderr, errors = "replace")
+except locale.Error:
+ pass
+
+class HTTPError(Exception):
+ pass
+
+class OSM_API(object):
+ url = 'https://master.apis.dev.openstreetmap.org/'
+ def __init__(self, username = None, password = None):
+ if username and password:
+ self.username = username
+ self.password = password
+ else:
+ self.username = ""
+ self.password = ""
+ self.changeset = None
+ self.tags = {}
+ self.progress_msg = None
+
+ def __del__(self):
+ #if self.changeset is not None:
+ # self.close_changeset()
+ pass
+
+ def msg(self, mesg):
+ sys.stderr.write(u"\r%s… " % (self.progress_msg))
+ sys.stderr.write(u"\r%s… %s" % (self.progress_msg, mesg))
+ sys.stderr.flush()
+
+ def request(self, conn, method, url, body, headers, progress):
+ if progress:
+ self.msg(u"making request")
+ conn.putrequest(method, url)
+ self.msg(u"sending headers")
+ if body:
+ conn.putheader('Content-Length', str(len(body)))
+ for hdr, value in headers.iteritems():
+ conn.putheader(hdr, value)
+ self.msg(u"end of headers")
+ conn.endheaders()
+ self.msg(u" 0%")
+ if body:
+ start = 0
+ size = len(body)
+ chunk = size / 100
+ if chunk < 16384:
+ chunk = 16384
+ while start < size:
+ end = min(size, start + chunk)
+ conn.send(body[start:end])
+ start = end
+ self.msg(u"%2i%%" % (start * 100 / size))
+ else:
+ self.msg(u" ")
+ conn.request(method, url, body, headers)
+
+ def _run_request(self, method, url, body = None, progress = 0, content_type = "text/xml"):
+ url = urlparse.urljoin(self.url, url)
+ purl = urlparse.urlparse(url)
+ if purl.scheme != "https":
+ raise ValueError, "Unsupported url scheme: %r" % (purl.scheme,)
+ if ":" in purl.netloc:
+ host, port = purl.netloc.split(":", 1)
+ port = int(port)
+ else:
+ host = purl.netloc
+ port = None
+ url = purl.path
+ if purl.query:
+ url += "?" + query
+ headers = {}
+ if body:
+ headers["Content-Type"] = content_type
+
+ try_no_auth = 0
+
+ if not try_no_auth and not self.username:
+ raise HTTPError, "Need a username"
+
+ try:
+ self.msg(u"connecting")
+ conn = httplib.HTTPSConnection(host, port)
+# conn.set_debuglevel(10)
+
+ if try_no_auth:
+ self.request(conn, method, url, body, headers, progress)
+ self.msg(u"waiting for status")
+ response = conn.getresponse()
+
+ if not try_no_auth or (response.status == httplib.UNAUTHORIZED and
+ self.username):
+ if try_no_auth:
+ conn.close()
+ self.msg(u"re-connecting")
+ conn = httplib.HTTPSConnection(host, port)
+# conn.set_debuglevel(10)
+
+ creds = self.username + ":" + self.password
+ headers["Authorization"] = "Basic " + \
+ creds.encode("base64").strip()
+ self.request(conn, method, url, body, headers, progress)
+ self.msg(u"waiting for status")
+ response = conn.getresponse()
+
+ if response.status == httplib.OK:
+ self.msg(u"reading response")
+ sys.stderr.flush()
+ response_body = response.read()
+ else:
+ raise HTTPError( "%02i: %s (%s)" % (response.status,
+ response.reason, response.read()))
+ finally:
+ conn.close()
+ return response_body
+
+ def get_changeset_tags(self):
+ if self.changeset is None:
+ raise RuntimeError, "Changeset not opened"
+ self.progress_msg = u"Getting changeset tags"
+ self.msg(u"")
+ reply = self._run_request("GET", "/api/0.6/changeset/" +
+ str(self.changeset), None)
+ root = ElementTree.XML(reply)
+ if root.tag != "osm" or root[0].tag != "changeset":
+ print >>sys.stderr, u"API returned unexpected XML!"
+ sys.exit(1)
+
+ for element in root[0]:
+ if element.tag == "tag" and "k" in element.attrib and \
+ "v" in element.attrib:
+ self.tags[element.attrib["k"]] = element.attrib["v"]
+
+ self.msg(u"done.")
+ print >>sys.stderr, u""
+
+ def set_changeset_tags(self):
+ self.progress_msg = u"Setting new changeset tags"
+ self.msg(u"")
+
+ root = ElementTree.Element("osm")
+ tree = ElementTree.ElementTree(root)
+ element = ElementTree.SubElement(root, "changeset")
+ for key in self.tags:
+ ElementTree.SubElement(element, "tag",
+ { "k": key, "v": self.tags[key] })
+
+ self._run_request("PUT", "/api/0.6/changeset/" +
+ str(self.changeset), ElementTree.tostring(root, "utf-8"))
+
+ self.msg(u"done, too.")
+ print >>sys.stderr, u""
+
+try:
+ this_dir = os.path.dirname(__file__)
+ try:
+ version = int(subprocess.Popen(["svnversion", this_dir], stdout = subprocess.PIPE).communicate()[0].strip())
+ except:
+ version = 1
+ if len(sys.argv) < 3 or (len(sys.argv) & 2):
+ print >>sys.stderr, u"Synopsis:"
+ print >>sys.stderr, u" %s <changeset> <key> <value> [...]"
+ sys.exit(1)
+
+ args = []
+ param = {}
+ num = 0
+ skip = 0
+ for arg in sys.argv[1:]:
+ num += 1
+ if skip:
+ skip -= 1
+ continue
+
+ if arg == "-u":
+ param['user'] = sys.argv[num + 1]
+ skip = 1
+ elif arg == "-p":
+ param['pass'] = sys.argv[num + 1]
+ skip = 1
+ else:
+ args.append(arg)
+
+ if 'user' in param:
+ login = param['user']
+ else:
+ login = raw_input("OSM login: ")
+ if not login:
+ sys.exit(1)
+ if 'pass' in param:
+ password = param['pass']
+ else:
+ password = raw_input("OSM password: ")
+ if not password:
+ sys.exit(1)
+
+ api = OSM_API(login, password)
+ api.changeset = int(args[0])
+
+ api.get_changeset_tags()
+ api.tags.update(zip(args[1::2], args[2::2]))
+ api.set_changeset_tags()
+except HTTPError as err:
+ print >>sys.stderr, err
+ sys.exit(1)
+except Exception,err:
+ print >>sys.stderr, repr(err)
+ traceback.print_exc(file=sys.stderr)
+ sys.exit(1)