Exemplo n.º 1
0
 def modify(self, daterange):
     if isinstance(daterange, DaterangeAtom):
         by_days = daterange.split(u'days')
         if self.direction == 1:
             return [(day[0] + self.modification, utils.end_of_day(day[0])) for day in by_days]
         elif self.direction == -1:
             return [(day[0], day[0]+self.modification) for day in by_days]
     else:
         raise ValueError(u'daterange must be a subclass of DaterangeAtom')
Exemplo n.º 2
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.')
Exemplo n.º 3
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 determine_home_work_places(user_id, nb_days=3, hour_threshold=3):
    home_hours = [(0, 7), (20, 23)]
    work_hours = [(9, 18)]
    home_threshold = 60 * 60 * hour_threshold * nb_days  # 4 hour threshold default
    work_threshold = 0

    places = {}

    # get all the days
    # compute the unique places visited and the time spend at these places
    days = []
    day = utils.previous_day(utils.today_string())
    for i in range(nb_days):
        days.append(day)
        day = utils.previous_day(day)

    for day in days:
        weekend = utils.is_weekend(day)
        visits = user_traces_db.load_user_visits_utc(user_id, day)

        if len(visits) == 0:
            return None, None

        if not weekend:
            work_threshold += 60 * 60 * hour_threshold

        # fix the last visit
        last_visit = visits[-1]
        utc_offset = last_visit['d_utc']

        if not utc_offset:
            return None, None

        last_visit_end = last_visit['d'] - utc_offset  # departure_utc - utc_offset
        last_visit_end = utils.end_of_day(last_visit_end)
        visits[-1]['d'] = last_visit_end + utc_offset

        for visit in visits:
            start = max(utils.start_of_day_str(day), visit['a'] - visit['d_utc'])  # arrival_utc and utc_offset
            end = visit['d'] - visit['d_utc']  # departure_utc and utc_offset
            place_id = visit['pid']

            # place = user_traces_db.load_user_place(user_id, place_id)
            # print("%s [%s %s -> %s %s] %s" % (day, utils.timestamp_to_day_str(start), utils.hm(start), utils.timestamp_to_day_str(end), utils.hm(end), place['name']))

            work_seconds = 0
            if not weekend:
                work_seconds = utils.seconds_in_hour_range(start, end, work_hours)
            home_seconds = utils.seconds_in_hour_range(start, end, home_hours)
            if place_id not in places:
                places[place_id] = [0, 0]
            places[place_id] = map(add, places[place_id], [home_seconds, work_seconds])

    new_places = {}
    for pid, p in places.items():
        new_places[pid] = list(p)

    # Determine the work and home places
    home_place = None
    home_places = [(pid, p[0]) for pid, p in new_places.items() if p[0] > home_threshold]
    if len(home_places):
        home_place = max(home_places, key=lambda x: x[1])

    # can have multiple work locations
    work_places = [pid for pid, p in new_places.items() if p[1] > work_threshold]

    return home_place[0] if home_place else None, work_places