diff --git a/alembic/versions/a328bf4f0932_store_encryption_state_event_in_db.py b/alembic/versions/a328bf4f0932_store_encryption_state_event_in_db.py
new file mode 100644
index 00000000..fa1c4367
--- /dev/null
+++ b/alembic/versions/a328bf4f0932_store_encryption_state_event_in_db.py
@@ -0,0 +1,38 @@
+"""Store encryption state event in db
+
+Revision ID: a328bf4f0932
+Revises: ccbaff858240
+Create Date: 2020-07-11 21:31:27.059813
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+from mautrix.client.state_store.sqlalchemy import SerializableType
+from mautrix.types import RoomEncryptionStateEventContent
+
+# revision identifiers, used by Alembic.
+revision = 'a328bf4f0932'
+down_revision = 'ccbaff858240'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ with op.batch_alter_table('mx_room_state', schema=None) as batch_op:
+ batch_op.add_column(sa.Column('encryption',
+ SerializableType(RoomEncryptionStateEventContent),
+ nullable=True))
+ batch_op.add_column(sa.Column('has_full_member_list', sa.Boolean(), nullable=True))
+ batch_op.add_column(sa.Column('is_encrypted', sa.Boolean(), nullable=True))
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ with op.batch_alter_table('mx_room_state', schema=None) as batch_op:
+ batch_op.drop_column('is_encrypted')
+ batch_op.drop_column('has_full_member_list')
+ batch_op.drop_column('encryption')
+ # ### end Alembic commands ###
diff --git a/mautrix_telegram/__main__.py b/mautrix_telegram/__main__.py
index 1af2ea3c..96baf513 100644
--- a/mautrix_telegram/__main__.py
+++ b/mautrix_telegram/__main__.py
@@ -17,6 +17,7 @@ from typing import Optional
from alchemysession import AlchemySessionContainer
+from mautrix.types import UserID, RoomID
from mautrix.bridge import Bridge
from mautrix.util.db import Base
@@ -32,7 +33,6 @@ from .formatter import init as init_formatter
from .matrix import MatrixHandler
from .portal import Portal, init as init_portal
from .puppet import Puppet, init as init_puppet
-from .sqlstatestore import SQLStateStore
from .user import User, init as init_user
from .version import version, linkified_version
@@ -53,7 +53,6 @@ class TelegramBridge(Bridge):
markdown_version = linkified_version
config_class = Config
matrix_class = MatrixHandler
- state_store_class = SQLStateStore
config: Config
session_container: AlchemySessionContainer
@@ -119,5 +118,17 @@ class TelegramBridge(Bridge):
self.manhole.close()
self.manhole = None
+ async def get_user(self, user_id: UserID) -> User:
+ return await User.get_by_mxid(user_id).ensure_started()
+
+ async def get_portal(self, room_id: RoomID) -> Portal:
+ return Portal.get_by_mxid(room_id)
+
+ async def get_puppet(self, user_id: UserID, create: bool = False) -> Puppet:
+ return Puppet.get_by_mxid(user_id, create=create)
+
+ async def get_double_puppet(self, user_id: UserID) -> Puppet:
+ return Puppet.get_by_custom_mxid(user_id)
+
TelegramBridge().run()
diff --git a/mautrix_telegram/commands/portal/util.py b/mautrix_telegram/commands/portal/util.py
index 6a2c156d..67ca5482 100644
--- a/mautrix_telegram/commands/portal/util.py
+++ b/mautrix_telegram/commands/portal/util.py
@@ -56,4 +56,4 @@ async def user_has_power_level(room_id: RoomID, intent: IntentAPI, sender: u.Use
except MatrixRequestError:
return False
event_type = EventType.find(f"net.maunium.telegram.{event}", t_class=EventType.Class.STATE)
- return intent.state_store.has_power_level(room_id, sender.mxid, event_type)
+ return await intent.state_store.has_power_level(room_id, sender.mxid, event_type)
diff --git a/mautrix_telegram/db/__init__.py b/mautrix_telegram/db/__init__.py
index 92a824f0..67c9779a 100644
--- a/mautrix_telegram/db/__init__.py
+++ b/mautrix_telegram/db/__init__.py
@@ -15,7 +15,7 @@
# along with this program. If not, see .
from sqlalchemy.engine.base import Engine
-from mautrix.bridge.db import UserProfile, RoomState
+from mautrix.client.state_store.sqlalchemy import UserProfile, RoomState
from .bot_chat import BotChat
from .message import Message
@@ -28,7 +28,4 @@ from .user import User, UserPortal, Contact
def init(db_engine: Engine) -> None:
for table in (Portal, Message, User, Contact, UserPortal, Puppet, TelegramFile, UserProfile,
RoomState, BotChat):
- table.db = db_engine
- table.t = table.__table__
- table.c = table.t.c
- table.column_names = table.c.keys()
+ table.bind(db_engine)
diff --git a/mautrix_telegram/example-config.yaml b/mautrix_telegram/example-config.yaml
index 3ec9ed5a..8f60b5f9 100644
--- a/mautrix_telegram/example-config.yaml
+++ b/mautrix_telegram/example-config.yaml
@@ -217,7 +217,7 @@ bridge:
# or a pickle file if the appservice database is sqlite.
#
# Format examples:
- # Pickle: pickle://filename.pickle
+ # Pickle: pickle:///filename.pickle
# Postgres: postgres://username:password@hostname/dbname
database: default
# Whether or not to explicitly set the avatar and room name for private
diff --git a/mautrix_telegram/matrix.py b/mautrix_telegram/matrix.py
index 06e1aa5b..3d2dc993 100644
--- a/mautrix_telegram/matrix.py
+++ b/mautrix_telegram/matrix.py
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-from typing import Dict, Set, Tuple, Union, Iterable, List, TYPE_CHECKING
+from typing import Dict, Set, Tuple, Union, Iterable, TYPE_CHECKING
from mautrix.bridge import BaseMatrixHandler
from mautrix.types import (Event, EventType, RoomID, UserID, EventID, ReceiptEvent, ReceiptType,
@@ -60,15 +60,6 @@ class MatrixHandler(BaseMatrixHandler):
self.bot = context.bot
self.previously_typing = {}
- async def get_user(self, user_id: UserID) -> 'u.User':
- return await u.User.get_by_mxid(user_id).ensure_started()
-
- async def get_portal(self, room_id: RoomID) -> 'po.Portal':
- return po.Portal.get_by_mxid(room_id)
-
- async def get_puppet(self, user_id: UserID) -> 'pu.Puppet':
- return pu.Puppet.get_by_mxid(user_id)
-
async def handle_puppet_invite(self, room_id: RoomID, puppet: pu.Puppet, inviter: u.User,
event_id: EventID) -> None:
intent = puppet.default_mxid_intent
diff --git a/mautrix_telegram/portal/base.py b/mautrix_telegram/portal/base.py
index b6d8c494..67170d3b 100644
--- a/mautrix_telegram/portal/base.py
+++ b/mautrix_telegram/portal/base.py
@@ -234,7 +234,7 @@ class BasePortal(ABC):
except MatrixRequestError:
return False
evt_type = EventType.find(f"net.maunium.telegram.{event}", t_class=EventType.Class.STATE)
- return self.main_intent.state_store.has_power_level(self.mxid, user.mxid, evt_type)
+ return await self.main_intent.state_store.has_power_level(self.mxid, user.mxid, evt_type)
def get_input_entity(self, user: 'AbstractUser'
) -> Awaitable[Union[TypeInputPeer, TypeInputChannel]]:
diff --git a/mautrix_telegram/portal/metadata.py b/mautrix_telegram/portal/metadata.py
index b50d3f90..26651cdd 100644
--- a/mautrix_telegram/portal/metadata.py
+++ b/mautrix_telegram/portal/metadata.py
@@ -219,14 +219,14 @@ class PortalMetadata(BasePortal, ABC):
if changed:
self.save()
await self.update_bridge_info()
- if self.sync_matrix_state:
- await self.main_intent.get_joined_members(self.mxid)
puppet = p.Puppet.get_by_custom_mxid(user.mxid)
if puppet:
try:
await puppet.intent.ensure_joined(self.mxid)
except Exception:
self.log.exception("Failed to ensure %s is joined to portal", user.mxid)
+ if self.sync_matrix_state:
+ await self.main_intent.get_joined_members(self.mxid)
async def create_matrix_room(self, user: 'AbstractUser', entity: Union[TypeChat, User] = None,
invites: InviteList = None, update_if_exists: bool = True,
@@ -409,7 +409,7 @@ class PortalMetadata(BasePortal, ABC):
self.mxid = room_id
self.by_mxid[self.mxid] = self
self.save()
- self.az.state_store.set_power_levels(self.mxid, power_levels)
+ await self.az.state_store.set_power_levels(self.mxid, power_levels)
user.register_portal(self)
asyncio.ensure_future(self.update_matrix_room(user, entity, direct, puppet,
levels=power_levels, users=users,
diff --git a/mautrix_telegram/portal/telegram.py b/mautrix_telegram/portal/telegram.py
index a581361c..bb27d5ca 100644
--- a/mautrix_telegram/portal/telegram.py
+++ b/mautrix_telegram/portal/telegram.py
@@ -451,8 +451,8 @@ class PortalTelegram(BasePortal, ABC):
await self.create_matrix_room(source, invites=[source.mxid], update_if_exists=False)
if (self.peer_type == "user" and sender.tgid == self.tg_receiver
- and not sender.is_real_user and not self.az.state_store.is_joined(self.mxid,
- sender.mxid)):
+ and not sender.is_real_user and not await self.az.state_store.is_joined(self.mxid,
+ sender.mxid)):
self.log.debug(f"Ignoring private chat message {evt.id}@{source.tgid} as receiver does"
" not have matrix puppeting and their default puppet isn't in the room")
return
diff --git a/mautrix_telegram/sqlstatestore.py b/mautrix_telegram/sqlstatestore.py
deleted file mode 100644
index 3b8c91ad..00000000
--- a/mautrix_telegram/sqlstatestore.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# mautrix-telegram - A Matrix-Telegram puppeting bridge
-# Copyright (C) 2019 Tulir Asokan
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-from mautrix.types import UserID
-from mautrix.bridge.db import SQLStateStore as BaseSQLStateStore
-
-from . import puppet as pu
-
-
-class SQLStateStore(BaseSQLStateStore):
- def is_registered(self, user_id: UserID) -> bool:
- puppet = pu.Puppet.get_by_mxid(user_id, create=False)
- if puppet:
- return puppet.is_registered
- custom_puppet = pu.Puppet.get_by_custom_mxid(user_id)
- if custom_puppet:
- return True
- return super().is_registered(user_id)
-
- def registered(self, user_id: UserID) -> None:
- puppet = pu.Puppet.get_by_mxid(user_id, create=True)
- if puppet:
- puppet.is_registered = True
- puppet.save()
- else:
- super().registered(user_id)
diff --git a/requirements.txt b/requirements.txt
index ca7257de..7963c099 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,6 +4,6 @@ ruamel.yaml>=0.15.35,<0.17
python-magic>=0.4,<0.5
commonmark>=0.8,<0.10
aiohttp>=3,<4
-mautrix==0.6.0.beta7
+mautrix==0.6.0rc2
telethon>=1.13,<1.16
telethon-session-sqlalchemy>=0.2.14,<0.3