Esempio n. 1
0
    def get(self):
        numDeleted = 0
        try:
            # Look for CameraEvents marked deleted
            q = CameraEvent.all()
            q.filter("deleted =",True)
            for event in q.fetch(10):
                # Delete any frames belonging to this deleted CameraSource.
                q2 = CameraFrame.all()
                q2.filter("event_id =", event.key())
                if q2.count() > 0:
                    for frame in q2.fetch(500):
                        frame.delete()
                        numDeleted += 1
                else:
                    # No more frames belonging to this event, so delete it too.
                    event.delete()
                    numDeleted += 1

            # Look for CameraSources marked deleted
            q = CameraSource.all()
            q.filter("deleted =",True)
            for cam in q.fetch(10):
                # Mark any events belonging to this deleted CameraSource as deleted.
                q2 = CameraEvent.all()
                q2.filter("camera_id =", cam.key()).filter("deleted =",False)
                for event in q2.fetch(100):
                    numDeleted += 1
                    event.deleted = True
                    event.put()

                # Delete any frames belonging to this deleted CameraSource.
                q2 = CameraFrame.all()
                q2.filter("camera_id =", cam.key())
                for frame in q2.fetch(500):
                    frame.delete()
                    numDeleted += 1

                # Only delete the camera itself if nothing else needed to be done.
                if numDeleted == 0:
                    cam.delete()
                    numDeleted += 1

        except DeadlineExceededError:
            pass

        self.response.headers['Content-Type'] = 'text/plain'
        self.response.out.write("Deleted %d objects." % numDeleted)
Esempio n. 2
0
    def get(self):
        keyname = self.request.get('event')
        if keyname is None:
            self.error(500)
            self.response.out.write("missing event")
            return

        event = CameraEvent.get(db.Key(keyname))
        if event is None or event.deleted == True:
            self.error(404)
            self.response.out.write("unknown event")
            return
            
        if not event.viewed:
            event.viewed = True
            event.put()

        q2 = CameraFrame.all()
        #q2.filter("event_id =", event.key()).order("image_time")
        q2.filter("camera_id =", event.camera_id).filter("image_time >=", event.event_start).filter("image_time <=", event.event_end).order("image_time")

        template_values = {
            'user': users.get_current_user(),
            'logout_url': users.create_logout_url('/'),
            'event': event,
            'framelist': q2.fetch(100),
            'timenow': datetime.utcnow(),
            }

        path = os.path.join(os.path.dirname(__file__), 'inc/imgseq.html')
        self.response.out.write(template.render(path, template_values))
Esempio n. 3
0
    def post(self):
        keyname = self.request.get('event')
        if keyname is not None:
            event = CameraEvent.get(db.Key(keyname))
            event.deleted = True
            event.put()

        self.response.out.write("deleted")
Esempio n. 4
0
    def get(self):
        keyname = self.request.get('camera')
        if keyname is not None:
            cam = CameraSource.get(db.Key(keyname))
        else:
            self.error(500)
            return

        period = self.request.get('period')
        q2 = CameraEvent.all()
        q2.filter("camera_id =", cam.key()).filter("deleted =", False).order("-event_start")
        if period == "today":
            q2.filter("event_start >=", datetime.now().replace(hour=0,minute=0,second=0))
        elif period == "yesterday":
            q2.filter("event_start >=", datetime.now().replace(hour=0,minute=0,second=0) - timedelta(days=1))
            q2.filter("event_start <", datetime.now().replace(hour=0,minute=0,second=0))
        elif period == "week":
            startofweek = datetime.now().replace(hour=0, minute=0, second=0) - timedelta(days=datetime.now().isoweekday() % 7)
            q2.filter("event_start >=", startofweek)
        elif period == "month":
            #startofmonth = datetime.now().replace(day=1,hour=0,minute=0,second=0)
            startofmonth = datetime.now().replace(hour=0, minute=0, second=0) - timedelta(days=30)
            q2.filter("event_start >=", startofmonth)
        elif period == "all":
            pass
        else:
            return

        #cam.total = q2.count()
        results = q2.fetch(1000)

        for event in results:
            event.duration_text = (event.event_end - event.event_start)


        template_values = {
            'user': users.get_current_user(),
            'logout_url': users.create_logout_url('/'),
            'camera': cam,
            'eventlist': results,
            'timenow': datetime.utcnow(),
            }

        path = os.path.join(os.path.dirname(__file__), 'inc/browse.html')
        self.response.out.write(template.render(path, template_values))
