Exemple #1
0
class HTTPRequestsBase(Retry, EnrichSignals, Block):
    """ A base for Blocks that makes HTTP Requests.

    Properties:
        url (str): URL to make request to.
        basic_auth_creds (obj): Basic Authentication credentials.
        http_method (select): HTTP method (ex. GET, POST,
            PUT, DELETE, etc).
    """
    version = VersionProperty('0.1.0')
    url = Property(title='URL Target',
                   default="http://127.0.0.1:8181",
                   order=1)
    basic_auth_creds = ObjectProperty(BasicAuthCreds,
                                      title='Credentials (BasicAuth)',
                                      default=BasicAuthCreds(),
                                      advanced=True,
                                      order=4)
    http_method = SelectProperty(HTTPMethod,
                                 default=HTTPMethod.GET,
                                 title='HTTP Method',
                                 order=0)
    headers = ListProperty(Header, title="Headers", default=[], order=2)
    require_json = BoolProperty(title="Require JSON Response",
                                default=False,
                                advanced=True,
                                order=5)
    verify = BoolProperty(title="Verify host's SSL certificate",
                          default=True,
                          advanced=True,
                          order=7)
    timeout = IntProperty(title='Request Timeout',
                          default=0,
                          allow_none=True,
                          advanced=True,
                          order=6)

    def process_signals(self, signals):
        new_signals = []
        for signal in signals:
            new_sigs = self._make_request(signal)
            if new_sigs:
                new_signals.extend(new_sigs)
        if new_signals:
            self.notify_signals(new_signals)

    def _make_request(self, signal):
        try:
            url = self.url(signal)
        except Exception as e:
            self.logger.warning(
                "Failed to evaluate url {} for incoming signal {}: {}".format(
                    self.url.value, signal.to_dict(), e))
            return
        timeout = self.timeout(signal) if self.timeout(signal) else None
        auth = self._create_auth()
        payload = self._create_payload(signal)
        headers = self._create_headers(signal)

        try:
            r = self.execute_with_retry(self._execute_request, url, auth,
                                        payload, headers, timeout)
        except:
            # out of retries for this signal
            return

        if 200 <= r.status_code < 300:
            return self._process_response(r, signal)
        else:
            self.logger.warning(
                "{} request to {} returned with response code: {}".format(
                    self.http_method(), url, r.status_code))
            return self._process_response(r, signal)

    def _execute_request(self, url, auth, data, headers, timeout):
        method = getattr(requests, self.http_method().value)

        self.logger.debug("Executing {} request to {} with data: {}".format(
            self.http_method(), url, {
                "auth": auth,
                "data": data,
                "headers": headers,
                "timeout": timeout
            }))

        return method(url,
                      auth=auth,
                      data=data,
                      headers=headers,
                      verify=self.verify(),
                      timeout=timeout)

    def _process_response(self, response, signal):
        result = []
        try:
            data = response.json()

            # if the response is a dictionary, build a signal
            if isinstance(data, dict):
                result = [self.get_output_signal(data, signal)]

            # if the response is a list, build a signal for each element
            elif isinstance(data, list):
                sigs = []
                for s in data:
                    sigs.append(self.get_output_signal(s, signal))
                if sigs:
                    result = sigs

            # otherwise, no dice on parsing the response body
            else:
                raise ValueError("Response body could not be parsed into "
                                 "Signal(s): {}".format(data))
        except ValueError:
            if not self.require_json():
                result = [
                    self.get_output_signal({'raw': response.text}, signal)
                ]
            else:
                self.logger.warning(
                    "Request was successful, but response was not "
                    "valid JSON. No response signal was created.")
                result = [signal]
        except Exception as e:
            self.logger.warning(
                "Request was successful but "
                "failed to create response signal: {}".format(e))
            result = [signal]
        finally:
            # Add the rest of the Response information to the signal
            for sig in result:
                try:
                    sig._resp = response.__dict__
                except:
                    self.logger.warning("Response failed to save to signal")

            self.logger.debug("{} request to {} returned with response code: "
                              "{}. Response: {}".format(
                                  self.http_method(), self.url(signal),
                                  response.status_code, response.__dict__))
            return result

    def _create_auth(self):
        if self.basic_auth_creds().username():
            return requests.auth.HTTPBasicAuth(
                self.basic_auth_creds().username(),
                self.basic_auth_creds().password())

    def _create_payload(self, signal):
        return json.dumps(signal.to_dict())

    def _create_headers(self, signal):
        headers = {}
        for header in self.headers():
            header_header = header.header(signal)
            header_value = header.value(signal)
            if header_header and header_value:
                headers[header_header] = header_value
        return headers
class TrackObjects(Block):

    version = VersionProperty('2.0.0')
    ipcam = BoolProperty(title='Use IP Camera?', default=False)
    camera = IntProperty(title='Camera Index', default=0)
    ipcam_address = StringProperty(title='IP Camera Address',
                                   default='',
                                   allow_none=True)
    video_ref = StringProperty(title='Path to video file',
                               default='',
                               allow_none=True)
    filters = ListProperty(ImageFilters,
                           title='Filters',
                           default=[])

    def __init__(self):
        super().__init__()
        self.video_capture = None

    def start(self):
        if not self.ipcam() and self.video_ref() is None:
            self.video_capture = cv2.VideoCapture(0)
        else:
            self.video_capture = cv2.VideoCapture(self.video_ref())

    def process_signals(self, signals):

        for signal in signals:
            try:
                (grabbed, frame) = self.video_capture.read()
            except:
                break
            if (not grabbed):
                break

            frame = imutils.resize(frame, width=600)
            
            # construct a mask and perform dialations and erosions to remove
            # any small blobs left in the mask
            for each in self.filters():
                if(str(each.filter_type()) == 'hsv'):
                    space = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
                else:
                    space = frame

                mask = cv2.inRange(space, tuple(each.filter_lo()),
                                   tuple(each.filter_hi()))
                mask = cv2.erode(mask, None, iterations=2)
                mask = cv2.dilate(mask, None, iterations=2)

                # find contours in the mask and initialize the current center
                cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
                                        cv2.CHAIN_APPROX_SIMPLE)[-2]

                if len(cnts) > 0:
                    # find the largest contour in the mask,
                    # then use to find centroid
                    c = max(cnts, key=cv2.contourArea)
                    ((x, y), radius) = cv2.minEnclosingCircle(c)
                    M = cv2.moments(c)
                    center = (int(M["m10"] / M["m00"]),
                              int(M["m01"] / M["m00"]))
                    # only proceed if the radius meets a minimum size
                    if radius > 10:
                        # draw the circle/centroid on the frame & update points
                        # NOTE: This could be removed if we don't need visual
                        cv2.circle(frame, (int(x), int(y)), int(radius),
                                   (0, 255, 255), 2)
                        cv2.circle(frame, center, 5, (0, 0, 255), -1)

                    # update the points queue
                    track_center = {
                        'object': each.obj(),
                        'x_coord': center[0],
                        'y_coord': center[1]
                    }

                else:
                    track_center = {
                        'object': each.obj(),
                        'x_coord': None,
                        'y_coord': None
                    }
                sig = Signal({
                    "track": track_center
                })

                self.notify_signals([sig])