Ejemplo n.º 1
0
 def callback_stream(self, stream: Stream) -> None:
     """
         Triggered asynchronously (in a different thread context) on every incoming stream
         request or file transfert requests.
         You can block this call until you are done with the stream.
         To signal that you accept / reject the file, simply call stream.accept()
         or stream.reject() and return.
         :param stream:
             the incoming stream request.
     """
     stream.reject()  # by default, reject the file as the plugin doesn't want it.
Ejemplo n.º 2
0
 def callback_stream(self, stream: Stream) -> None:
     """
         Triggered asynchronously (in a different thread context) on every incoming stream
         request or file transfert requests.
         You can block this call until you are done with the stream.
         To signal that you accept / reject the file, simply call stream.accept()
         or stream.reject() and return.
         :param stream:
             the incoming stream request.
     """
     stream.reject(
     )  # by default, reject the file as the plugin doesn't want it.
Ejemplo n.º 3
0
def test_streaming():
    canary = b'this is my test' * 1000
    source = Stream(SimpleIdentifier("*****@*****.**"), BytesIO(canary))
    clients = [StreamingClient() for i in range(50)]
    Tee(source, clients).run()
    for client in clients:
        assert client.response == canary
Ejemplo n.º 4
0
    def send_stream_request(self,
                            identifier,
                            fsource,
                            name='file',
                            size=None,
                            stream_type=None):
        """Starts a file transfer.

        :param identifier: ZulipPerson or ZulipRoom
            Identifier of the Person or Room to send the stream to.

        :param fsource: str, dict or binary data
            File URL or binary content from a local file.
            Optionally a dict with binary content plus metadata can be given.
            See `stream_type` for more details.

        :param name: str, optional
            Name of the file. Not sure if this works always.

        :param size: str, optional
            Size of the file obtained with os.path.getsize.
            This is only used for debug logging purposes.

        :param stream_type: str, optional
            Type of the stream. Choices: 'document', 'photo', 'audio', 'video', 'sticker', 'location'.
            Right now used for debug logging purposes only.

        :return stream: str or Stream
            If `fsource` is str will return str, else return Stream.
        """
        def _metadata(fsource):
            if isinstance(fsource, dict):
                return fsource.pop('content'), fsource
            else:
                return fsource, None

        def _is_valid_url(url):
            try:
                from urlparse import urlparse
            except Exception:
                from urllib.parse import urlparse

            return bool(urlparse(url).scheme)

        content, meta = _metadata(fsource)
        if isinstance(content, str):
            if not _is_valid_url(content):
                raise ValueError("Not valid URL: {}".format(content))
            else:
                raise NotImplementedError(
                    "The Zulip backend does not yet support URL stream requests."
                )
        else:
            stream = Stream(identifier, content, name, size, stream_type)
            log.debug(
                "Requesting upload of {0} to {1} (size hint: {2}, stream type: {3})"
                .format(name, identifier, size, stream_type))
            self.thread_pool.apply_async(self._zulip_upload_stream, (stream, ))

        return stream
Ejemplo n.º 5
0
 def send_stream_request(self, identifier, fsource, name='file', size=None, stream_type=None):
     """Starts a file transfer. For Slack, the size and stream_type are unsupported"""
     stream = Stream(identifier, fsource, name, size, stream_type)
     log.debug("Requesting upload of {0} to {1} (size hint: {2}, stream type: {3})".format(name,
               identifier.channelname, size, stream_type))
     self.thread_pool.putRequest(WorkRequest(self._slack_upload, args=(stream,)))
     return stream
Ejemplo n.º 6
0
    def send_stream_request(
        self,
        identifier: Identifier,
        fsource: BinaryIO,
        name: Optional[str] = None,
        size: Optional[int] = None,
        stream_type: Optional[str] = None,
    ) -> Stream:
        # Creates a new connection
        dcc = self.dcc_listen("raw")
        msg_parts = map(
            str,
            (
                "SEND",
                name,
                irc.client.ip_quad_to_numstr(dcc.localaddress),
                dcc.localport,
                size,
            ),
        )
        msg = subprocess.list2cmdline(msg_parts)
        self.connection.ctcp("DCC", identifier.nick, msg)
        stream = Stream(identifier, fsource, name, size, stream_type)
        self.transfers[dcc] = stream

        return stream