Esempio n. 5
0
    def get(self):
        q = CameraSource.all()
        q.filter("deleted =", False).order("-creation_time")

        results = q.fetch(MAX_CAMERAS)
        startofweek = datetime.now().replace(hour=0, minute=0, second=0) - timedelta(days=datetime.now().isoweekday() % 7)
        #startofmonth = datetime.now().replace(day=1,hour=0,minute=0,second=0)
        startofmonth = datetime.now().replace(hour=0, minute=0, second=0) - timedelta(days=30)
        startofyesterday = datetime.now().replace(hour=0,minute=0,second=0) - timedelta(days=1)
        startoftoday = datetime.now().replace(hour=0,minute=0,second=0)

        for cam in results:

            # Generate a human-readable status indicator.
            # TODO: cam.enabled, cam.last_poll_time, cam.last_poll_result
            if not cam.enabled:
                cam.status_text = "Disabled"
            else:
                lastimg_time = memcache.get("camera{%s}.lastimg_time" % cam.key())
                if lastimg_time is None:
                    cam.status_text = "Enabled, but not recently polled"
                else:
                    td = (datetime.now() - lastimg_time)
                    cam.status_text = "Enabled, polled %s ago" % td


            # TODO: deleted frames should not be included in these counts.
            qf = CameraFrame.all(keys_only=True)
            qf.filter("camera_id =", cam.key())
            qe = CameraEvent.all(keys_only=True)
            qe.filter("deleted =", False).filter("camera_id =", cam.key())
            cam.ftotal = qf.count()
            cam.etotal = qe.count()

            qf.filter("image_time >=", startofmonth)
            qe.filter("event_start >=", startofmonth)
            cam.fthismonth = qf.count()
            cam.ethismonth = qe.count()

            qf.filter("image_time >=", startofweek)
            qe.filter("event_start >=", startofweek)
            cam.fthisweek = qf.count()
            cam.ethisweek = qe.count()

            qf.filter("image_time >=", startoftoday)
            qe.filter("event_start >=", startoftoday)
            cam.ftoday = qf.count()
            cam.etoday = qe.count()

            qf = CameraFrame.all(keys_only=True)
            qf.filter("camera_id =", cam.key())
            qf.filter("image_time >=", startofyesterday)
            qf.filter("image_time <", startoftoday)
            qe = CameraEvent.all(keys_only=True)
            qe.filter("deleted =", False)
            qe.filter("camera_id =", cam.key())
            qe.filter("event_start >=", startofyesterday)
            qe.filter("event_start <", startoftoday)
            cam.fyesterday = qf.count()
            cam.eyesterday = qe.count()


        template_values = {
            'user': users.get_current_user(),
            'logout_url': users.create_logout_url('/'),
            'camlist': results,
            'timenow': datetime.utcnow(),
            }

        path = os.path.join(os.path.dirname(__file__), 'inc/summary.html')
        self.response.out.write(template.render(path, template_values))
Esempio n. 6
0
    def pollCamera(self, cam):
        # update the last time we attempted to poll this camera.
        # do this first in case we hit an exception while attempting to poll.
        memcache.set("camera{%s}.lastpoll_time" % cam.key(), datetime.now())

        # capture an image from the remote camera.
        response = self.captureImage(cam)
        capture_time = datetime.now()
        if response is None:
            return False
        
        # store the full frame in memcache.
        memcache.set("camera{%s}.lastimg_orig" % cam.key(), response.content)
        memcache.set("camera{%s}.lastimg_time" % cam.key(), capture_time)

        # decide whether there is motion found.
        (motion_rating, motion_found) = self.detectMotion(cam, response.content)
        
        # add to an existing event if needed
        eventkey = memcache.get("camera{%s}.eventkey" % cam.key())
        if eventkey == "trigger":
            motion_found = True
            eventkey = None

        if eventkey is not None:
            #
            # An existing event was found, so just add this frame to it.
            #
            event = CameraEvent.get(db.Key(eventkey))

            # store frame in the database
            frame = CameraFrame(camera_id = cam.key(),
                                event_id = event.key(),
                                full_size_image = response.content,
                                image_time = capture_time,
                                alarmed = motion_found,
                                motion_rating = motion_rating)
            frame.put()

            # update the event in the database
            if motion_rating > event.max_motion_rating:
                event.max_motion_rating = motion_rating

            event.total_frames += 1
            event.total_motion_rating += motion_rating
            event.avg_motion_rating = event.total_motion_rating / event.total_frames

            event.event_end = capture_time
            if motion_found:
                event.alarm_frames += 1
                event.last_motion_time = capture_time

            event.put()

            # stop the event, if it's time
            td = (capture_time - event.last_motion_time)
            total_seconds = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
            if (not motion_found) and (total_seconds > cam.num_secs_after):
                memcache.delete("camera{%s}.eventkey" % cam.key())
                return False

            return True

        elif motion_found:
            #
            # No existing event found, so start a new event.
            #
            event = CameraEvent(total_frames = 1,
                                alarm_frames = 1,
                                event_start = capture_time,
                                event_end = capture_time,
                                max_motion_rating = motion_rating,
                                total_motion_rating = motion_rating,
                                avg_motion_rating = motion_rating,
                                last_motion_time = capture_time,
                                camera_id = cam.key(),
                                viewed = False,
                                archived = False,
                                deleted = False)
            event.put()

            # store frame in the database
            frame = CameraFrame(camera_id = cam.key(),
                                event_id = event.key(),
                                full_size_image = response.content,
                                image_time = capture_time,
                                alarmed = motion_found,
                                motion_rating = motion_rating)
            frame.put()

            # keep the event open.
            memcache.set("camera{%s}.eventkey" % cam.key(), str(event.key()))
            return True
        else:
            # No motion found and not currently in an event.
            return False