A library that computes the ephemerides.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

111 行
2.7 KiB

  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))