Ejemplo n.º 1
0
    def loop(self):
        checkins = get_plugin('foursquare').get_checkins().output
        if not checkins:
            return

        last_checkin = checkins[0]
        last_checkin_created_at = last_checkin.get('createdAt', 0)
        if self._last_created_at and last_checkin_created_at <= self._last_created_at:
            return

        self.bus.post(FoursquareCheckinEvent(checkin=last_checkin))
        self._last_created_at = last_checkin_created_at
        get_plugin('variable').set(
            **{self._last_created_at_varname: self._last_created_at})
Ejemplo n.º 2
0
    def __init__(self, boards: List[str], token: str, **kwargs):
        """
        :param boards: List of boards to subscribe, by ID or name.
        :param token: Trello web client API token.
        """

        super().__init__(**kwargs)
        self._plugin: TrelloPlugin = get_plugin('trello')
        self.token = token
        self._req_id = 0
        self._boards_by_id = {}
        self._boards_by_name = {}

        for b in boards:
            b = self._plugin.get_board(b).board
            # noinspection PyUnresolvedReferences
            self._boards_by_id[b.id] = b
            # noinspection PyUnresolvedReferences
            self._boards_by_name[b.name] = b

        self.url = self._websocket_url_base.format(token=self.token)
        self._connected = Event()

        self._items = {}
        self._event_handled = False
Ejemplo n.º 3
0
def get_or_create_ngrok_tunnel() -> str:
    """
    This method creates an ngrok tunnel for the local web application,
    useful to register public HTTPS callback URLs on the fly from plugins
    and backends.
    """
    global _app_tunnel_url
    with _app_tunnel_lock:
        if _app_tunnel_url:
            return _app_tunnel_url

        local_port = _get_http_port()

        ngrok = None
        if Config.get('ngrok'):
            ngrok = get_plugin('ngrok')

        assert ngrok, 'The ngrok plugin is required in order to subscribe to notifications'
        tunnel_response = ngrok.create_tunnel(
            resource=local_port,
            protocol='http',
            bind_tls=True,
        ).output

        _app_tunnel_url = tunnel_response.get('url')
        assert _app_tunnel_url, 'Unable to create an ngrok tunnel'
        return _app_tunnel_url
Ejemplo n.º 4
0
    def loop(self):
        last_seen_id = int(self.last_seen_id)
        new_last_seen_id = int(last_seen_id)
        plugin: NextcloudPlugin = get_plugin('nextcloud')
        # noinspection PyUnresolvedReferences
        activities = plugin.get_activities(sort='desc',
                                           url=self.url,
                                           username=self.username,
                                           password=self.password,
                                           object_type=self.object_type,
                                           object_id=self.object_id).output

        events = []
        for activity in activities:
            if last_seen_id and activity['activity_id'] <= last_seen_id:
                break

            events.append(self._activity_to_event(activity))

            if not new_last_seen_id or activity[
                    'activity_id'] > new_last_seen_id:
                new_last_seen_id = int(activity['activity_id'])

        for evt in events[::-1]:
            self.bus.post(evt)

        if new_last_seen_id and last_seen_id != new_last_seen_id:
            self.last_seen_id = new_last_seen_id
Ejemplo n.º 5
0
    def _get_direction_from_sensors(self):
        if Direction.DIR_AUTO.value not in self.directions:
            raise RuntimeError(
                "Can't start auto pilot: " +
                "no sensor configured in gpio.zeroborg.directions.auto")

        direction = None

        for sensor in self.directions[Direction.DIR_AUTO.value]['sensors']:
            plugin = get_plugin(sensor['plugin'])
            if not sensor:
                raise RuntimeError('No such sensor: ' + sensor['plugin'])

            value = self._get_measurement(plugin=plugin,
                                          timeout=sensor['timeout'])
            threshold = sensor['threshold']

            if value >= threshold and 'above_threshold_direction' in sensor:
                direction = sensor['above_threshold_direction']
            elif 'below_threshold_direction' in sensor:
                direction = sensor['below_threshold_direction']

            logging.info('Sensor: {}\tMeasurement: {}\tDirection: {}'.format(
                sensor['plugin'], value, direction))

        return direction
Ejemplo n.º 6
0
    def __init__(self,
                 queue='platypush_bus_mq',
                 redis_args={},
                 *args,
                 **kwargs):
        """
        :param queue: Queue name to listen on (default: ``platypush_bus_mq``)
        :type queue: str

        :param redis_args: Arguments that will be passed to the redis-py constructor (e.g. host, port, password), see http://redis-py.readthedocs.io/en/latest/
        :type redis_args: dict
        """

        super().__init__(*args, **kwargs)

        self.queue = queue
        self.redis_args = redis_args

        if not redis_args:
            try:
                redis_plugin = get_plugin('redis')
                if redis_plugin and redis_plugin.kwargs:
                    self.redis_args = redis_plugin.kwargs
            except:
                pass

        self.redis = Redis(**self.redis_args)
