Example #1
0
    def _on_www_authenticate(self, future: Future) -> None:
        try:
            data = future.result()
        except Exception as e:
            self._error(e)
        else:
            if self._check_error():
                return

            data = data.strip()

            m = re.match(b'Basic\s*realm="([a-zA-Z0-9\-\s]+)"', data)
            if m:
                logging.debug('mjpg client using basic authentication')

                auth_header = utils.build_basic_header(self._username,
                                                       self._password)
                w_data = b'GET / HTTP/1.1\r\nAuthorization: %s\r\nConnection: close\r\n\r\n' % auth_header
                w_future = utils.cast_future(self.write(w_data))
                w_future.add_done_callback(self._seek_http)

                return

            if data.startswith('Digest'):
                logging.debug('mjpg client using digest authentication')

                parts = data[7:].split(',')
                parts_dict = dict(p.split('=', 1) for p in parts)
                parts_dict = {
                    p[0]: p[1].strip('"')
                    for p in list(parts_dict.items())
                }

                self._auth_digest_state = parts_dict

                auth_header = utils.build_digest_header(
                    'GET', '/', self._username, self._password,
                    self._auth_digest_state)
                w_data = b'GET / HTTP/1.1\r\nAuthorization: %s\r\nConnection: close\r\n\r\n' % auth_header
                w_future = utils.cast_future(self.write(w_data))
                w_future.add_done_callback(self._seek_http)

                return

            logging.error('mjpg client unknown authentication header: "%s"' %
                          data)
            self._seek_content_length()
Example #2
0
    def _on_before_content_length(self, future: Future):
        try:
            future.result()
        except Exception as e:
            self._error(e)
        else:
            if self._check_error():
                return

            r_future = utils.cast_future(self.read_until(b'\r\n\r\n'))
            r_future.add_done_callback(self._on_content_length)
Example #3
0
    def _on_before_www_authenticate(self, future: Future) -> None:
        try:
            future.result()
        except Exception as e:
            self._error(e)
        else:
            if self._check_error():
                return

            r_future = utils.cast_future(self.read_until(b'\r\n'))
            r_future.add_done_callback(self._on_www_authenticate)
Example #4
0
    def _on_content_length(self, future: Future):
        try:
            data = future.result()
        except Exception as e:
            self._error(e)
        else:
            if self._check_error():
                return

            matches = re.findall(rb'(\d+)', data)
            if not matches:
                self._error(
                    'could not find content length in mjpg header line "%(header)s"'
                    % {'header': data})

                return

            length = int(matches[0])

            r_future = utils.cast_future(self.read_bytes(length))
            r_future.add_done_callback(self._on_jpg)
Example #5
0
    def do_request() -> 'Future[HTTPResponse]':
        if url_obj.username:
            auth = auth_modes[0]

        else:
            auth = 'no'

        logging.debug('testing (m)jpg netcam at %s using %s authentication' %
                      (url, auth))

        request = HTTPRequest(url,
                              auth_username=url_obj.username,
                              auth_password=url_obj.password or '',
                              auth_mode=auth_modes.pop(0),
                              connect_timeout=settings.REMOTE_REQUEST_TIMEOUT,
                              request_timeout=settings.REMOTE_REQUEST_TIMEOUT,
                              header_callback=on_header,
                              validate_cert=settings.VALIDATE_CERTS)

        fetch_future = cast_future(
            AsyncHTTPClient(force_instance=True).fetch(request))
        fetch_future.add_done_callback(on_response)
        return fetch_future
Example #6
0
def make_message(subject, message, camera_id, moment, timespan, callback):
    camera_config = config.get_camera(camera_id)

    # we must start the IO loop for the media list subprocess polling
    io_loop = IOLoop.instance()

    def on_media_files(media_files):
        io_loop.stop()

        timestamp = time.mktime(moment.timetuple())

        if media_files:
            logging.debug('got media files')

            # filter out non-recent media files
            media_files = [
                m for m in media_files
                if abs(m['timestamp'] - timestamp) < timespan
            ]
            media_files.sort(key=lambda m: m['timestamp'], reverse=True)
            media_files = [
                os.path.join(camera_config['target_dir'],
                             re.sub('^/', '', m['path'])) for m in media_files
            ]

            logging.debug('selected %d pictures' % len(media_files))

        format_dict = {
            'camera': camera_config['camera_name'],
            'hostname': socket.gethostname(),
            'moment': moment.strftime('%Y-%m-%d %H:%M:%S'),
        }

        if settings.LOCAL_TIME_FILE:
            format_dict['timezone'] = tzctl.get_time_zone()

        else:
            format_dict['timezone'] = 'local time'

        logging.debug('creating email message')

        m = message % format_dict
        s = subject % format_dict
        s = s.replace('\n', ' ')

        m += '\n\n'
        m += 'motionEye.'

        callback(s, m, media_files)

    if not timespan:
        return on_media_files([])

    logging.debug('waiting for pictures to be taken')
    time.sleep(timespan)  # give motion some time to create motion pictures

    prefix = None
    picture_filename = camera_config.get('picture_filename')
    snapshot_filename = camera_config.get('snapshot_filename')

    if ((picture_filename or snapshot_filename) and not picture_filename or
            picture_filename.startswith('%Y-%m-%d/') and not snapshot_filename
            or snapshot_filename.startswith('%Y-%m-%d/')):
        prefix = moment.strftime('%Y-%m-%d')
        logging.debug('narrowing down still images path lookup to %s' % prefix)

    fut = utils.cast_future(
        mediafiles.list_media(camera_config,
                              media_type='picture',
                              prefix=prefix))
    fut.add_done_callback(on_media_files)

    io_loop.start()
Example #7
0
    def _seek_content_length(self):
        if self._check_error():
            return

        r_future = utils.cast_future(self.read_until(b'Content-Length:'))
        r_future.add_done_callback(self._on_before_content_length)
Example #8
0
 def _seek_www_authenticate(self) -> None:
     future = utils.cast_future(self.read_until(b'WWW-Authenticate:'))
     future.add_done_callback(self._on_before_www_authenticate)
Example #9
0
    def _seek_http(self) -> None:
        if self._check_error():
            return

        future = utils.cast_future(self.read_until_regex(b'HTTP/1.\d \d+ '))
        future.add_done_callback(self._on_http)