示例#1
0
    def channels_to_file(self, channels):
        logging.info('Writing imported files.')
        headers = RadioChannelDefault.create_empty().headers()
        writer = RadioWriter.output_writer('import_result.csv', '\r\n')
        writer.writerow(headers)
        channel_num = 1
        for chan in channels:  # who is this for chan
            channel_default = RadioChannelBuilder.casted(
                chan, radio_types.DEFAULT)
            writer.writerow(channel_default.output(channel_num))
            channel_num += 1
        writer.close()

        result_path = PathManager.get_output_path('import_result.csv')
        logging.info(
            f'Import complete! Your imported file is in `{result_path}`')
示例#2
0
    def _output_radioids(self):
        logging.info(f"Writing {radio_types.D878} radio IDs")
        if self._dmr_ids is None:
            logging.error(f"No DMR ids found for {radio_types.D878}.")
            return

        radio_id_file = RadioWriter.output_writer(
            f'{radio_types.D878}/{radio_types.D878}_radioid.csv', '\r\n')

        headers = DmrIdD878.create_empty()
        radio_id_file.writerow(headers.headers())
        number = 1
        for dmr_id in self._dmr_ids.values():
            casted_id = DmrIdBuilder.casted(dmr_id, radio_types.D878)
            radio_id_file.writerow(casted_id.output(number))
            number += 1

        radio_id_file.close()
        return
示例#3
0
    def _output_zones(self):
        logging.info(f"Writing {radio_types.D878} zones")
        if self._zones is None:
            logging.error(f"No zones list found for {radio_types.D878}.")
            return

        zone_file = RadioWriter.output_writer(
            f'{radio_types.D878}/{radio_types.D878}_zone.csv', '\r\n')

        headers = RadioZoneD878.create_empty()
        zone_file.writerow(headers.headers())
        for zone in self._zones.values():
            if not zone.has_channels():
                continue
            casted_zone = RadioZoneBuilder.casted(zone.cols,
                                                  zone._associated_channels,
                                                  radio_types.D878)
            zone_file.writerow(casted_zone.output())

        zone_file.close()
示例#4
0
    def _output_contacts(self):
        logging.info(f"Writing {radio_types.D878} contacts")
        if self._digital_contacts is None:
            logging.error(f"No digital contacts found for {radio_types.D878}.")
            return

        dmr_contact_file = RadioWriter.output_writer(
            f'{radio_types.D878}/{radio_types.D878}_talkgroup.csv', '\r\n')

        headers = DmrContactD878.create_empty()
        dmr_contact_file.writerow(headers.headers())
        number = 1
        for dmr_contact in self._digital_contacts.values():
            casted_contact = DmrContactBuilder.casted(dmr_contact,
                                                      radio_types.D878)
            row_data = casted_contact.output(number)
            dmr_contact_file.writerow(row_data)
            number += 1

        dmr_contact_file.close()
    def output(self):
        gpx = gpxpy.gpx.GPX()
        gpx.name = 'Ham Radio Stations'
        gpx.description = 'Ham radio station locations generated by Ham Radio Sync'

        for channel in self._channels:
            if channel.latitude.fmt_val() is None or channel.longitude.fmt_val(
            ) is None:
                continue

            gpx_waypoint = gpxpy.gpx.GPXWaypoint()
            gpx_waypoint.latitude = channel.latitude.fmt_val()
            gpx_waypoint.longitude = channel.longitude.fmt_val()
            gpx_waypoint.name = channel.name.fmt_val()
            gpx_waypoint.description = self._get_description(channel)
            gpx.waypoints.append(gpx_waypoint)

        xml = gpx.to_xml()
        writer = RadioWriter.output_writer(
            f'{radio_types.GPX}/ham_radio_sync.gpx', '\r\n')
        writer.write_raw(xml)
        writer.close()
示例#6
0
    def _output_user(self):
        logging.info(f"Writing {radio_types.D878} users")
        if self._users is None:
            logging.error(f"No zones list found for {radio_types.D878}.")
            return

        users_file = RadioWriter.output_writer(
            f'{radio_types.D878}/{radio_types.D878}_digital_contacts.csv',
            '\n')

        headers = DmrUserD878.create_empty()
        users_file.writerow(headers.headers())

        rows_processed = 1
        for user in self._users.values():
            casted_user = DmrUserBuilder.casted(user.cols, radio_types.D878)
            users_file.writerow(casted_user.output(None))
            rows_processed += 1
            logging.debug(f"Writing user row {rows_processed}")
            if rows_processed % file_util.USER_LINE_LOG_INTERVAL == 0:
                logging.info(f"Writing user row {rows_processed}")

        users_file.close()
