Ejemplo n.º 1
0
async def _print_comic(bot, event, num=None):
    info = await _get_comic(bot, num)
    image_id = info['image_id']

    context = {
        "parser": False,
    }

    msg1 = [
        ChatMessageSegment("xkcd #%s: " % info['num']),
        ChatMessageSegment(info["title"], is_bold=True),
    ]
    msg2 = [
        ChatMessageSegment(info["alt"]),
    ] + ChatMessageSegment.from_str(
        '\n- <i><a href="https://xkcd.com/%s">CC-BY-SA xkcd</a></i>' %
        info['num'])
    if "link" in info and info["link"]:
        msg2.extend(
            ChatMessageSegment.from_str("\n* see also %s" % info["link"]))

    await bot.coro_send_message(event.conv.id_, msg1, context)
    await bot.coro_send_message(
        event.conv.id_, msg2, context, image_id=image_id
    )  # image appears above text, so order is [msg1, image, msg2]
Ejemplo n.º 2
0
    async def _async_send_message(self, message, targets):
        conversations = []
        for target in targets:
            conversation = None
            if 'id' in target:
                conversation = self._conversation_list.get(target['id'])
            elif 'name' in target:
                conversation = self._resolve_conversation_name(target['name'])
            if conversation is not None:
                conversations.append(conversation)

        if not conversations:
            return False

        from hangups import ChatMessageSegment, hangouts_pb2
        messages = []
        for segment in message:
            if 'parse_str' in segment and segment['parse_str']:
                messages.extend(ChatMessageSegment.from_str(segment['text']))
            else:
                if 'parse_str' in segment:
                    del segment['parse_str']
                messages.append(ChatMessageSegment(**segment))
            messages.append(ChatMessageSegment('',
                                               segment_type=hangouts_pb2.
                                               SEGMENT_TYPE_LINE_BREAK))

        if not messages:
            return False
        for conv in conversations:
            await conv.send_message(messages)
Ejemplo n.º 3
0
    def post(self, request, format=None):
        serializer = MessageSerializer(data=request.data)
        serializer.is_valid()
        message = serializer.data

        m = Members
        client = m.get_client(message.get('user_id'))
        if client:
            conversation = client._conv_list.get(message.get('conv_id'))
            loop = m.get_loop(message.get('user_id'))
            if conversation:
                # testできたら移動
                text = message.get('message')
                image_file = None
                segments = ChatMessageSegment.from_str(text)

                asyncio.async(
                    conversation.send_message(segments, image_file=image_file),
                    loop=loop
                ).add_done_callback(self._on_message_sent)

                return HttpResponse("ok")

        # 該当するuser, conv_idがない場合
        raise Http404
Ejemplo n.º 4
0
    async def _async_send_message(self, message, targets):
        conversations = []
        for target in targets:
            conversation = None
            if CONF_CONVERSATION_ID in target:
                conversation = self._conversation_list.get(
                    target[CONF_CONVERSATION_ID])
            elif CONF_CONVERSATION_NAME in target:
                conversation = self._resolve_conversation_name(
                    target[CONF_CONVERSATION_NAME])
            if conversation is not None:
                conversations.append(conversation)

        if not conversations:
            return False

        from hangups import ChatMessageSegment, hangouts_pb2
        messages = []
        for segment in message:
            if 'parse_str' in segment and segment['parse_str']:
                messages.extend(ChatMessageSegment.from_str(segment['text']))
            else:
                if 'parse_str' in segment:
                    del segment['parse_str']
                messages.append(ChatMessageSegment(**segment))
            messages.append(ChatMessageSegment('',
                                               segment_type=hangouts_pb2.
                                               SEGMENT_TYPE_LINE_BREAK))

        if not messages:
            return False
        for conv in conversations:
            await conv.send_message(messages)
Ejemplo n.º 5
0
def _print_comic(bot, event, num=None):
    info = yield from _get_comic(bot, num)
    image_id = info['image_id']
    
    context = {
        "parser": False,
    }
    
    msg1 = [
        ChatMessageSegment("xkcd #%s: " % info['num']),
        ChatMessageSegment(info["title"], is_bold=True),
    ]
    msg2 = [
        ChatMessageSegment(info["alt"]),
    ] + ChatMessageSegment.from_str('<br/>- <i><a href="https://xkcd.com/%s">CC-BY-SA xkcd</a></i>' % info['num'])
    if "link" in info and info["link"]:
        msg2.extend(ChatMessageSegment.from_str("<br/>* see also %s" % info["link"]))
    
    yield from bot.coro_send_message(event.conv.id_, msg1, context)
    yield from bot.coro_send_message(event.conv.id_, msg2, context, image_id=image_id) # image appears above text, so order is [msg1, image, msg2]
