def reconvertible_text(self): if self.direction == -1: start_text = (utils.start_of_day(datetime.datetime.utcnow()) + self.modification).strftime(u'%I:%M %p') return u'before {start_text}'.format(start_text=start_text) elif self.direction == 1: end_text = (utils.start_of_day(datetime.datetime.utcnow()) + self.modification).strftime(u'%I:%M %p') return u'after {end_text}'.format(end_text=end_text)
def parse_date_range(nltext, src_time): """ Takes a natural language representation of time range and returns datetime representation of time boundaries of this range. Returns None, if valid time range cannot be retrieved from the input. """ hrange = __analyze_range(nltext, src_time) src_time = utils.start_of_day(src_time) if hrange: end_date = hrange.starts + hrange.lasts if end_date <= src_time: start_date = hrange.starts + datetime.timedelta(days=7) hrange = __HandleableRange(start_date, hrange.lasts, hrange.handle_next) end_date = hrange.starts + hrange.lasts # See if a positional modifier is present. pos_mod = re.search(r'\b(next|\d+)\b', nltext, flags=re.X|re.I) pos_match = re.search(r'\b\d+\b', nltext, flags=re.X|re.I) pos_count = int(pos_match.group()) if pos_match else 1 if not pos_mod: start_date = hrange.starts if hrange.starts > src_time else src_time return (start_date, end_date) else: start_date = hrange.starts d = hrange.handle_next() d = d * pos_count start_date += d end_date += d start_date = start_date if start_date > src_time else src_time return (start_date, end_date) else: return None
def __from_match(self, match, src_time): """ Initialize the instance given a plaintext match string.""" # It's possible to match but not be parseable because our regex allows values with no meridian. # parsedatetime needs this however so we just append PM unless we know otherwise. append_meridien_match = self.EXTRACTION_REGEX.search(match) if append_meridien_match: if not append_meridien_match.groupdict().get(u'meridian'): match = match + " PM" seed_dt = utils.safe_parsedatetime_first_nlp(match, src_time).get(u'datetime') if seed_dt: direction = self.__find_direction(match) self.match = match if direction == 1: self.direction = 1 self.modification = seed_dt - utils.start_of_day(seed_dt) elif direction == -1: self.direction = -1 self.modification = seed_dt - utils.start_of_day(seed_dt) else: raise ValueError(u'AbsoluteOneWayInnerDayModifierAtom cannot parse and intialized from given match value = '\ + unicode(match))
def split(self, split_on=u'days'): """ Convenience function that allows a DateRange to be split into a list of single days.""" # Map split on string to a recurrence rule. split_on_rules = {u'days': rrule.DAILY, u'weeks': rrule.WEEKLY, u'months': rrule.MONTHLY} # If there is a valid rule return a split date range. rule = split_on_rules.get(split_on) if rule: splits = list(rrule.rrule(rule, count=((self.end - utils.start_of_day(self.start)).days), dtstart=self.start, until=self.end)) return [(s, utils.end_of_day(s)) for s in splits] else: raise ValueError(u'split_on value not supported.')
def __from_match(self, match, src_time, parse_type=u'range'): """ Initialize the instance given a plaintext match string.""" seed_dt = utils.safe_parsedatetime_first_nlp(match, src_time).get(u'datetime') if seed_dt: if parse_type == u'range': start = utils.start_of_day(seed_dt) end = utils.end_of_day(seed_dt) elif parse_type == u'exact': start = seed_dt end = seed_dt + datetime.timedelta(seconds=0) else: raise ValueError(u'Invalid value for parse_type. Try "range" or "exact"') # The special case in which an entire month is specified and not a specific date during it. if not re.search('[0-9]', match) and start.day == 1 and u'day' not in match: end = utils.end_of_month(seed_dt) DaterangeAtom.__init__(self, start, end, match, src_time) else: raise ValueError(u'CalendarDateRangeAtom cannot parse and intialized from given match value = '\ + unicode(match))
def __analyze_range(nltext, src_time): """ Takes a natural language representation of time range and maps it to proper Range object. Returns None, if valid time range cannot be retrieved from the input. """ # Construct the current reference time from the source time. if isinstance(src_time, datetime.datetime): src_time = utils.start_of_day(src_time) else: raise ValueError(u'Invalid `src_time`. Must be of time datetime.datetime') # Construct regex to find various range types. range_expr = r''' (?P<weekend>weekend)| (?P<week>week)| (?P<month>month)s?''' range_regex = re.compile(range_expr, flags=re.I|re.X) range_match = range_regex.search(nltext) # Return a __HandleableRange based on the match group type. if range_match: if range_match.group('weekend'): return __HandleableRange( __get_weekday_datetime(SATURDAY, src_time), datetime.timedelta(days=2), lambda: datetime.timedelta(days=7) ) elif range_match.group('week'): return __HandleableRange( __get_weekday_datetime(MONDAY, src_time), datetime.timedelta(days=5), lambda: datetime.timedelta(days=7) ) elif range_match.group('month'): return __HandleableRange( src_time.replace(day=1), relativedelta(months=1), lambda: relativedelta(months=1) ) else: return None
def process_trace_from_db(user_id, day, pool, logging): # get the raw points from the database raw_points = user_traces_db.load_raw_points(user_id, day) # get the last point from the previous day previous_day_raw_points = user_traces_db.load_raw_points(user_id, utils.previous_day(day)) if previous_day_raw_points: last_point = previous_day_raw_points[-1] # take the last raw point of the previous day utc_offset = last_point[3] - last_point[2] # time difference between the local and UTC times last_point[3] = utils.next_day_ts(utils.start_of_day(last_point[3])) last_point[2] = last_point[3] - utc_offset raw_points.insert(0, last_point) # extract the stays from the raw points logging.info("Extracting the stay points") s = extract_stays(raw_points) # generate the visits logging.info("Generating the visits") generate_visits(s, user_id, day, pool)
def reconvertible_text(self): start_time = utils.start_of_day(datetime.datetime.utcnow()) + self.modification[0] start_text = start_time.strftime(u'%I:%M %p') end_time = utils.start_of_day(datetime.datetime.utcnow()) + self.modification[1] end_text = end_time.strftime(u'%I:%M %p') return u'from {start_text} to {end_text}'.format(start_text=start_text, end_text=end_text)
def reconvertible_text(self): start_text = (utils.start_of_day(datetime.datetime.utcnow()) + self.modification).strftime(u'%I:%M %p') return u'at {start_text}'.format(start_text=start_text)