Ejemplo n.º 7
0
 def send_stream_request(self, identifier, fsource, name='file', size=None, stream_type=None):
     """Starts a file transfer. For Slack, the size and stream_type are unsupported"""
     stream = Stream(identifier, fsource, name, size, stream_type)
     log.debug('Requesting upload of %s to %s (size hint: %d, stream type: %s).',
               name, identifier.channelname, size, stream_type)
     self.thread_pool.apply_async(self._slack_upload, (stream,))
     return stream
Ejemplo n.º 8
0
    def send_stream_request(
        self,
        user: Identifier,
        fsource: BinaryIO,
        name: str = None,
        size: int = None,
        stream_type: str = None,
    ) -> Stream:
        """
        Starts a file transfer. For Slack, the size and stream_type are unsupported

        :param user: is the identifier of the person you want to send it to.
        :param fsource: is a file object you want to send.
        :param name: is an optional filename for it.
        :param size: not supported in Slack backend
        :param stream_type: not supported in Slack backend

        :return Stream: object on which you can monitor the progress of it.
        """
        stream = Stream(user, fsource, name, size, stream_type)
        log.debug(
            "Requesting upload of %s to %s (size hint: %d, stream type: %s).",
            name,
            user.channelname,
            size,
            stream_type,
        )
        self.thread_pool.apply_async(self._slack_upload, (stream, ))
        return stream
Ejemplo n.º 9
0
def test_streaming():
    canary = b"this is my test" * 1000
    source = Stream(TestPerson("*****@*****.**"), BytesIO(canary))
    clients = [StreamingClient() for _ in range(50)]
    Tee(source, clients).run()
    for client in clients:
        assert client.response == canary
Ejemplo n.º 10
0
 def send_stream_request(self,
                         identifier,
                         fsource,
                         name=None,
                         size=None,
                         stream_type=None):
     s = Stream(identifier, fsource, name, size, stream_type)
     self.conn.send_stream_request(s)
     return s
Ejemplo n.º 11
0
 def on_file_send_request(self, friend_number, file_number, file_size, filename):
     logging.debug("TOX: incoming file transfer %s : %s", friend_number, filename)
     # make a pipe on which we will be able to write from tox
     pipe = ToxStreamer()
     # make the original stream with all the info
     stream = Stream(self.friend_to_idd(friend_number), pipe, filename, file_size)
     # store it for tracking purposes
     self.incoming_streams[(friend_number, file_number)] = (pipe, stream)
     # callback err so it will duplicate the stream and send it to all the plugins
     self.backend.callback_stream(stream)
     # always say ok, and kill it later if finally we don't want it
     self.file_send_control(friend_number, 1, file_number, Tox.FILECONTROL_ACCEPT)
Ejemplo n.º 12
0
    def send_stream_request(self, identifier, fsource, name='file', size=None, stream_type=None):
        """
        Send a file to Cisco Webex Teams

        :param user: is the identifier of the person you want to send it to.
        :param fsource: is a file object you want to send.
        :param name: is an optional filename for it.
        :param size: not supported in Webex Teams backend
        :param stream_type: not supported in Webex Teams backend
        """
        log.debug(f'Requesting upload of {fsource.name} to {identifier}.')
        stream = Stream(identifier, fsource, name, size, stream_type)
#        self.thread_pool.apply_async(self._teams_upload, (stream,))
        self._teams_upload(stream)
        return stream
Ejemplo n.º 13
0
    def send_stream_request(
        self, identifier, fsource, name="file.txt", size=None, stream_type=None
    ):
        """Starts a file transfer.
        note, fsource used to make the stream needs to be in open/rb state
        """

        stream = Stream(
            identifier=identifier,
            fsource=fsource,
            name=name,
            size=size,
            stream_type=stream_type,
        )
        result = self.thread_pool.apply_async(self._hipchat_upload, (stream,))
        log.debug("Response from server: %s", result.get(timeout=10))
        return stream
Ejemplo n.º 14
0
 def _slack_upload(self, stream: Stream) -> None:
     """
     Performs an upload defined in a stream
     :param stream: Stream object
     :return: None
     """
     try:
         stream.accept()
         resp = self.webclient.files_upload(channels=stream.identifier.channelid,
                                            filename=stream.name,
                                            file=stream)
         if 'ok' in resp and resp['ok']:
             stream.success()
         else:
             stream.error()
     except Exception:
         log.exception(f'Upload of {stream.name} to {stream.identifier.channelname} failed.')
