def loadFont(self, section: SectionProxy, name: str, fontNameDef: str = "Helvetica", fontSizeDef: int = 32, isBoldDef: bool = False, isItalicDef: bool = False) -> Tuple[str, int, bool, bool]: if not isinstance(section, SectionProxy): raise TypeError("section") fontName = section.get(name + "Name", fontNameDef) fontSize = section.getint(name + "Size", fontSizeDef) isBold = section.getboolean(name + "Bold", isBoldDef) isItalic = section.getboolean(name + "Italic", isItalicDef) return (fontName, fontSize, isBold, isItalic)
def from_config(cls, section: configparser.SectionProxy, option_handler_id: str = None) -> OptionHandler: """ Create a handler of this class based on the configuration in the config section. :param section: The configuration section :param option_handler_id: Optional extra identifier :return: A handler object :rtype: OptionHandler """ authoritative = section.getboolean('authoritative', False) return cls(authoritative)
def get_cloud_cover_icon(cloud_cover: float, images: Icons, fonts: Fonts, config: SectionProxy) -> Image.Image: if (config.getboolean('RANDOMIZE_WEATHER_ICONS')): icon_index = random.randint(0, 9) else: icon_index = math.nan if math.isnan(cloud_cover) else round( cloud_cover) if (not math.isnan(icon_index) and 0 <= icon_index <= 9): return images['misc'][f'cloud_cover_{icon_index}'] icon = images['misc']['cloud_cover_0'].copy() draw = ImageDraw.Draw(icon) text = "NaN" if math.isnan(icon_index) else str(icon_index) draw.text((icon.width // 2, icon.height // 2), text, font=fonts['font_md'], fill="black", anchor='mm') return icon
def __init__(self, config: SectionProxy, **kwargs): host = config.get("host") port = config.getint("port") username = config.get("user") password = config.get("password") tls = config.getboolean("use_ssl") tlsCAFile = config.get("ca_file_path") if tls else None authSource = config.get("auth_source") super().__init__( host=host, port=port, username=username, password=password, authSource=authSource, tls=tls, tlsCAFile=tlsCAFile, **kwargs, )
def get_forecats_weather_icon(weather_symbol_3, is_daylight: bool, images: Icons, fonts: Fonts, config: SectionProxy) -> Image.Image: if (config.getboolean('RANDOMIZE_WEATHER_ICONS')): icon_set = images['forecast'][random.choice( list(images['forecast'].keys()))] return utils.get_icon_variant(is_daylight, icon_set) if (math.isnan(weather_symbol_3)): return utils.get_missing_weather_icon_icon(math.nan, is_daylight, images, fonts) icon_index = round(weather_symbol_3) if (not icon_index in images['forecast']): return utils.get_missing_weather_icon_icon(icon_index, is_daylight, images, fonts) icon_set = images['forecast'][icon_index] return utils.get_icon_variant(is_daylight, icon_set)
def __get_option_with_default_value(section: configparser.SectionProxy, option, default_value, data_type: str = ""): if section is not None and option in section: try: if data_type == "bool": temp = section.getboolean(option) elif data_type == "int": temp = section.getint(option) elif data_type == "float": temp = section.getfloat(option) else: temp = section.get(option) if option is None: log.warning(f"Setting '{option}' is present but has no value. Please refer to 'config.default' for an example config.") return default_value else: return temp except ValueError: return default_value log.error(f"Setting '{option}' is missing from config. Please refer to 'config.default' for an example config.") return default_value
def factory(conf: SectionProxy, force_installation: bool): """ Parses the configuration and returns the correct Installer :param conf: the configuration of the program to install :param force_installation: if reinstalling is enabled or not :return: an Installer instance """ if "git_repo" in conf: return GitInstaller(conf, force_installation) elif "svn_repo" in conf: return SVNInstaller(conf, force_installation) elif conf.get("system_package", False): return DependenciesInstaller.factory([conf.get("name")]) elif conf.getboolean("license", False): return LicensedSourceInstaller(conf, force_installation) elif conf.get("url", None): return DownloadableSourceInstaller(conf, force_installation) elif conf.get("source", None): return SourceInstaller(conf, force_installation) else: raise RuntimeError("There was an error while configuring the Installer to use")
def factory(conf: SectionProxy, force_installation: bool): """ Parses the configuration and returns the correct Installer :param conf: the configuration of the program to install :param force_installation: if reinstalling is enabled or not :return: an Installer instance """ if "git_repo" in conf: return GitInstaller(conf, force_installation) elif "svn_repo" in conf: return SVNInstaller(conf, force_installation) elif conf.get("system_package", False): return DependenciesInstaller.factory([conf.get("name")]) elif conf.getboolean("license", False): return LicensedSourceInstaller(conf, force_installation) elif conf.get("url", None): return DownloadableSourceInstaller(conf, force_installation) elif conf.get("source", None): return SourceInstaller(conf, force_installation) else: raise RuntimeError( "There was an error while configuring the Installer to use")
def read_work_mode_settings(self, work_mode_section: configparser.SectionProxy): """ read settings from given sections, if no value found, no value would change better be called after the reset so the variables won't be None :return: None """ # check str to determine the value of enum for the configparser does not support enum type yet self.work_mode = work_mode_section.get('work_mode', self.work_mode) if WorkMode.hot_key_mode.__str__() == work_mode_section.get( 'work_mode'): self.work_mode = WorkMode.hot_key_mode else: self.work_mode = WorkMode.key_word_replace_mode self.substitute_keyword = work_mode_section.get( 'substitute_keyword', self.substitute_keyword) self.ignore_prefix = work_mode_section.getboolean( 'ignore_prefix', self.ignore_prefix) self.trigger_key = work_mode_section.get('trigger_key', self.trigger_key) self.hot_key = work_mode_section.get('hot_key', self.hot_key)
def __init__( self, config: SectionProxy, client: pymongo.MongoClient = None, experiment=None, ): if not client: client = AutoMongoClient(config=config) if not self.validate_client(client, config): raise ValueError( "The client and configuration contain different values for 'host'." ) super().__init__(client=client, database=config.get("database"), collection=config.get("collection"), activation_level=config.getint("level"), experiment=experiment, name=config.get("name"), encrypt=config.getboolean("encrypt", fallback=False), misc_collection=config.get("misc_collection"))
def get_celestial_panel(position: Position, fonts: Fonts, config: SectionProxy) -> Image.Image: logger = logging.getLogger(__name__) logger.info('Generating celestial panel') x_size = 400 y_size = 600 image = Image.new('L', (x_size, y_size), 0xff) draw = ImageDraw.Draw(image) utils.draw_title(draw, fonts['font_sm'], 'SKY') # Icons now = datetime.datetime.now().astimezone() dusks_and_dawns = get_dusks_and_dawns(position, now) tick_height = 50 y_base = 80 + (9 - len(dusks_and_dawns["twilights"])) * tick_height // 2 x_base = 150 tick_width = 20 tick_gap = 20 arrow_gap = 5 arrow_width = 25 y_position = y_base for shade in dusks_and_dawns["twilights"]: color = get_shade_color(shade) draw.rectangle( ((x_base + tick_gap, y_position), (x_base + tick_gap + tick_width, y_position + tick_height)), color) y_position += tick_height y_position = y_base for new_threshold in dusks_and_dawns["times"]: (hours, minutes) = parse_sunrise_sunset_hour_minute(new_threshold) draw.text((x_base - 60, y_position + tick_height), ":", font=fonts['font_xs'], fill=0, anchor='mm') draw.text((x_base - 53, y_position + tick_height), minutes, font=fonts['font_xs'], fill=0, anchor='lm') draw.text((x_base - 67, y_position + tick_height), hours, font=fonts['font_xs'], fill=0, anchor='rm') draw.rectangle(((x_base + 10, y_position + tick_height - 1), (x_base + 20, y_position + tick_height + 1)), "#000") y_position += tick_height arrow_offset = y_base + dusks_and_dawns[ "now_index"] * tick_height + tick_height // 2 draw.polygon([(x_base + tick_gap + tick_width + arrow_gap + arrow_width, -10 + arrow_offset), (x_base + tick_gap + tick_width + arrow_gap, arrow_offset), (x_base + tick_gap + tick_width + arrow_gap + arrow_width, 10 + arrow_offset)], "#000") (moon_phase, percent) = get_moon_phase() moon_font_chr = get_moon_phase_chr(moon_phase) font_moon = fonts['font_misc_md'] draw.text((3 * x_size // 4, 90), moon_font_chr, font=font_moon, fill=0, anchor="ma") ascent, descent = font_moon.getmetrics() utils.draw_quantity(draw, (3 * x_size // 4, 90 + ascent + descent + 70), str(round(percent)), '%', fonts) # Borders if (config.getboolean('DRAW_PANEL_BORDERS')): draw.polygon([(0, 0), (x_size - 1, 0), (x_size - 1, y_size - 1), (0, y_size - 1), (0, 0)]) return image
def get_observation_panel(location: str, images: Icons, fonts: Fonts, config: SectionProxy) -> Image.Image: logger = logging.getLogger(__name__) logger.info('Generating observation panel') icon_size = 280 (observations, first_position, first_position_name) = get_observations(location) logger.info('Received data: %s', repr(observations)) latest_date = max(observations.keys()) latest_date_local = utils.utc_datetime_string_to_local_datetime( latest_date) is_daylight = get_is_daylight(first_position, latest_date) x_size = 650 y_size = 550 latest = observations[latest_date] image = Image.new('L', (x_size, y_size), 0xff) draw = ImageDraw.Draw(image) utils.draw_title(draw, fonts['font_sm'], 'OUT', first_position_name, fonts['font_xxs']) delimiter_x = 525 data_y_base = 100 # Temperature utils.draw_quantity(draw, (delimiter_x, data_y_base + 120), str(latest["t2m"]), '°C', fonts, 'font_lg', 'font_sm') # Feels like temp_feels = get_feels_like_temperature(latest["t2m"], latest["ws_10min"], 0, latest["rh"] / 100) # temp_feels = get_feels_like_temperature(latest["t2m"], latest["ws_10min"], latest['dir_1min'], latest["rh"]/100) utils.draw_quantity(draw, (delimiter_x, data_y_base + 210), str(round(temp_feels)), '°C', fonts) # Relative humidity utils.draw_quantity(draw, (delimiter_x, data_y_base + 280), str(round(latest["rh"])), '%', fonts) # Barometric pressure utils.draw_quantity(draw, (delimiter_x, data_y_base + 350), str(round(latest["p_sea"])), 'hPa', fonts) # Wind speed utils.draw_quantity( draw, (delimiter_x, data_y_base + 420), f'{round(latest["ws_10min"])} – {round(latest["wg_10min"])}', 'm/s', fonts) # Weather icon cloud_coverage = latest['n_man'] margin = 15 y_top = y_size - icon_size - margin weather_icon = icons.get_scaled_image( get_observation_icon(latest['wawa'], cloud_coverage, is_daylight, images, fonts, config), icon_size) image.paste(weather_icon, (margin, y_top), weather_icon) # Warning icon if (utils.show_temperatur_warning_icon(latest["t2m"], latest_date_local, config)): warning_icon = icons.get_scaled_image(images['misc']['warning'], 60) image.paste( warning_icon, (margin + weather_icon.width - 2 * warning_icon.width // 3, y_top + weather_icon.height - 2 * warning_icon.height // 3), warning_icon) row_y_base = data_y_base # Cloud cover cloud_cover_icon = icons.get_scaled_image( utils.get_cloud_cover_icon(cloud_coverage, images, fonts, config), 160) image.paste( cloud_cover_icon, (margin + icon_size // 2 - cloud_cover_icon.width // 2, row_y_base), cloud_cover_icon) # Wind direction w_dir = latest['wd_10min'] if (not math.isnan(w_dir)): wind_image = icons.get_scaled_image(images['misc']['wind_icon'], 160) wind_image_rot = wind_image.rotate(-w_dir + 180, fillcolor=0xff, resample=Image.BICUBIC) image.paste(wind_image_rot, (margin + icon_size // 2 - cloud_cover_icon.width // 2, row_y_base), wind_image_rot) # Borders if (config.getboolean('DRAW_PANEL_BORDERS')): draw.polygon([(0, 0), (x_size - 1, 0), (x_size - 1, y_size - 1), (0, y_size - 1), (0, 0)]) return image
def get_forecasts_panel( images: Icons, fonts: Fonts, config: SectionProxy) -> tuple[Image.Image, tuple[str, str]]: logger = logging.getLogger(__name__) logger.info('Generating forecast panel') icon_width = config.getint('ICON_WIDTH') count = 7 x_size = 1872 y_size = 800 (forecasts, first_position, first_position_name) = get_forecasts(config.get('FMI_LOCATION'), count, 6) logger.info('Received data: %s', repr(forecasts)) dates = sorted(forecasts.keys()) image = Image.new('L', (x_size, y_size), 0xff) draw = ImageDraw.Draw(image) utils.draw_title(draw, fonts['font_sm'], 'FORECAST', first_position_name, fonts['font_xxs']) data_y_base = 100 for date, i in zip(dates, range(len(dates))): is_daylight = get_is_daylight(first_position, date) data = forecasts[date] date_local = utils.utc_datetime_string_to_local_datetime(date) date_formatted = date_local.strftime('%-H:%M') x_step = x_size // count x_base = x_step // 2 # Time draw.text((x_base + i * x_step, data_y_base + 10), date_formatted, font=(fonts['font_sm'] if date_formatted != "15:00" else fonts['font_sm_bold']), fill=0, anchor='mt') # Weather icon icon_position = (x_base + i * x_step - config.getint('ICON_WIDTH') // 2, data_y_base + 80) weather_icon = icons.get_scaled_image( get_forecats_weather_icon(data['WeatherSymbol3'], is_daylight, images, fonts, config), icon_width) image.paste(weather_icon, icon_position, weather_icon) # Warning icon if (utils.show_temperatur_warning_icon(data["Temperature"], date_local, config)): warning_icon = icons.get_scaled_image(images['misc']['warning'], 50) image.paste(warning_icon, (icon_position[0] + weather_icon.width - 2 * warning_icon.width // 3, icon_position[1] + weather_icon.height - 2 * warning_icon.height // 3), warning_icon) # Temperature utils.draw_quantity(draw, (x_base + i * x_step, data_y_base + 350), str(round(data["Temperature"])), '°C', fonts) # Wind speed utils.draw_quantity(draw, (x_base + i * x_step, data_y_base + 420), str(round(data["WindSpeedMS"])), 'm/s', fonts) # Cloud cover cloud_cover_raw = data["TotalCloudCover"] cloud_cover = math.nan if math.isnan( cloud_cover_raw) else cloud_cover_raw / 100 * 8 cloud_cover_icon = icons.get_scaled_image( utils.get_cloud_cover_icon(cloud_cover, images, fonts, config), 160) image.paste(cloud_cover_icon, (x_base + i * x_step - cloud_cover_icon.width // 2, data_y_base + 440), cloud_cover_icon) # Wind direction wind_image = icons.get_scaled_image(images['misc']['wind_icon'], 160) wind_image_rot = wind_image.rotate(-data['WindDirection'] + 180, fillcolor=0xff, resample=Image.BICUBIC) image.paste(wind_image_rot, (x_base + i * x_step - wind_image_rot.width // 2, data_y_base + 440), wind_image_rot) # Borders if (config.getboolean('DRAW_PANEL_BORDERS')): draw.polygon([(0, 0), (x_size - 1, 0), (x_size - 1, y_size - 1), (0, y_size - 1), (0, 0)]) return (image, first_position)
def _convert_config_value(section: SectionProxy, key: str) -> Union[str, bool]: """Parse ConfigParser's boolean values.""" try: return section.getboolean(key) except ValueError: return section.get(key)
def __init__(self, record_conf: configparser.SectionProxy): self.A = record_conf.getboolean('A', False) self.AAAA = record_conf.getboolean('AAAA', False) self.name = record_conf.name self.ttl = record_conf.getint('ttl', 120)
def process_realm( cfg: SectionProxy, realm_name: str, realms: Dict[str, RealmData], ) -> RealmData: """take a realm config section and turn it into RealmData, resolving interfaces and addresses as needed""" logging.debug('processing realm "%s"', realm_name) parent_realm_name = cfg.get('include_realm', fallback=None) if parent_realm_name is not None: # Is the realm we depend on already loaded? if parent_realm_name not in realms: logging.debug( 'processing of realm "%s" delayed, because of dependency on "%s"', realm_name, parent_realm_name, ) # No, so delay loading this realm and try again later. raise RealmDepenencyNotLoaded() realm_data = RealmData(realm_name, parent=realms[parent_realm_name]) else: realm_data = RealmData(realm_name) realm_data.vid = cfg.getint('vid', fallback=realm_data.vid) realm_data.dhcp_local_port = cfg.getint( 'dhcp_local_port', fallback=realm_data.dhcp_local_port) if 'dhcp_listening_device' in cfg: realm_data.dhcp_listening_device = cfg.get('dhcp_listening_device') # If a device is explicitly set, the listening IP needs to be explicitly # set too (or the implicit detection needs to be performed again). realm_data.dhcp_listening_ip = None realm_data.dhcp_listening_ip = cfg.get( 'dhcp_listening_ip', fallback=realm_data.dhcp_listening_ip) realm_data.provide_default_route = cfg.getboolean( 'provide_default_route', fallback=realm_data.provide_default_route) realm_data.default_gateway_ipv4 = cfg.get( 'default_gateway_ipv4', fallback=realm_data.default_gateway_ipv4) realm_data.subnet_ipv6 = cfg.get('subnet_ipv6', fallback=realm_data.subnet_ipv6) realm_data.subnet_ipv4 = cfg.get('subnet_ipv4', fallback=realm_data.subnet_ipv4) realm_data.default_gateway_ipv6 = cfg.get( 'default_gateway_ipv6', fallback=realm_data.default_gateway_ipv6) if 'static_routes_ipv4' in cfg: realm_data.static_routes_ipv4 = parse_static_routes_ipv4( cfg.get('static_routes_ipv4')) if 'static_routes_ipv6' in cfg: realm_data.static_routes_ipv6 = parse_static_routes_ipv6( cfg.get('static_routes_ipv6')) if (realm_data.dhcp_listening_device is not None and realm_data.dhcp_listening_ip is None): # We need to determine an IPv4 address on the specified network # device. realm_data.dhcp_listening_ip = get_ip_for_iface( realm_data.dhcp_listening_device) if 'dhcp_server_ips' in cfg: realm_data.dhcp_server_ips = [ socket.gethostbyname(i.strip()) for i in cfg.get('dhcp_server_ips').split(',') ] realm_data.expected_dhcp_lease_time = cfg.getint( 'expected_dhcp_lease_time', fallback=realm_data.expected_dhcp_lease_time) return realm_data