Ejemplo n.º 7
0
 def _stop_torrent(self):
     # noinspection PyBroadException
     try:
         torrents = get_plugin(self.torrent_plugin)
         torrents.quit()
     except Exception as e:
         self.logger.warning(f'Could not stop torrent plugin: {str(e)}')
Ejemplo n.º 8
0
    def __init__(self):
        db_plugin = get_plugin('db')
        if not db_plugin:
            raise ModuleNotFoundError(
                'Please enable/configure the db plugin for multi-user support')

        self._engine = db_plugin._get_engine()
Ejemplo n.º 9
0
    def _status(self, host, port):
        sock = self._connect(host, port)

        request = {
            'id': self._get_req_id(),
            'jsonrpc': '2.0',
            'method': 'Server.GetStatus'
        }

        get_plugin('music.snapcast')._send(sock, request)
        try:
            return self._recv(sock).get('result', {}).get('server', {})
        except Exception as e:
            self.logger.warning('Unable to connect to {}:{}: {}'.format(
                host, port, str(e)))
            self._socks[host] = None
Ejemplo n.º 10
0
    def get_measurement(self):
        """
        Wrapper around ``plugin.get_measurement()`` that can filter events on specified enabled sensors data or on
        specified tolerance values. It can be overridden by derived classes.
        """
        if not self.plugin:
            raise NotImplementedError('No plugin specified')

        reload = False
        success = False
        data = None

        while not success:
            try:
                plugin = get_plugin(self.plugin, reload=reload)
                data = plugin.get_data(**self.plugin_args).output
                if reload:
                    self.logger.info('Backend successfully restored')

                success = True
            except Exception as e:
                self.logger.warning('Unexpected exception while getting data: {}'.format(str(e)))
                self.logger.exception(e)
                reload = True
                time.sleep(5)

            if self.enabled_sensors and data is not None:
                data = {
                    sensor: data[sensor]
                    for sensor, enabled in self.enabled_sensors.items()
                    if enabled and sensor in data
                }

        return data
Ejemplo n.º 11
0
    def on_stop(self):
        if not self.plugin:
            return

        plugin = get_plugin(self.plugin)
        if plugin and hasattr(plugin, 'close'):
            plugin.close()
Ejemplo n.º 12
0
    def search(self, query):
        self.logger.info('Searching torrents for "{}"'.format(query))

        torrents = get_plugin('torrent')
        if not torrents:
            raise RuntimeError('Torrent plugin not available/configured')
        return torrents.search(query, ).output
Ejemplo n.º 13
0
 def _stop_torrent(self):
     # noinspection PyBroadException
     try:
         torrents = get_plugin(self.torrent_plugin)
         torrents.quit()
     except:
         pass
Ejemplo n.º 14
0
 def _youtube_search_api(query):
     return [{
         'url':
         'https://www.youtube.com/watch?v=' + item['id']['videoId'],
         **item.get('snippet', {}),
     } for item in get_plugin('google.youtube').search(query=query).output
             if item.get('id', {}).get('kind') == 'youtube#video']
Ejemplo n.º 15
0
    def run(self):
        super().run()
        plugin: WeatherBuienradarPlugin = get_plugin('weather.buienradar')
        self.logger.info('Initialized weather forecast backend')

        while not self.should_stop():
            weather = plugin.get_weather().output
            precip = plugin.get_precipitation().output
            del weather['measured']

            if precip != self.last_precip:
                self.bus.post(
                    NewPrecipitationForecastEvent(
                        plugin_name='weather.buienradar',
                        average=precip.get('average'),
                        total=precip.get('total'),
                        time_frame=precip.get('time_frame')))

            if weather != self.last_weather:
                self.bus.post(
                    NewWeatherConditionEvent(
                        **{
                            **weather,
                            'plugin_name': 'weather.buienradar',
                        }))

            self.last_weather = weather
            self.last_precip = precip
            time.sleep(self.poll_seconds)