Ejemplo n.º 6
0
    def _update(self, data) -> None:
        self.reachable = getattr(data, 'reachable', None)
        self.available = getattr(data, 'available', None)

        device_status = getattr(data, 'device_status', None)

        self.mobile = getattr(device_status, 'mobile', None)
        self.desktop = getattr(device_status, 'desktop', None)
        self.tablet = getattr(device_status, 'tablet', None)

        mood_message = getattr(data, 'mood_message', None)
        mood_content = getattr(mood_message, 'mood_content', None)
        segment = getattr(mood_content, 'segment', None)
        mood_segment = [ChatMessageSegment.deserialize(segment) for segment in segment]

        self.mood_message = [segment.text for segment in mood_segment]

        last_seen = getattr(data, 'last_seen', None)

        self.last_seen = parsers.from_timestamp(getattr(last_seen, 'last_seen_timestamp_usec', None))
        self.since_last_seen = getattr(last_seen, 'usec_since_last_seen', None) // 1000000
Ejemplo n.º 7
0
    def get(self, request):
        m = Members
        client = m.get_client('test')
        if client:
            conversation = client._conv_list.get('UgyUUHcz02x_EFXA-Ht4AaABAagB_N-DBw')
            if conversation:
                # testできたら移動
                text = 'メッセージ送信テスト'
                image_file = None
                segments = ChatMessageSegment.from_str(text)

                loop = m.get_loop('test')
                asyncio.async(
                    conversation.send_message(segments, image_file=image_file),
                    loop=loop
                ).add_done_callback(self._on_message_sent)

                # 成功したら最新のconversationを返却
                # 若干遅延するからやめておきたい
                serializer = ConversationSerializer(conversation)
                return JSONResponse(serializer.data)

        # 該当するuser, conv_idがない場合
        raise Http404
Ejemplo n.º 8
0
    async def _async_send_message(self, message, targets, data):
        conversations = []
        for target in targets:
            conversation = None
            if CONF_CONVERSATION_ID in target:
                conversation = self._conversation_list.get(
                    target[CONF_CONVERSATION_ID])
            elif CONF_CONVERSATION_NAME in target:
                conversation = self._resolve_conversation_name(
                    target[CONF_CONVERSATION_NAME])
            if conversation is not None:
                conversations.append(conversation)

        if not conversations:
            return False

        from hangups import ChatMessageSegment, hangouts_pb2
        messages = []
        for segment in message:
            if messages:
                messages.append(ChatMessageSegment('',
                                                   segment_type=hangouts_pb2.
                                                   SEGMENT_TYPE_LINE_BREAK))
            if 'parse_str' in segment and segment['parse_str']:
                messages.extend(ChatMessageSegment.from_str(segment['text']))
            else:
                if 'parse_str' in segment:
                    del segment['parse_str']
                messages.append(ChatMessageSegment(**segment))

        image_file = None
        if data:
            if data.get('image_url'):
                uri = data.get('image_url')
                try:
                    websession = async_get_clientsession(self.hass)
                    async with websession.get(uri, timeout=5) as response:
                        if response.status != 200:
                            _LOGGER.error(
                                'Fetch image failed, %s, %s',
                                response.status,
                                response
                            )
                            image_file = None
                        else:
                            image_data = await response.read()
                            image_file = io.BytesIO(image_data)
                            image_file.name = "image.png"
                except (asyncio.TimeoutError, aiohttp.ClientError) as error:
                    _LOGGER.error(
                        'Failed to fetch image, %s',
                        type(error)
                    )
                    image_file = None
            elif data.get('image_file'):
                uri = data.get('image_file')
                if self.hass.config.is_allowed_path(uri):
                    try:
                        image_file = open(uri, 'rb')
                    except IOError as error:
                        _LOGGER.error(
                            'Image file I/O error(%s): %s',
                            error.errno,
                            error.strerror
                        )
                else:
                    _LOGGER.error('Path "%s" not allowed', uri)

        if not messages:
            return False
        for conv in conversations:
            await conv.send_message(messages, image_file)
Ejemplo n.º 9
0
def text_to_segments(text):
    """Create list of message segments from text"""
    return ChatMessageSegment.from_str(text)
