示例#1
0
    def get_licence_plate_details(self, plate):
        result = {}

        plate = licence_plate.normalize(plate)

        try:
            owner_lookup = self.car_owners.lookup(plate)
            if owner_lookup:
                result.update({
                    'owner_slackid': owner_lookup['slackid'],
                    'owner_name': owner_lookup['name']
                })
        except Exception as e:
            log.warning('Failed to car_owner: %s', str(e))

        try:
            details = self.rdw_client.get_rdw_details(plate)
            if details:
                result.update(details)
        except Exception as e:
            log.warning('Failed to fetch RDW-details: %s', str(e))

        if len(result.keys()) == 0:
            return None
        return result
示例#2
0
    def lookup(self, plate):
        """
        :return: Dict with 'name' and 'slackid' or None is not found
        """
        plate = licence_plate.normalize(plate)
        assert len(plate) == 6, 'Length of the licence plate must be 6 (without any dashes)'

        self.load()
        if plate not in self.owners_df.index:
            log.info('Owner lookup for %s result: not found.', plate)
            return None

        res = self.owners_df.loc[plate]
        log.info('Owner lookup for %s result: found: %s', plate, res.to_dict())
        return res.to_dict()
示例#3
0
    def tag(self, plate, slackid=None, name=None):
        plate = licence_plate.normalize(plate)
        assert len(plate) == 6, 'Length of the licence plate must be 6 (without any dashes)'

        if slackid and slackid.startswith('@'):
            slackid = slackid[1:]

        self.load()
        if plate in self.owners_df.index:
            self.owners_df.loc[plate, 'slackid'] = slackid or ''
            self.owners_df.loc[plate, 'name'] = name or ''
        else:
            new_data = pd.Series({'slackid': slackid, 'name': name}, name=plate)
            self.owners_df = self.owners_df.append(new_data)
            self.owners_df = self.owners_df.where((pd.notnull(self.owners_df)), None)
        self.save()
示例#4
0
    def get_car_details(self, plate):
        plate = licence_plate.normalize(plate)
        assert len(plate) == 6, 'Length of the licenceplate must be 6 (without any dashes).'

        if self.last_failure and (dt.datetime.now() - self.last_failure).total_seconds() < self.service_failure_timeout:
            log.warning("Finnik last request failed less than %s sec ago (skip)", self.service_failure_timeout)
            return None

        try:
            # Slack-commands are synchronous, max timeout 3sec
            # Slack events are asynchronous, than we have enough time.
            res = requests.get('https://autorapport.finnik.nl/kenteken/' + plate, timeout=(3, 3))
            res.raise_for_status()
        except Exception as e:
            self.enable_service_timeout()
            log.warning("Request to Finnik failed, Disable service for %s sec.", self.service_failure_timeout)
            raise e

        self.disable_service_timeout()

        soup = BeautifulSoup(res.content, "html.parser")
        div_base = soup.find('div', id="base")
        div_summary = soup.find("div", id="summary-new")
        div_value = soup.find("div", id="value")

        if not div_base or not div_summary:
            log.warning("Successful response, but element div with id='base' or id='summary-new') not found! "
                        "Is the site changed? Disable service for %s sec.", self.service_failure_timeout)
            self.enable_service_timeout()
            return None

        result = {
            'brand': div_base.find('div', id='value-basis-gegevens-merk').text,
            'model': div_base.find('div', id='value-basis-gegevens-model').text,
            'apk': div_summary.find(id="value-apk").text,
            'price': self._get_price(div_summary),
            'bpm': self._get_bpm(div_value),
            'acceleration': self._get_acceleration(div_summary, plate),
        }
        log.info("Finnik lookup for %s result: %s", plate, result)
        return result
示例#5
0
    def get_licence_plate_details(self, plate):
        result = {}

        plate = licence_plate.normalize(plate)
        # TODO: Async 3 services at the same time.
        try:
            owner_lookup = self.car_owners.lookup(plate)
            if owner_lookup:
                result.update({
                    'owner_slackid': owner_lookup['slackid'],
                    'owner_name': owner_lookup['name']
                })
        except Exception as e:
            log.warning('Failed to car_owner: %s', str(e))

        try:
            details = self.rdw_client.get_rdw_details(plate)
            if details:
                result.update(details)
        except Exception as e:
            log.warning('Failed to fetch RDW-details: %s', str(e))

        try:
            details = self.finnik_client.get_car_details(plate)
            if details:
                # Do not overwrite existing values.
                # So the RDW has preference over Finnik.
                missing_values = {
                    k: v
                    for k, v in details.items() if v and result.get(k) is None
                }
                result.update(missing_values)
        except Exception as e:
            log.warning('Failed to fetch acceleration from Finnik: %s', str(e))

        if len(result.keys()) == 0:
            return None
        return result
示例#6
0
    def command_car(self, user_id, text):
        if 'help' in text.lower().strip() or len(text.lower().strip()) == 0:
            return messages.command_car_usage

        words = text.strip().split(" ")
        first_cmd = words[0]

        if len(words) == 1 and first_cmd.lower() in ['tag', 'untag']:
            return messages.command_tag_usage

        if len(words) == 1:
            plate = licence_plate.normalize(first_cmd)
            if not licence_plate.is_valid(plate):
                return messages.command_invalid_licence_plate(first_cmd)
            details = self.get_licence_plate_details(plate)
            if not details:
                return messages.lookup_no_details_found(plate)
            return messages.lookup_found_with_details(plate, details)

        sub_command = first_cmd.lower().strip()
        if sub_command in ['tag', 'untag']:
            plate = licence_plate.normalize(words[1])

            if not licence_plate.is_valid(plate):
                return messages.command_invalid_licence_plate(words[1])

            if 'tag' == sub_command:
                if len(words) == 2:
                    self.car_owners.tag(plate, slackid=user_id)
                    logging.info('Tagged "%s" to SlackId: %s  (executor: %s)',
                                 plate, user_id, user_id)
                    return messages.command_tag_added(plate, user_id=user_id)

                owner = str(' '.join(words[2:])).strip()
                match_in_quotes = re.match(r"[\"“](.+?)[\"”]", owner)

                owner_min_chars = 3
                owner_max_chars = 32

                if owner.startswith('@'):
                    owner_slack_id = owner
                    if owner_slack_id.lower() == '@me':
                        owner_slack_id = user_id
                    # TODO validate slackId with UserInfo

                    self.car_owners.tag(plate, slackid=owner_slack_id)
                    logging.info('Tagged "%s" to SlackId: %s  (executor: %s)',
                                 plate, owner_slack_id, user_id)
                    return messages.command_tag_added(plate,
                                                      user_id=owner_slack_id)

                elif match_in_quotes:
                    owner = match_in_quotes.group(1)
                    if len(owner) < owner_min_chars or len(
                            owner
                    ) > owner_max_chars or not self._is_valid_owner(owner):
                        return messages.command_invalid_owner(
                            owner,
                            min_chars=owner_min_chars,
                            max_chars=owner_max_chars)
                    self.car_owners.tag(plate, name=owner)
                    return messages.command_tag_added(plate, owner=owner)
                else:
                    return messages.command_invalid_owner(
                        owner,
                        min_chars=owner_min_chars,
                        max_chars=owner_max_chars)

            if 'untag' == sub_command:
                self.car_owners.untag(user_id, plate)
                return messages.command_untag(plate)

        return messages.command_car_usage