Ejemplo n.º 16
0
    def _process_devices(self, client, msg):
        devices_info = {
            device.get('friendly_name', device.get('ieee_address')): device
            for device in msg
        }

        # noinspection PyProtectedMember
        event_args = {'host': client._host, 'port': client._port}
        client.subscribe(
            *
            [self.base_topic + '/' + device for device in devices_info.keys()])

        for name, device in devices_info.items():
            if name not in self._devices:
                self.bus.post(
                    ZigbeeMqttDeviceConnectedEvent(device=name, **event_args))

            exposes = (device.get('definition', {}) or {}).get('exposes', [])
            client.publish(
                self.base_topic + '/' + name + '/get',
                json.dumps(
                    get_plugin('zigbee.mqtt').build_device_get_request(
                        exposes)))

        devices_copy = [*self._devices.keys()]
        for name in devices_copy:
            if name not in devices_info:
                self.bus.post(
                    ZigbeeMqttDeviceRemovedEvent(device=name, **event_args))
                del self._devices[name]

        self._devices = {device: {} for device in devices_info.keys()}
Ejemplo n.º 17
0
    def _get_feed_latest_timestamp(cls, url: str) -> Optional[datetime.datetime]:
        t = get_plugin('variable').get(
            cls._get_feed_latest_timestamp_varname(url)
        ).output.get(cls._get_feed_latest_timestamp_varname(url))

        if t:
            return dateutil.parser.isoparse(t)
Ejemplo n.º 18
0
    def _init_models(self, models):
        if not models:
            raise AttributeError('Please specify at least one voice model')

        self.models = {}
        for name, conf in models.items():
            if name in self.models:
                raise AttributeError('Duplicate model key {}'.format(name))

            model_file = conf.get('voice_model_file')
            detect_sound = conf.get('detect_sound')

            if not model_file:
                raise AttributeError('No voice_model_file specified for model {}'.format(name))

            model_file = os.path.abspath(os.path.expanduser(model_file))
            assistant_plugin_name = conf.get('assistant_plugin')

            if detect_sound:
                detect_sound = os.path.abspath(os.path.expanduser(detect_sound))

            if not os.path.isfile(model_file):
                raise FileNotFoundError('Voice model file {} does not exist or it not a regular file'.
                                        format(model_file))

            self.models[name] = {
                'voice_model_file': model_file,
                'sensitivity': conf.get('sensitivity', 0.5),
                'detect_sound': detect_sound,
                'assistant_plugin': get_plugin(assistant_plugin_name) if assistant_plugin_name else None,
                'assistant_language': conf.get('assistant_language'),
            }
Ejemplo n.º 19
0
    def get_measurement(self):
        plugin = get_plugin('system')
        battery = plugin.sensors_battery().output

        return {
            'battery_percent': battery.get('percent'),
            'battery_power_plugged': bool(battery.get('power_plugged')),
        }
Ejemplo n.º 20
0
def get_all_backends():
    manifests = {mf.component_name for mf in get_manifests(Backend)}
    return {
        backend_name: backend_info
        for backend_name, backend_info in get_plugin(
            'inspect').get_all_backends().output.items()
        if backend_name in manifests
    }
Ejemplo n.º 21
0
def get_all_plugins():
    manifests = {mf.component_name for mf in get_manifests(Plugin)}
    return {
        plugin_name: plugin_info
        for plugin_name, plugin_info in get_plugin(
            'inspect').get_all_plugins().output.items()
        if plugin_name in manifests
    }
Ejemplo n.º 22
0
        def _thread_func(_n_tries, errors=None):
            response = None

            if self.action.startswith('procedure.'):
                context['n_tries'] = _n_tries
                response = self._execute_procedure(**context)
                if response is not None:
                    self._send_response(response)
                return response
            else:
                action = self.expand_value_from_context(self.action, **context)
                (module_name, method_name) = get_module_and_method_from_action(action)
                plugin = get_plugin(module_name)

            try:
                # Run the action
                args = self._expand_context(**context)
                args = self.expand_value_from_context(args, **context)
                response = plugin.run(method=method_name, **args)

                if response and response.is_error():
                    logger.warning(('Response processed with errors from ' +
                                    'action {}: {}').format(
                        action, str(response)))
                elif not response.disable_logging:
                    logger.info('Processed response from action {}: {}'.
                                format(action, str(response)))
            except Exception as e:
                # Retry mechanism
                plugin.logger.exception(e)
                logger.warning(('Uncaught exception while processing response ' +
                                'from action [{}]: {}').format(action, str(e)))

                errors = errors or []
                if str(e) not in errors:
                    errors.append(str(e))

                response = Response(output=None, errors=errors)
                if _n_tries-1 > 0:
                    logger.info('Reloading plugin {} and retrying'.format(module_name))
                    get_plugin(module_name, reload=True)
                    response = _thread_func(_n_tries=_n_tries - 1, errors=errors)
            finally:
                self._send_response(response)
                return response
Ejemplo n.º 23
0
    def get_chromecast(self, chromecast):
        from .lib.plexcast import PlexController

        hndl = PlexController()
        hndl.namespace = 'urn:x-cast:com.google.cast.sse'
        cast = get_plugin('media.chromecast').get_chromecast(chromecast)
        cast.register_handler(hndl)

        return (cast, hndl)
