Exemplo n.º 1
0
 async def put(self, channel, msg):
     if channel.source in self._hook.config["channels"]:
         ref = await self._hook.send(channel.source, msg)
         return [immp.Receipt(ref.key, channel)]
     else:
         raise immp.PlugError("Send to unknown sync channel: {}".format(
             repr(channel)))
Exemplo n.º 2
0
 async def delete(self, ref, sent=None):
     queue = []
     for channel, ids in ref.ids.items():
         for id_ in ids:
             if not (sent and sent.channel == channel and sent.id == id_):
                 queue.append(immp.Receipt(id_, channel).delete())
     if queue:
         await gather(*queue)
Exemplo n.º 3
0
 async def _parse_main(cls,
                       slack,
                       json,
                       event,
                       channel,
                       parent=True,
                       revision=None):
     id_, at = cls._parse_meta(slack, event)
     edited = bool(revision)
     deleted = False
     text = event["text"]
     user = await cls._parse_author(slack, event)
     action = False
     reply_to = joined = left = title = None
     attachments = []
     if user and text and re.match(r"<@{}(\|.*?)?> ".format(user.id), text):
         # Own username at the start of the message, assume it's an action.
         action = True
         text = re.sub(r"^<@{}(\|.*?)?> ".format(user.id), "", text)
     if event["subtype"] in ("channel_join", "group_join"):
         action = True
         joined = [user]
     elif event["subtype"] in ("channel_leave", "group_leave"):
         action = True
         left = [user]
     elif event["subtype"] in ("channel_name", "group_name"):
         action = True
         title = event["name"]
     elif event["subtype"] == "me_message":
         action = True
     elif event["subtype"] == "reminder_add":
         action = True
         # Slack leaves a leading space in the message text: " set up a reminder..."
         text = text.lstrip()
     thread = recent = None
     if event["thread_ts"]:
         thread = immp.Receipt(event["thread_ts"],
                               immp.Channel(slack, event["channel"]))
     if thread and parent:
         try:
             thread = await slack.get_message(thread, False)
         except MessageNotFound:
             pass
     if isinstance(thread, immp.Message):
         for reply in thread.raw["replies"][::-1]:
             if reply["ts"] not in (event["ts"], event["thread_ts"]):
                 # Reply to a thread with at least one other message, use the next most
                 # recent rather than the parent.
                 recent = immp.Receipt(reply["ts"], channel)
                 break
     if recent and parent:
         try:
             recent = await slack.get_reply(channel.source,
                                            event["thread_ts"], recent.id,
                                            False)
         except MessageNotFound:
             pass
     if thread and recent:
         # Don't walk the whole thread, just link to the parent after one step.
         recent.reply_to = thread
         reply_to = recent
     else:
         reply_to = recent or thread
     for file in event["files"]:
         try:
             attachments.append(SlackFile.from_file(slack, file))
         except MessageNotFound:
             pass
     for attach in event["attachments"]:
         if attach["is_msg_unfurl"]:
             # We have the message ID as the timestamp, fetch the whole message to embed it.
             try:
                 unfurl = cls.from_unfurl(slack, attach)
                 attachments.append(await slack.resolve_message(unfurl))
             except MessageNotFound:
                 pass
         elif attach["image_url"]:
             attachments.append(
                 immp.File(title=attach["title"],
                           type_=immp.File.Type.image,
                           source=attach["image_url"]))
         elif attach["fallback"]:
             if text:
                 text = "{}\n---\n{}".format(text, attach["fallback"])
             else:
                 text = attach["fallback"]
     if text:
         # Messages can be shared either in the UI, or by pasting an archive link.  The latter
         # unfurls async (it comes through as an edit, which we ignore), so instead we can look
         # up the message ourselves and embed it.
         regex = r"https://{}.slack.com/archives/([^/]+)/p([0-9]+)".format(
             slack._team["domain"])
         for channel_id, link in re.findall(regex, text):
             # Archive links are strange and drop the period from the ts value.
             ts = link[:-6] + "." + link[-6:]
             refs = [
                 attach.id for attach in attachments
                 if isinstance(attach, immp.Receipt)
             ]
             if ts not in refs:
                 try:
                     receipt = immp.Receipt(ts,
                                            immp.Channel(slack, channel_id))
                     attachments.append(await
                                        slack.resolve_message(receipt))
                 except MessageNotFound:
                     pass
         if re.match("^<{}>$".format(regex), text):
             # Strip the message text if the entire body was just a link.
             text = None
         else:
             text = await SlackRichText.from_mrkdwn(slack, text)
     return immp.SentMessage(id_=id_,
                             channel=channel,
                             at=at,
                             revision=revision,
                             edited=edited,
                             deleted=deleted,
                             text=text,
                             user=user,
                             action=action,
                             reply_to=reply_to,
                             joined=joined,
                             left=left,
                             title=title,
                             attachments=attachments,
                             raw=json)
Exemplo n.º 4
0
 def from_unfurl(cls, slack, attach):
     unfurl = _Schema.msg_unfurl(attach)
     return immp.Receipt(unfurl["ts"],
                         immp.Channel(slack, unfurl["channel_id"]))
Exemplo n.º 5
0
    async def from_message(cls,
                           discord_,
                           message,
                           edited=False,
                           deleted=False):
        """
        Convert a :class:`discord.Message` into a :class:`.Message`.

        Args:
            discord (.DiscordPlug):
                Related plug instance that provides the event.
            message (discord.Message):
                Discord message object received from a channel.
            edited (bool):
                Whether this message comes from an edit event.
            deleted (bool):
                Whether this message comes from a delete event.

        Returns:
            .DiscordMessage:
                Parsed message object.
        """
        text = reply_to = None
        channel = immp.Channel(discord_, message.channel.id)
        user = DiscordUser.from_user(discord_, message.author)
        attachments = []
        if message.content:
            text = DiscordRichText.from_message(discord_, message)
        if message.reference:
            receipt = immp.Receipt(
                message.reference.message_id,
                immp.Channel(discord_, message.reference.channel_id))
            reply_to = await discord_.get_message(receipt)
        for attach in message.attachments:
            if attach.filename.endswith((".jpg", ".png", ".gif")):
                type_ = immp.File.Type.image
            elif attach.filename.endswith((".mp4", ".webm")):
                type_ = immp.File.Type.video
            else:
                type_ = immp.File.Type.unknown
            attachments.append(
                immp.File(title=attach.filename,
                          type_=type_,
                          source=attach.url))
        for embed in message.embeds:
            if embed.image.url and embed.image.url.rsplit(
                    ".", 1)[1] in ("jpg", "png", "gif"):
                attachments.append(
                    immp.File(type_=immp.File.Type.image,
                              source=embed.image.url))
        return immp.SentMessage(
            id_=message.id,
            channel=channel,
            # Timestamps are naive but in UTC.
            at=message.created_at.replace(tzinfo=timezone.utc),
            # Edited timestamp is blank for new messages, but updated in
            # existing objects when the message is later edited.
            revision=(message.edited_at or message.created_at).timestamp(),
            edited=edited,
            deleted=deleted,
            text=text,
            user=user,
            reply_to=reply_to,
            attachments=attachments,
            raw=message)