Ejemplo n.º 15
0
 def _slack_upload(self, stream: Stream) -> None:
     """
     Performs an upload defined in a stream
     :param stream: Stream object
     :return: None
     """
     try:
         stream.accept()
         resp = self.api_call('files.upload', data={
             'channels': stream.identifier.channelid,
             'filename': stream.name,
             'file': stream
         })
         if 'ok' in resp and resp['ok']:
             stream.success()
         else:
             stream.error()
     except Exception:
         log.exception(f'Upload of {stream.name} to {stream.identifier.channelname} failed.')
Ejemplo n.º 16
0
 def _telegram_upload_stream(self, stream: Stream, **kwargs) -> None:
     """Perform upload defined in a stream."""
     msg = None
     try:
         stream.accept()
         msg = self._telegram_special_message(
             chat_id=stream.identifier.id,
             content=stream.raw,
             msg_type=stream.stream_type,
             **kwargs,
         )
     except Exception:
         log.exception(
             f"Upload of {stream.name} to {stream.identifier} failed.")
     else:
         if msg is None:
             stream.error()
         else:
             stream.success()
Ejemplo n.º 17
0
 def _slack_upload(self, stream: Stream) -> None:
     """
     Performs an upload defined in a stream
     :param stream: Stream object
     :return: None
     """
     try:
         stream.accept()
         resp = self.api_call('files.upload', data={
             'channels': stream.identifier.channelid,
             'filename': stream.name,
             'file': stream
         })
         if 'ok' in resp and resp['ok']:
             stream.success()
         else:
             stream.error()
     except Exception:
         log.exception(f'Upload of {stream.name} to {stream.identifier.channelname} failed.')
Ejemplo n.º 18
0
 def _slack_upload(self, stream: Stream) -> None:
     """
     Performs an upload defined in a stream
     :param stream: Stream object
     :return: None
     """
     try:
         stream.accept()
         resp = self.api_call(
             "files.upload",
             data={
                 "channels": stream.identifier.channelid,
                 "filename": stream.name,
                 "file": stream,
             },
         )
         if "ok" in resp and resp["ok"]:
             stream.success()
         else:
             stream.error()
     except Exception:
         log.exception(
             f"Upload of {stream.name} to {stream.identifier.channelname} failed."
         )
Ejemplo n.º 19
0
    def send_stream_request(self,
                            identifier,
                            fsource,
                            name='file',
                            size=None,
                            stream_type=None):
        """Starts a file transfer.

        :param identifier: TelegramPerson or TelegramMUCOccupant
            Identifier of the Person or Room to send the stream to.

        :param fsource: str, dict or binary data
            File URL or binary content from a local file.
            Optionally a dict with binary content plus metadata can be given.
            See `stream_type` for more details.

        :param name: str, optional
            Name of the file. Not sure if this works always.

        :param size: str, optional
            Size of the file obtained with os.path.getsize.
            This is only used for debug logging purposes.

        :param stream_type: str, optional
            Type of the stream. Choices: 'document', 'photo', 'audio', 'video', 'sticker', 'location'.

            If 'video', a dict is optional as {'content': fsource, 'duration': str}.
            If 'voice', a dict is optional as {'content': fsource, 'duration': str}.
            If 'audio', a dict is optional as {'content': fsource, 'duration': str, 'performer': str, 'title': str}.

            For 'location' a dict is mandatory as {'latitude': str, 'longitude': str}.
            For 'venue': TODO # see: https://core.telegram.org/bots/api#sendvenue

        :return stream: str or Stream
            If `fsource` is str will return str, else return Stream.
        """
        def _telegram_metadata(fsource):
            if isinstance(fsource, dict):
                return fsource.pop('content'), fsource
            else:
                return fsource, None

        def _is_valid_url(url):
            try:
                from urlparse import urlparse
            except Exception:
                from urllib.parse import urlparse

            return bool(urlparse(url).scheme)

        content, meta = _telegram_metadata(fsource)
        if isinstance(content, str):
            if not _is_valid_url(content):
                raise ValueError("Not valid URL: {}".format(content))

            self._telegram_special_message(chat_id=identifier.id,
                                           content=content,
                                           msg_type=stream_type,
                                           **meta)
            log.debug(
                "Requesting upload of {0} to {1} (size hint: {2}, stream type: {3})"
                .format(name, identifier.username, size, stream_type))

            stream = content
        else:
            stream = Stream(identifier, content, name, size, stream_type)
            log.debug(
                "Requesting upload of {0} to {1} (size hint: {2}, stream type: {3})"
                .format(name, identifier, size, stream_type))
            self.thread_pool.apply_async(self._telegram_upload_stream,
                                         (stream, ))

        return stream