示例#7
0
    def generate_all_declared(self):
        file_errors = self._validator.validate_files_exist()
        self._validator.flush_names()
        if len(file_errors) > 0:
            return False

        results = self._migrations.check_migrations_needed()
        if len(results.keys()) > 0:
            logging.warning(
                'You may be using an old version of the input files. Have you run migrations?'
            )
            logging.warning("Migrations check is under the 'File' menu.")
            sleep(1)

        for radio in radio_types.radio_choices():
            radio_folder = PathManager.get_output_path(radio)
            if not os.path.exists(radio_folder):
                continue
            logging.info(f'Deleting old output folder `{radio}`')
            FileUtil.safe_delete_dir(radio_folder)

        digital_contacts, digi_contact_errors = self._generate_digital_contact_data(
        )
        dmr_ids, dmr_id_errors = self._generate_dmr_id_data()
        zones, zone_errors = self._generate_zone_data()
        user, user_data_errors = self._generate_user_data()
        preload_errors = digi_contact_errors + dmr_id_errors + zone_errors + user_data_errors

        feed = PathManager.open_input_file('input.csv', 'r')
        csv_reader = csv.DictReader(feed)

        radio_channel_errors = []
        radio_channels = []
        line_num = 1
        for line in csv_reader:
            line_errors = self._validator.validate_radio_channel(
                line, line_num, feed.name, digital_contacts, zones)
            radio_channel_errors += line_errors
            line_num += 1

            if len(line_errors) > 0:
                continue

            radio_channel = RadioChannel(line, digital_contacts, dmr_ids)
            radio_channels.append(radio_channel)

            if radio_channel.zone_id.fmt_val(None) is not None:
                zones[radio_channel.zone_id.fmt_val()].add_channel(
                    radio_channel)
        feed.close()

        all_errors = preload_errors + radio_channel_errors
        if len(all_errors) > 0:
            logging.error('--- VALIDATION ERRORS, CANNOT CONTINUE ---')
            for err in all_errors:
                logging.error(
                    f'\t\tfile: `{err.file_name}` line:{err.line_num} validation error: {err.message}'
                )
            return False
        else:
            logging.info(
                'File validation complete, no obvious formatting errors found')

        radio_files = dict()
        headers_gen = RadioChannel.create_empty()
        FileUtil.safe_create_dir('out')

        channel_numbers = dict()
        for radio in self.radio_list:
            radio_casted = RadioChannelBuilder.casted(headers_gen, radio)
            FileUtil.safe_create_dir(f'out/{radio}')
            logging.info(f'Generating for radio type `{radio}`')

            if radio_casted.skip_radio_csv():
                logging.info(
                    f'`{radio}` uses special output style. Skipping channels csv'
                )
                continue
            output = RadioWriter.output_writer(f'{radio}/{radio}_channels.csv',
                                               '\r\n')
            file_headers = radio_casted.headers()
            output.writerow(file_headers)
            radio_files[radio] = output
            channel_numbers[radio] = 1

        logging.info('Processing radio channels')
        line = 1
        for radio_channel in radio_channels:
            logging.debug(f'Processing radio line {line}')
            if line % file_util.RADIO_LINE_LOG_INTERVAL == 0:
                logging.info(f'Processing radio line {line}')
            line += 1
            for radio in self.radio_list:
                if radio not in radio_files.keys():
                    continue

                if not radio_types.supports_dmr(
                        radio) and radio_channel.is_digital():
                    continue

                casted_channel = RadioChannelBuilder.casted(
                    radio_channel, radio)

                input_data = casted_channel.output(channel_numbers[radio])
                radio_files[radio].writerow(input_data)
                channel_numbers[radio] += 1

        additional_data = RadioAdditional(radio_channels, dmr_ids,
                                          digital_contacts, zones, user)
        for radio in self.radio_list:
            if radio in radio_files.keys():
                radio_files[radio].close()
            casted_additional_data = RadioAdditionalBuilder.casted(
                additional_data, radio)
            casted_additional_data.output()

        logging.info(f'''Radio generator complete. Your output files are in 
					`{os.path.abspath('out')}`
					The next step is to import these files into your radio programming application. (e.g. CHiRP)'''
                     )
        return True