def test_lido_route_no_tracksnat(self): with open(DATADIR + '/KJFK-LFPG 27Mar2015 05:45z.txt', 'r') as f: ofp = OFP(f.read()) ofp.text = ofp.text.replace('TRACKSNAT', 'TRACKSNA*') self.assertEqual( ' '.join(ofp.lido_route), 'KJFK GREKI DCT MARTN DCT EBONY N247A ALLRY DCT 51N050W ' '53N040W 55N030W 55N020W DCT RESNO DCT NETKI DCT BAKUR UN546 ' 'STU UP2 NIGIT UL18 SFD UM605 BIBAX N4918.0E00134.2 ' 'N4917.5E00145.4 N4915.7E00223.3 N4915.3E00230.9 ' 'N4913.9E00242.9 LFPG' )
def test_lido_route_with_naty_no_tracksnat(self): with open(DATADIR + '/AF007_KJFK-LFPG_13Mar2016_00:15z_OFP_6_0_1.txt', 'r') as f: ofp = OFP(f.read()) ofp.text = ofp.text.replace('TRACKSNAT', 'TRACKSNA*') self.assertEqual( ' '.join(ofp.lido_route), 'KJFK HAPIE DCT YAHOO DCT DOVEY NATY NERTU DCT TAKAS UN490 ' 'MOSIS UN491 BETUV UY111 ' 'JSY UY111 INGOR UM25 LUKIP N4918.0E00134.2 ' 'N4917.5E00145.4 N4910.2E00150.4 LFPG' )
def test_lido_route_no_fpl(self, logger): with open(DATADIR + '/KJFK-LFPG 27Mar2015 05:45z.txt', 'r') as f: ofp = OFP(f.read()) ofp.text = ofp.text.replace('ATC FLIGHT PLAN', 'ATC*FLIGHT*PLAN') self.assertEqual( ' '.join(ofp.lido_route), 'KJFK GREKI MARTN EBONY ALLRY N5100.0W05000.0 N5300.0W04000.0 ' 'N5500.0W03000.0 N5500.0W02000.0 RESNO NETKI BAKUR STU NUMPO ' 'OKESI BEDEK NIGIT VAPID MID SFD WAFFU HARDY XIDIL PETAX BIBAX ' 'KOLIV MOPAR N4915.7E00223.3 CRL N4913.9E00242.9 LFPG' ) logger.assert_called_with('ATC FLIGHT PLAN not found')
def test_lido_route_with_naty_no_fpl(self, logger): with open(DATADIR + '/AF007_KJFK-LFPG_13Mar2016_00:15z_OFP_6_0_1.txt', 'r') as f: ofp = OFP(f.read()) ofp.text = ofp.text.replace('ATC FLIGHT PLAN', 'ATC*FLIGHT*PLAN') self.assertEqual( ' '.join(ofp.lido_route), 'KJFK HAPIE YAHOO DOVEY N4200.0W06000.0 N4300.0W05000.0 ' 'N4600.0W04000.0 N4900.0W03000.0 N4900.0W02000.0 BEDRA NERTU ' 'TAKAS ALUTA MOSIS DEKOR NERLA RUSIB BETUV JSY INGOR LUKIP ' 'KOLIV MOPAR N4910.2E00150.4 LFPG' ) logger.assert_called_with('ATC FLIGHT PLAN not found')
def test_fpl_lookup_error(self, logger): ofp = OFP('') self.assertEqual(ofp.fpl, []) logger.assert_called_with('ATC FLIGHT PLAN not found') logger.reset_mock() ofp = OFP('ATC FLIGHT PLANblabla') logger.assert_called_with( 'enclosing brackets not found in ATC FLIGHT PLAN') self.assertEqual(ofp.fpl, []) logger.reset_mock() ofp = OFP('ATC FLIGHT PLAN(blabla)') self.assertEqual(ofp.fpl, []) logger.assert_called_with('incomplete Flight Plan') logger.reset_mock()
def copy_lido_route(action_in, params): """ Copy the Lido route into the clipboard :param action_in: the input passed to the action :param params: the workflow parameters for the action Usage from Editorial is: # -*- coding: utf-8 -*- from __future__ import unicode_literals import workflow from editolido.workflows.lido2mapsme import copy_lido_route params = workflow.get_parameters() action_in = workflow.get_input() workflow.set_output(copy_lido_route(action_in, params)) """ from editolido.ofp import OFP # noinspection PyUnresolvedReferences import clipboard # EDITORIAL Module # noinspection PyUnresolvedReferences import console # EDITORIAL Module if params['Copier']: ofp = OFP(action_in) clipboard.set(' '.join(ofp.lido_route)) if params['Durée'] > 0 and params['Notification']: console.hud_alert(params['Notification'], 'success', float(params['Durée'])) return ofp.text return action_in
def test_ogimet_from_VOBL(self): # BLR filepath = DATADIR + '/AF191_VOBL-LFPG_30Dec2016_21:50z_OFP_20_0_1.txt' with open(filepath, 'r') as f: ofp = OFP(f.read()) route = ogimet_route(ofp.route) points = [p.name for p in route if p.name] self.assertEqual(points[0], '43296') self.assertEqual(points[-1], 'LFPG') self.assertLessEqual(len(points), 21)
def test_ogimet_to_VOBL(self): # BLR filepath = DATADIR + '/AF192_LFPG-VOBL_28Dec2016_10:25z_OFP_12_0_1.txt' with open(filepath, 'r') as f: ofp = OFP(f.read()) route = ogimet_route(ofp.route) points = [p.name for p in route if p.name] self.assertEqual(points[0], 'LFPG') self.assertEqual(points[-1], '43296') self.assertLessEqual(len(points), 21)
def test_ogimet_from_FAOR(self): # JNB filepath = DATADIR + '/AF995_FAOR-LFPG_09Jun2016_16:50z_OFP_9_0_1.txt' with open(filepath, 'r') as f: ofp = OFP(f.read()) route = ogimet_route(ofp.route) points = [p.name for p in route if p.name] self.assertEqual(points[0], 'FAJS') # FAOR => FAJS self.assertEqual(points[-1], 'LFPG') self.assertLess(len(points), 21)
def test_ogimet_to_FAOR(self): # JNB filepath = DATADIR + '/AF990_LFPG-FAOR_05Jun2016_21:25z_OFP_12_0_1.txt' with open(filepath, 'r') as f: ofp = OFP(f.read()) route = ogimet_route(ofp.route) points = [p.name for p in route if p.name] self.assertEqual(points[0], 'LFPG') self.assertEqual(points[-1], 'FAJS') # FAOR => FAJS self.assertLessEqual(len(points), 21)
def test_gramet_image_from_ogimet(self): filepath = DATADIR + '/AF191_VOBL-LFPG_30Dec2016_21:50z_OFP_20_0_1.txt' with io.open(filepath, 'r', encoding="utf-8") as f: ofp = OFP(f.read()) url, _, _ = ogimet_url_and_route_and_tref(ofp) image_src, ogimet_serverid = get_gramet_image_url(url) self.assertTrue(image_src) self.assertEqual(image_src[-4:], '.png') self.assertEqual(image_src[0:22], 'http://www.ogimet.com/')
def test_ogimet_AF010_NVP(self): # BLR filepath = DATADIR + '/AF 010_LFPG-KJFK_27Sep2019_1450z_OFP_6_nvp_pdfminer.txt' with io.open(filepath, 'r', encoding="utf-8") as f: ofp = OFP(f.read()) route = ogimet_route(ofp.route) points = [p.name for p in route if p.name] self.assertEqual( ' '.join(points), 'LFPG LFPB 07002 03559 03354 EGNH 03916 CWCA 71513 71634 KPWM KBOS KPVD 72501 72505 KJFK' )
def test_ogimet_AF191(self): # BLR filepath = DATADIR + '/AF191_VOBL-LFPG_30Dec2016_21:50z_OFP_20_0_1.txt' with io.open(filepath, 'r', encoding="utf-8") as f: ofp = OFP(f.read()) route = ogimet_route(ofp.route) points = [p.name for p in route if p.name] self.assertEqual( ' '.join(points), '43296 43264 43160 43109 OIKB 40851 40821 OIIK OITZ OITT 17024 15561 15499 15460 15182 LKTB 11406 10605 06484 LFPC LFPG' )
def test_lido_route_with_naty_no_fpl(self, logger): text = load_text(DATADIR + '/AF007_KJFK-LFPG_13Mar2016_00:15z_OFP_6_0_1.txt') text = text.replace('ATC FLIGHT PLAN', 'ATC*FLIGHT*PLAN') ofp = OFP(text) self.assertEqual( ' '.join(ofp.lido_route), 'KJFK HAPIE YAHOO DOVEY N4200.0W06000.0 N4300.0W05000.0 ' 'N4600.0W04000.0 N4900.0W03000.0 N4900.0W02000.0 BEDRA NERTU ' 'TAKAS ALUTA MOSIS DEKOR NERLA RUSIB BETUV JSY INGOR LUKIP ' 'KOLIV MOPAR N4910.2E00150.4 LFPG') logger.assert_called_with('ATC FLIGHT PLAN not found')
def test_lido_route_no_fpl(self, logger): text = load_text(DATADIR + '/KJFK-LFPG 27Mar2015 05:45z OFP.txt') text = text.replace('ATC FLIGHT PLAN', 'ATC*FLIGHT*PLAN') ofp = OFP(text) self.maxDiff = None self.assertEqual( ' '.join(ofp.lido_route), 'KJFK GREKI MARTN EBONY ALLRY N5100.0W05000.0 N5300.0W04000.0 ' 'N5500.0W03000.0 N5500.0W02000.0 RESNO NETKI BAKUR STU NUMPO ' 'OKESI BEDEK NIGIT VAPID MID SFD WAFFU HARDY XIDIL PETAX BIBAX ' 'KOLIV MOPAR N4915.7E00223.3 CRL N4913.9E00242.9 LFPG') logger.assert_called_with('ATC FLIGHT PLAN not found')
def test_kml_segments_ofp6752_05Feb2017(self): """ Ensure all waypoints and in the good order """ from editolido.ofp import OFP with open(DATADIR + '/AF6752_FMEE-FMMI_05Feb2017_11:50z_OFP_5_0_1.txt', 'r') as f: ofp = OFP(f.read()) kml = KMLGenerator() kml.add_folder('rmain') kml.add_segments('rmain', ofp.route) self.assertEqual(6, len(kml.folders['rmain']))
def test_ogimet_existing_airports(self): filepath = DATADIR + '/KJFK-LFPG 27Mar2015 05:45z OFP.txt' with open(filepath, 'r') as f: ofp = OFP(f.read()) route = ogimet_route(ofp.route) points = [p.name for p in route if p.name] self.assertEqual(points[0], 'KJFK') self.assertEqual(points[-1], 'LFPG') self.assertLess(len(points), 21) self.assertEqual([ u'KJFK', u'74483', u'KNHZ', u'KEPO', u'CYSU', u'CWDO', u'03976', u'03966', u'03716', u'EGDL', u'EGVO', u'07040', u'LFOB', u'LFPC', u'LFPG' ], points)
def test_kml_ofp374_22Jul2016(self): """ Ensure all waypoints and in the good order """ from editolido.ofp import OFP with open(DATADIR + '/AF374_LFPG-CYVR_22Jul2016_08:45z_OFP_8_0_1.txt', 'r') as f: ofp = OFP(f.read()) kml = KMLGenerator(point_template="{coordinates}") kml.add_folder('rmain') kml.add_points('rmain', ofp.route) coords = ["{1:.6f},{0:.6f}".format(p.latitude, p.longitude) for p in ofp.route] self.assertEqual(coords, kml.folders['rmain'])
def test_ogimet_url(self): try: # noinspection PyUnresolvedReferences,PyCompatibility from urlparse import urlsplit, parse_qs except ImportError: # noinspection PyUnresolvedReferences,PyCompatibility from urllib.parse import urlsplit, parse_qs filepath = DATADIR + '/AF191_VOBL-LFPG_30Dec2016_21:50z_OFP_20_0_1.txt' with open(filepath, 'r') as f: ofp = OFP(f.read()) url, route, tref = ogimet_url_and_route_and_tref(ofp) self.maxDiff = None self.assertEqual( url, "http://www.ogimet.com/display_gramet.php?" "lang=en&hini=0&tref={0}" "&hfin=10&fl=310&hl=3000&aero=yes" "&wmo=43296_43264_43160_43109_OIKB_40851_40821_OIIK_OITZ_OITT_" "17024_15561_15499_15460_15182_LKTB_11406_10605_06484_LFPC_LFPG" "&submit=submit".format(tref))
def save_kml(content, save=None, reldir=None, filename=None, workflow_in=None): """ :param content: :param save: :param reldir: :param filename: :param workflow_in: :return: Usage from Editorial is: # -*- coding: utf-8 -*- from __future__ import unicode_literals import workflow from editolido.workflows.lido2mapsme import save_kml params = workflow.get_parameters() filename = params.get('Nom', '') or '{flight}_{departure}-{destination}_{date}_{datetime:%H:%M}z_OFP_{ofp}.kml' workflow_in = workflow.get_variable('workflow_in') save = params.get('Sauvegarder', False) content = params.get('Contenu', '') or workflow.get_input() reldir = params.get('Dossier', '') or '_lido2mapsme_/KML' workflow.set_output(save_kml(content, save=save, reldir=reldir, filename=filename, workflow_in=workflow_in)) """ if save: from editolido.ofp import OFP ofp = OFP(workflow_in) if content: try: filename = filename.format(**ofp.infos) except (KeyError, TypeError): filename = '_ofp_non_reconnu_.kml' save_document(content, reldir, filename) return content
def load_ofp(filepath): return OFP(load_text(filepath))
def test_missing_tracks(self): ofp = OFP('blabla blabla') self.assertEqual(list(ofp.tracks()), []) with self.assertRaises(LookupError): ofp.tracks_iterator()
def test_missing_wpt_coordinates_alternate(self, logger): ofp = OFP('blabla blabla') self.assertFalse(list(ofp.wpt_coordinates_alternate())) logger.assert_called_with('WPT COORDINATES not found')
def test_missing_wpt_coordinates(self, logger): ofp = OFP('blabla blabla') with self.assertRaises(KeyboardInterrupt): list(ofp.wpt_coordinates()) logger.assert_called_with('WPT COORDINATES not found')
def lido2mapsme(action_in, params, use_segments=False, kmlargs=None, debug=False, fishfile=None): """ Lido2Mapsme KML rendering action :param fishfile: absolute path to a fishfile or None :param action_in: unicode action input :param params: dict action's parameters :param use_segments: plot route as LineString segments instead of a single LineString (Avenza fix) :param kmlargs: optional dictionnary for KML Generator :param debug: bool determines wether or not to print ogimet debug messages :return: """ from editolido.constants import NAT_POSITION_ENTRY, PIN_NONE from editolido.fishpoint import find_fishfile from editolido.geopoint import GeoPoint from editolido.kml import KMLGenerator from editolido.ofp import OFP from editolido.route import Route ofp = OFP(action_in) if kmlargs: kml = KMLGenerator(**kmlargs) else: kml = KMLGenerator() pin_rnat = params.get('Repère NAT', PIN_NONE) pin_rmain = params.get('Point Route', PIN_NONE) pin_ralt = params.get('Point Dégagement', PIN_NONE) kml.add_folders('greatcircle', ('rnat', pin_rnat), ('rnat_incomplete', pin_rnat), ('ralt', pin_ralt), ('rmain', pin_rmain)) route_name = "{departure}-{destination}".format(**ofp.infos) route = ofp.route route.name = route_name route.description = ofp.description # set route/line plot method add_kml_route = kml.add_segments if use_segments else kml.add_line natmarks = [] if params.get('Afficher NAT', False): pin_pos = 0 if params['Position repère'] == NAT_POSITION_ENTRY else -1 fishfile = fishfile if fishfile else find_fishfile() if debug: print("using fish points file %s\n" % fishfile) for track in ofp.tracks(fishfile=fishfile): if track: folder = 'rnat_incomplete' if not track.is_complete else 'rnat' add_kml_route(folder, track) if pin_rnat != PIN_NONE: if track.is_mine: p = GeoPoint(track[0], name=track.name, description=track.description) natmarks.append(p) kml.add_point(folder, p, style=pin_rnat) p = GeoPoint(track[-1], name=track.name, description=track.description) natmarks.append(p) kml.add_point(folder, p, style=pin_rnat) else: p = GeoPoint(track[pin_pos], name=track.name, description=track.description) natmarks.append(p) kml.add_point(folder, p, style=pin_rnat) else: print("empty track found %s" % track.name) if params.get('Afficher Ortho', False): greatcircle = Route( (route[0], route[-1])).split(300, name="Ortho %s" % route_name) add_kml_route('greatcircle', greatcircle) add_kml_route('rmain', route) if pin_rmain != PIN_NONE: kml.add_points('rmain', route, excluded=natmarks, style=pin_rmain) if params.get('Afficher Dégagement', False): alt_route = Route(ofp.wpt_coordinates_alternate(), name="Route Dégagement") add_kml_route('ralt', alt_route) if pin_ralt != PIN_NONE: kml.add_points('ralt', alt_route[1:], style=pin_ralt) kml = kml.render( name=ofp.description, rnat_color=params.get('Couleur NAT', '') or '60DA25A8', ogimet_color=params.get('Couleur Ogimet', '') or '40FF0000', greatcircle_color=params.get('Couleur Ortho', '') or '5F1478FF', rmain_color=params.get('Couleur Route', '') or 'FFDA25A8', ralt_color=params.get('Couleur Dégagement', '') or 'FFFF00FF', rnat_incomplete_color=params.get('Couleur NAT incomplet', '') or 'FF0000FF', ) try: # noinspection PyUnresolvedReferences import clipboard # EDITORIAL Module json_results = { 'type': '__editolido__.extended_clipboard', 'lido_route': ' '.join(ofp.lido_route), 'kml': kml, } clipboard.set(json.dumps(json_results)) except ImportError: pass return kml
def lido2gramet(action_in, params=None): """ Puts the Ogimet/Gramet route in the clipboard Output kml route if params['Afficher Ogimet'] is True :param action_in: the OFP text :param params: workflow action parameters :return: unicode kml or None Usage from Editorial is: # -*- coding: utf-8 -*- from __future__ import unicode_literals import workflow from editolido.workflows.lido2gramet import lido2gramet params = workflow.get_parameters() action_in = workflow.get_input() workflow.set_output(lido2gramet(action_in, params=params)) """ import datetime from editolido.ofp import OFP from editolido.ofp_infos import utc from editolido.kml import KMLGenerator from editolido.ogimet import \ ogimet_url_and_route_and_tref,\ get_gramet_image_url from editolido.constants import PIN_ORANGE params = params or {} ofp = OFP(action_in) kml = KMLGenerator() taxitime = (ofp.infos['taxitime'] or int(params.get('Temps de roulage', '') or '15')) ogimet_url, route, tref = ogimet_url_and_route_and_tref(ofp, taxitime=taxitime) url, ogimet_serverid = get_gramet_image_url(ogimet_url) url = url or ogimet_url # noinspection PyUnresolvedReferences,PyPackageRequirements import clipboard # EDITORIAL module clipboard.set(url) switch_sigmets = params.get('Afficher SIGMETs', True) switch_ogimet = params.get('Afficher Ogimet', True) switch_kml = params.get('Générer KML', None) # 1.0.x compatibility if switch_kml is not None: switch_ogimet = switch_sigmets = switch_kml if switch_ogimet: kml.add_folder('ogimet') kml.add_line('ogimet', route) if switch_sigmets: pin_sigmets = params.get('Label SIGMET', PIN_ORANGE) kml.add_folder('SIGMETs', pin=pin_sigmets) try: jsondata = get_sigmets_json() or {} except requests.exceptions.RequestException: pass else: try: add_sigmets(kml, 'SIGMETs', jsondata) except ValueError: pass name = ("Route Gramet/SIGMETs {flight} {departure}-{destination} " "{tref_dt:%d%b%Y %H:%M}z OFP {ofp}".format( tref_dt=datetime.datetime.fromtimestamp(tref, tz=utc), **ofp.infos)) if switch_ogimet or switch_sigmets: kml = kml.render( name=name, ogimet_color=params.get('Couleur Ogimet', '') or '40FF0000', SIGMETs_color=params.get('Couleur SIGMET', '') or '50143CFA') try: # noinspection PyUnresolvedReferences,PyPackageRequirements import clipboard # EDITORIAL Module json_results = { 'type': '__editolido__.extended_clipboard', 'gramet_url': url, 'ogimet_url': ogimet_url, 'ogimet_serverid': ogimet_serverid, 'kml': kml, } clipboard.set(json.dumps(json_results)) except ImportError: pass return kml try: # noinspection PyUnresolvedReferences,PyPackageRequirements import clipboard # EDITORIAL Module json_results = { 'type': '__editolido__.extended_clipboard', 'gramet_url': url, 'ogimet_url': ogimet_url, 'ogimet_serverid': ogimet_serverid, 'kml': '', } clipboard.set(json.dumps(json_results)) except ImportError: pass return ''
def load_or_save(action_in, save=None, reldir=None, filename=None): """ Load/Save action input :param action_in: workflow action input :param save: bool switch to save or not :param reldir: relative path to folder containing the saved elements :param filename: filename to use (Python template format) :return: unicode action_out Usage from Editorial is: # -*- coding: utf-8 -*- from __future__ import unicode_literals import workflow from editolido.workflows.lido2mapsme import load_or_save params = workflow.get_parameters() filename = params.get('Nom', '') or '{flight}_{departure}-{destination}_{date}_{datetime:%H:%M}z_OFP_{ofp}.txt' action_in = workflow.get_input() save = params.get('Sauvegarder', False) reldir = params.get('Dossier', '') or '_lido2mapsme_/data' workflow.set_output(load_or_save(action_in, save=save, reldir=reldir, filename=filename)) """ # noinspection PyUnresolvedReferences import console # EDITORIAL module # noinspection PyUnresolvedReferences import dialogs # EDITORIAL module from editolido.ofp import OFP from editolido.constants import OGIMET_IMAGE_URL_MODE ofp = None if action_in and action_in != OGIMET_IMAGE_URL_MODE: ofp = OFP(action_in) if not ofp.infos: save = True # force saving of unknown ofp if save and action_in and action_in != OGIMET_IMAGE_URL_MODE: try: filename = filename.format(**ofp.infos) except (KeyError, TypeError): filename = '_ofp_non_reconnu_.kml' save_document(action_in, reldir, filename) print("OFP non reconnu, merci de créer un ticket (issue) sur:") print("https://github.com/flyingeek/editolido/issues") print("N'oubliez pas de joindre votre OFP en pdf.") print("Vous pouvez aussi le poster sur Yammer (groupe Mapsme)") raise KeyboardInterrupt else: save_document(ofp.text, reldir, filename) return ofp.text elif not action_in or action_in == OGIMET_IMAGE_URL_MODE: # Load try: files = os.listdir(get_abspath(reldir)) if not files: raise OSError except OSError: console.alert('Aucune sauvegarde disponible', 'sauvegarder au moins une fois', 'Annuler', hide_cancel_button=True) raise KeyboardInterrupt else: filename = dialogs.list_dialog('Choisir un fichier', files) if not filename: raise KeyboardInterrupt return load_document(reldir, filename) or '' return action_in
def test_get_between(self): with open(DATADIR + '/KJFK-LFPG 27Mar2015 05:45z.txt', 'r') as f: ofp = OFP(f.read()) s = ofp.get_between('WPT COORDINATES', '----') self.assertEqual(s[:4], 'KJFK') self.assertEqual(s[-21:-17], 'LFPG') s = ofp.get_between('WPT COORDINATES', '----', inclusive=True) self.assertTrue(s.startswith('WPT COORDINATES')) self.assertTrue(s.endswith('----')) self.assertEqual(s[15:19], 'KJFK') self.assertEqual(s[-25:-21], 'LFPG') with self.assertRaises(LookupError): ofp.get_between('####', '----') with self.assertRaises(EOFError): ofp.get_between('WPT COORDINATES', '****', end_is_optional=False) s = ofp.get_between('WPT COORDINATES', '****') self.assertTrue(s.endswith('STANDARD\n')) s = ofp.get_between('WPT COORDINATES', '****', inclusive=True) self.assertTrue(s.endswith('****')) s = ofp.get_between(None, 'KJFK/LFPG') self.assertEqual(s, 'retrieved: 27Mar/0429zAF 009 ') s = ofp.get_between('USED AS A ', None) self.assertEqual(s, 'STANDARD\n') s = ofp.get_between(None, None) self.assertEqual(s, ofp.text)