예제 #1
0
 def get_parent_video(self):
     from cave.libcave.video import Video  #need to keep this here to avoid circular import...
     vids = Video.get_all(filter_str="WHERE id=%d" % self.vid)
     if len(vids) != 1:
         self.log.error("ERROR: invalid parent video")
         return None
     else:
         return vids[0]
예제 #2
0
            def add_hash():
                SqlClass.turn_off_commits()
                videos = Video.get_all()
                tags = [video.get_tags() for video in videos]
                # We need to get all the frame info before
                # we erase the video table!
                for tag_ls in tags:
                    for tag in tag_ls:
                        tag._populate_frame_dict()

                for video in videos:
                    if not video.present():
                        self.log.error(
                            "Not all videos are present, cannot upgrade database!"
                        )
                        return False

                [video.remove() for video in videos]
                Video.remove_table()
                Video.table_setup()
                for i, video in enumerate(videos):
                    video.video_hash = \
                      hash_video(self.get_absolute_path(video.video_path))
                    Video.add(video)
                    for tag in tags[i]:
                        self.log.info("Adding tag %s in video %s" %
                                      (tag, video.video_path))
                        Tag.tag_add(tag)

                SqlClass.turn_on_commits()
                self.conn.commit()
                return True
예제 #3
0
 def addVideo(self, vidName, camera, vidPath, logPath=None, meta=""):
     vid_hash = hash_video(vidPath)
     # uncertain what meta is, so I'm ignoring for now
     vid = Video.new(name=vidName,
                     meta=meta,
                     linked_camera=camera,
                     video_hash=vid_hash,
                     video_path=vidPath,
                     log_path=logPath)
예제 #4
0
    def populate_info(self):
        self.total_frames = 0
        for vid in Video.get_all():
            tgs = vid.get_tags()
            for tag in tgs:
                if tag.active:
                    frame_list = tag.get_frame_list()[::self.skip_value]
                    self.total_frames += len(frame_list)

        print("Frames to process: %d" % self.total_frames)
예제 #5
0
    def redraw(self, filter_str=""):
        #TODO: Sort by creation time
        #TODO: Do some hierarchical organization (by day)

        red_fmt = "<span background='red'>%s</span>"
        treestore = Gtk.TreeStore(object, str, str, str, bool)
        vds = Video.get_all(filter_str)
        if self.videofinder is None:
            self.missing_hashes = {}
        for v in vds:
            if not v.present():
                if hasattr(v, "video_hash"):
                    if self.videofinder is None or not self.done_searching:
                        fmt = red_fmt % "%s [MISSING - Searching...]"
                        if self.videofinder is None:
                            self.missing_hashes[v.video_hash] = v
                    else:
                        fmt = red_fmt % "%s [MISSING - Not found.]"

                else:
                    self.log.warning( \
                  "Video %s is missing but has no hash; won't search" % v)
                    fmt = red_fmt % "%s [MISSING - No Hash.]"

            else:
                fmt = "%s"

            rowparent = treestore.append(None, \
         (v, fmt % v.video_path, "", "", any([t.active for t in v.get_tags()])))
            for t in v.get_tags():
                if len(t.test_pos) > 0 or len(t.test_neg) > 0:
                    accuracy = "%.1f%%" % \
        (float(len(t.test_pos)) / (len(t.test_pos) + len(t.test_neg)) * 100)

                else:
                    accuracy = ""

                treestore.append(rowparent, \
                   (t, t.mission_element, t.tag_type, accuracy, t.active))

        # Spawn a search for the missing videos.
        if self.videofinder is None and len(self.missing_hashes):
            self.videofinder = VideoFinder(self.parent.db.root_dir, \
                                           self.missing_found)
            map(self.videofinder.request_search, self.missing_hashes.keys())
            self.done_searching = False
            self.videofinder.start()

        self.treestore = treestore
        self.tree.set_model(treestore)
        self.tree.expand_all()
예제 #6
0
    def populate_info(self):
        self.info_text = self.builder.get_object("infoText")

        self.total_frames = 0

        for vid in Video.get_all():
            tgs = vid.get_tags()
            for tag in tgs:
                if tag.active:
                    frame_list = list(tag.get_frame_list())[::self.skip_value]
                    self.total_frames += len(frame_list)

        self.info_text.set_text("Frames to process: %d" % self.total_frames)

        start_enabled = self.total_frames > 0
        self.builder.get_object("startButton").set_sensitive(start_enabled)
        self.builder.get_object("trainButton").set_sensitive(start_enabled)
예제 #7
0
    def database_add_callback(self, av):
        self.logger.debug("Callback executed")

        if av.log_filename is None:
            log_path = ""
        else:
            log_path = self.db.get_relative_path(av.log_filename)

        vid_path = self.db.get_relative_path(av.video_filename)
        if vid_path is None:
            return

        self.logger.info("Hashing video \"%s\"..." % av.video_filename)

        vid = Video.new(name=av.video_name,
                        video_path=vid_path,
                        log_path=log_path,
                        linked_camera=av.linked_camera,
                        meta=av.meta,
                        video_hash=hash_video(av.video_filename))
        self.logger.info("Added video \"%s\" to database (id #%d)" %
                         (vid.name, vid.id))
        self.statusbar.display("Added video \"%s\"" % vid.name, 3)
        self.video_tree_manager.redraw()