Ejemplo n.º 10
0
    def receive(self, msg, conv, user):
        clients = []
        for userObject in conv.users:
            nick = name_to_nick(userObject.full_name)
            clients.append(nick)
        sender = name_to_nick(user.full_name)

        imageLinks = re.findall("((?:https?:\/\/)?(?:[\da-z\.-]+)\.(?:[a-z\.]{2,6})(?:[\/\w\.-]+)(\.jpg|\.png|\.jpeg|\.gif)\/?)", msg)
        for link in imageLinks:
            if link[0].find("https://lh3.googleusercontent") == -1:
                tmp_file = "/home/lshetron/.monopoly/tmp/" + str(random.randint(0,100)) + link[1]
                try:
                    with urllib.request.urlopen(link[0]) as response, open(tmp_file, "wb") as out:
                        data = response.read()
                        out.write(data)
                    self.message("", open(tmp_file, "rb"))
                except urllib.error.URLError as e:
                    print("Error opening file: ", e)
                except Exception as e:
                    print("Exception encountered: ", e)

        for subscriber, conv_id in self.swift.subscribers:
            re_mentions = re.compile('{0}|{1}|{2}'.format(name_to_nick(subscriber),
                                     *subscriber.split()), re.IGNORECASE)
            if (re.search(re_mentions, msg)
                and user.full_name != subscriber
                and len(clients) > 2
                and name_to_nick(subscriber) in clients):
                highlighted = re.sub(re_mentions, lambda x: '<b>' + x.group(0) + '</b>', msg)
                yield from self.swift.notify('<b>{0}</b> mentioned you in <i>{1}</i>:\n"{2}"'
                    .format(user.full_name, conv.name, highlighted), conv_id)
                print("Forwarded hangouts mention to {0}".format(subscriber))

        if re.search("!subscribe", msg, re.IGNORECASE):
            if user.full_name not in [name for name, id in self.swift.subscribers]:
                client_id = self.client.get_client_generated_id()
                inviteeID = hangouts_pb2.InviteeID(gaia_id=user.id_.gaia_id)
                conversation_request = hangouts_pb2.CreateConversationRequest(
                    request_header = self.client.get_request_header(),
                    type = CONVERSATION_TYPE_ONE_TO_ONE,
                    client_generated_id = client_id,
                    invitee_id = [inviteeID])
                res = yield from self.client.create_conversation(conversation_request)
                conv_id = res.conversation.conversation_id.id

                welcome_msg = ChatMessageSegment.from_str(
                    '<b>Welcome to Monopoly Swift Notifications!</b>\n' +
                    '<i>This channel will be used to receive alerts for IRC private ' +
                    'messages, channel mentions, and hangouts mentions.</i>\n\n' +
                    'To unsubscribe,\njust say <b><i>!unsubscribe</i></b>')
                new_conv = self.conv_list.get(conv_id)
                asyncio.async(new_conv.send_message(welcome_msg, image_file=None))

                if conv_id == conv.id_:
                    self.subscribe(user.full_name, conv_id, True)
                else:
                    self.subscribe(user.full_name, conv_id)
            else:
                self.message("<b>{0}</b> is already subscribed to receive alerts."
                    .format(user.full_name))

        elif re.search("!unsubscribe", msg, re.IGNORECASE):
            if user.full_name in [name for name, id in self.swift.subscribers]:
                for subscriber, id in self.swift.subscribers:
                    if user.full_name == subscriber:
                        self.unsubscribe(user.full_name, id)
            else:
                self.message("<b>{0}</b> is not currently subscribed to receive alerts."
                    .format(user.full_name))

        # Avoid outputting twice
        if re.search("trumpism", msg, re.IGNORECASE):
            if self.g_ratelimiter.queue(sender):
                self.message("<i>{0}</i>".format(self.donald.trumpism()))
        else:
            # TODO should ratelimit
            provoked = self.donald.provoke(msg)
            if provoked:
                self.message("<i>{0}</i>".format(provoked))

        buffer = super().receive(msg, sender, clients)
        self.send(buffer, conv)
Ejemplo n.º 11
0
 def _segments(self):
     """List of :class:`ChatMessageSegment` in message (:class:`list`)."""
     seg_list = self._event.chat_message.message_content.segment
     return [ChatMessageSegment.deserialize(seg) for seg in seg_list]
