def test_zip(out_file, test_file): assert not out_file.exists() with Miz(test_file) as miz: miz.zip(out_file) assert out_file.exists() with Miz(out_file) as miz2: assert miz.mission.d == miz2.mission.d miz.mission.weather.cloud_density = 4 assert not miz.mission.d == miz2.mission.d
def test_sortie_name(test_file, out_file): with Miz(test_file) as miz: assert miz.mission.sortie_name == 'sortie_test' wrong_sortie_names = [1, 0, -1, True, None] for wrong_sortie_name in wrong_sortie_names: with pytest.raises(ValueError): miz.mission.sortie_name = wrong_sortie_name miz.mission.sortie_name = 'caribou' assert miz.mission.sortie_name == 'caribou' miz.zip(out_file) with Miz(out_file) as miz: assert miz.mission.sortie_name == 'caribou'
def test_set_hidden(test_file, out_file): with Miz(test_file) as miz: group = miz.mission.get_group_by_name('etcher') assert isinstance(group, Group) assert not group.group_hidden group.group_hidden = True assert group.group_hidden miz.zip(out_file) with Miz(out_file) as miz: new_group = miz.mission.get_group_by_name('etcher') assert isinstance(new_group, Group) for attrib in [x for x in Group.attribs if not x == 'group_hidden']: assert getattr(group, attrib) == getattr(new_group, attrib) assert group.group_hidden
def decompose(miz_file: Path, output_folder: Path): """ Decompose this Miz into json Args: output_folder: folder to output the json structure as a Path miz_file: MIZ file path as a Path """ mission_folder, assets_folder = NewMiz._get_subfolders(output_folder) NewMiz._wipe_folders(mission_folder, assets_folder) LOGGER.info('unzipping mission file') with Miz(miz_file) as miz: version = miz.mission.d['version'] LOGGER.debug(f'mission version: "{version}"') LOGGER.info(f'copying assets to: "{assets_folder}"') ignore = shutil.ignore_patterns('mission', 'mapResource', 'dictionary') shutil.copytree(miz.temp_dir, assets_folder, ignore=ignore) LOGGER.info( f'decomposing mission table into: "{mission_folder}" (this will take a while)' ) NewMiz._decompose_dict(miz.mission.d, 'base_info', mission_folder, version, miz)
def test_temp_dir_cleaning(test_file): mis = Miz(test_file) mis.unzip() assert mis.temp_dir.exists() assert mis.temp_dir.glob('*') mis._remove_temp_dir() assert not mis.temp_dir.exists()
def test_objects(all_objects): with Miz(all_objects) as miz: _ = miz.mission._blue_coa.get_country_by_id(2) country = miz.mission._blue_coa.get_country_by_id(2) assert isinstance(country, Country) assert country.groups assert country.units for category in ('helicopter', 'ship', 'vehicle', 'plane'): assert country.get_groups_from_category(category) assert country.get_units_from_category(category) for group in country.get_groups_from_category(category): assert isinstance(group, Group) for unit in country.get_units_from_category(category): assert isinstance(unit, BaseUnit) for wrong_category in (True, -1, 0, 1, False, None, 'caribou'): with pytest.raises(ValueError, msg=wrong_category): for _ in country.get_groups_from_category(wrong_category): pass with pytest.raises(ValueError, msg=wrong_category): for _ in country.get_units_from_category(wrong_category): pass for id_ in (1, 2, 3, 4): assert isinstance(country.get_group_by_id(id_), Group) assert isinstance(country.get_unit_by_id(id_), BaseUnit) assert country.get_unit_by_id(5) is None assert country.get_group_by_id(5) is None for group_name in ('New Vehicle Group', 'New Helicopter Group', 'New Airplane Group', 'New Ship Group'): assert isinstance(country.get_group_by_name(group_name), Group) assert country.get_group_by_name('some other group') is None for unit_name in ('Unit #1', 'Unit #001', 'Pilot #001', 'Pilot #002'): assert isinstance(country.get_unit_by_name(unit_name), BaseUnit) assert country.get_unit_by_name('some other unit') is None
def recompose(src: Path, target_file: Path): """ Recompose a Miz from json object Args: src: folder containing the json structure target_file: target Miz file """ mission_folder, assets_folder = NewMiz._get_subfolders(src) # pylint: disable=c-extension-no-member base_info = ujson.loads( Path(mission_folder, 'base_info.json').read_text(encoding=ENCODING)) version = base_info['__version__'] target_file.write_bytes(dummy_miz) with Miz(target_file) as miz: LOGGER.info( f're-composing mission table from folder: "{mission_folder}"') miz.mission.d = NewMiz._recreate_dict_from_folder( mission_folder, version) for item in assets_folder.iterdir(): target = Path(miz.temp_dir, item.name).absolute() if item.is_dir(): if target.exists(): shutil.rmtree(target) shutil.copytree(item.absolute(), target) elif item.is_file(): shutil.copy(item.absolute(), target) miz.zip(target_file)
def test_group_start_time(test_file, out_file): with Miz(test_file) as miz: group = miz.mission.get_group_by_name('etcher') assert miz.mission.mission_start_time == group.group_start_time assert miz.mission.mission_start_datetime_as_string == group.group_start_date_time_as_string assert group.group_start_date_time_as_string == '01/06/2011 12:00:00' assert group.group_start_delay == 0 group.group_start_delay += 60 assert group.group_start_date_time_as_string == '01/06/2011 12:01:00' group.group_start_delay += 3600 assert group.group_start_date_time_as_string == '01/06/2011 13:01:00' group.group_start_delay = 0 group.group_start_delay = 3600 assert group.group_start_date_time_as_string == '01/06/2011 13:00:00' miz.zip(out_file) with Miz(out_file) as miz: group = miz.mission.get_group_by_name('etcher') assert group.group_start_delay == 3600
def test_large_zip(large_file): with Miz(large_file, keep_temp_dir=True) as miz: out_file = miz.zip() assert Path(out_file).exists() try: with Miz(out_file) as miz2: assert miz.mission.d == miz2.mission.d miz.mission.weather.cloud_density = 4 assert not miz.mission.d == miz2.mission.d sleep(1) m1 = miz.mission_file m2 = miz2.mission_file with open(m1, encoding=ENCODING) as _f: t1 = _f.read() with open(m2, encoding=ENCODING) as _f: t2 = _f.read() assert t1 == t2 finally: Path(out_file).unlink()
def test_get_country(mission, test_file): assert isinstance(mission.blue_coa.get_country_by_id(2), Country) assert isinstance(mission.blue_coa.get_country_by_name('USA'), Country) with pytest.raises(ValueError): mission.red_coa.get_country_by_name('USA') with pytest.raises(ValueError): mission.red_coa.get_country_by_id(2) with Miz(test_file) as miz: assert isinstance(miz.mission._blue_coa.get_country_by_name('USA'), Country)
def test_get_groups_from_category(mission, all_objects): for invalid_category in ('caribou', 'Plane', 'plAne', 'ships', -1, 0, 1, True, False, None): with pytest.raises(ValueError): for _ in mission.blue_coa.get_groups_from_category( invalid_category): pass with Miz(all_objects) as miz: for category in ('ship', 'plane', 'helicopter', 'vehicle'): value = 0 for group in miz.mission._blue_coa.get_groups_from_category( category): assert isinstance(group, Group) assert group.group_category == category value += 1 assert value == 1
def set_weather_from_metar( metar: typing.Union[Metar.Metar, str], in_file: typing.Union[str, Path], out_file: typing.Union[str, Path] = None ) -> typing.Tuple[typing.Union[str, None], typing.Union[str, None]]: """ Applies the weather from a METAR object to a MIZ file Args: metar: metar object in_file: path to MIZ file out_file: path to output MIZ file (will default to in_file) Returns: tuple of error, success """ error, metar = custom_metar.CustomMetar.get_metar(metar) if error: return error, None LOGGER.debug(f'METAR: {metar.code}') in_file = elib.path.ensure_file(in_file) if out_file is None: out_file = in_file else: out_file = elib.path.ensure_file(out_file, must_exist=False) LOGGER.debug(f'applying metar: {in_file} -> {out_file}') try: LOGGER.debug('building MissionWeather') _mission_weather = mission_weather.MissionWeather(metar) with Miz(str(in_file)) as miz: _mission_weather.apply_to_miz(miz) miz.zip(str(out_file)) return None, f'successfully applied METAR to {in_file}' except ValueError: error = f'Unable to apply METAR string to the mission.\n' \ f'This is most likely due to a freak value, this feature is still experimental.\n' \ f'I will fix it ASAP !' return error, None
def main(miz_path): """ Artifact from earlier development """ from emiz.miz import Miz with Miz(miz_path) as m: mis = m.mission result = defaultdict(dict) for unit in mis.units: airport, spot = unit.group_name.split('#') spot = int(spot) # print(airport, int(spot), unit.unit_position) result[airport][spot] = unit.unit_position import pickle with open('_parking_spots.py', mode='w') as f: f.write('parkings = {}\n'.format(pickle.dumps(result)))
def test_large_decode(large_file): miz = Miz(large_file) miz.unzip() miz.decode()
def test_context(test_file): with Miz(test_file) as miz: assert isinstance(miz.mission, Mission) assert isinstance(miz.l10n, dict) assert miz.zip_content
def test_bad_zip_file(bad_zip_file): from zipfile import BadZipFile mis = Miz(bad_zip_file) with pytest.raises(BadZipFile): mis.unzip()
def edit_miz( # noqa: C901 infile: str, outfile: str = None, metar: typing.Union[str, Metar] = None, time: str = None, min_wind: int = 0, max_wind: int = 40 ) -> str: # noinspection SpellCheckingInspection """ Edit an opened MIZ file and sets the time and date and the weather Args: infile: source file outfile: output file (will default to source file) metar: metar string, ICAO or object to apply time: time string to apply (YYYYMMDDHHMMSS) min_wind: minimum wind max_wind: maximum wind Returns: String containing error """ if outfile is None: LOGGER.debug(f'editing in place: {infile}') outfile = infile else: LOGGER.debug(f'editing miz file: {infile} -> {outfile}') mission_weather = mission_time = None if metar: error, metar = emiz.weather.custom_metar.CustomMetar.get_metar(metar) if error: return error mission_weather = emiz.weather.mission_weather.MissionWeather(metar, min_wind=min_wind, max_wind=max_wind) if time: try: mission_time = MissionTime.from_string(time) except ValueError: return f'badly formatted time string: {time}' if not mission_weather and not mission_time: return 'nothing to do!' with Miz(infile) as miz: if mission_weather: LOGGER.debug('applying MissionWeather') if not mission_weather.apply_to_miz(miz): return 'error while applying METAR to mission' if mission_time: LOGGER.debug('applying MissionTime') if not mission_time.apply_to_miz(miz): return 'error while setting time on mission' try: miz.zip(outfile) return '' except OSError: return f'permission error: cannot edit "{outfile}"; maybe it is in use ?'
def test_is_unzipped(test_file): mis = Miz(test_file) assert not mis.zip_content mis.unzip() assert mis.zip_content
def test_missing_file_in_miz(missing_file): missing = Miz(missing_file) with pytest.raises(FileNotFoundError): missing.unzip()
def test_next_unit_id(mission, duplicate_group_id): assert mission.next_unit_id == 42 with pytest.raises(IndexError): with Miz(duplicate_group_id) as miz: assert miz.mission.next_unit_id
def test_decode(test_file): miz = Miz(test_file) miz.unzip() miz.decode()
def test_unzip(test_file): miz = Miz(test_file) miz.unzip()
def get_metar_from_mission( mission_file: str, icao: str = 'XXXX', time: str = None, ) -> str: """ Builds a dummy METAR string from a mission file Args: mission_file: input mission file icao: dummy ICAO (defaults to XXXX) time: dummy time (defaults to now()) Returns: METAR str """ def _get_wind(mission_: Mission): wind_dir = emiz.weather.utils.reverse_direction(mission_.weather.wind_at_ground_level_dir) wind_speed = int(mission_.weather.wind_at_ground_level_speed) return f'{wind_dir:03}{wind_speed:02}MPS' def _get_precipitations(mission_: Mission): precipitations_ = { 0: '', 1: 'RA', 2: 'SN', 3: '+RA', 4: '+SN', } return precipitations_[mission_.weather.precipitations] def _get_clouds(mission_: Mission): density = { 0: '', 1: 'FEW', 2: 'FEW', 3: 'FEW', 4: 'SCT', 5: 'SCT', 6: 'SCT', 7: 'BKN', 8: 'BKN', 9: 'OVC', 10: 'OVC', } if mission_.weather.cloud_density == 0: return '' density = density[mission_.weather.cloud_density] base = int(round(mission_.weather.cloud_base * 3.28084, -2) / 100) return f'{density}{base:03}' def _get_temp(mission_: Mission): temperature = mission_.weather.temperature minus = 'M' if temperature < 0 else '' temperature = abs(temperature) return f'{minus}{temperature:02}/{minus}{temperature:02}' def _get_pressure(mission_: Mission): hpa = round(mission_.weather.qnh / 0.75006156130264) return f'Q{hpa}' if time is None: now = datetime.utcnow() day = now.day hour = now.hour minute = now.minute time = f'{day:02}{hour:02}{minute:02}Z' with Miz(mission_file) as miz: mission = miz.mission wind = _get_wind(mission) visibility = min(mission.weather.visibility, 9999) if mission.weather.fog_enabled: visibility = min(mission.weather.fog_visibility, visibility) precipitations = _get_precipitations(mission) clouds = _get_clouds(mission) temp = _get_temp(mission) pres = _get_pressure(mission) # noinspection SpellCheckingInspection qual = 'NOSIG' if visibility == 9999 and int(round(mission.weather.cloud_base * 3.28084, -2)) >= 5000: # noinspection SpellCheckingInspection visibility = 'CAVOK' else: visibility = ('{:04d}M'.format(visibility)) metar = f'{icao} {time} {wind} {visibility} {precipitations} {clouds} {temp} {pres} {qual}' return re.sub(' +', ' ', metar)
def test_init(test_file): Miz(test_file) with pytest.raises(FileNotFoundError): Miz('./i_do_not_exist')