Esempio n. 1
0
    async def _update_title(self, title: str, sender: Optional['p.Puppet'] = None,
                            save: bool = False) -> bool:
        if self.title == title:
            return False

        self.title = title
        await self._try_set_state(sender, EventType.ROOM_NAME,
                                  RoomNameStateEventContent(name=self.title))
        if save:
            self.save()
        return True
Esempio n. 2
0
 def set_room_name(self, room_id: RoomID, name: str,
                   **kwargs) -> Awaitable[EventID]:
     return self.send_state_event(room_id, EventType.ROOM_NAME,
                                  RoomNameStateEventContent(name=name),
                                  **kwargs)
Esempio n. 3
0
    async def _exec(self, evt: MessageEvent, **kwargs: Any) -> None:
        if not self._exec_ok(evt):
            self.log.debug(f"Ignoring exec {evt.event_id} from {evt.sender} in {evt.room_id}")
            return

        http = self.client.api.session
        old_name = await self.get_cached_name(evt.room_id)
        old_topic = await self.get_cached_topic(evt.room_id)
        devices = {}
        if old_name:
            devices["name"] = old_name
        if old_topic:
            devices["topic"] = old_topic
        reply_to_id = evt.content.get_reply_to()
        if reply_to_id:
            reply_to_evt = await self.client.get_event(evt.room_id, reply_to_id)
            if reply_to_evt.content.msgtype.is_media:
                url = self.client.api.get_download_url(reply_to_evt.content.url)
                max_size = 8 * 1024 * 1024
                async with self.client.api.session.head(url) as response:
                    if int(response.headers["Content-Length"]) > max_size:
                        await evt.reply("File too large")
                        return
                file = await self.client.download_media(reply_to_evt.content.url)
                if len(file) > max_size:
                    await evt.reply("File too large")
                    return
                devices["reply"] = base64.b64encode(file).decode("utf-8")
            else:
                devices["reply"] = reply_to_evt.content.body

        localpart, server = self.client.parse_user_id(evt.sender)
        resp = await http.post(self.config["server"], data=json.dumps({
            **kwargs,
            "user": evt.sender,
            "home": re.sub(r"//+", "/", f"/{server}/{localpart}"),
            "devices": devices,
        }))
        if resp.status == 502:
            await evt.respond("maush is currently down")
            return
        data = await resp.json()
        self.log.debug("Execution response for %s: %s", evt.sender, data)
        if not data["ok"]:
            self.log.error("Exec failed: %s", data["error"])
            await evt.respond(data["error"])
            return

        dur = round(data["duration"] / 1_000_000, 1)
        ret = data["return"]
        if ret != 0:
            resp = f"Exited with code {ret} in {dur} ms. "
        else:
            resp = f"Completed in {dur} ms. "
        if data["timeout"]:
            resp += "**Execution timed out**. "
        if data["stdout"]:
            stdout = data["stdout"].strip().replace("```", r"\```")
            if len(stdout) >= 8190:
                stdout = stdout[:8192] + "[…]"
            resp += f"**stdout:**\n```\n{stdout}\n```\n"
        if data["stderr"]:
            stderr = data["stderr"].strip().replace("```", r"\```")
            if len(stderr) >= 8190:
                stderr = stderr[:8192] + "[…]"
            resp += f"**stderr:**\n```\n{stderr}\n```\n"

        resp = resp.strip()
        if resp:
            await evt.respond(resp)

        new_dev = data["devices"]
        new_name = new_dev.get("name") or ""
        if new_name:
            new_name = new_name.strip()
        new_topic = new_dev.get("topic") or ""
        if new_topic:
            new_topic = new_topic.strip()
        if new_name != old_name:
            await self.client.send_state_event(evt.room_id, EventType.ROOM_NAME,
                                               RoomNameStateEventContent(name=new_name))
            self.name_cache[evt.room_id] = new_name
        if new_topic != old_topic:
            await self.client.send_state_event(evt.room_id, EventType.ROOM_TOPIC,
                                               RoomTopicStateEventContent(topic=new_topic))
            self.topic_cache[evt.room_id] = new_topic