Add room unbridge command
This commit is contained in:
@@ -85,6 +85,8 @@
|
|||||||
* [x] Upgrading the chat of a portal room into a supergroup (`upgrade`)
|
* [x] Upgrading the chat of a portal room into a supergroup (`upgrade`)
|
||||||
* [x] Change username of supergroup/channel (`group-name`)
|
* [x] Change username of supergroup/channel (`group-name`)
|
||||||
* [x] Getting the Telegram invite link to a Matrix room (`invite-link`)
|
* [x] Getting the Telegram invite link to a Matrix room (`invite-link`)
|
||||||
|
* [ ] Bridging existing Matrix rooms to existing Telegram chats (`bridge`)
|
||||||
|
* [ ] Unbridging Matrix rooms from Telegram chats (`unbridge`)
|
||||||
* Bridge administration
|
* Bridge administration
|
||||||
* [x] Clean up and forget a portal room (`delete-portal`)
|
* [x] Clean up and forget a portal room (`delete-portal`)
|
||||||
* [x] Find and clean up old portal rooms (`clean-rooms`)
|
* [x] Find and clean up old portal rooms (`clean-rooms`)
|
||||||
|
|||||||
@@ -127,10 +127,10 @@ class StateStore:
|
|||||||
def get_power_levels(self, room):
|
def get_power_levels(self, room):
|
||||||
return self.power_levels[room]
|
return self.power_levels[room]
|
||||||
|
|
||||||
def has_power_level(self, room, user, event, is_state_event=False):
|
def has_power_level(self, room, user, event, is_state_event=False, default=None):
|
||||||
room_levels = self.power_levels.get(room, {})
|
room_levels = self.power_levels.get(room, {})
|
||||||
default_required = (room_levels.get("state_default", 50) if is_state_event
|
default_required = default or (room_levels.get("state_default", 50) if is_state_event
|
||||||
else room_levels.get("events_default", 0))
|
else room_levels.get("events_default", 0))
|
||||||
required = room_levels.get("events", {}).get(event, default_required)
|
required = room_levels.get("events", {}).get(event, default_required)
|
||||||
has = room_levels.get("users", {}).get(user, room_levels.get("users_default", 0))
|
has = room_levels.get("users", {}).get(user, room_levels.get("users_default", 0))
|
||||||
return has >= required
|
return has >= required
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ async def execute_room_cleanup(evt, rooms_to_clean):
|
|||||||
await room.cleanup_and_delete()
|
await room.cleanup_and_delete()
|
||||||
cleaned += 1
|
cleaned += 1
|
||||||
elif isinstance(room, str):
|
elif isinstance(room, str):
|
||||||
await po.Portal.cleanup_room(evt.az.intent, room, type="Room")
|
await po.Portal.cleanup_room(evt.az.intent, room, message="Room deleted")
|
||||||
cleaned += 1
|
cleaned += 1
|
||||||
evt.sender.command_status = None
|
evt.sender.command_status = None
|
||||||
await evt.reply(f"{cleaned} rooms cleaned up successfully.")
|
await evt.reply(f"{cleaned} rooms cleaned up successfully.")
|
||||||
|
|||||||
@@ -69,8 +69,10 @@ def help(evt):
|
|||||||
#### Portal management
|
#### Portal management
|
||||||
**upgrade** - Upgrade a normal Telegram group to a supergroup.
|
**upgrade** - Upgrade a normal Telegram group to a supergroup.
|
||||||
**invite-link** - Get a Telegram invite link to the current chat.
|
**invite-link** - Get a Telegram invite link to the current chat.
|
||||||
**delete-portal** - Forget the current portal room. Only works for group chats; to delete
|
**delete-portal** - Remove all users from the current portal room and forget the portal.
|
||||||
a private chat portal, simply leave the room.
|
Only works for group chats; to delete a private chat portal, simply
|
||||||
|
leave the room.
|
||||||
|
**unbridge** - Remove puppets from the current portal room and forget the portal.
|
||||||
**group-name** <_name_|`-`> - Change the username of a supergroup/channel. To disable, use a dash
|
**group-name** <_name_|`-`> - Change the username of a supergroup/channel. To disable, use a dash
|
||||||
(`-`) as the name.
|
(`-`) as the name.
|
||||||
**clean-rooms** - Clean up unused portal/management rooms.
|
**clean-rooms** - Clean up unused portal/management rooms.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
from telethon.errors import *
|
from telethon.errors import *
|
||||||
|
from mautrix_appservice import MatrixRequestError
|
||||||
|
|
||||||
from .. import portal as po
|
from .. import portal as po
|
||||||
from . import command_handler
|
from . import command_handler
|
||||||
@@ -38,34 +39,78 @@ async def invite_link(evt):
|
|||||||
return await evt.reply("You don't have the permission to create an invite link.")
|
return await evt.reply("You don't have the permission to create an invite link.")
|
||||||
|
|
||||||
|
|
||||||
@command_handler(needs_admin=True)
|
async def _has_access_to(room, intent, sender, event, default=50):
|
||||||
async def delete_portal(evt):
|
if sender.is_admin:
|
||||||
room_id = evt.args[0] if len(evt.args) > 0 else evt.room_id
|
return True
|
||||||
|
# Make sure the state store contains the power levels.
|
||||||
|
try:
|
||||||
|
await intent.get_power_levels(room)
|
||||||
|
except MatrixRequestError:
|
||||||
|
return False
|
||||||
|
return intent.state_store.has_power_level(room, sender.mxid,
|
||||||
|
event=f"net.maunium.telegram.{event}",
|
||||||
|
default=default)
|
||||||
|
|
||||||
|
|
||||||
|
async def _get_portal_and_check_permission(evt, permission, action=None, allow_that=False):
|
||||||
|
room_id = evt.args[0] if len(evt.args) > 0 and allow_that else evt.room_id
|
||||||
|
|
||||||
portal = po.Portal.get_by_mxid(room_id)
|
portal = po.Portal.get_by_mxid(room_id)
|
||||||
if not portal:
|
if not portal:
|
||||||
that_this = "This" if room_id == evt.room_id else "That"
|
that_this = "This" if room_id == evt.room_id else "That"
|
||||||
return await evt.reply(f"{that_this} is not a portal room.")
|
return await evt.reply(f"{that_this} is not a portal room."), False
|
||||||
|
|
||||||
|
if not _has_access_to(portal.mxid, portal.main_intent, evt.sender, permission):
|
||||||
|
action = action or f"{permission.replace('_', ' ')}s"
|
||||||
|
return await evt.reply(f"You do not have the permissions to {action}."), False
|
||||||
|
return portal, True
|
||||||
|
|
||||||
|
|
||||||
|
def _get_portal_murder_function(action, room_id, function, command, completed_message):
|
||||||
async def post_confirm(confirm):
|
async def post_confirm(confirm):
|
||||||
evt.sender.command_status = None
|
confirm.sender.command_status = None
|
||||||
if len(confirm.args) > 0 and confirm.args[0] == "confirm-delete":
|
if len(confirm.args) > 0 and confirm.args[0] == f"confirm-{command}":
|
||||||
await portal.cleanup_and_delete()
|
await function()
|
||||||
if confirm.room_id != room_id:
|
if confirm.room_id != room_id:
|
||||||
return await confirm.reply("Portal successfully deleted.")
|
return await confirm.reply(completed_message)
|
||||||
else:
|
else:
|
||||||
return await confirm.reply("Portal deletion cancelled.")
|
return await confirm.reply(f"{action} cancelled.")
|
||||||
|
|
||||||
evt.sender.command_status = {
|
return {
|
||||||
"next": post_confirm,
|
"next": post_confirm,
|
||||||
"action": "Portal deletion",
|
"action": action,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@command_handler()
|
||||||
|
async def delete_portal(evt):
|
||||||
|
portal, ok = await _get_portal_and_check_permission(evt, "delete_portal")
|
||||||
|
if not ok:
|
||||||
|
return
|
||||||
|
|
||||||
|
evt.sender.command_status = _get_portal_murder_function("Portal deletion", portal.mxid,
|
||||||
|
portal.cleanup_and_delete, "delete",
|
||||||
|
"Portal successfully deleted.")
|
||||||
return await evt.reply("Please confirm deletion of portal "
|
return await evt.reply("Please confirm deletion of portal "
|
||||||
f"[{room_id}](https://matrix.to/#/{room_id}) "
|
f"[{portal.alias or portal.mxid}](https://matrix.to/#/{portal.mxid}) "
|
||||||
f"to Telegram chat \"{portal.title}\" "
|
f"to Telegram chat \"{portal.title}\" "
|
||||||
"by typing `$cmdprefix+sp confirm-delete`")
|
"by typing `$cmdprefix+sp confirm-delete`")
|
||||||
|
|
||||||
|
|
||||||
|
@command_handler()
|
||||||
|
async def unbridge(evt):
|
||||||
|
portal, ok = await _get_portal_and_check_permission(evt, "unbridge_room", allow_that=False)
|
||||||
|
if not ok:
|
||||||
|
return
|
||||||
|
|
||||||
|
evt.sender.command_status = _get_portal_murder_function("Room unbridging", portal.mxid,
|
||||||
|
portal.unbridge, "unbridge",
|
||||||
|
"Room successfully unbridged.")
|
||||||
|
return await evt.reply(f"Please confirm unbridging chat \"{portal.title}\" from room "
|
||||||
|
f"[{portal.alias or portal.mxid}](https://matrix.to/#/{portal.mxid}) "
|
||||||
|
"by typing `$cmdprefix+sp confirm-unbridge`")
|
||||||
|
|
||||||
|
|
||||||
async def _get_initial_state(evt):
|
async def _get_initial_state(evt):
|
||||||
state = await evt.az.intent.get_room_state(evt.room_id)
|
state = await evt.az.intent.get_room_state(evt.room_id)
|
||||||
title = None
|
title = None
|
||||||
|
|||||||
@@ -484,19 +484,24 @@ class Portal:
|
|||||||
return authenticated
|
return authenticated
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def cleanup_room(intent, room_id, type="Portal"):
|
async def cleanup_room(intent, room_id, message="Portal deleted", puppets_only=False):
|
||||||
try:
|
try:
|
||||||
members = await intent.get_room_members(room_id)
|
members = await intent.get_room_members(room_id)
|
||||||
except MatrixRequestError:
|
except MatrixRequestError:
|
||||||
members = []
|
members = []
|
||||||
for user in members:
|
for user in members:
|
||||||
if user != intent.mxid:
|
is_puppet = p.Puppet.get_id_from_mxid(user)
|
||||||
|
if user != intent.mxid and (not puppets_only or is_puppet):
|
||||||
try:
|
try:
|
||||||
await intent.kick(room_id, user, f"{type} deleted.")
|
await intent.kick(room_id, user, message)
|
||||||
except (MatrixRequestError, IntentError):
|
except (MatrixRequestError, IntentError):
|
||||||
pass
|
pass
|
||||||
await intent.leave_room(room_id)
|
await intent.leave_room(room_id)
|
||||||
|
|
||||||
|
async def unbridge(self):
|
||||||
|
await self.cleanup_room(self.main_intent, self.mxid, "Room unbridged", puppets_only=True)
|
||||||
|
self.delete()
|
||||||
|
|
||||||
async def cleanup_and_delete(self):
|
async def cleanup_and_delete(self):
|
||||||
await self.cleanup_room(self.main_intent, self.mxid)
|
await self.cleanup_room(self.main_intent, self.mxid)
|
||||||
self.delete()
|
self.delete()
|
||||||
|
|||||||
Reference in New Issue
Block a user