[chirp_devel] [PATCH] Query/Import RepeaterBook by Proximity. #3261
# HG changeset patch # User Tom Hayward tom@tomh.us # Date 1484520680 28800 # Sun Jan 15 14:51:20 2017 -0800 # Node ID d013774b40f91784b33c1fe7ea672cbbdd77ab51 # Parent 2d6eac7045613677c20ebadd4e5e4c23888423be Query/Import RepeaterBook by Proximity. #3261
diff -r 2d6eac704561 -r d013774b40f9 chirp/drivers/repeaterbook.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chirp/drivers/repeaterbook.py Sun Jan 15 14:51:20 2017 -0800 @@ -0,0 +1,32 @@ +# Copyright 2016 Tom Hayward tom@tomh.us +# +# 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 3 of the License, or +# (at your option) any later version. +# +# 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, see http://www.gnu.org/licenses/. + +from chirp import chirp_common +from chirp.drivers import generic_csv + + +class RBRadio(generic_csv.CSVRadio, chirp_common.NetworkSourceRadio): + VENDOR = "RepeaterBook" + MODEL = "" + + def _clean_comment(self, headers, line, mem): + "Converts iso-8859-1 encoded comments to unicode for pyGTK." + mem.comment = unicode(mem.comment, 'iso-8859-1') + return mem + + def _clean_name(self, headers, line, mem): + "Converts iso-8859-1 encoded names to unicode for pyGTK." + mem.name = unicode(mem.name, 'iso-8859-1') + return mem diff -r 2d6eac704561 -r d013774b40f9 chirp/ui/mainapp.py --- a/chirp/ui/mainapp.py Sat Jan 14 20:22:23 2017 -0800 +++ b/chirp/ui/mainapp.py Sun Jan 15 14:51:20 2017 -0800 @@ -29,7 +29,7 @@
from chirp.ui import inputdialog, common from chirp import platform, directory, util -from chirp.drivers import generic_xml, generic_csv +from chirp.drivers import generic_xml, generic_csv, repeaterbook from chirp.drivers import ic9x, kenwood_live, idrp, vx7, vx5, vx6 from chirp.drivers import icf, ic9x_icf from chirp import CHIRP_VERSION, chirp_common, detect, errors @@ -867,7 +867,7 @@
self.window.set_cursor(None)
- def do_repeaterbook_prompt(self): + def do_repeaterbook_political_prompt(self): if not CONF.get_bool("has_seen_credit", "repeaterbook"): d = gtk.MessageDialog(parent=self, buttons=gtk.BUTTONS_OK) d.set_markup("<big><big><b>RepeaterBook</b></big>\r\n" + @@ -943,9 +943,9 @@
return True
- def do_repeaterbook(self, do_import): + def do_repeaterbook_political(self, do_import): self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) - if not self.do_repeaterbook_prompt(): + if not self.do_repeaterbook_political_prompt(): self.window.set_cursor(None) return
@@ -973,6 +973,7 @@ query = query % (code, band and band or "%%", county and county or "%%") + print query
# Do this in case the import process is going to take a while # to make sure we process events leading up to this @@ -988,24 +989,117 @@ self.window.set_cursor(None) return
- class RBRadio(generic_csv.CSVRadio, - chirp_common.NetworkSourceRadio): - VENDOR = "RepeaterBook" - MODEL = "" + try: + # Validate CSV + radio = repeaterbook.RBRadio(filename) + if radio.errors: + reporting.report_misc_error("repeaterbook", + ("query=%s\n" % query) + + ("\n") + + ("\n".join(radio.errors))) + except errors.InvalidDataError, e: + common.show_error(str(e)) + self.window.set_cursor(None) + return + except Exception, e: + common.log_exception()
- def _clean_comment(self, headers, line, mem): - "Converts iso-8859-1 encoded comments to unicode for pyGTK." - mem.comment = unicode(mem.comment, 'iso-8859-1') - return mem + reporting.report_model_usage(radio, "import", True)
- def _clean_name(self, headers, line, mem): - "Converts iso-8859-1 encoded names to unicode for pyGTK." - mem.name = unicode(mem.name, 'iso-8859-1') - return mem + self.window.set_cursor(None) + if do_import: + eset = self.get_current_editorset() + count = eset.do_import(filename) + else: + self.do_open_live(radio, read_only=True) + + def do_repeaterbook_proximity_prompt(self): + default_band = "--All--" + try: + code = int(CONF.get("band", "repeaterbook")) + for k, v in RB_BANDS.items(): + if code == v: + default_band = k + break + except: + pass + fields = {"1Location": (gtk.Entry(), lambda x: x.get_text()), + "2Distance": (gtk.Entry(), lambda x: x.get_text()), + "3Band": (miscwidgets.make_choice( + sorted(RB_BANDS.keys(), key=key_bands), + False, default_band), + lambda x: RB_BANDS[x.get_active_text()]), + } + + d = inputdialog.FieldDialog(title=_("RepeaterBook Query"), + parent=self) + for k in sorted(fields.keys()): + d.add_field(k[1:], fields[k][0]) + if isinstance(fields[k][0], gtk.Entry): + fields[k][0].set_text( + CONF.get(k[1:].lower(), "repeaterbook") or "") + + while d.run() == gtk.RESPONSE_OK: + valid = True + for k, (widget, fn) in fields.items(): + try: + print "set:", k[1:].lower(), fn(widget) + CONF.set( + k[1:].lower(), str(fn(widget)), "repeaterbook") + continue + except NotImplementedError: + pass + common.show_error("Invalid value for %s" % k[1:]) + valid = False + break + + if valid: + d.destroy() + return True + + d.destroy() + return False + + def do_repeaterbook_proximity(self, do_import): + self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) + if not self.do_repeaterbook_proximity_prompt(): + self.window.set_cursor(None) + return + + loc = CONF.get("location", "repeaterbook") + + try: + dist = int(CONF.get("distance", "repeaterbook")) + except: + dist = 20 + + try: + band = int(CONF.get("band", "repeaterbook")) or '%' + band = str(band) + except: + band = '%' + + query = "https://www.repeaterbook.com/repeaters/downloads/CHIRP/" \ + "app_direct.php?loc=%s&band=%s&dist=%s" % (loc, band, dist) + print query + + # Do this in case the import process is going to take a while + # to make sure we process events leading up to this + gtk.gdk.window_process_all_updates() + while gtk.events_pending(): + gtk.main_iteration(False) + + fn = tempfile.mktemp(".csv") + filename, headers = urllib.urlretrieve(query, fn) + if not os.path.exists(filename): + LOG.error("Failed, headers were: %s", headers) + common.show_error(_("RepeaterBook query failed")) + self.window.set_cursor(None) + return
try: # Validate CSV - radio = RBRadio(filename) + radio = repeaterbook.RBRadio(filename) if radio.errors: reporting.report_misc_error("repeaterbook", ("query=%s\n" % query) + @@ -1505,8 +1599,10 @@ self.do_radioreference(action[0] == "i") elif action == "export": self.do_export() - elif action in ["qrbook", "irbook"]: - self.do_repeaterbook(action[0] == "i") + elif action in ["qrbookpolitical", "irbookpolitical"]: + self.do_repeaterbook_political(action[0] == "i") + elif action in ["qrbookproximity", "irbookproximity"]: + self.do_repeaterbook_proximity(action[0] == "i") elif action in ["qpr", "ipr"]: self.do_przemienniki(action[0] == "i") elif action == "about": @@ -1596,14 +1692,20 @@ <menu action="importsrc" name="importsrc"> <menuitem action="idmrmarc"/> <menuitem action="iradioreference"/> - <menuitem action="irbook"/> + <menu action="irbook" name="irbook"> + <menuitem action="irbookpolitical"/> + <menuitem action="irbookproximity"/> + </menu> <menuitem action="ipr"/> <menuitem action="irfinder"/> </menu> <menu action="querysrc" name="querysrc"> <menuitem action="qdmrmarc"/> <menuitem action="qradioreference"/> - <menuitem action="qrbook"/> + <menu action="qrbook" name="qrbook"> + <menuitem action="qrbookpolitical"/> + <menuitem action="qrbookproximity"/> + </menu> <menuitem action="qpr"/> <menuitem action="qrfinder"/> </menu> @@ -1679,6 +1781,10 @@ None, None, self.mh), ('irfinder', None, _("RFinder"), None, None, self.mh), ('irbook', None, _("RepeaterBook"), None, None, self.mh), + ('irbookpolitical', None, _("RepeaterBook political query"), None, + None, self.mh), + ('irbookproximity', None, _("RepeaterBook proximity query"), None, + None, self.mh), ('ipr', None, _("przemienniki.net"), None, None, self.mh), ('querysrc', None, _("Query data source"), None, None, self.mh), ('qdmrmarc', None, _("DMR-MARC Repeaters"), None, None, self.mh), @@ -1687,6 +1793,10 @@ ('qrfinder', None, _("RFinder"), None, None, self.mh), ('qpr', None, _("przemienniki.net"), None, None, self.mh), ('qrbook', None, _("RepeaterBook"), None, None, self.mh), + ('qrbookpolitical', None, _("RepeaterBook political query"), None, + None, self.mh), + ('qrbookproximity', None, _("RepeaterBook proximity query"), None, + None, self.mh), ('export_chirp', None, _("CHIRP Native File"), None, None, self.mh), ('export_csv', None, _("CSV File"), None, None, self.mh),
participants (1)
-
Tom Hayward