def to_hour_tex(self, tz, script, reference_date=None): if self.jd_start is not None: start_time = '~%s' % default_if_none(tz.julian_day_to_local_time(julian_day=self.jd_start).get_hour_str(reference_date=reference_date), "") else: start_time = '' if self.jd_end is not None: end_time = '%s' % default_if_none(tz.julian_day_to_local_time(julian_day=self.jd_end).get_hour_str(reference_date=reference_date), "") else: end_time = '' return "%s\\RIGHTarrow{}%s" % (start_time, end_time)
def __repr__(self): from jyotisha.panchaanga.temporal import time return "%s: (%s, %s)" % ( default_if_none(self.name, "?"), default_if_none( time.ist_timezone.julian_day_to_local_time_str( jd=self.jd_start), "?"), default_if_none( time.ist_timezone.julian_day_to_local_time_str(jd=self.jd_end), "?"))
def to_hour_text(self, tz, script=sanscript.ISO, reference_date=None): if self.jd_start is not None: start_time = '%s' % default_if_none(tz.julian_day_to_local_time(julian_day=self.jd_start).get_hour_str(reference_date=reference_date), "") else: start_time = '' if self.jd_end is not None: end_time = '%s' % default_if_none(tz.julian_day_to_local_time(julian_day=self.jd_end).get_hour_str(reference_date=reference_date), "") else: end_time = '' hour_text = "%s►%s" % (start_time, end_time) return sanscript.transliterate(hour_text, _from=sanscript.ISO, _to=script)
def to_hour_md(self, tz, script, reference_date=None): name = names.translate_or_transliterate( text=self.name, source_script=xsanscript.DEVANAGARI, script=script) return "**%s**—%s-%s" % ( name, default_if_none( tz.julian_day_to_local_time( julian_day=self.jd_start).get_hour_str( reference_date=reference_date), "?"), default_if_none( tz.julian_day_to_local_time( julian_day=self.jd_end).get_hour_str( reference_date=reference_date), "?"))
def find(self, jd1: float, jd2: float, target_anga_id: int) -> Optional[Interval]: """Computes anga spans for sunrise_day_angas such as tithi, nakshatra, yoga and karana. Args: :param jd1: return the first span that starts after this date :param jd2: return the first span that ends before this date Returns: None if target_anga_id was not found Interval, with boundary jds None if they don't occur within [jd1, jd2] """ if isinstance(target_anga_id, Number): # TODO: Remove this backward compatibility fix target_anga = Anga.get_cached(index=target_anga_id, anga_type_id=self.anga_type.name) else: target_anga = target_anga_id anga_interval = AngaSpan(jd_start=None, jd_end=None, anga=target_anga) anga_interval.jd_start = self.find_anga_start_between( jd1=jd1, jd2=jd2, target_anga=target_anga) next_anga = target_anga + 1 anga_interval.jd_end = self.find_anga_start_between( jd1=default_if_none(anga_interval.jd_start, jd1), jd2=jd2, target_anga=next_anga) if anga_interval.jd_start is None and anga_interval.jd_end is None: if self._get_anga(jd=jd1) != target_anga: return None return anga_interval
def __init__(self, city, start_date, end_date, computation_system: ComputationSystem = None): """Constructor for the panchaanga. """ super(Panchaanga, self).__init__() self.version = Panchaanga.LATEST_VERSION self.city = city self.start_date = Date(*([int(x) for x in start_date.split('-')])) if isinstance(start_date, str) else start_date self.start_date.set_time_to_day_start() self.end_date = Date(*([int(x) for x in end_date.split('-')])) if isinstance(end_date, str) else end_date self.end_date.set_time_to_day_start() self.computation_system = default_if_none(computation_system, ComputationSystem.DEFAULT) self.jd_start = time.utc_gregorian_to_jd(self.start_date) self.jd_end = time.utc_gregorian_to_jd(self.end_date) self.duration = int(self.jd_end - self.jd_start) + 1 # For accurate festival assignment, we sometimes need panchaanga information about succeeding or preceeding days. # For example, consider a festival to be selebrated during naxatra 27 in solar sideral month 9. If naxatra 27 occurs twice in sidereal_solar_month 9 (gap of 27+ daus), the latter occurence is to be selected - the former day will not get a festival. self.duration_posterior_padding = int(self.duration + 30) self.duration_prior_padding = 2 self.weekday_start = time.get_weekday(self.jd_start) self.festival_id_to_days = defaultdict(set, {}) self.compute_angas(compute_lagnas=self.computation_system.options.lagnas) if not self.computation_system.options.no_fests: self.update_festival_details()
def __init__(self, city: City, date: Date, computation_system=None, previous_day_panchaanga=None) -> None: """Constructor for the panchaanga. """ super(DailyPanchaanga, self).__init__() self.city = city self.date = date date.set_time_to_day_start() self.julian_day_start = Timezone( self.city.timezone).local_time_to_julian_day(date=self.date) self.computation_system = default_if_none(computation_system, ComputationSystem.DEFAULT) self.jd_sunrise = None self.jd_sunset = None self.jd_previous_sunset = None self.jd_next_sunrise = None self.jd_moonrise = None self.jd_moonset = None self.lagna_data = None self.sunrise_day_angas = None self.solar_sidereal_date_sunset = None self.tropical_date_sunset = None self.lunar_month_sunrise = None self.shraaddha_tithi = [] self.festival_id_to_instance = {} self.mauDhyas = None self.amauDhyas = None self.compute_sun_moon_transitions( previous_day_panchaanga=previous_day_panchaanga) self.compute_solar_day_sunset( previous_day_panchaanga=previous_day_panchaanga) self.set_tropical_date_sunset( previous_day_panchaanga=previous_day_panchaanga) self.day_length_based_periods = DayLengthBasedPeriods( jd_previous_sunset=self.jd_previous_sunset, jd_sunrise=self.jd_sunrise, jd_sunset=self.jd_sunset, jd_next_sunrise=self.jd_next_sunrise, weekday=self.date.get_weekday()) if self.computation_system.lunar_month_assigner_type is not None: lunar_month_assigner = LunarMonthAssigner.get_assigner( computation_system=self.computation_system) self.set_lunar_month_sunrise( month_assigner=lunar_month_assigner, previous_day_panchaanga=previous_day_panchaanga) self.set_mauDhyas()
def get_all_angas_in_period(self, jd1, jd2): spans = [] jd_start = None anga_now = self._get_anga(jd=jd1) while default_if_none(jd_start, jd1) <= jd2: next_anga = anga_now + 1 jd_end = self.find_anga_start_between(target_anga=next_anga, jd1=default_if_none( jd_start, jd1), jd2=jd2) spans.append( AngaSpan(jd_start=jd_start, jd_end=jd_end, anga=anga_now)) if jd_end is None: break else: anga_now = next_anga jd_start = jd_end return spans
def get_spans_in_period(self, jd_start, jd_end, target_anga_id): if jd_start > jd_end: raise ValueError((jd_start, jd_end)) jd_bracket_L = jd_start spans = [] while jd_bracket_L <= jd_end: # A whole period plus 4 angas beyond jd_bracket_L, which might be 2 angas behind the target anga. jd_bracket_R = min( jd_bracket_L + (1 + 4.0 / self.anga_type.num_angas) * self.anga_type.mean_period_days, jd_end) span = self.find(jd1=jd_bracket_L, jd2=jd_bracket_R, target_anga_id=target_anga_id) if span is None: break else: spans.append(span) # A whole period minus 2 angas as the next seek boundary jd_bracket_L = default_if_none( span.jd_start, jd_bracket_L) + self.anga_type.mean_period_days * ( 1 - 2.0 / self.anga_type.num_angas) return spans
def add_festival_events(day_index, ics_calendar, panchaanga, languages, scripts): daily_panchaanga = panchaanga.daily_panchaangas_sorted()[day_index] for festival_instance_in in sorted( daily_panchaanga.festival_id_to_instance.values()): festival_instance = deepcopy(festival_instance_in) fest_id = festival_instance.name all_day = False if festival_instance.interval is None: all_day = True elif default_if_none(festival_instance.interval.get_jd_length(), 0) > 0.75: all_day = True set_interval(daily_panchaanga, festival_instance) if fest_id.find('samApanam') != -1: # It's an ending event full_festival_instance = get_full_festival_instance( festival_instance=festival_instance, daily_panchaangas=panchaanga.daily_panchaangas_sorted(), day_index=day_index) if full_festival_instance is not None: event = festival_instance_to_event( festival_instance=full_festival_instance, languages=languages, scripts=scripts, panchaanga=panchaanga, all_day=True) ics_calendar.add_component(event) event = festival_instance_to_event(festival_instance=festival_instance, languages=languages, scripts=scripts, panchaanga=panchaanga, all_day=all_day) ics_calendar.add_component(event)
def __repr__(self): return "%s %s %s" % (self.name, str(default_if_none( self.ordinal, "")), str(default_if_none(self.interval, "")))
def get_description(festival_instance, fest_details_dict, script, truncate=True, header_md="#####"): fest_id = festival_instance.name.replace('/', ' or ') desc = None if re.match('aGgArakI.*saGkaTahara-caturthI-vratam', fest_id): fest_id = fest_id.replace('aGgArakI~', '') if fest_id in fest_details_dict: desc = fest_details_dict[fest_id].get_description_string( script=script, header_md=header_md) desc += 'When `caturthI` occurs on a Tuesday, it is known as `aGgArakI` and is even more sacred.' else: logging.warning('No description found for caturthI festival %s!' % fest_id) elif re.match('.*-.*-EkAdazI', fest_id) is not None: # Handle ekaadashii descriptions differently ekad = '-'.join( fest_id.split('-')[1:]) # get rid of sarva etc. prefix! ekad_suff_pos = ekad.find(' (') if ekad_suff_pos != -1: # ekad_suff = ekad[ekad_suff_pos + 1:-1] ekad = ekad[:ekad_suff_pos] if ekad in fest_details_dict: desc = fest_details_dict[ekad].get_description_string( script=script, include_url=True, include_shlokas=True, truncate=truncate, header_md=header_md) else: logging.warning( 'No description found for Ekadashi festival %s (%s)!' % (ekad, fest_id)) elif fest_id.find('saGkrAntiH') != -1: # Handle Sankranti descriptions differently planet_trans = fest_id.split('~')[0] # get rid of ~(rAshi name) etc. if planet_trans in fest_details_dict: desc = fest_details_dict[planet_trans].get_description_string( script=script, include_url=True, include_shlokas=True, truncate=truncate, header_md=header_md) else: logging.warning('No description found for festival %s!' % planet_trans) elif fest_id in fest_details_dict: desc = fest_details_dict[fest_id].get_description_string( script=script, include_url=True, include_shlokas=True, truncate=truncate, include_images=False, header_md=header_md) if desc is None: # Check approx. match matched_festivals = [] for fest_key in fest_details_dict: if fest_id.startswith(fest_key): matched_festivals += [fest_key] if matched_festivals == []: logging.warning('No description found for festival %s!' % fest_id) elif len(matched_festivals) > 1: logging.warning( 'No exact match found for festival %s! Found more than one approximate match: %s' % (fest_id, str(matched_festivals))) else: desc = fest_details_dict[ matched_festivals[0]].get_description_string( script=script, include_url=True, include_shlokas=True, truncate=True, header_md=header_md) return default_if_none(desc, "")
def describe_fest(rule, include_images, include_shlokas, include_url, is_brief, script, truncate, header_md="#####"): # Get the Blurb blurb = get_timing_summary(rule) # Get the URL description_string = get_description_str_with_shlokas(include_shlokas, rule, script) if include_images: if rule.image is not None: image_string = '![](https://github.com/jyotisham/adyatithi/blob/master/images/%s)\n\n' % rule.image # Now compose the description string based on the values of # include_url, include_images, is_brief if not is_brief: final_description_string = blurb else: final_description_string = '' final_description_string += description_string if include_images: final_description_string += image_string url = rule.get_url() if truncate: if len(final_description_string) > 450: # Truncate final_description_string = '\n\n%s Details\n- [Edit config file](%s)\n- Tags: %s\n\n' % (header_md, url, ' '.join(default_if_none(rule.tags, []))) if not is_brief: ref_list = get_references_md(rule) final_description_string += '\n\n%s Details\n%s- [Edit config file](%s)\n- Tags: %s\n\n' % (header_md, ref_list, url, ' '.join(default_if_none(rule.tags, []))) return final_description_string