Ejemplo n.º 24
0
    def last_seen_id(self) -> Optional[int]:
        if self._last_seen_id is None:
            variables: VariablePlugin = get_plugin('variable')
            last_seen_id = variables.get(
                self._LAST_ACTIVITY_VARNAME).output.get(
                    self._LAST_ACTIVITY_VARNAME)
            self._last_seen_id = last_seen_id

        return self._last_seen_id
Ejemplo n.º 25
0
    def _addr_tracker(self, addr):
        with self._bt_lock:
            name = get_plugin('bluetooth').lookup_name(
                addr, timeout=self.scan_duration).name

        if name is None:
            self._remove_last_seen_device(addr)
        else:
            self._add_last_seen_device({'addr': addr, 'name': name})
Ejemplo n.º 26
0
    def __init__(self, **kwargs):
        """
        The plugin will create a table named ``variable`` on the database
        configured in the :mod:`platypush.plugins.db` plugin. You'll have
        to specify a default ``engine`` in your ``db`` plugin configuration.
        """

        super().__init__(**kwargs)
        self.db_plugin = get_plugin('db')
        self.redis_plugin = get_plugin('redis')

        db = Config.get('db')
        self.db_config = {
            'engine': db.get('engine'),
            'args': db.get('args', []),
            'kwargs': db.get('kwargs', {})
        }

        self._create_tables()
Ejemplo n.º 27
0
    def loop(self):
        builds = get_plugin('travisci').builds(limit=1).output
        if not builds:
            return

        last_build = builds[0]
        last_build_finished_at = self._convert_iso_date(last_build.get('finished_at', 0))
        if not last_build_finished_at:
            return

        if self._last_build_finished_at and last_build_finished_at <= self._last_build_finished_at:
            return

        if last_build.get('state') == 'passed':
            evt_type = TravisciBuildPassedEvent
        elif last_build.get('state') == 'failed':
            evt_type = TravisciBuildFailedEvent
        else:
            return

        evt = evt_type(repository_id=last_build.get('repository', {}).get('id'),
                       repository_name=last_build.get('repository', {}).get('name'),
                       repository_slug=last_build.get('repository').get('slug'),
                       build_id=int(last_build.get('id')),
                       build_number=int(last_build.get('number')),
                       duration=last_build.get('duration'),
                       previous_state=last_build.get('previous_state'),
                       private=last_build.get('private'),
                       tag=last_build.get('tag'),
                       branch=last_build.get('branch', {}).get('name'),
                       commit_id=last_build.get('commit', {}).get('id'),
                       commit_sha=last_build.get('commit', {}).get('sha'),
                       commit_message=last_build.get('commit', {}).get('message'),
                       committed_at=self._convert_iso_date(
                           last_build.get('commit', {}).get('committed_at')),
                       created_by=last_build.get('created_by', {}).get('login'),
                       started_at=self._convert_iso_date(last_build.get('started_at')),
                       finished_at=self._convert_iso_date(last_build.get('finished_at')))

        self.bus.post(evt)
        self._last_build_finished_at = last_build_finished_at
        get_plugin('variable').set(**{self._last_build_finished_at_varname: self._last_build_finished_at})
Ejemplo n.º 28
0
    def __init__(self,
                 authorized_chat_ids: Optional[List[Union[str, int]]] = None,
                 **kwargs):
        """
        :param authorized_chat_ids: Optional list of chat_id/user_id which are authorized to send messages to
            the bot. If nothing is specified then no restrictions are applied.
        """

        super().__init__(**kwargs)
        self.authorized_chat_ids = set(authorized_chat_ids or [])
        self._plugin: ChatTelegramPlugin = get_plugin('chat.telegram')
Ejemplo n.º 29
0
    def _get_playing_plugin(self):
        if self.plugin:
            status = self.plugin.status()
            if status['state'] == PlayerState.PLAY.value or state['state'] == PlayerState.PAUSE.value:
                return self.plugin

        for plugin in self._supported_plugins:
            try:
                player = get_plugin(plugin)
            except:
                try:
                    player = get_plugin(plugin, reload=True)
                except:
                    continue

            status = player.status().output
            if status['state'] == PlayerState.PLAY.value or status['state'] == PlayerState.PAUSE.value:
                return player

        return None
Ejemplo n.º 30
0
    def send_message(self, msg):
        websocket = get_plugin('websocket')
        websocket_args = {}

        if self.ssl_context:
            url = 'wss://localhost:{}'.format(self.port)
            websocket_args['ssl'] = self.ssl_context
        else:
            url = 'ws://localhost:{}'.format(self.port)

        websocket.send(url=url, msg=msg, **websocket_args)