diff --git a/README.md b/README.md index 5515ccf..6f52be9 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ > This is pre-production, location of methods and names of paths can change > > This will be split up into modules per file and this will be just a collection holder +> See [Deprecated](#deprecated) below This is a pip package that can be installed into any project and covers the following parts @@ -42,6 +43,15 @@ This is a pip package that can be installed into any project and covers the foll - csv_handling/csv_interface: The CSV DictWriter interface is just in a very basic way implemented - script_handling/script_helpers: No idea if there is need for this, tests are written but not finished +## Deprecated + +All content in this module will move to stand alone libraries, as of now the following entries have moved and will throw deprecated warnings if used + +- var_handling.enum_base: corelibs-enum-base +- var_handling.var_helpers: corelibs-var +- datetime_handling: corelibs-datetime +- string_handling.text_colors: corelibs-text-colors + ## UV setup uv must be [installed](https://docs.astral.sh/uv/getting-started/installation/) diff --git a/pyproject.toml b/pyproject.toml index cc92725..cc3188e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,12 +6,20 @@ description = "Collection of utils for Python scripts" readme = "README.md" requires-python = ">=3.13" dependencies = [ + "corelibs-datetime>=1.0.1", + "corelibs-enum-base>=1.0.0", + "corelibs-var>=1.0.0", "cryptography>=46.0.3", "jmespath>=1.0.1", "jsonpath-ng>=1.7.0", "psutil>=7.0.0", "requests>=2.32.4", ] + +# MARK: build system +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" # set this to disable publish to pypi (pip) # classifiers = ["Private :: Do Not Upload"] @@ -21,10 +29,10 @@ name = "opj-pypi" url = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/" publish-url = "https://git.egplusww.jp/api/packages/PyPI/pypi" -# MARK: build system -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +[tool.uv.sources] +corelibs-enum-base = { index = "opj-pypi" } +corelibs-datetime = { index = "opj-pypi" } +corelibs-var = { index = "opj-pypi" } [dependency-groups] dev = [ diff --git a/src/corelibs/datetime_handling/datetime_helpers.py b/src/corelibs/datetime_handling/datetime_helpers.py index d33504c..c7918e8 100644 --- a/src/corelibs/datetime_handling/datetime_helpers.py +++ b/src/corelibs/datetime_handling/datetime_helpers.py @@ -2,26 +2,13 @@ Various string based date/time helpers """ -import time as time_t from datetime import datetime, time -from zoneinfo import ZoneInfo, ZoneInfoNotFoundError -from typing import Callable - -DAYS_OF_WEEK_LONG_TO_SHORT: dict[str, str] = { - 'Monday': 'Mon', - 'Tuesday': 'Tue', - 'Wednesay': 'Wed', - 'Thursday': 'Thu', - 'Friday': 'Fri', - 'Saturday': 'Sat', - 'Sunday': 'Sun', -} -DAYS_OF_WEEK_ISO: dict[int, str] = { - 1: 'Mon', 2: 'Tue', 3: 'Wed', 4: 'Thu', 5: 'Fri', 6: 'Sat', 7: 'Sun' -} -DAYS_OF_WEEK_ISO_REVERSED: dict[str, int] = {value: key for key, value in DAYS_OF_WEEK_ISO.items()} +from warnings import deprecated +from zoneinfo import ZoneInfo +from corelibs_datetime import datetime_helpers +@deprecated("Use corelibs_datetime.datetime_helpers.create_time instead") def create_time(timestamp: float, timestamp_format: str = "%Y-%m-%d %H:%M:%S") -> str: """ just takes a timestamp and prints out humand readable format @@ -35,21 +22,17 @@ def create_time(timestamp: float, timestamp_format: str = "%Y-%m-%d %H:%M:%S") - Returns: str -- _description_ """ - return time_t.strftime(timestamp_format, time_t.localtime(timestamp)) + return datetime_helpers.create_time(timestamp, timestamp_format) +@deprecated("Use corelibs_datetime.datetime_helpers.get_system_timezone instead") def get_system_timezone(): """Get system timezone using datetime's automatic detection""" # Get current time with system timezone - local_time = datetime.now().astimezone() - - # Extract timezone info - system_tz = local_time.tzinfo - timezone_name = str(system_tz) - - return system_tz, timezone_name + return datetime_helpers.get_system_timezone() +@deprecated("Use corelibs_datetime.datetime_helpers.parse_timezone_data instead") def parse_timezone_data(timezone_tz: str = '') -> ZoneInfo: """ parses a string to get the ZoneInfo @@ -62,40 +45,10 @@ def parse_timezone_data(timezone_tz: str = '') -> ZoneInfo: Returns: ZoneInfo -- _description_ """ - try: - return ZoneInfo(timezone_tz) - except (ZoneInfoNotFoundError, ValueError, TypeError): - # use default - time_tz, time_tz_str = get_system_timezone() - if time_tz is None: - return ZoneInfo('UTC') - # TODO build proper TZ lookup - tz_mapping = { - 'JST': 'Asia/Tokyo', - 'KST': 'Asia/Seoul', - 'IST': 'Asia/Kolkata', - 'CST': 'Asia/Shanghai', # Default to China for CST - 'AEST': 'Australia/Sydney', - 'AWST': 'Australia/Perth', - 'EST': 'America/New_York', - 'EDT': 'America/New_York', - 'CDT': 'America/Chicago', - 'MST': 'America/Denver', - 'MDT': 'America/Denver', - 'PST': 'America/Los_Angeles', - 'PDT': 'America/Los_Angeles', - 'GMT': 'UTC', - 'UTC': 'UTC', - 'CET': 'Europe/Berlin', - 'CEST': 'Europe/Berlin', - 'BST': 'Europe/London', - } - try: - return ZoneInfo(tz_mapping[time_tz_str]) - except (ZoneInfoNotFoundError, IndexError) as e: - raise ValueError(f"No mapping for {time_tz_str}: {e}") from e + return datetime_helpers.parse_timezone_data(timezone_tz) +@deprecated("Use corelibs_datetime.datetime_helpers.get_datetime_iso8601 instead") def get_datetime_iso8601(timezone_tz: str | ZoneInfo = '', sep: str = 'T', timespec: str = 'microseconds') -> str: """ set a datetime in the iso8601 format with microseconds @@ -103,12 +56,13 @@ def get_datetime_iso8601(timezone_tz: str | ZoneInfo = '', sep: str = 'T', times Returns: str -- _description_ """ - # parse if this is a string - if isinstance(timezone_tz, str): - timezone_tz = parse_timezone_data(timezone_tz) - return datetime.now(timezone_tz).isoformat(sep=sep, timespec=timespec) + try: + return datetime_helpers.get_datetime_iso8601(timezone_tz, sep, timespec) + except KeyError as e: + raise ValueError(f"Deprecated ValueError, change to KeyError: {e}") from e +@deprecated("Use corelibs_datetime.datetime_helpers.validate_date instead") def validate_date(date: str, not_before: datetime | None = None, not_after: datetime | None = None) -> bool: """ check if Y-m-d or Y/m/d are parsable and valid @@ -119,20 +73,10 @@ def validate_date(date: str, not_before: datetime | None = None, not_after: date Returns: bool -- _description_ """ - formats = ['%Y-%m-%d', '%Y/%m/%d'] - for __format in formats: - try: - __date = datetime.strptime(date, __format).date() - if not_before is not None and __date < not_before.date(): - return False - if not_after is not None and __date > not_after.date(): - return False - return True - except ValueError: - continue - return False + return datetime_helpers.validate_date(date, not_before, not_after) +@deprecated("Use corelibs_datetime.datetime_helpers.parse_flexible_date instead") def parse_flexible_date( date_str: str, timezone_tz: str | ZoneInfo | None = None, @@ -154,49 +98,14 @@ def parse_flexible_date( Returns: datetime | None -- _description_ """ - - date_str = date_str.strip() - - # Try different parsing methods - parsers: list[Callable[[str], datetime]] = [ - # ISO 8601 format, also with missing "T" - lambda x: datetime.fromisoformat(x), # pylint: disable=W0108 - lambda x: datetime.fromisoformat(x.replace(' ', 'T')), # pylint: disable=W0108 - # Simple date format - lambda x: datetime.strptime(x, "%Y-%m-%d"), - # datetime without T - lambda x: datetime.strptime(x, "%Y-%m-%d %H:%M:%S"), - lambda x: datetime.strptime(x, "%Y-%m-%d %H:%M:%S.%f"), - # Alternative ISO formats (fallback) - lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S"), - lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S.%f"), - ] - - if timezone_tz is not None: - if isinstance(timezone_tz, str): - timezone_tz = parse_timezone_data(timezone_tz) - - date_new = None - for parser in parsers: - try: - date_new = parser(date_str) - break - except ValueError: - continue - - if date_new is not None: - if timezone_tz is not None: - # shift time zone (default), this will change the date - # if the date has no +HH:MM it will take the local time zone as base - if shift_time_zone: - return date_new.astimezone(timezone_tz) - # just add the time zone - return date_new.replace(tzinfo=timezone_tz) - return date_new - - return None + return datetime_helpers.parse_flexible_date( + date_str, + timezone_tz, + shift_time_zone + ) +@deprecated("Use corelibs_datetime.datetime_helpers.compare_dates instead") def compare_dates(date1_str: str, date2_str: str) -> None | bool: """ compare two dates, if the first one is newer than the second one return True @@ -210,23 +119,10 @@ def compare_dates(date1_str: str, date2_str: str) -> None | bool: Returns: None | bool -- _description_ """ - - try: - # Parse both dates - date1 = parse_flexible_date(date1_str) - date2 = parse_flexible_date(date2_str) - - # Check if parsing was successful - if date1 is None or date2 is None: - return None - - # Compare dates - return date1.date() > date2.date() - - except ValueError: - return None + return datetime_helpers.compare_dates(date1_str, date2_str) +@deprecated("Use corelibs_datetime.datetime_helpers.find_newest_datetime_in_list instead") def find_newest_datetime_in_list(date_list: list[str]) -> None | str: """ Find the newest date from a list of ISO 8601 formatted date strings. @@ -238,31 +134,10 @@ def find_newest_datetime_in_list(date_list: list[str]) -> None | str: Returns: str: The date string with the newest/latest date, or None if list is empty or all dates are invalid """ - if not date_list: - return None - - valid_dates: list[tuple[str, datetime]] = [] - - for date_str in date_list: - try: - # Parse the date string and store both original string and parsed datetime - parsed_date = parse_flexible_date(date_str) - if parsed_date is None: - continue - valid_dates.append((date_str, parsed_date)) - except ValueError: - # Skip invalid date strings - continue - - if not valid_dates: - return None - - # Find the date string with the maximum datetime value - newest_date_str: str = max(valid_dates, key=lambda x: x[1])[0] - - return newest_date_str + return datetime_helpers.find_newest_datetime_in_list(date_list) +@deprecated("Use corelibs_datetime.datetime_helpers.parse_day_of_week_range instead") def parse_day_of_week_range(dow_days: str) -> list[tuple[int, str]]: """ Parse a day of week list/range string and return a list of tuples with day index and name. @@ -279,59 +154,13 @@ def parse_day_of_week_range(dow_days: str) -> list[tuple[int, str]]: """ # we have Sun twice because it can be 0 or 7 # Mon is 1 and Sun is 7, which is ISO standard - dow_day = dow_days.split(",") - dow_day = [day.strip() for day in dow_day if day.strip()] - __out_dow_days: list[tuple[int, str]] = [] - for __dow_day in dow_day: - # if we have a "-" in there fill - if "-" in __dow_day: - __dow_range = __dow_day.split("-") - __dow_range = [day.strip().capitalize() for day in __dow_range if day.strip()] - try: - start_day = DAYS_OF_WEEK_ISO_REVERSED[__dow_range[0]] - end_day = DAYS_OF_WEEK_ISO_REVERSED[__dow_range[1]] - except KeyError: - # try long time - try: - start_day = DAYS_OF_WEEK_ISO_REVERSED[DAYS_OF_WEEK_LONG_TO_SHORT[__dow_range[0]]] - end_day = DAYS_OF_WEEK_ISO_REVERSED[DAYS_OF_WEEK_LONG_TO_SHORT[__dow_range[1]]] - except KeyError as e: - raise ValueError(f"Invalid day of week entry found: {__dow_day}: {e}") from e - # Check if this spans across the weekend (e.g., Fri-Mon) - if start_day > end_day: - # Handle weekend-spanning range: start_day to 7, then 1 to end_day - __out_dow_days.extend( - [ - (i, DAYS_OF_WEEK_ISO[i]) - for i in range(start_day, 8) # start_day to Sunday (7) - ] - ) - __out_dow_days.extend( - [ - (i, DAYS_OF_WEEK_ISO[i]) - for i in range(1, end_day + 1) # Monday (1) to end_day - ] - ) - else: - # Normal range: start_day to end_day - __out_dow_days.extend( - [ - (i, DAYS_OF_WEEK_ISO[i]) - for i in range(start_day, end_day + 1) - ] - ) - else: - try: - __out_dow_days.append((DAYS_OF_WEEK_ISO_REVERSED[__dow_day], __dow_day)) - except KeyError as e: - raise ValueError(f"Invalid day of week entry found: {__dow_day}: {e}") from e - # if there are duplicates, alert - if len(__out_dow_days) != len(set(__out_dow_days)): - raise ValueError(f"Duplicate day of week entries found: {__out_dow_days}") - - return __out_dow_days + try: + return datetime_helpers.parse_day_of_week_range(dow_days) + except KeyError as e: + raise ValueError(f"Deprecated ValueError, change to KeyError: {e}") from e +@deprecated("Use corelibs_datetime.datetime_helpers.parse_time_range instead") def parse_time_range(time_str: str, time_format: str = "%H:%M") -> tuple[time, time]: """ Parse a time range string in the format "HH:MM-HH:MM" and return a tuple of two time objects. @@ -347,22 +176,13 @@ def parse_time_range(time_str: str, time_format: str = "%H:%M") -> tuple[time, t Returns: tuple[time, time] -- start time, end time: leading zeros formattd """ - __time_str = time_str.strip() - # split by "-" - __time_split = __time_str.split("-") - if len(__time_split) != 2: - raise ValueError(f"Invalid time block: {__time_str}") try: - __time_start = datetime.strptime(__time_split[0], time_format).time() - __time_end = datetime.strptime(__time_split[1], time_format).time() - except ValueError as e: - raise ValueError(f"Invalid time block format [{__time_str}]: {e}") from e - if __time_start >= __time_end: - raise ValueError(f"Invalid time block set, start time after end time or equal: {__time_str}") - - return __time_start, __time_end + return datetime_helpers.parse_time_range(time_str, time_format) + except KeyError as e: + raise ValueError(f"Deprecated ValueError, change to KeyError: {e}") from e +@deprecated("Use corelibs_datetime.datetime_helpers.times_overlap_or_connect instead") def times_overlap_or_connect(time1: tuple[time, time], time2: tuple[time, time], allow_touching: bool = False) -> bool: """ Check if two time ranges overlap or connect @@ -375,16 +195,10 @@ def times_overlap_or_connect(time1: tuple[time, time], time2: tuple[time, time], Returns: bool: True if ranges overlap or connect (based on allow_touching) """ - start1, end1 = time1 - start2, end2 = time2 - - if allow_touching: - # Only check for actual overlap (touching is OK) - return start1 < end2 and start2 < end1 - # Check for overlap OR touching - return start1 <= end2 and start2 <= end1 + return datetime_helpers.times_overlap_or_connect(time1, time2, allow_touching) +@deprecated("Use corelibs_datetime.datetime_helpers.is_time_in_range instead") def is_time_in_range(current_time: str, start_time: str, end_time: str) -> bool: """ Check if current_time is within start_time and end_time (inclusive) @@ -399,18 +213,10 @@ def is_time_in_range(current_time: str, start_time: str, end_time: str) -> bool: bool -- _description_ """ # Convert string times to time objects - current = datetime.strptime(current_time, "%H:%M:%S").time() - start = datetime.strptime(start_time, "%H:%M:%S").time() - end = datetime.strptime(end_time, "%H:%M:%S").time() - - # Handle case where range crosses midnight (e.g., 22:00 to 06:00) - if start <= end: - # Normal case: start time is before end time - return start <= current <= end - # Crosses midnight: e.g., 22:00 to 06:00 - return current >= start or current <= end + return datetime_helpers.is_time_in_range(current_time, start_time, end_time) +@deprecated("Use corelibs_datetime.datetime_helpers.reorder_weekdays_from_today instead") def reorder_weekdays_from_today(base_day: str) -> dict[int, str]: """ Reorder the days of the week starting from the specified base_day. @@ -422,18 +228,8 @@ def reorder_weekdays_from_today(base_day: str) -> dict[int, str]: dict[int, str] -- A dictionary mapping day numbers to day names. """ try: - today_num = DAYS_OF_WEEK_ISO_REVERSED[base_day] - except KeyError: - try: - today_num = DAYS_OF_WEEK_ISO_REVERSED[DAYS_OF_WEEK_LONG_TO_SHORT[base_day]] - except KeyError as e: - raise ValueError(f"Invalid day name provided: {base_day}: {e}") from e - # Convert to list of tuples - items = list(DAYS_OF_WEEK_ISO.items()) - # Reorder: from today onwards + from beginning to yesterday - reordered_items = items[today_num - 1:] + items[:today_num - 1] - - # Convert back to dictionary - return dict(reordered_items) + return datetime_helpers.reorder_weekdays_from_today(base_day) + except KeyError as e: + raise ValueError(f"Deprecated ValueError, change to KeyError: {e}") from e # __END__ diff --git a/src/corelibs/datetime_handling/timestamp_convert.py b/src/corelibs/datetime_handling/timestamp_convert.py index 8e3974d..7130df8 100644 --- a/src/corelibs/datetime_handling/timestamp_convert.py +++ b/src/corelibs/datetime_handling/timestamp_convert.py @@ -2,19 +2,22 @@ Convert timestamp strings with time units into seconds and vice versa. """ -from math import floor -import re -from corelibs.var_handling.var_helpers import is_float +from warnings import deprecated +from corelibs_datetime import timestamp_convert +from corelibs_datetime.timestamp_convert import TimeParseError as NewTimeParseError, TimeUnitError as NewTimeUnitError +@deprecated("Use corelibs_datetime.timestamp_convert.TimeParseError instead") class TimeParseError(Exception): """Custom exception for time parsing errors.""" +@deprecated("Use corelibs_datetime.timestamp_convert.TimeUnitError instead") class TimeUnitError(Exception): """Custom exception for time parsing errors.""" +@deprecated("Use corelibs_datetime.timestamp_convert.convert_to_seconds instead") def convert_to_seconds(time_string: str | int | float) -> int: """ Conver a string with time units into a seconds string @@ -35,67 +38,15 @@ def convert_to_seconds(time_string: str | int | float) -> int: # skip out if this is a number of any type # numbers will br made float, rounded and then converted to int - if is_float(time_string): - return int(round(float(time_string))) - time_string = str(time_string) - - # Check if the time string is negative - negative = time_string.startswith('-') - if negative: - time_string = time_string[1:] # Remove the negative sign for processing - - # Define time unit conversion factors - unit_factors: dict[str, int] = { - 'Y': 31536000, # 365 days * 86400 seconds/day - 'M': 2592000 * 12, # 1 year in seconds (assuming 365 days per year) - 'd': 86400, # 1 day in seconds - 'h': 3600, # 1 hour in seconds - 'm': 60, # minutes to seconds - 's': 1 # 1 second in seconds - } - long_unit_names: dict[str, str] = { - 'year': 'Y', - 'years': 'Y', - 'month': 'M', - 'months': 'M', - 'day': 'd', - 'days': 'd', - 'hour': 'h', - 'hours': 'h', - 'minute': 'm', - 'minutes': 'm', - 'min': 'm', - 'second': 's', - 'seconds': 's', - 'sec': 's', - } - - total_seconds = 0 - - seen_units: list[str] = [] # Track units that have been encountered - - # Use regex to match number and time unit pairs - for match in re.finditer(r'(\d+)\s*([a-zA-Z]+)', time_string): - value, unit = int(match.group(1)), match.group(2) - - # full name check, fallback to original name - unit = long_unit_names.get(unit.lower(), unit) - - # Check for duplicate units - if unit in seen_units: - raise TimeParseError(f"Unit '{unit}' appears more than once.") - # Check invalid unit - if unit not in unit_factors: - raise TimeUnitError(f"Unit '{unit}' is not a valid unit name.") - # Add to total seconds based on the units - if unit in unit_factors: - total_seconds += value * unit_factors[unit] - - seen_units.append(unit) - - return -total_seconds if negative else total_seconds + try: + return timestamp_convert.convert_to_seconds(time_string) + except NewTimeParseError as e: + raise TimeParseError(f"Deprecated, use corelibs_datetime.timestamp_convert.TimeParseError: {e}") from e + except NewTimeUnitError as e: + raise TimeUnitError(f"Deprecated, use corelibs_datetime.timestamp_convert.TimeUnitError: {e}") from e +@deprecated("Use corelibs_datetime.timestamp_convert.seconds_to_string instead") def seconds_to_string(seconds: str | int | float, show_microseconds: bool = False) -> str: """ Convert seconds to compact human readable format (e.g., "1d 2h 3m 4.567s") @@ -111,46 +62,10 @@ def seconds_to_string(seconds: str | int | float, show_microseconds: bool = Fals Returns: str: Compact human readable time format """ - # if not int or float, return as is - if not isinstance(seconds, (int, float)): - return seconds - # Handle negative values - negative = seconds < 0 - seconds = abs(seconds) - - whole_seconds = int(seconds) - fractional = seconds - whole_seconds - - days = whole_seconds // 86400 - hours = (whole_seconds % 86400) // 3600 - minutes = (whole_seconds % 3600) // 60 - secs = whole_seconds % 60 - - parts: list[str] = [] - if days > 0: - parts.append(f"{days}d") - if hours > 0: - parts.append(f"{hours}h") - if minutes > 0: - parts.append(f"{minutes}m") - - # Handle seconds with fractional part - if fractional > 0: - if show_microseconds: - total_seconds = secs + fractional - formatted = f"{total_seconds:.6f}".rstrip('0').rstrip('.') - parts.append(f"{formatted}s") - else: - total_seconds = secs + fractional - formatted = f"{total_seconds:.3f}".rstrip('0').rstrip('.') - parts.append(f"{formatted}s") - elif secs > 0 or not parts: - parts.append(f"{secs}s") - - result = " ".join(parts) - return f"-{result}" if negative else result + return timestamp_convert.seconds_to_string(seconds, show_microseconds) +@deprecated("Use corelibs_datetime.timestamp_convert.convert_timestamp instead") def convert_timestamp(timestamp: float | int | str, show_microseconds: bool = True) -> str: """ format timestamp into human readable format. This function will add 0 values between set values @@ -168,33 +83,6 @@ def convert_timestamp(timestamp: float | int | str, show_microseconds: bool = Tr Returns: str -- _description_ """ - if not isinstance(timestamp, (int, float)): - return timestamp - # cut of the ms, but first round them up to four - __timestamp_ms_split = str(round(timestamp, 4)).split(".") - timestamp = int(__timestamp_ms_split[0]) - negative = timestamp < 0 - timestamp = abs(timestamp) - try: - ms = int(__timestamp_ms_split[1]) - except IndexError: - ms = 0 - timegroups = (86400, 3600, 60, 1) - output: list[int] = [] - for i in timegroups: - output.append(int(floor(timestamp / i))) - timestamp = timestamp % i - # output has days|hours|min|sec ms - time_string = "" - if output[0]: - time_string = f"{output[0]}d " - if output[0] or output[1]: - time_string += f"{output[1]}h " - if output[0] or output[1] or output[2]: - time_string += f"{output[2]}m " - time_string += f"{output[3]}s" - if show_microseconds: - time_string += f" {ms}ms" if ms else " 0ms" - return f"-{time_string}" if negative else time_string + return timestamp_convert.convert_timestamp(timestamp, show_microseconds) # __END__ diff --git a/src/corelibs/datetime_handling/timestamp_strings.py b/src/corelibs/datetime_handling/timestamp_strings.py index 6aa3f80..7fc5d51 100644 --- a/src/corelibs/datetime_handling/timestamp_strings.py +++ b/src/corelibs/datetime_handling/timestamp_strings.py @@ -2,31 +2,20 @@ Current timestamp strings and time zones """ -from datetime import datetime -from zoneinfo import ZoneInfo, ZoneInfoNotFoundError +from warnings import deprecated +from zoneinfo import ZoneInfo +from corelibs_datetime import timestamp_strings -class TimestampStrings: +class TimestampStrings(timestamp_strings.TimestampStrings): """ set default time stamps """ TIME_ZONE: str = 'Asia/Tokyo' + @deprecated("Use corelibs_datetime.timestamp_strings.TimestampStrings instead") def __init__(self, time_zone: str | ZoneInfo | None = None): - self.timestamp_now = datetime.now() - # set time zone as string - time_zone = time_zone if time_zone is not None else self.TIME_ZONE - self.time_zone = str(time_zone) if not isinstance(time_zone, str) else time_zone - # set ZoneInfo type - try: - self.time_zone_zi = ZoneInfo(self.time_zone) - except ZoneInfoNotFoundError as e: - raise ValueError(f'Zone could not be loaded [{self.time_zone}]: {e}') from e - self.timestamp_now_tz = datetime.now(self.time_zone_zi) - self.today = self.timestamp_now.strftime('%Y-%m-%d') - self.timestamp = self.timestamp_now.strftime("%Y-%m-%d %H:%M:%S") - self.timestamp_tz = self.timestamp_now_tz.strftime("%Y-%m-%d %H:%M:%S %Z") - self.timestamp_file = self.timestamp_now.strftime("%Y-%m-%d_%H%M%S") + super().__init__(time_zone) # __END__ diff --git a/src/corelibs/var_handling/enum_base.py b/src/corelibs/var_handling/enum_base.py index fa2b967..0aa4cd1 100644 --- a/src/corelibs/var_handling/enum_base.py +++ b/src/corelibs/var_handling/enum_base.py @@ -3,7 +3,9 @@ Enum base classes """ from enum import Enum +from warnings import deprecated from typing import Any +# from corelibs_enum_base.enum_base import EnumBase as CorelibsEnumBase class EnumBase(Enum): @@ -14,6 +16,7 @@ class EnumBase(Enum): """ @classmethod + @deprecated("Use corelibs_enum_base.EnumBase instead") def lookup_key(cls, enum_key: str): """Lookup from key side (must be string)""" # if there is a ":", then this is legacy, replace with ___ @@ -27,6 +30,7 @@ class EnumBase(Enum): raise ValueError(f"Invalid key: {enum_key}") from e @classmethod + @deprecated("Use corelibs_enum_base.EnumBase instead") def lookup_value(cls, enum_value: Any): """Lookup through value side""" try: @@ -35,6 +39,7 @@ class EnumBase(Enum): raise ValueError(f"Invalid value: {enum_value}") from e @classmethod + @deprecated("Use corelibs_enum_base.EnumBase instead") def from_any(cls, enum_any: Any): """ This only works in the following order @@ -62,14 +67,17 @@ class EnumBase(Enum): raise ValueError(f"Could not find as key or value: {enum_any}") from e return cls.lookup_value(enum_any) + @deprecated("Use corelibs_enum_base.EnumBase instead") def to_value(self) -> Any: """Convert to value""" return self.value + @deprecated("Use corelibs_enum_base.EnumBase instead") def to_lower_case(self) -> str: """return lower case""" return self.name.lower() + @deprecated("Use corelibs_enum_base.EnumBase instead") def __str__(self) -> str: """return [Enum].NAME like it was called with .name""" return self.name diff --git a/src/corelibs/var_handling/var_helpers.py b/src/corelibs/var_handling/var_helpers.py index 2f3b2a9..4daf6d0 100644 --- a/src/corelibs/var_handling/var_helpers.py +++ b/src/corelibs/var_handling/var_helpers.py @@ -3,8 +3,11 @@ variable convert, check, etc helepr """ from typing import Any +from warnings import deprecated +import corelibs_var.var_helpers +@deprecated("Use corelibs_var.var_helpers.is_int instead") def is_int(string: Any) -> bool: """ check if a value is int @@ -15,15 +18,10 @@ def is_int(string: Any) -> bool: Returns: bool -- _description_ """ - try: - int(string) - return True - except TypeError: - return False - except ValueError: - return False + return corelibs_var.var_helpers.is_int(string) +@deprecated("Use corelibs_var.var_helpers.is_float instead") def is_float(string: Any) -> bool: """ check if a value is float @@ -34,15 +32,10 @@ def is_float(string: Any) -> bool: Returns: bool -- _description_ """ - try: - float(string) - return True - except TypeError: - return False - except ValueError: - return False + return corelibs_var.var_helpers.is_float(string) +@deprecated("Use corelibs_var.var_helpers.str_to_bool instead") def str_to_bool(string: str): """ convert string to bool @@ -56,10 +49,6 @@ def str_to_bool(string: str): Returns: _type_ -- _description_ """ - if string == "True" or string == "true": - return True - if string == "False" or string == "false": - return False - raise ValueError(f"Invalid boolean string: {string}") + return corelibs_var.var_helpers.str_to_bool(string) # __END__ diff --git a/uv.lock b/uv.lock index cfc9a3d..5c742db 100644 --- a/uv.lock +++ b/uv.lock @@ -111,6 +111,9 @@ name = "corelibs" version = "0.36.0" source = { editable = "." } dependencies = [ + { name = "corelibs-datetime" }, + { name = "corelibs-enum-base" }, + { name = "corelibs-var" }, { name = "cryptography" }, { name = "jmespath" }, { name = "jsonpath-ng" }, @@ -127,6 +130,9 @@ dev = [ [package.metadata] requires-dist = [ + { name = "corelibs-datetime", specifier = ">=1.0.1", index = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/" }, + { name = "corelibs-enum-base", specifier = ">=1.0.0", index = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/" }, + { name = "corelibs-var", specifier = ">=1.0.0", index = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/" }, { name = "cryptography", specifier = ">=46.0.3" }, { name = "jmespath", specifier = ">=1.0.1" }, { name = "jsonpath-ng", specifier = ">=1.7.0" }, @@ -141,6 +147,36 @@ dev = [ { name = "pytest-cov", specifier = ">=6.2.1" }, ] +[[package]] +name = "corelibs-datetime" +version = "1.0.1" +source = { registry = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/" } +dependencies = [ + { name = "corelibs-var" }, +] +sdist = { url = "https://git.egplusww.jp/api/packages/PyPI/pypi/files/corelibs-datetime/1.0.1/corelibs_datetime-1.0.1.tar.gz", hash = "sha256:ff58c6f824f35b87b1a5c153f65fdd82b65e42bb5a649d46d9115dc5fa61042f" } +wheels = [ + { url = "https://git.egplusww.jp/api/packages/PyPI/pypi/files/corelibs-datetime/1.0.1/corelibs_datetime-1.0.1-py3-none-any.whl", hash = "sha256:f1a4d431f9f913dd39976a119ff8a2db34e966c61b1775c26b0da72a8bdb5ec1" }, +] + +[[package]] +name = "corelibs-enum-base" +version = "1.0.0" +source = { registry = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/" } +sdist = { url = "https://git.egplusww.jp/api/packages/PyPI/pypi/files/corelibs-enum-base/1.0.0/corelibs_enum_base-1.0.0.tar.gz", hash = "sha256:c696a297d88f674d40e5d190f396909b5f663a995ac735e545ceb5bb4907121d" } +wheels = [ + { url = "https://git.egplusww.jp/api/packages/PyPI/pypi/files/corelibs-enum-base/1.0.0/corelibs_enum_base-1.0.0-py3-none-any.whl", hash = "sha256:c305d4063c69021aaf9ef75fbcce961039dae3c3de7820febeac7082c998a1f8" }, +] + +[[package]] +name = "corelibs-var" +version = "1.0.0" +source = { registry = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/" } +sdist = { url = "https://git.egplusww.jp/api/packages/PyPI/pypi/files/corelibs-var/1.0.0/corelibs_var-1.0.0.tar.gz", hash = "sha256:b85d6fd3802a1b687290666e4b1dbb47cf9723aa72bf73eb004e9e4936776364" } +wheels = [ + { url = "https://git.egplusww.jp/api/packages/PyPI/pypi/files/corelibs-var/1.0.0/corelibs_var-1.0.0-py3-none-any.whl", hash = "sha256:a3546785bf9c94eec08b5c500b69b971e83e11d92bc0e4d3cbd9411a561fdbc2" }, +] + [[package]] name = "coverage" version = "7.12.0"