Ejemplo n.º 12
0
 def convert(self, source, slack):
     if isinstance(source, str):
         # Parse, then convert reparser.Segment to hangups.ChatMessageSegment.
         segments = [
             ChatMessageSegment(seg.text, **seg.params)
             for seg in self.parse(source)
         ]
     else:
         # We'll assume it's already a ChatMessageSegment list.
         segments = source
     formatted = ""
     current = []
     for seg in segments:
         if seg.type_ == hangouts_pb2.SEGMENT_TYPE_LINE_BREAK:
             # Insert closing tags for all current formatting, in reverse order.
             for chars in reversed(current):
                 formatted += chars
             # Start a new line.
             formatted += "\n"
             # Now reinsert the current formatting.
             for chars in current:
                 formatted += chars
             continue
         if self.from_slack:
             text = seg.text.replace("&gt;", ">").replace("&lt;",
                                                          "<").replace(
                                                              "&amp;", "&")
             if seg.link_target:
                 if seg.link_target[0] == "@":
                     # User link, just replace with the plain username.
                     user = seg.link_target[1:]
                     if user in slack.users:
                         user = slack.users[user]["name"]
                     text = "@{}".format(user)
                 elif seg.link_target[0] == "#":
                     # Channel link, just replace with the plain channel name.
                     channel = seg.link_target[1:]
                     if channel in slack.channels:
                         channel = slack.channels[channel]["name"]
                     text = "#{}".format(channel)
                 else:
                     # Markdown link: [label](target)
                     text = "[{}]({})".format(
                         text, message_parser.url_complete(seg.link_target))
         else:
             text = seg.text.replace("&", "&amp;").replace(">",
                                                           "&gt;").replace(
                                                               "<", "&lt;")
             if seg.link_target:
                 if text == seg.link_target:
                     # Slack implicit link: <target>
                     text = "<{}>".format(seg.link_target)
                 else:
                     # Slack link with label: <target|label>
                     text = "<{}|{}>".format(seg.link_target, text)
         # Compare formatting of the previous segment to the current one.
         formatting = {
             self.bold: seg.is_bold,
             self.italic: seg.is_italic,
             self.strike: seg.is_strikethrough
         }
         # Insert closing tags for any formatting that ends here.
         # Apply in reverse order to opened tags.
         for chars in reversed(current):
             if not formatting[chars]:
                 formatted += chars
                 current.remove(chars)
         # Insert opening tags for any formatting that starts here.
         for chars, condition in formatting.items():
             if condition and chars not in current:
                 formatted += chars
                 current.append(chars)
         # XXX: May generate tags closed in the wrong order: *bold _bold+italic* italic_
         # Testing suggests both Slack and Hangouts can cope with this though.
         formatted += text
     # Close any remaining format tags.
     formatted += "".join(reversed(current))
     return formatted
Ejemplo n.º 13
0
 def notify(self, message, conv_id):
     segment = ChatMessageSegment.from_str(message)
     conv = self.h_conv_list.get(conv_id)
     asyncio.async(conv.send_message(segment, image_file=None))
Ejemplo n.º 14
0
def text_to_segments(text):
    """Create list of message segments from text"""
    return ChatMessageSegment.from_str(text)
Ejemplo n.º 15
0
 def send(self, buffer, conv):
     for msg in buffer:
         segments = ChatMessageSegment.from_str(msg[0])
         asyncio.async(conv.send_message(segments, image_file=msg[1]))
Ejemplo n.º 16
0
    async def _async_send_message(self, message, targets, data):
        conversations = []
        for target in targets:
            conversation = None
            if CONF_CONVERSATION_ID in target:
                conversation = self._conversation_list.get(target[CONF_CONVERSATION_ID])
            elif CONF_CONVERSATION_NAME in target:
                conversation = self._resolve_conversation_name(
                    target[CONF_CONVERSATION_NAME]
                )
            if conversation is not None:
                conversations.append(conversation)

        if not conversations:
            return False

        from hangups import ChatMessageSegment, hangouts_pb2

        messages = []
        for segment in message:
            if messages:
                messages.append(
                    ChatMessageSegment(
                        "", segment_type=hangouts_pb2.SEGMENT_TYPE_LINE_BREAK
                    )
                )
            if "parse_str" in segment and segment["parse_str"]:
                messages.extend(ChatMessageSegment.from_str(segment["text"]))
            else:
                if "parse_str" in segment:
                    del segment["parse_str"]
                messages.append(ChatMessageSegment(**segment))

        image_file = None
        if data:
            if data.get("image_url"):
                uri = data.get("image_url")
                try:
                    websession = async_get_clientsession(self.hass)
                    async with websession.get(uri, timeout=5) as response:
                        if response.status != 200:
                            _LOGGER.error(
                                "Fetch image failed, %s, %s", response.status, response
                            )
                            image_file = None
                        else:
                            image_data = await response.read()
                            image_file = io.BytesIO(image_data)
                            image_file.name = "image.png"
                except (asyncio.TimeoutError, aiohttp.ClientError) as error:
                    _LOGGER.error("Failed to fetch image, %s", type(error))
                    image_file = None
            elif data.get("image_file"):
                uri = data.get("image_file")
                if self.hass.config.is_allowed_path(uri):
                    try:
                        image_file = open(uri, "rb")
                    except OSError as error:
                        _LOGGER.error(
                            "Image file I/O error(%s): %s", error.errno, error.strerror
                        )
                else:
                    _LOGGER.error('Path "%s" not allowed', uri)

        if not messages:
            return False
        for conv in conversations:
            await conv.send_message(messages, image_file)
Ejemplo n.º 17
0
 def __init__(self, text: str):
     self.text: str = text
     self._segment: List[ChatMessageSegment] = ChatMessageSegment.from_str(text)