Esempio n. 1
0
 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
Esempio n. 3
0
 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))
Esempio n. 4
0
 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.')
Esempio n. 5
0
 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)
Esempio n. 8
0
 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)
Esempio n. 9
0
 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)