File indexing completed on 2023-09-24 04:00:55

0001 # SPDX-License-Identifier: LGPL-2.1-or-later
0002 #
0003 # SPDX-FileCopyrightText: 2012-2014 Rene Kuettner <rene@bitkanal.net>
0004 #
0005 
0006 from __future__ import print_function
0007 
0008 import time
0009 import calendar
0010 
0011 from lxml import etree
0012 from lxml.builder import ElementMaker
0013 
0014 
0015 class SpaceObject(object):
0016 
0017     DATE_FORMAT             = '%Y-%m-%d %H:%M'
0018 
0019     # object catagories 
0020     CATEGORY_SPACECRAFTS    = "Spacecrafts"
0021     CATEGORY_SPACEPROBES    = "Spaceprobes"
0022     CATEGORY_MOONS          = "Moons"
0023 
0024     # body constants
0025     BODY_MERCUR             = "Mercur"
0026     BODY_VENUS              = "Venus"
0027     BODY_EARTH              = "Earth"
0028     BODY_MARS               = "Mars"
0029     BODY_JUPITER            = "Jupiter"
0030     BODY_SATURN             = "Saturn"
0031     BODY_URANUS             = "Uranus"
0032     BODY_NEPTUN             = "Neptun"
0033     BODY_MOON               = "Moon"
0034 
0035     def __init__(self, **kwargs):
0036         super(SpaceObject, self).__init__()
0037         self._data_source = None
0038         self._filename_prefix = None
0039         self._name = None
0040         self._category = None
0041         self._related_body = None
0042         self._mission_start = None
0043         self._mission_end = None
0044         self._data_from = None
0045         self._data_until = None
0046         self._data_interval_days = 31
0047         for prop in kwargs.keys():
0048             if hasattr(self, prop):
0049                 setattr(self, prop, kwargs[prop])
0050 
0051     @property
0052     def data_source(self):
0053         return self._data_source
0054 
0055     @property
0056     def filename_prefix(self):
0057         if self._filename_prefix is None:
0058             # let's hope this is valid:
0059             return self.name.replace(' ', '_').lower()
0060         return self._filename_prefix
0061 
0062     @filename_prefix.setter
0063     def filename_prefix(self, value):
0064         self._filename_prefix = str(value)
0065 
0066     @property
0067     def name(self):
0068         return self._name
0069 
0070     @name.setter
0071     def name(self, value):
0072         self._name = str(value)
0073 
0074     @property
0075     def category(self):
0076         return self._category
0077 
0078     @category.setter
0079     def category(self, value):
0080         self._category = str(value)
0081 
0082     @property
0083     def related_body(self):
0084         return self._related_body
0085 
0086     @related_body.setter
0087     def related_body(self, value):
0088         self._related_body = str(value)
0089 
0090     @property
0091     def mission_start(self):
0092         return self._mission_start
0093 
0094     @mission_start.setter
0095     def mission_start(self, value):
0096         t = time.strptime(value, self.DATE_FORMAT)
0097         self._mission_start = calendar.timegm(t)
0098 
0099     @property
0100     def mission_end(self):
0101         return self._mission_end
0102 
0103     @mission_end.setter
0104     def mission_end(self, value):
0105         t = time.strptime(value, self.DATE_FORMAT)
0106         self._mission_end = calendar.timegm(t)
0107 
0108     @property
0109     def data_from(self):
0110         if self._data_from is None:
0111            if self.mission_start is None:
0112                return time.time() - (time.time() % (3600*24)) + 1
0113            else:
0114                return self.mission_start + (24*3600)
0115         return self._data_from
0116 
0117     @data_from.setter
0118     def data_from(self, value):
0119         t = time.strptime(value, self.DATE_FORMAT)
0120         self._data_from = calendar.timegm(t)
0121 
0122     @property
0123     def data_until(self):
0124         if self._data_until is None:
0125             if self.mission_end is None:
0126                 return time.time()
0127             else:
0128                 return self.mission_end - (24*3600)
0129         return self._data_until
0130 
0131     @data_until.setter
0132     def data_until(self, value):
0133         t = time.strptime(value, self.DATE_FORMAT)
0134         self._data_until = calendar.timegm(t)
0135 
0136     @property
0137     def data_for_day(self):
0138         return self.data_until - (self.data_until % (3600*24)) + 1
0139 
0140     @data_for_day.setter
0141     def data_for_day(self, value):
0142         tm = time.strptime(value, self.DATE_FORMAT)
0143         t = calendar.timegm(tm)
0144         self._data_from = t
0145         self._data_until = t + 60
0146 
0147     @property
0148     def data_interval_days(self):
0149         return self._data_interval_days
0150 
0151     @data_interval_days.setter
0152     def data_interval_days(self, value):
0153         self._data_interval_days = int(value)
0154 
0155 
0156 class TASCSpaceObject(SpaceObject):
0157 
0158     def __init__(self, **kwargs):
0159         super(TASCSpaceObject, self).__init__(**kwargs)
0160         self._tasc_mission = None
0161 
0162     @property
0163     def tasc_mission(self):
0164         if self._tasc_mission is None:
0165             return self.name
0166         return self._tasc_mission
0167 
0168     @tasc_mission.setter
0169     def tasc_mission(self, value):
0170         self._tasc_mission = value
0171 
0172 
0173 class HorizonsSpaceObject(SpaceObject):
0174 
0175     def __init__(self, **kwargs):
0176         super(HorizonsSpaceObject, self).__init__(**kwargs)
0177         self._horizons_id = None
0178 
0179     @property
0180     def horizons_id(self):
0181         if self._horizons_id is None:
0182             return self.name
0183         return self._horizons_id
0184 
0185     @horizons_id.setter
0186     def horizons_id(self, value):
0187         self._horizons_id = value
0188 
0189 
0190 class SpaceObjectCatalog(object):
0191 
0192     def __init__(self, filename, baseURL):
0193         super(SpaceObjectCatalog, self).__init__()
0194         self._filename = filename;
0195         self._baseURL = baseURL
0196         self._file = None
0197         self._open()
0198         self._initXML();
0199 
0200     def __del__(self):
0201         self._close()
0202 
0203     def add(self, space_obj, latest_vector):
0204         #url  = self._baseURL + "/" + space_obj.filename_prefix + '.txt'
0205         #icon = self._baseURL + "/" + space_obj.filename_prefix + '.png'
0206         satellite = self._E.satellite(
0207             self._E.name(space_obj.name),
0208             self._E.category(space_obj._category),
0209             self._E.relatedBody(space_obj.related_body),
0210             self._E.stateVector(
0211                 self._E.position(
0212                     x=str(latest_vector[1]),
0213                     y=str(latest_vector[2]),
0214                     z=str(latest_vector[3])
0215                 ),
0216                 self._E.velocity(
0217                     x=str(latest_vector[4]),
0218                     y=str(latest_vector[5]),
0219                     z=str(latest_vector[6])
0220                 ),
0221             mjd=str(latest_vector[0])
0222             ),
0223             #allvectors=url,
0224             #icon=icon,
0225         )
0226         mission = self._E.mission()
0227         if space_obj.mission_start is not None:
0228             mission.append(self._E.start(str(space_obj.mission_start)))
0229         if space_obj.mission_end is not None:
0230             mission.append(self._E.end(str(space_obj.mission_end)))
0231         if len(mission):
0232             satellite.append(mission)
0233         self._xml.append(satellite)
0234         print(space_obj.name + " added to object catalog.")
0235 
0236     def write(self):
0237         print("Writing catalog to file: " + self._filename)
0238         self._file.write(etree.tostring(self._xml,
0239                                         pretty_print=True,
0240                                         xml_declaration=True,
0241                                         encoding='utf-8'))
0242 
0243     def _initXML(self):
0244         self._E = ElementMaker(
0245             namespace="http://marble.kde.org/satellitecatalog",
0246             nsmap={'msc' : "http://marble.kde.org/satellitecatalog"})
0247         self._xml = self._E.MarbleSatelliteCatalog()
0248 
0249     def _open(self):
0250         self._file = open(self._filename, 'w+')
0251         self._file.truncate()
0252 
0253     def _close(self):
0254         self._file.close()