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()
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)
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)
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)
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
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()
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)
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)
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)