Esempio n. 1
0
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Set up Hook by getting the access token and list of actions."""
    username = config.get(CONF_USERNAME)
    password = config.get(CONF_PASSWORD)
    websession = async_get_clientsession(hass)

    response = None
    try:
        with async_timeout.timeout(TIMEOUT, loop=hass.loop):
            response = yield from websession.post(
                '{}{}'.format(HOOK_ENDPOINT, 'user/login'),
                data={
                    'username': username,
                    'password': password})
        data = yield from response.json()
    except (asyncio.TimeoutError,
            aiohttp.errors.ClientError,
            aiohttp.errors.ClientDisconnectedError) as error:
        _LOGGER.error("Failed authentication API call: %s", error)
        return False
    finally:
        if response is not None:
            yield from response.release()

    try:
        token = data['data']['token']
    except KeyError:
        _LOGGER.error("No token. Check username and password")
        return False

    response = None
    try:
        with async_timeout.timeout(TIMEOUT, loop=hass.loop):
            response = yield from websession.get(
                '{}{}'.format(HOOK_ENDPOINT, 'device'),
                params={"token": data['data']['token']})
        data = yield from response.json()
    except (asyncio.TimeoutError,
            aiohttp.errors.ClientError,
            aiohttp.errors.ClientDisconnectedError) as error:
        _LOGGER.error("Failed getting devices: %s", error)
        return False
    finally:
        if response is not None:
            yield from response.release()

    yield from async_add_devices(
        HookSmartHome(
            hass,
            token,
            d['device_id'],
            d['device_name'])
        for lst in data['data']
        for d in lst)
Esempio n. 2
0
async def test_events(docker, testing_images, event_loop):
    subscriber = docker.events.subscribe()

    # Do some stuffs to generate events.
    config = {"Cmd": ["/bin/ash"], "Image": "alpine:latest"}
    container = await docker.containers.create_or_replace(
        config=config, name="aiodocker-testing-temp"
    )
    await container.start()
    await container.delete(force=True)

    events_occurred = []
    while True:
        try:
            with timeout(0.2):
                event = await subscriber.get()
            if event["Actor"]["ID"] == container._id:
                events_occurred.append(event["Action"])
        except asyncio.TimeoutError:
            # no more events
            break
        except asyncio.CancelledError:
            break

    assert events_occurred == ["create", "start", "kill", "die", "destroy"]

    await docker.events.stop()
Esempio n. 3
0
        async def async_service_handler(service):
            """Execute a shell command service."""
            payload = None
            if template_payload:
                payload = bytes(
                    template_payload.async_render(variables=service.data),
                    'utf-8')

            try:
                with async_timeout.timeout(timeout, loop=hass.loop):
                    request = await getattr(websession, method)(
                        template_url.async_render(variables=service.data),
                        data=payload,
                        auth=auth,
                        headers=headers
                    )

                if request.status < 400:
                    _LOGGER.info("Success call %s.", request.url)
                else:
                    _LOGGER.warning(
                        "Error %d on call %s.", request.status, request.url)

            except asyncio.TimeoutError:
                _LOGGER.warning("Timeout call %s.", request.url)

            except aiohttp.ClientError:
                _LOGGER.error("Client error %s.", request.url)
Esempio n. 4
0
async def websocket_subscription(hass, connection, msg):
    """Handle request for account info."""
    cloud = hass.data[DOMAIN]

    with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
        response = await cloud.fetch_subscription_info()

    if response.status != 200:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'request_failed', 'Failed to request subscription'))

    data = await response.json()

    # Check if a user is subscribed but local info is outdated
    # In that case, let's refresh and reconnect
    if data.get('provider') and cloud.iot.state != STATE_CONNECTED:
        _LOGGER.debug(
            "Found disconnected account with valid subscriotion, connecting")
        await hass.async_add_executor_job(
            auth_api.renew_access_token, cloud)

        # Cancel reconnect in progress
        if cloud.iot.state != STATE_DISCONNECTED:
            await cloud.iot.disconnect()

        hass.async_create_task(cloud.iot.connect())

    connection.send_message(websocket_api.result_message(msg['id'], data))
Esempio n. 5
0
    async def async_start(self) -> None:
        """Finalize startup from inside the event loop.

        This method is a coroutine.
        """
        _LOGGER.info("Starting Home Assistant")
        self.state = CoreState.starting

        setattr(self.loop, '_thread_ident', threading.get_ident())
        self.bus.async_fire(EVENT_HOMEASSISTANT_START)

        try:
            # Only block for EVENT_HOMEASSISTANT_START listener
            self.async_stop_track_tasks()
            with timeout(TIMEOUT_EVENT_START):
                await self.async_block_till_done()
        except asyncio.TimeoutError:
            _LOGGER.warning(
                'Something is blocking Home Assistant from wrapping up the '
                'start up phase. We\'re going to continue anyway. Please '
                'report the following info at http://bit.ly/2ogP58T : %s',
                ', '.join(self.config.components))

        # Allow automations to set up the start triggers before changing state
        await asyncio.sleep(0)

        if self.state != CoreState.starting:
            _LOGGER.warning(
                'Home Assistant startup has been interrupted. '
                'Its state may be inconsistent.')
            return

        self.state = CoreState.running
        _async_create_timer(self)
Esempio n. 6
0
    async def wait_for_groups(hass, groups):
        """Wait until all groups are present, or timeout."""
        # pylint: disable=protected-access

        def _test_groups(groups):
            """Return whether all groups exist now."""
            for group in groups:
                coordinator = group[0]

                # Test that coordinator is coordinating
                current_group = coordinator._sonos_group
                if coordinator != current_group[0]:
                    return False

                # Test that slaves match
                if set(group[1:]) != set(current_group[1:]):
                    return False

            return True

        try:
            with async_timeout.timeout(5):
                while not _test_groups(groups):
                    await hass.data[DATA_SONOS].topology_condition.wait()
        except asyncio.TimeoutError:
            _LOGGER.warning("Timeout waiting for target groups %s", groups)

        for entity in hass.data[DATA_SONOS].entities:
            entity.soco._zgs_cache.clear()
Esempio n. 7
0
async def async_aiohttp_proxy_web(hass, request, web_coro,
                                  buffer_size=102400, timeout=10):
    """Stream websession request to aiohttp web response."""
    try:
        with async_timeout.timeout(timeout, loop=hass.loop):
            req = await web_coro

    except asyncio.CancelledError:
        # The user cancelled the request
        return

    except asyncio.TimeoutError as err:
        # Timeout trying to start the web request
        raise HTTPGatewayTimeout() from err

    except aiohttp.ClientError as err:
        # Something went wrong with the connection
        raise HTTPBadGateway() from err

    try:
        return await async_aiohttp_proxy_stream(
            hass,
            request,
            req.content,
            req.headers.get(CONTENT_TYPE)
        )
    finally:
        req.close()
Esempio n. 8
0
    def async_get_tts_audio(self, message):
        """Load TTS from voicerss."""
        websession = async_get_clientsession(self.hass)
        form_data = self.form_data.copy()

        form_data['src'] = message

        request = None
        try:
            with async_timeout.timeout(10, loop=self.hass.loop):
                request = yield from websession.post(
                    VOICERSS_API_URL, data=form_data
                )

                if request.status != 200:
                    _LOGGER.error("Error %d on load url %s.",
                                  request.status, request.url)
                    return (None, None)
                data = yield from request.read()

                if data in ERROR_MSG:
                    _LOGGER.error(
                        "Error receive %s from voicerss.", str(data, 'utf-8'))
                    return (None, None)

        except (asyncio.TimeoutError, aiohttp.errors.ClientError):
            _LOGGER.error("Timeout for voicerss api.")
            return (None, None)

        finally:
            if request is not None:
                yield from request.release()

        return (self.extension, data)
Esempio n. 9
0
 def _call_web_gateway(self, resource, use_get=True):
     """Call web gateway for data."""
     response = None
     session = None
     url = self._build_url(resource)
     try:
         _LOGGER.debug("Attempting to retrieve SPC data from %s", url)
         session = aiohttp.ClientSession()
         with async_timeout.timeout(10, loop=self._hass.loop):
             action = session.get if use_get else session.put
             response = yield from action(url)
         if response.status != 200:
             _LOGGER.error(
                 "SPC Web Gateway returned http status %d, response %s",
                 response.status, (yield from response.text()))
             return False
         result = yield from response.json()
     except asyncio.TimeoutError:
         _LOGGER.error("Timeout getting SPC data from %s", url)
         return False
     except aiohttp.ClientError:
         _LOGGER.exception("Error getting SPC data from %s", url)
         return False
     finally:
         if session:
             yield from session.close()
         if response:
             yield from response.release()
     _LOGGER.debug("Data from SPC: %s", result)
     return result
Esempio n. 10
0
async def get_device(hass, config, event_types=None, signal_callback=None):
    """Create a Axis device."""
    import axis

    device = axis.AxisDevice(
        loop=hass.loop, host=config[CONF_HOST],
        username=config[CONF_USERNAME],
        password=config[CONF_PASSWORD],
        port=config[CONF_PORT], web_proto='http',
        event_types=event_types, signal=signal_callback)

    try:
        with async_timeout.timeout(15):
            await hass.async_add_executor_job(device.vapix.load_params)
        return device

    except axis.Unauthorized:
        LOGGER.warning("Connected to device at %s but not registered.",
                       config[CONF_HOST])
        raise AuthenticationRequired

    except (asyncio.TimeoutError, axis.RequestError):
        LOGGER.error("Error connecting to the Axis device at %s",
                     config[CONF_HOST])
        raise CannotConnect

    except axis.AxisException:
        LOGGER.exception('Unknown Axis communication error occurred')
        raise AuthenticationRequired
Esempio n. 11
0
def get_session_id(hass, websession, username, password, login_url):
    """Get a session id."""
    auth_payload = {
        'api': AUTH_API,
        'method': 'Login',
        'version': '2',
        'account': username,
        'passwd': password,
        'session': 'SurveillanceStation',
        'format': 'sid'
    }
    auth_req = None
    try:
        with async_timeout.timeout(TIMEOUT, loop=hass.loop):
            auth_req = yield from websession.get(
                login_url,
                params=auth_payload
            )
        auth_resp = yield from auth_req.json()
        return auth_resp['data']['sid']

    except (asyncio.TimeoutError, aiohttp.errors.ClientError):
        _LOGGER.exception("Error on %s", login_url)
        return False

    finally:
        if auth_req is not None:
            yield from auth_req.release()
Esempio n. 12
0
    def async_camera_image(self):
        """Return a still image response from the camera."""
        image_url = SYNO_API_URL.format(
            self._synology_url, WEBAPI_PATH, self._camera_path)

        image_payload = {
            'api': CAMERA_API,
            'method': 'GetSnapshot',
            'version': '1',
            'cameraId': self._camera_id
        }
        try:
            with async_timeout.timeout(TIMEOUT, loop=self.hass.loop):
                response = yield from self._websession.get(
                    image_url,
                    params=image_payload
                )
        except (asyncio.TimeoutError, aiohttp.errors.ClientError):
            _LOGGER.exception("Error on %s", image_url)
            return None

        image = yield from response.read()
        yield from response.release()

        return image
Esempio n. 13
0
    def is_connected(self):
        """Return True if it connected to HassIO supervisor.

        This method is a coroutine.
        """
        try:
            with async_timeout.timeout(TIMEOUT, loop=self.loop):
                request = yield from self.websession.get(
                    "http://{}{}".format(self._ip, "/supervisor/ping")
                )

                if request.status != 200:
                    _LOGGER.error("Ping return code %d.", request.status)
                    return False

                answer = yield from request.json()
                return answer and answer['result'] == 'ok'

        except asyncio.TimeoutError:
            _LOGGER.error("Timeout on ping request")

        except aiohttp.ClientError as err:
            _LOGGER.error("Client error on ping request %s", err)

        return False
Esempio n. 14
0
    async def async_update(self):
        """Get the ComEd Hourly Pricing data from the web service."""
        try:
            if self.type == CONF_FIVE_MINUTE or \
                    self.type == CONF_CURRENT_HOUR_AVERAGE:
                url_string = _RESOURCE
                if self.type == CONF_FIVE_MINUTE:
                    url_string += '?type=5minutefeed'
                else:
                    url_string += '?type=currenthouraverage'

                with async_timeout.timeout(60, loop=self.loop):
                    response = await self.websession.get(url_string)
                    # The API responds with MIME type 'text/html'
                    text = await response.text()
                    data = json.loads(text)
                    self._state = round(
                        float(data[0]['price']) + self.offset, 2)

            else:
                self._state = None

        except (asyncio.TimeoutError, aiohttp.ClientError) as err:
            _LOGGER.error("Could not get data from ComEd API: %s", err)
        except (ValueError, KeyError):
            _LOGGER.warning("Could not update status for %s", self.name)
Esempio n. 15
0
    def command_proxy(self, path, request):
        """Return a client request with proxy origin for HassIO supervisor.

        This method is a coroutine.
        """
        try:
            data = None
            headers = None
            with async_timeout.timeout(TIMEOUT, loop=self.loop):
                data = yield from request.read()
                if data:
                    headers = {CONTENT_TYPE: request.content_type}
                else:
                    data = None

            method = getattr(self.websession, request.method.lower())
            client = yield from method(
                "http://{}/{}".format(self._ip, path), data=data,
                headers=headers
            )

            return client

        except aiohttp.ClientError as err:
            _LOGGER.error("Client error on api %s request %s.", path, err)

        except asyncio.TimeoutError:
            _LOGGER.error("Client timeout error on api request %s.", path)

        raise HTTPBadGateway()
Esempio n. 16
0
def async_get_last_state(hass, entity_id: str):
    """Restore state."""
    if DATA_RESTORE_CACHE in hass.data:
        return hass.data[DATA_RESTORE_CACHE].get(entity_id)

    if _RECORDER not in hass.config.components:
        return None

    if hass.state not in (CoreState.starting, CoreState.not_running):
        _LOGGER.debug("Cache for %s can only be loaded during startup, not %s",
                      entity_id, hass.state)
        return None

    try:
        with async_timeout.timeout(RECORDER_TIMEOUT, loop=hass.loop):
            connected = yield from wait_connection_ready(hass)
    except asyncio.TimeoutError:
        return None

    if not connected:
        return None

    if _LOCK not in hass.data:
        hass.data[_LOCK] = asyncio.Lock(loop=hass.loop)

    with (yield from hass.data[_LOCK]):
        if DATA_RESTORE_CACHE not in hass.data:
            yield from hass.async_add_job(
                _load_restore_cache, hass)

    return hass.data.get(DATA_RESTORE_CACHE, {}).get(entity_id)
Esempio n. 17
0
    def async_get_tts_audio(self, message, language, options=None):
        """Load TTS from yandex."""
        websession = async_get_clientsession(self.hass)
        actual_language = language

        try:
            with async_timeout.timeout(10, loop=self.hass.loop):
                url_param = {
                    'text': message,
                    'lang': actual_language,
                    'key': self._key,
                    'speaker': self._speaker,
                    'format': self._codec,
                    'emotion': self._emotion,
                    'speed': self._speed
                }

                request = yield from websession.get(
                    YANDEX_API_URL, params=url_param)

                if request.status != 200:
                    _LOGGER.error("Error %d on load URL %s",
                                  request.status, request.url)
                    return (None, None)
                data = yield from request.read()

        except (asyncio.TimeoutError, aiohttp.ClientError):
            _LOGGER.error("Timeout for yandex speech kit API")
            return (None, None)

        return (self._codec, data)
Esempio n. 18
0
    async def get_data(self, url):
        """Load data from specified url."""
        from buienradar.buienradar import (CONTENT,
                                           MESSAGE, STATUS_CODE, SUCCESS)

        _LOGGER.debug("Calling url: %s...", url)
        result = {SUCCESS: False, MESSAGE: None}
        resp = None
        try:
            websession = async_get_clientsession(self.hass)
            with async_timeout.timeout(10, loop=self.hass.loop):
                resp = await websession.get(url)

                result[STATUS_CODE] = resp.status
                result[CONTENT] = await resp.text()
                if resp.status == 200:
                    result[SUCCESS] = True
                else:
                    result[MESSAGE] = "Got http statuscode: %d" % (resp.status)

                return result
        except (asyncio.TimeoutError, aiohttp.ClientError) as err:
            result[MESSAGE] = "%s" % err
            return result
        finally:
            if resp is not None:
                await resp.release()
Esempio n. 19
0
    async def post(self, request):
        """Trigger a Google Actions sync."""
        hass = request.app['hass']
        cloud = hass.data[DOMAIN]
        websession = hass.helpers.aiohttp_client.async_get_clientsession()

        with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
            await hass.async_add_job(auth_api.check_token, cloud)

        with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
            req = await websession.post(
                cloud.google_actions_sync_url, headers={
                    'authorization': cloud.id_token
                })

        return self.json({}, status_code=req.status)
Esempio n. 20
0
    def async_start(self):
        """Finalize startup from inside the event loop.

        This method is a coroutine.
        """
        _LOGGER.info("Starting Home Assistant")
        self.state = CoreState.starting

        # pylint: disable=protected-access
        self.loop._thread_ident = threading.get_ident()
        self.bus.async_fire(EVENT_HOMEASSISTANT_START)

        try:
            # Only block for EVENT_HOMEASSISTANT_START listener
            self.async_stop_track_tasks()
            with timeout(TIMEOUT_EVENT_START, loop=self.loop):
                yield from self.async_block_till_done()
        except asyncio.TimeoutError:
            _LOGGER.warning(
                'Something is blocking Home Assistant from wrapping up the '
                'start up phase. We\'re going to continue anyway. Please '
                'report the following info at http://bit.ly/2ogP58T : %s',
                ', '.join(self.config.components))

        # Allow automations to set up the start triggers before changing state
        yield from asyncio.sleep(0, loop=self.loop)
        self.state = CoreState.running
        _async_create_timer(self)
Esempio n. 21
0
    def _async_ws_function(self, function):
        """Execute a command on UPC firmware webservice."""
        try:
            with async_timeout.timeout(10, loop=self.hass.loop):
                # The 'token' parameter has to be first, and 'fun' second
                # or the UPC firmware will return an error
                response = yield from self.websession.post(
                    "http://{}/xml/getter.xml".format(self.host),
                    data="token={}&fun={}".format(self.token, function),
                    headers=self.headers,
                    allow_redirects=False
                )

                # error?
                if response.status != 200:
                    _LOGGER.warning("Receive http code %d", response.status)
                    self.token = None
                    return

                # load data, store token for next request
                self.token = response.cookies['sessionToken'].value
                return (yield from response.text())

        except (asyncio.TimeoutError, aiohttp.ClientError):
            _LOGGER.error("Error on %s", function)
            self.token = None
Esempio n. 22
0
    def send_command(self, command, method="post", payload=None, timeout=10):
        """Send API command to Hass.io.

        This method is a coroutine.
        """
        try:
            with async_timeout.timeout(timeout, loop=self.loop):
                request = yield from self.websession.request(
                    method, "http://{}{}".format(self._ip, command),
                    json=payload, headers={
                        X_HASSIO: os.environ.get('HASSIO_TOKEN', "")
                    })

                if request.status not in (200, 400):
                    _LOGGER.error(
                        "%s return code %d.", command, request.status)
                    return None

                answer = yield from request.json()
                return answer

        except asyncio.TimeoutError:
            _LOGGER.error("Timeout on %s request", command)

        except aiohttp.ClientError as err:
            _LOGGER.error("Client error on %s request %s", command, err)

        return None
Esempio n. 23
0
    async def receive(self, timeout: Optional[float]=None) -> WSMessage:
        while True:
            if self._waiting is not None:
                raise RuntimeError(
                    'Concurrent call to receive() is not allowed')

            if self._closed:
                return WS_CLOSED_MESSAGE
            elif self._closing:
                await self.close()
                return WS_CLOSED_MESSAGE

            try:
                self._waiting = self._loop.create_future()
                try:
                    with async_timeout.timeout(
                            timeout or self._receive_timeout,
                            loop=self._loop):
                        msg = await self._reader.read()
                    self._reset_heartbeat()
                finally:
                    waiter = self._waiting
                    self._waiting = None
                    set_result(waiter, True)
            except (asyncio.CancelledError, asyncio.TimeoutError):
                self._close_code = 1006
                raise
            except EofStream:
                self._close_code = 1000
                await self.close()
                return WSMessage(WSMsgType.CLOSED, None, None)
            except ClientError:
                self._closed = True
                self._close_code = 1006
                return WS_CLOSED_MESSAGE
            except WebSocketError as exc:
                self._close_code = exc.code
                await self.close(code=exc.code)
                return WSMessage(WSMsgType.ERROR, exc, None)
            except Exception as exc:
                self._exception = exc
                self._closing = True
                self._close_code = 1006
                await self.close()
                return WSMessage(WSMsgType.ERROR, exc, None)

            if msg.type == WSMsgType.CLOSE:
                self._closing = True
                self._close_code = msg.data
                if not self._closed and self._autoclose:
                    await self.close()
            elif msg.type == WSMsgType.CLOSING:
                self._closing = True
            elif msg.type == WSMsgType.PING and self._autoping:
                await self.pong(msg.data)
                continue
            elif msg.type == WSMsgType.PONG and self._autoping:
                continue

            return msg
Esempio n. 24
0
    async def async_update(self):
        """Get the TekSavvy bandwidth data from the web service."""
        headers = {"TekSavvy-APIKey": self.api_key}
        _LOGGER.debug("Updating TekSavvy data")
        url = "https://api.teksavvy.com/"\
              "web/Usage/UsageSummaryRecords?$filter=IsCurrent%20eq%20true"
        with async_timeout.timeout(REQUEST_TIMEOUT, loop=self.loop):
            req = await self.websession.get(url, headers=headers)
        if req.status != 200:
            _LOGGER.error("Request failed with status: %u", req.status)
            return False

        try:
            data = await req.json()
            for (api, ha_name) in API_HA_MAP:
                self.data[ha_name] = float(data["value"][0][api])
            on_peak_download = self.data["onpeak_download"]
            on_peak_upload = self.data["onpeak_upload"]
            off_peak_download = self.data["offpeak_download"]
            off_peak_upload = self.data["offpeak_upload"]
            limit = self.data["limit"]
            # Support "unlimited" users
            if self.bandwidth_cap > 0:
                self.data["usage"] = 100*on_peak_download/self.bandwidth_cap
            else:
                self.data["usage"] = 0
            self.data["usage_gb"] = on_peak_download
            self.data["onpeak_total"] = on_peak_download + on_peak_upload
            self.data["offpeak_total"] =\
                off_peak_download + off_peak_upload
            self.data["onpeak_remaining"] = limit - on_peak_download
            return True
        except ValueError:
            _LOGGER.error("JSON Decode Failed")
            return False
Esempio n. 25
0
    async def fetching_data(self, *_):
        """Get the latest data from yr.no."""
        import xmltodict

        def try_again(err: str):
            """Retry in 15 to 20 minutes."""
            minutes = 15 + randrange(6)
            _LOGGER.error("Retrying in %i minutes: %s", minutes, err)
            async_call_later(self.hass, minutes*60, self.fetching_data)
        try:
            websession = async_get_clientsession(self.hass)
            with async_timeout.timeout(10, loop=self.hass.loop):
                resp = await websession.get(
                    self._url, params=self._urlparams)
            if resp.status != 200:
                try_again('{} returned {}'.format(resp.url, resp.status))
                return
            text = await resp.text()

        except (asyncio.TimeoutError, aiohttp.ClientError) as err:
            try_again(err)
            return

        try:
            self.data = xmltodict.parse(text)['weatherdata']
        except (ExpatError, IndexError) as err:
            try_again(err)
            return

        await self.updating_devices()
        async_call_later(self.hass, 60*60, self.fetching_data)
Esempio n. 26
0
    def _command_proxy(self, path, request):
        """Return a client request with proxy origin for Hass.io supervisor.

        This method is a coroutine.
        """
        read_timeout = _get_timeout(path)
        hass = request.app['hass']

        try:
            data = None
            headers = {X_HASSIO: os.environ.get('HASSIO_TOKEN', "")}
            with async_timeout.timeout(10, loop=hass.loop):
                data = yield from request.read()
                if data:
                    headers[CONTENT_TYPE] = request.content_type
                else:
                    data = None

            method = getattr(self._websession, request.method.lower())
            client = yield from method(
                "http://{}/{}".format(self._host, path), data=data,
                headers=headers, timeout=read_timeout
            )

            return client

        except aiohttp.ClientError as err:
            _LOGGER.error("Client error on api %s request %s", path, err)

        except asyncio.TimeoutError:
            _LOGGER.error("Client timeout error on API request %s", path)

        raise HTTPBadGateway()
Esempio n. 27
0
async def _gw_start(hass, gateway):
    """Start the gateway."""
    # Don't use hass.async_create_task to avoid holding up setup indefinitely.
    connect_task = hass.loop.create_task(gateway.start())

    @callback
    def gw_stop(event):
        """Trigger to stop the gateway."""
        hass.async_create_task(gateway.stop())
        if not connect_task.done():
            connect_task.cancel()

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, gw_stop)
    if gateway.device == 'mqtt':
        # Gatways connected via mqtt doesn't send gateway ready message.
        return
    gateway_ready = asyncio.Future()
    gateway_ready_key = MYSENSORS_GATEWAY_READY.format(id(gateway))
    hass.data[gateway_ready_key] = gateway_ready

    try:
        with async_timeout.timeout(GATEWAY_READY_TIMEOUT, loop=hass.loop):
            await gateway_ready
    except asyncio.TimeoutError:
        _LOGGER.warning(
            "Gateway %s not ready after %s secs so continuing with setup",
            gateway.device, GATEWAY_READY_TIMEOUT)
    finally:
        hass.data.pop(gateway_ready_key, None)
Esempio n. 28
0
def test_recv_timeout(loop, test_client):

    @asyncio.coroutine
    def handler(request):
        ws = web.WebSocketResponse()
        yield from ws.prepare(request)

        yield from ws.receive_str()

        yield from asyncio.sleep(0.1, loop=request.app.loop)

        yield from ws.close()
        return ws

    app = web.Application()
    app.router.add_route('GET', '/', handler)
    client = yield from test_client(app)
    resp = yield from client.ws_connect('/')
    yield from resp.send_str('ask')

    with pytest.raises(asyncio.TimeoutError):
        with async_timeout.timeout(0.01, loop=app.loop):
            yield from resp.receive()

    yield from resp.close()
Esempio n. 29
0
def get_newest_version(hass, huuid, include_components):
    """Get the newest Home Assistant version."""
    if huuid:
        info_object = yield from get_system_info(hass, include_components)
        info_object['huuid'] = huuid
    else:
        info_object = {}

    session = async_get_clientsession(hass)
    try:
        with async_timeout.timeout(5, loop=hass.loop):
            req = yield from session.post(UPDATER_URL, json=info_object)
        _LOGGER.info(("Submitted analytics to Home Assistant servers. "
                      "Information submitted includes %s"), info_object)
    except (asyncio.TimeoutError, aiohttp.ClientError):
        _LOGGER.error("Could not contact Home Assistant Update to check "
                      "for updates")
        return None

    try:
        res = yield from req.json()
    except ValueError:
        _LOGGER.error("Received invalid JSON from Home Assistant Update")
        return None

    try:
        res = RESPONSE_SCHEMA(res)
        return res['version'], res['release-notes']
    except vol.Invalid:
        _LOGGER.error("Got unexpected response: %s", res)
        return None
Esempio n. 30
0
    async def get_device_state(self, hass):
        """Get the latest data from REST API and update the state."""
        websession = async_get_clientsession(hass)

        with async_timeout.timeout(self._timeout, loop=hass.loop):
            req = await websession.get(self._resource, auth=self._auth,
                                       headers=self._headers)
            text = await req.text()

        if self._is_on_template is not None:
            text = self._is_on_template.async_render_with_possible_json_value(
                text, 'None')
            text = text.lower()
            if text == 'true':
                self._state = True
            elif text == 'false':
                self._state = False
            else:
                self._state = None
        else:
            if text == self._body_on.template:
                self._state = True
            elif text == self._body_off.template:
                self._state = False
            else:
                self._state = None

        return req
Esempio n. 31
0
async def get_controller(hass,
                         host,
                         username,
                         password,
                         port,
                         site,
                         verify_ssl,
                         async_callback=None):
    """Create a controller object and verify authentication."""
    sslcontext = None

    if verify_ssl:
        session = aiohttp_client.async_get_clientsession(hass)
        if isinstance(verify_ssl, str):
            sslcontext = ssl.create_default_context(cafile=verify_ssl)
    else:
        session = aiohttp_client.async_create_clientsession(
            hass, verify_ssl=verify_ssl, cookie_jar=CookieJar(unsafe=True))

    controller = aiounifi.Controller(
        host,
        username=username,
        password=password,
        port=port,
        site=site,
        websession=session,
        sslcontext=sslcontext,
        callback=async_callback,
    )

    try:
        async with async_timeout.timeout(10):
            await controller.check_unifi_os()
            await controller.login()
        return controller

    except aiounifi.Unauthorized as err:
        LOGGER.warning(
            "Connected to UniFi Network at %s but not registered: %s",
            host,
            err,
        )
        raise AuthenticationRequired from err

    except (
            asyncio.TimeoutError,
            aiounifi.BadGateway,
            aiounifi.ServiceUnavailable,
            aiounifi.RequestError,
            aiounifi.ResponseError,
    ) as err:
        LOGGER.error("Error connecting to the UniFi Network at %s: %s", host,
                     err)
        raise CannotConnect from err

    except aiounifi.LoginRequired as err:
        LOGGER.warning(
            "Connected to UniFi Network at %s but login required: %s",
            host,
            err,
        )
        raise AuthenticationRequired from err

    except aiounifi.AiounifiException as err:
        LOGGER.exception(
            "Unknown UniFi Network communication error occurred: %s", err)
        raise AuthenticationRequired from err
Esempio n. 32
0
async def get_the_latest_chapter(chapter_url, timeout=15):
    try:
        with async_timeout.timeout(timeout):
            url = parse_qs(urlparse(chapter_url).query).get('url', '')
            novels_name = parse_qs(urlparse(chapter_url).query).get('novels_name', '')
            data = None
            if url and novels_name:
                url = url[0]
                novels_name = novels_name[0]
                netloc = urlparse(url).netloc
                if netloc in LATEST_RULES.keys():
                    headers = {
                        'user-agent': await get_random_user_agent()
                    }
                    try:
                        html = await target_fetch(url=url, headers=headers, timeout=timeout)
                        if html is None:
                            html = get_html_by_requests(url=url, headers=headers, timeout=timeout)
                    except TypeError:
                        html = get_html_by_requests(url=url, headers=headers, timeout=timeout)
                    except Exception as e:
                        LOGGER.exception(e)
                        return None
                    try:
                        soup = BeautifulSoup(html, 'html5lib')
                    except Exception as e:
                        LOGGER.exception(e)
                        return None
                    latest_chapter_name, latest_chapter_url = None, None
                    if LATEST_RULES[netloc].plan:
                        meta_value = LATEST_RULES[netloc].meta_value
                        latest_chapter_name = soup.select(
                            'meta[property="{0}"]'.format(meta_value["latest_chapter_name"])) or soup.select(
                            'meta[name="{0}"]'.format(meta_value["latest_chapter_name"]))

                        latest_chapter_name = latest_chapter_name[0].get('content',
                                                                         None) if latest_chapter_name else None
                        latest_chapter_url = soup.select(
                            'meta[property="{0}"]'.format(meta_value["latest_chapter_url"])) or soup.select(
                            'meta[name="{0}"]'.format(meta_value["latest_chapter_url"]))
                        latest_chapter_url = urljoin(chapter_url, latest_chapter_url[0].get('content',
                                                                                            None)) if latest_chapter_url else None
                    else:
                        selector = LATEST_RULES[netloc].selector
                        content_url = selector.get('content_url')
                        if selector.get('id', None):
                            latest_chapter_soup = soup.find_all(id=selector['id'])
                        elif selector.get('class', None):
                            latest_chapter_soup = soup.find_all(class_=selector['class'])
                        else:
                            latest_chapter_soup = soup.select(selector.get('tag'))
                        if latest_chapter_soup:
                            if content_url == '1':
                                # TODO
                                pass
                            elif content_url == '0':
                                # TODO
                                pass
                            else:
                                latest_chapter_url = content_url + latest_chapter_soup[0].get('href', None)
                            latest_chapter_name = latest_chapter_soup[0].get('title', None)
                    if latest_chapter_name and latest_chapter_url:
                        time_current = get_time()
                        # print(latest_chapter_url)
                        data = {
                            "latest_chapter_name": latest_chapter_name,
                            "latest_chapter_url": latest_chapter_url,
                            "owllook_chapter_url": chapter_url,
                            "owllook_content_url": "/owllook_content?url={latest_chapter_url}&name={name}&chapter_url={chapter_url}&novels_name={novels_name}".format(
                                latest_chapter_url=latest_chapter_url,
                                name=latest_chapter_name,
                                chapter_url=url,
                                novels_name=novels_name,
                            ),
                        }
                        # 存储最新章节
                        motor_db = MotorBase().get_db()
                        await motor_db.latest_chapter.update_one(
                            {"novels_name": novels_name, 'owllook_chapter_url': chapter_url},
                            {'$set': {'data': data, "finished_at": time_current}}, upsert=True)
            return data
    except Exception as e:
        LOGGER.exception(e)
        return None
Esempio n. 33
0
async def fetch(session: aiohttp.ClientSession, feed_url: str) -> dict:
    with async_timeout.timeout(10):
        async with session.get(feed_url) as response:
            return await response.text()
Esempio n. 34
0
async def get_tide_table(config, last_tide_in_the_past=None):
    # get the tide data from Weather Underground
    logging.info('loading new tide table')
    while True:
        try:
            async with aiohttp.ClientSession() as session:
                async with async_timeout.timeout(config.seconds_for_timeout):
                    async with session.get(config.target_url) as response:
                        raw_tide_data = json.loads(await response.text())
                        break
        except Exception as e:
            logging.error('problem reading {}: {}'.format(
                config.target_url, e))
            logging.info('retrying after 20 second pause')
            asyncio.sleep(20.0)
            raise

    # The raw tide data has junk in it that we don't want
    # Pare it down to just the High Tide and Low Tide events
    # ignoring all the other events that Weather Underground
    # gives in the tide data (sunset, sunrise, moonset, moonrise,
    # moon phase, ...)
    raw_tide_list = []
    try:
        for item in raw_tide_data["tide"]["tideSummary"]:
            if item["data"]["type"] in ("High Tide", "Low Tide"):
                raw_tide_list.append((item["data"]["type"],
                                      datetime(
                                          int(item["utcdate"]["year"]),
                                          int(item["utcdate"]["mon"]),
                                          int(item["utcdate"]["mday"]),
                                          int(item["utcdate"]["hour"]),
                                          int(item["utcdate"]["min"]),
                                      )))
    except KeyError:
        logging.error(
            'Weather Underground is not currently supplying Tide data for this location'
        )
        raise Exception('Bad Location')
    if not len(raw_tide_list):
        logging.error(
            'Weather Underground is not currently supplying Tide data for this location'
        )
        raise Exception('Bad Location')

    # Now create a more useful list of tide events as tuples of
    # (TideType, TideTime, TimeToNextTide, StepTimeForNextTide
    future_tides_list = []
    for i, (tide_type_str, tide_datetime) in enumerate(raw_tide_list[:-1]):
        future_tides_list.append((
            tide_type_str,  # TideType
            tide_datetime,  # TideTime
            raw_tide_list[i + 1][1] - tide_datetime,  # TimeToNextTide
            (raw_tide_list[i + 1][1] - tide_datetime) /
            120  # StepTimeForNextTide
        ))

    # We need the last tide event, but Weather Underground only gives us
    # future events.  Guess about timing of the previous tide was if it wasn't
    # already passed in to this method
    if last_tide_in_the_past is None:
        logging.debug(
            '{}, {} no previous tide information, guessing...'.format(
                config.city_name,
                config.state_code,
            ))
        last_tide_in_the_past = (
            "Low Tide"
            if future_tides_list[0][0] == "High Tide" else "High Tide",
            future_tides_list[0][1] - future_tides_list[0][2],
            future_tides_list[0][2],
            future_tides_list[0][3],
        )

    # Create a tide table - a list of tide tuples where the first entry is the
    # most recent tide event in the past
    tide_table = [last_tide_in_the_past]
    tide_table.extend(future_tides_list)

    return tide_table
Esempio n. 35
0
    async def async_call(
        self,
        domain: str,
        service: str,
        service_data: Optional[Dict] = None,
        blocking: bool = False,
        context: Optional[Context] = None,
    ) -> Optional[bool]:
        """
        Call a service.

        Specify blocking=True to wait till service is executed.
        Waits a maximum of SERVICE_CALL_LIMIT.

        If blocking = True, will return boolean if service executed
        successfully within SERVICE_CALL_LIMIT.

        This method will fire an event to call the service.
        This event will be picked up by this ServiceRegistry and any
        other ServiceRegistry that is listening on the EventBus.

        Because the service is sent as an event you are not allowed to use
        the keys ATTR_DOMAIN and ATTR_SERVICE in your service_data.

        This method is a coroutine.
        """
        domain = domain.lower()
        service = service.lower()
        context = context or Context()
        service_data = service_data or {}

        try:
            handler = self._services[domain][service]
        except KeyError:
            raise ServiceNotFound(domain, service) from None

        if handler.schema:
            processed_data = handler.schema(service_data)
        else:
            processed_data = service_data

        service_call = ServiceCall(domain, service, processed_data, context)

        self._hass.bus.async_fire(
            EVENT_CALL_SERVICE,
            {
                ATTR_DOMAIN: domain.lower(),
                ATTR_SERVICE: service.lower(),
                ATTR_SERVICE_DATA: service_data,
            },
            context=context,
        )

        if not blocking:
            self._hass.async_create_task(
                self._safe_execute(handler, service_call))
            return None

        try:
            with timeout(SERVICE_CALL_LIMIT):
                await asyncio.shield(
                    self._execute_service(handler, service_call))
            return True
        except asyncio.TimeoutError:
            return False
Esempio n. 36
0
async def async_setup_entry(hass: HomeAssistant,
                            entry: config_entries.ConfigEntry) -> bool:
    """Set up the ISY 994 integration."""
    # As there currently is no way to import options from yaml
    # when setting up a config entry, we fallback to adding
    # the options to the config entry and pull them out here if
    # they are missing from the options
    _async_import_options_from_data_if_missing(hass, entry)

    hass.data[DOMAIN][entry.entry_id] = {}
    hass_isy_data = hass.data[DOMAIN][entry.entry_id]

    hass_isy_data[ISY994_NODES] = {SENSOR_AUX: []}
    for platform in PLATFORMS:
        hass_isy_data[ISY994_NODES][platform] = []

    hass_isy_data[ISY994_PROGRAMS] = {}
    for platform in PROGRAM_PLATFORMS:
        hass_isy_data[ISY994_PROGRAMS][platform] = []

    hass_isy_data[ISY994_VARIABLES] = []

    isy_config = entry.data
    isy_options = entry.options

    # Required
    user = isy_config[CONF_USERNAME]
    password = isy_config[CONF_PASSWORD]
    host = urlparse(isy_config[CONF_HOST])

    # Optional
    tls_version = isy_config.get(CONF_TLS_VER)
    ignore_identifier = isy_options.get(CONF_IGNORE_STRING,
                                        DEFAULT_IGNORE_STRING)
    sensor_identifier = isy_options.get(CONF_SENSOR_STRING,
                                        DEFAULT_SENSOR_STRING)
    variable_identifier = isy_options.get(CONF_VAR_SENSOR_STRING,
                                          DEFAULT_VAR_SENSOR_STRING)

    if host.scheme == "http":
        https = False
        port = host.port or 80
        session = aiohttp_client.async_create_clientsession(
            hass, verify_ssl=False, cookie_jar=CookieJar(unsafe=True))
    elif host.scheme == "https":
        https = True
        port = host.port or 443
        session = aiohttp_client.async_get_clientsession(hass)
    else:
        _LOGGER.error("The isy994 host value in configuration is invalid")
        return False

    # Connect to ISY controller.
    isy = ISY(
        host.hostname,
        port,
        username=user,
        password=password,
        use_https=https,
        tls_ver=tls_version,
        webroot=host.path,
        websession=session,
        use_websocket=True,
    )

    try:
        async with async_timeout.timeout(60):
            await isy.initialize()
    except asyncio.TimeoutError as err:
        raise ConfigEntryNotReady(
            f"Timed out initializing the ISY; device may be busy, trying again later: {err}"
        ) from err
    except ISYInvalidAuthError as err:
        raise ConfigEntryAuthFailed(
            f"Invalid credentials for the ISY: {err}") from err
    except ISYConnectionError as err:
        raise ConfigEntryNotReady(
            f"Failed to connect to the ISY, please adjust settings and try again: {err}"
        ) from err
    except ISYResponseParseError as err:
        raise ConfigEntryNotReady(
            f"Invalid XML response from ISY; Ensure the ISY is running the latest firmware: {err}"
        ) from err

    _categorize_nodes(hass_isy_data, isy.nodes, ignore_identifier,
                      sensor_identifier)
    _categorize_programs(hass_isy_data, isy.programs)
    _categorize_variables(hass_isy_data, isy.variables, variable_identifier)

    # Dump ISY Clock Information. Future: Add ISY as sensor to Hass with attrs
    _LOGGER.info(repr(isy.clock))

    hass_isy_data[ISY994_ISY] = isy
    _async_get_or_create_isy_device_in_registry(hass, entry, isy)

    # Load platforms for the devices in the ISY controller that we support.
    await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

    @callback
    def _async_stop_auto_update(event: Event) -> None:
        """Stop the isy auto update on Home Assistant Shutdown."""
        _LOGGER.debug("ISY Stopping Event Stream and automatic updates")
        isy.websocket.stop()

    _LOGGER.debug("ISY Starting Event Stream and automatic updates")
    isy.websocket.start()

    entry.async_on_unload(entry.add_update_listener(_async_update_listener))
    entry.async_on_unload(
        hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP,
                                   _async_stop_auto_update))

    # Register Integration-wide Services:
    async_setup_services(hass)

    return True
Esempio n. 37
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
    """Set up Shelly from a config entry."""
    hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id] = {}
    hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id][DEVICE] = None

    temperature_unit = "C" if hass.config.units.is_metric else "F"

    options = aioshelly.ConnectionOptions(
        entry.data[CONF_HOST],
        entry.data.get(CONF_USERNAME),
        entry.data.get(CONF_PASSWORD),
        temperature_unit,
    )

    coap_context = await get_coap_context(hass)

    device = await aioshelly.Device.create(
        aiohttp_client.async_get_clientsession(hass),
        coap_context,
        options,
        False,
    )

    dev_reg = await device_registry.async_get_registry(hass)
    identifier = (DOMAIN, entry.unique_id)
    device_entry = dev_reg.async_get_device(identifiers={identifier}, connections=set())
    if device_entry and entry.entry_id not in device_entry.config_entries:
        device_entry = None

    sleep_period = entry.data.get("sleep_period")

    @callback
    def _async_device_online(_):
        _LOGGER.debug("Device %s is online, resuming setup", entry.title)
        hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id][DEVICE] = None

        if sleep_period is None:
            data = {**entry.data}
            data["sleep_period"] = get_device_sleep_period(device.settings)
            data["model"] = device.settings["device"]["type"]
            hass.config_entries.async_update_entry(entry, data=data)

        hass.async_create_task(async_device_setup(hass, entry, device))

    if sleep_period == 0:
        # Not a sleeping device, finish setup
        _LOGGER.debug("Setting up online device %s", entry.title)
        try:
            async with async_timeout.timeout(AIOSHELLY_DEVICE_TIMEOUT_SEC):
                await device.initialize(True)
        except (asyncio.TimeoutError, OSError) as err:
            raise ConfigEntryNotReady from err

        await async_device_setup(hass, entry, device)
    elif sleep_period is None or device_entry is None:
        # Need to get sleep info or first time sleeping device setup, wait for device
        hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id][DEVICE] = device
        _LOGGER.debug(
            "Setup for device %s will resume when device is online", entry.title
        )
        device.subscribe_updates(_async_device_online)
        await device.coap_request("s")
    else:
        # Restore sensors for sleeping device
        _LOGGER.debug("Setting up offline device %s", entry.title)
        await async_device_setup(hass, entry, device)

    return True
Esempio n. 38
0
async def trim_fn(c, m):
    chat_id = m.chat.id
    if c.CURRENT_PROCESSES.get(chat_id, 0) == Config.MAX_PROCESSES_PER_USER:
        await m.reply_text(
            'You have reached the maximum parallel processes! Try again after one of them finishes.',
            True)
        return
    if not c.CURRENT_PROCESSES.get(chat_id):
        c.CURRENT_PROCESSES[chat_id] = 0
    c.CURRENT_PROCESSES[chat_id] += 1

    message = await c.get_messages(chat_id, m.reply_to_message.message_id)
    await m.reply_to_message.delete()
    media_msg = message.reply_to_message

    if media_msg.empty:
        await m.reply_text(
            'Why did you delete the file 😠, Now i cannot help you 😒.',
            True)
        c.CURRENT_PROCESSES[chat_id] -= 1
        return

    try:
        start, end = [int(i) for i in m.text.split(':')]
    except:
        await m.reply_text('Please follow the specified format', True)
        c.CURRENT_PROCESSES[chat_id] -= 1
        return

    if (start >= end) or (start < 0):
        await m.reply_text('Invalid range!', True)
        c.CURRENT_PROCESSES[chat_id] -= 1
        return

    request_duration = end - start

    if request_duration > Config.MAX_TRIM_DURATION:
        await m.reply_text(
            f'Please provide any range that\'s upto {Config.MAX_TRIM_DURATION}s. Your requested range **{start}:{end}** is `{request_duration}s` long!',
            True)
        c.CURRENT_PROCESSES[chat_id] -= 1
        return

    uid = str(uuid.uuid4())
    output_folder = Config.SMPL_OP_FLDR.joinpath(uid)
    os.makedirs(output_folder, exist_ok=True)

    if Config.TRACK_CHANNEL:
        tr_msg = await media_msg.forward(Config.TRACK_CHANNEL)
        await tr_msg.reply_text(f"User id: `{chat_id}`")

    if media_msg.media:
        typ = 1
    else:
        typ = 2

    snt = await m.reply_text('Processing your request, Please wait! 😴',
                             True)

    try:
        async with timeout(Config.TIMEOUT) as cm:
            start_time = time.time()

            if typ == 2:
                file_link = media_msg.text
            else:
                file_link = generate_stream_link(media_msg)

            await snt.edit_text(
                '😀 Trimming Your Video! This might take some time.')

            duration = await get_duration(file_link)
            if isinstance(duration, str):
                await snt.edit_text("😟 Sorry! I cannot open the file.")
                l = await media_msg.forward(Config.LOG_CHANNEL)
                await l.reply_text(
                    f'stream link : {file_link}\n\ntrim video requested\n\n{start}:{end}',
                    True)
                c.CURRENT_PROCESSES[chat_id] -= 1
                return

            if (start >= duration) or (end >= duration):
                await snt.edit_text(
                    "😟 Sorry! The requested range is out of the video's duration!."
                )
                c.CURRENT_PROCESSES[chat_id] -= 1
                return

            log.info(
                f"Trimming video (duration {request_duration}s from {start}) from location: {file_link} for {chat_id}"
            )

            sample_file = output_folder.joinpath(f'trim_video.mkv')
            subtitle_option = await fix_subtitle_codec(file_link)

            ffmpeg_cmd = f"ffmpeg -hide_banner -ss {start} -i {shlex.quote(file_link)} -t {request_duration} -map 0 -c copy {subtitle_option} {sample_file}"
            output = await run_subprocess(ffmpeg_cmd)
            log.debug(output)

            if (not sample_file.exists()) or (os.path.getsize(sample_file)
                                              == 0):
                await snt.edit_text(
                    '😟 Sorry! video trimming failed possibly due to some infrastructure failure 😥.'
                )
                ffmpeg_output = output[0].decode() + '\n' + output[1].decode()
                l = await media_msg.forward(Config.LOG_CHANNEL)
                await l.reply_text(
                    f'stream link : {file_link}\n\nVideo trimm failed. **{start}:{end}**\n\n{ffmpeg_output}',
                    True)
                c.CURRENT_PROCESSES[chat_id] -= 1
                return

            thumb = await generate_thumbnail_file(sample_file, uid)

            await snt.edit_text(
                '🤓 Video trimmed successfully!, Now starting to upload!')

            await m.reply_chat_action("upload_video")

            await m.reply_video(
                video=str(sample_file),
                quote=True,
                caption=
                f"Trimmed video from {datetime.timedelta(seconds=start)} to {datetime.timedelta(seconds=end)}",
                duration=request_duration,
                thumb=thumb,
                supports_streaming=True)

            await snt.edit_text(
                f'Successfully completed process in {datetime.timedelta(seconds=int(time.time()-start_time))}\n\nIf You find me helpful, please rate me [here](tg://resolve?domain=botsarchive&post=1206).'
            )
            c.CURRENT_PROCESSES[chat_id] -= 1
    except (asyncio.TimeoutError, asyncio.CancelledError):
        await snt.edit_text(
            '😟 Sorry! Video trimming failed due to timeout. Your process was taking too long to complete, hence cancelled'
        )
        c.CURRENT_PROCESSES[chat_id] -= 1
    except Exception as e:
        log.error(e, exc_info=True)
        await snt.edit_text(
            '😟 Sorry! Video trimming failed possibly due to some infrastructure failure 😥.'
        )

        l = await media_msg.forward(Config.LOG_CHANNEL)
        await l.reply_text(
            f'sample video requested and some error occoured\n\n{traceback.format_exc()}',
            True)
        c.CURRENT_PROCESSES[chat_id] -= 1