A library that computes the ephemerides.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

core.py 2.7 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/usr/bin/env python3
  2. import os
  3. import re
  4. from shutil import rmtree
  5. from pathlib import Path
  6. from datetime import date
  7. from dateutil.relativedelta import relativedelta
  8. from skyfield.api import Loader
  9. from skyfield.timelib import Time
  10. from skyfield.nutationlib import iau2000b
  11. CACHE_FOLDER = str(Path.home()) + "/.kosmorro-cache"
  12. class Environment:
  13. def __init__(self):
  14. self._vars = {}
  15. def __set__(self, key, value):
  16. self._vars[key] = value
  17. def __getattr__(self, key):
  18. return self._vars[key] if key in self._vars else None
  19. def __str__(self):
  20. return self._vars.__str__()
  21. def __len__(self):
  22. return len(self._vars)
  23. def get_env() -> Environment:
  24. environment = Environment()
  25. for var in os.environ:
  26. if not re.search("^KOSMORRO_", var):
  27. continue
  28. [_, env] = var.split("_", 1)
  29. environment.__set__(env.lower(), os.getenv(var))
  30. return environment
  31. def get_loader():
  32. return Loader(CACHE_FOLDER)
  33. def get_timescale():
  34. return get_loader().timescale()
  35. def get_skf_objects():
  36. return get_loader()("de421.bsp")
  37. def get_iau2000b(time: Time):
  38. return iau2000b(time.tt)
  39. def clear_cache():
  40. rmtree(CACHE_FOLDER)
  41. def flatten_list(the_list: list):
  42. new_list = []
  43. for item in the_list:
  44. if isinstance(item, list):
  45. for item2 in flatten_list(item):
  46. new_list.append(item2)
  47. continue
  48. new_list.append(item)
  49. return new_list
  50. def get_date(date_arg: str) -> date:
  51. if re.match(r"^\d{4}-\d{2}-\d{2}$", date_arg):
  52. try:
  53. return date.fromisoformat(date_arg)
  54. except ValueError as error:
  55. raise ValueError(
  56. _("The date {date} is not valid: {error}").format(
  57. date=date_arg, error=error.args[0]
  58. )
  59. ) from error
  60. elif re.match(r"^([+-])(([0-9]+)y)?[ ]?(([0-9]+)m)?[ ]?(([0-9]+)d)?$", date_arg):
  61. def get_offset(date_arg: str, signifier: str):
  62. if re.search(r"([0-9]+)" + signifier, date_arg):
  63. return abs(
  64. int(re.search(r"[+-]?([0-9]+)" + signifier, date_arg).group(0)[:-1])
  65. )
  66. return 0
  67. days = get_offset(date_arg, "d")
  68. months = get_offset(date_arg, "m")
  69. years = get_offset(date_arg, "y")
  70. if date_arg[0] == "+":
  71. return date.today() + relativedelta(days=days, months=months, years=years)
  72. return date.today() - relativedelta(days=days, months=months, years=years)
  73. else:
  74. error_msg = "The date {date} does not match the required YYYY-MM-DD format or the offset format."
  75. raise ValueError(error_msg.format(date=date_arg))