async def _update_about(self, about: str, sender: Optional['p.Puppet'] = None, save: bool = False) -> bool: if self.about == about: return False self.about = about await self._try_set_state(sender, EventType.ROOM_TOPIC, RoomTopicStateEventContent(topic=self.about)) if save: self.save() return True
def set_room_topic(self, room_id: RoomID, topic: str, **kwargs) -> Awaitable[EventID]: return self.send_state_event(room_id, EventType.ROOM_TOPIC, RoomTopicStateEventContent(topic=topic), **kwargs)
async def urandom(self, evt: MessageEvent, args: Args) -> None: evt.disable_reply = "reply" not in args and "replay" not in args if "help" in args: await evt.reply(helps.get(args["help"], HELP_UNKNOWN)) return try: length = int(args["len"]) except (KeyError, ValueError): length = DEFAULT_LENGTH if length > MAX_LENGTH: await evt.reply("Too high length") return elif length < 0: await evt.reply("Invalid length") return rand = sys_rand if "seed" in args: if args["seed"] == True: rand = random else: try: rand = random.Random(int(args["seed"])) except ValueError: await evt.reply("Invalid seed") return if "alphabet" in args: alphabet = args["alphabet"] if "space" in args: alphabet = alphabet.replace(args["space"], " ") if "permutation" in args or "shuffle" in args: data = list(alphabet) rand.shuffle(data) randomness = "".join(data) else: randomness = "".join(rand.choices(alphabet, k=length or DEFAULT_LENGTH)) elif "urange" in args: ranges: List[Tuple[int, int]] = [] weights: List[int] = [] try: lim = range(0x110000) for urange in args["urange"].split(","): start, end = parse_urange(urange.strip()) if start == 0 or end == 0: await evt.reply( 'Exception in thread "main" java.lang.NullPointerException \n' ' at Urandom.handle_command(Urandom.java:216)') return if start not in lim: raise ValueError("range start not in range(0x110000)") elif end not in lim: raise ValueError("range end not in range(0x110000)") ranges.append((start, end + 1)) weights.append(end - start + 1) except (KeyError, ValueError): await evt.reply("Invalid unicode range") self.log.exception("Invalid unicode range") return randomness = "".join(chr(rand.randrange(start, end)) for start, end in rand.choices(ranges, weights, k=length or DEFAULT_LENGTH)) else: urandom = (sys_urandom if rand == sys_rand else lambda n: bytes(rand.randint(0, 255) for i in range(n))) randomness = urandom(length or DEFAULT_LENGTH) base = args.get("base", DEFAULT_BASE) if base == "raw": randomness = str(randomness) elif base == "16" or base == "hex": randomness = b16encode(randomness).decode("utf-8") elif base == "32": randomness = b32encode(randomness).decode("utf-8").rstrip("=") elif base == "64": randomness = b64encode(randomness).decode("utf-8").rstrip("=") elif base == "85": randomness = b85encode(randomness).decode("utf-8") elif base == "65536": randomness = b65536encode(randomness) else: await evt.reply("Unknown base") if "topic" in args: await self.client.send_state_event(evt.room_id, EventType.ROOM_TOPIC, RoomTopicStateEventContent(topic=randomness)) else: await evt.reply(TextMessageEventContent(body=randomness, msgtype=MessageType.NOTICE))
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