Ejemplo n.º 1
0
    def _create_file_and_symlinks(self, begin, end, cam_id, extension=''):
        begin_dt = to_datetime(begin)
        end_dt = to_datetime(end)

        def spans_multiple_directories(first_ts, end_dt):
            return self._path_for_dt(first_ts) != \
                self._path_for_dt(end_dt)

        fname = self._get_filename(begin_dt, end_dt, cam_id, extension)
        _mkdir_p(os.path.dirname(fname))
        if not os.path.exists(fname):
            open(fname, 'a').close()
        iter_ts = end
        symlinks = []
        while spans_multiple_directories(begin_dt, iter_ts):
            path = self._path_for_dt(iter_ts)
            link_fname = self._get_filename(begin_dt, end, cam_id, extension,
                                            path)
            symlinks.append(link_fname)
            link_dir = os.path.dirname(link_fname)
            _mkdir_p(link_dir)
            rel_goal = os.path.relpath(fname, start=link_dir)
            os.symlink(rel_goal, link_fname)
            iter_path = self._step_one_directory(iter_ts, 'backward')
            iter_ts = self._get_time_from_path(iter_path)
        return fname, symlinks
Ejemplo n.º 2
0
    def find_by_ts(self, ts, cam_id=None):
        """Return all video file paths that belong to the `ts`.

        Args:
            ts (datetime): timestamp to search for.
            cam_id (int): camera id to search for.

        Returns:
            list(string): paths of video files.
        """
        # TODO(gitmirgut): Check if 20min is to big and if its also needed for time near 23:59..
        dt = bbb_p.to_datetime(ts)
        paths = self._paths_for_dt_cam(dt, cam_id, abs=True)

        # check if time is near 0 hour, to get paths from the day before.
        time_delta = datetime.timedelta(minutes=20)
        shift_time = dt - time_delta
        if shift_time.day != dt.day:
            # TODO(gitmirgut): Change it to append.
            paths = paths + self._paths_for_dt_cam(shift_time, cam_id, abs=True)
        video_paths = []
        for path in paths:
            fnames = self._all_videos_in(path)
            fname_parts = [(f, bbb_p.parse_video_fname(f)) for f in fnames]
            for fname, (camId, begin, end) in fname_parts:
                if begin <= dt < end:
                    video_paths.append(os.path.join(path, fname))
                    # TODO(gitmirgut): insert breake
        return video_paths
Ejemplo n.º 3
0
    def find_closest_videos(self, ts, cam_id, abs=False):
        """Return closest videos to the given timestamp.

        If the timestamp is contained in a video interval, then the returned list consists only of
        this video. If the timestamp is outside of video intervals, the list contains two videos,
        which are around that timestamp.

        Args:
            ts (datetime): timestamp to search for.
            cam_id (int): camera id to search for.

        Returns:
            list(string): paths of video files.
        """
        # TODO(gitmirgut): Check if 20min is to big and if its also needed for time near 23:59..
        dt = bbb_p.to_datetime(ts)

        paths = [self._path_for_dt_cam(dt, cam_id, abs=True)]

        # check if time is near 0 hour, to get paths from the day before.
        time_delta = datetime.timedelta(minutes=20)
        shift_time = dt - time_delta
        print('time')
        print(dt)
        print(shift_time)
        if shift_time.day != dt.day:
            paths.append(self._path_for_dt_cam(shift_time, cam_id, abs))

        shift_time = dt + time_delta
        if shift_time.day != dt.day:
            paths.append(self._path_for_dt_cam(shift_time, cam_id, abs))

        paths.sort()
        prev = None
        succ = None
        for path in paths:
            fnames = self._all_videos_in(path)
            fnames.sort()
            fnames_parts = [(f, bbb_p.parse_video_fname(f)) for f in fnames]
            for fname, (camId, begin, end) in fnames_parts:
                if begin <= ts < end:
                    ret = fname
                    if abs:
                        return [os.path.join(path, ret)]
                    else:
                        return [ret]
                elif end < ts:
                    prev = fname
                elif ts < begin:
                    succ = fname
                    if abs:
                        return [os.path.join(path, prev), os.path.join(path, succ)]
                    else:
                        return [prev, succ]
Ejemplo n.º 4
0
 def _path_for_dt(self, time, abs=False):
     dt = to_datetime(time)
     minutes = int(
         math.floor(dt.minute / self.minute_step) * self.minute_step)
     values = (dt.year, dt.month, dt.day, dt.hour, minutes)
     format_parts = list(
         map(lambda t: t[0].format(t[1]), zip(self._DIR_FORMAT_PARTS,
                                              values)))
     if abs:
         return self._join_with_repo_dir(*format_parts)
     else:
         return os.path.join(*format_parts)