예제 #8
0
    def get_frames(self, vision_enable=True):
        melements = get_registered_elements()
        frame_count = 0

        for vid in Video.get_all():
            tgs = vid.get_tags()
            if len(tgs) > 0:
                self.log.info("Loading video id %d" % vid.id)
                #if(self.parent != None):
                #    self.parent.video_box.load_video(vid)
                # XXX The below sleep was added to prevent a "Bus Error"
                # XXX when running a test with a lot of disabled tags - Alex S.
                # TODO FIX
                sleep(0.1)

            for tag in filter(lambda t: t.active, tgs):
                frame_list = tag.get_frame_list()[::self.skip]
                if len(frame_list) > 0:
                    #Carry out testing on this tag
                    self.log.info("Testing tag #%d (%d frames)" %
                                  (tag.id, len(frame_list)))
                    frame_list.sort()
                    tag.clear_test_results()
                    if vision_enable:
                        if not melements.has_key(tag.mission_element):
                            self.log.warning(
                                "Skipping tag %s; not a mission element." %
                                tag.mission_element)
                            continue

                        m_element = melements[tag.mission_element]()
                        m_element.init(
                        )  #Turn on vision for this mission element

                    for frame in frame_list:
                        #The test of the frame
                        if vision_enable:
                            yield frame, tag, m_element
                        else:
                            yield frame, tag

                        frame_count += 1
                        self.status_callback(frame_count)

                        if self.has_aborted():
                            break

                    if vision_enable:
                        m_element.deinit(
                        )  #Turn off vision for this mission element

                    self.log.info("Waiting for module shutdown")
                    sleep(
                        1
                    )  # We sleep here because vision will reset the enabled flag if vision is stopped and started too qucikly
                    # This happens if we immediately stop and start the same vision module
                    # TODO: Refactor to fix this (or fix this behavior in vision)
                    # Testing could potentially time out if a vision module does not shut down within
                    # this period
                if self.has_aborted():
                    break
            if self.has_aborted():
                break
예제 #9
0
    def __init__(self, filename):
        if filename is None:
            self.log.warning("Invalid database filename specified")
            self.error = True
            return None

        try:
            self.conn = sqlite3.connect(filename, check_same_thread=False, \
                                                  isolation_level="EXCLUSIVE")
        except sqlite3.OperationalError:
            self.log.error("Failed to open database file: %s" % filename)
            self.error = True
            return None

        self.conn.row_factory = sqlite3.Row  #return rows objects instead of raw tuples
        self.c = self.conn.cursor()

        self.c.execute("PRAGMA synchronous = 0")
        self.c.execute("PRAGMA journal_mode = OFF")

        self.filename = os.path.abspath(filename)
        self.root_dir = os.path.dirname(self.filename)

        DBInfo.link_sqlite(self)
        Video.link_sqlite(self)
        Tag.link_sqlite(self)

        ### Upgrade functionality
        db_version = DBInfo.get_version()
        if db_version > DATABASE_VERSION:
            self.log.error(
                "Are you trying to provide a database file from the future? Why would you do that? (provided database version %d; expected <= %d)"
                % (db_version, DATABASE_VERSION))
            self.error = True
            return None

        if db_version != DATABASE_VERSION:
            self.log.warning(
                "Old database version (database is version %d and most recent is version %d)"
                % (db_version, DATABASE_VERSION))

            backup_filename = "cave_upgrade_backup"
            self.log.info("Creating database backup at %s" % backup_filename)
            shutil.copy2(filename, backup_filename)

            #Methods provided to upgrade an old database version to the newest version
            #Running update_functions[i] must upgrade a database of version i-1 to version i.
            #An upgrade function should be provided whenever the DATABASE_VERSION is updated to
            #ensure old versions are still compatible
            upgrade_functions = {}

            def add_hash():
                SqlClass.turn_off_commits()
                videos = Video.get_all()
                tags = [video.get_tags() for video in videos]
                # We need to get all the frame info before
                # we erase the video table!
                for tag_ls in tags:
                    for tag in tag_ls:
                        tag._populate_frame_dict()

                for video in videos:
                    if not video.present():
                        self.log.error(
                            "Not all videos are present, cannot upgrade database!"
                        )
                        return False

                [video.remove() for video in videos]
                Video.remove_table()
                Video.table_setup()
                for i, video in enumerate(videos):
                    video.video_hash = \
                      hash_video(self.get_absolute_path(video.video_path))
                    Video.add(video)
                    for tag in tags[i]:
                        self.log.info("Adding tag %s in video %s" %
                                      (tag, video.video_path))
                        Tag.tag_add(tag)

                SqlClass.turn_on_commits()
                self.conn.commit()
                return True

            upgrade_functions[2] = add_hash

            while db_version < DATABASE_VERSION:
                i = db_version + 1
                if i not in upgrade_functions.keys():
                    self.error = True
                    self.log.error(
                        "Unable to upgrade database to version %d: No upgrade functionality provided."
                        % i)
                    return None
                self.log.info("Upgrading database from version %d to %d" \
                              % (db_version, i))
                try:
                    success = upgrade_functions[i]()
                except Exception as e:
                    traceback.print_exc()
                    success = False

                if success:
                    DBInfo.set_version(i)
                    db_version = i
                else:
                    self.log.error("Upgrading database failed.")
                    shutil.copy2(backup_filename, filename)
                    os.remove(backup_filename)
                    break
        ###

        self.log.info("Database linked to %s" % filename)
        self.error = False