Ejemplo n.º 5
0
    def _step_one_directory(self, path, direction='forward'):
        if type(path) == str:
            dt = self._get_time_from_path(path)
        else:
            dt = to_datetime(path)

        offset = timedelta(minutes=self.minute_step)
        if direction == 'forward':
            dt += offset
        elif direction == 'backward':
            dt -= offset
        else:
            raise ValueError("Unknown direction {}.".format(direction))
        return self._path_for_dt(dt)
Ejemplo n.º 6
0
 def find(self, ts, cam=None):
     """
     Returns all files that includes detections to the given timestamp `ts`.
     TODO: UTC timestamps! Generall
     """
     dt = to_datetime(ts)
     path = self._path_for_dt(dt)
     if not os.path.exists(self._join_with_repo_dir(path)):
         return []
     fnames = self._all_files_in(path)
     fnames_parts = [(f, self._parse_repo_fname(f)) for f in fnames]
     if cam is not None:
         fnames_parts = list(
             filter(lambda f, p: p[CAM_IDX] == cam, fnames_parts))
     found_files = []
     for fname, (camId, begin, end) in fnames_parts:
         if begin <= dt < end:
             found_files.append(self._join_with_repo_dir(path, fname))
     return found_files
Ejemplo n.º 7
0
    def _path_for_dt_cam(self, ts, cam_id, abs=False):
        """Return the directory path of videos to the given timestamp.

        Args:
            ts (datetime): Timestamp to search for.
            cam_id (int): Camera id to search for.
            abs (bool): If *True* returns the absolute path to the directory.

        Returns:
            string: path of the directory
        """
        dt = bbb_p.to_datetime(ts)
        if cam_id not in self.valid_cam_ids:
            raise ValueError("Unknown camera id {cam_id}.".format(cam_id=cam_id))
        # TODO(gitmirgut) is this possible for videos of 2015? Mabye the day folders are in Berlin
        # style and not in ISO8601 style
        format = self.dir_format.format(dt=dt, cam_id=cam_id)
        if abs:
            return os.path.join(self.root_dir, format)
        else:
            return format
Ejemplo n.º 8
0
    def iter_fnames(self, begin=None, end=None, cam=None):
        """
        Returns a generator that yields filenames in sorted order.
        From `begin` to `end`.

        Args:
            begin (Optional timestamp): The first filename contains at least one frame with a
                timestamp greater or equal to `begin`. If `begin` is not set, it will
                start with the earliest file.
            end (Optional timestamp): The last filename contains at least one
                frame with a timestamp smaller then `end`.
                If not set, it will continue until the last file.
            cam (Optional int): Only yield filenames with this cam id.

        Example:

        .. code::

            Files:        A     B     C        D     E
            Frames:    |-----|-----|-----|  |-----|-----|
                            ⬆          ⬆
                          begin       end

        This should return the files A, B and C.
        If `begin` and `end` are `None`, then all will be yield.
        """
        def remove_links(directory, fnames):
            assert os.path.isdir(directory)
            assert os.path.isabs(directory)
            return list(
                filter(
                    lambda f: not os.path.islink(os.path.join(directory, f)),
                    fnames))

        if begin is None:
            current_path = self._get_earliest_path()
            begin = pytz.utc.localize(datetime.min)

        else:
            begin = to_datetime(begin)
            current_path = self._path_for_dt(begin, abs=True)

        # if the repository is empty, current_path is the root_dir
        if current_path == self.root_dir:
            return

        if end is None:
            end_dir = self._get_latest_path()
            end = pytz.utc.localize(datetime.max)
        else:
            end = to_datetime(end)
            end_dir = self._path_for_dt(end, abs=True)

        iter_range = TimeInterval(begin, end)
        first_directory = True
        while True:
            fnames = self._all_files_in(current_path)
            if not first_directory:
                fnames = remove_links(current_path, fnames)
            else:
                first_directory = False

            parsed_fname = [self._parse_repo_fname(f) for f in fnames]
            cam_id_begin_end_fnames = [
                (c, b, e, f) for (c, b, e), f in zip(parsed_fname, fnames)
            ]
            if cam is not None:
                cam_id_begin_end_fnames = list(
                    filter(lambda p: p[CAM_IDX] == cam,
                           cam_id_begin_end_fnames))

            cam_id_begin_end_fnames.sort(key=lambda p: p[BEGIN_IDX])
            for cam_idx, begin_ts, end_ts, fname in cam_id_begin_end_fnames:
                if iter_range.in_interval(begin_ts) or iter_range.in_interval(
                        end_ts):
                    yield self._join_with_repo_dir(current_path, fname)

            if end_dir == current_path:
                break
            else:
                current_path = self._step_to_next_directory(
                    current_path, direction='forward')
                current_path = self._join_with_repo_dir(current_path)