diff --git a/alembic/versions/fccd1f95544d_add_online_field_to_clients.py b/alembic/versions/fccd1f95544d_add_online_field_to_clients.py new file mode 100644 index 0000000..1f7eabe --- /dev/null +++ b/alembic/versions/fccd1f95544d_add_online_field_to_clients.py @@ -0,0 +1,30 @@ +"""Add online field to clients + +Revision ID: fccd1f95544d +Revises: d295f8dcfa64 +Create Date: 2020-03-06 15:07:50.136644 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'fccd1f95544d' +down_revision = 'd295f8dcfa64' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table("client") as batch_op: + batch_op.add_column(sa.Column('online', sa.Boolean(), nullable=False, server_default=sa.sql.expression.true())) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table("client") as batch_op: + batch_op.drop_column('online') + # ### end Alembic commands ### diff --git a/maubot/client.py b/maubot/client.py index a7ea3d4..1c2ccc9 100644 --- a/maubot/client.py +++ b/maubot/client.py @@ -21,7 +21,8 @@ from aiohttp import ClientSession from mautrix.errors import MatrixInvalidToken, MatrixRequestError from mautrix.types import (UserID, SyncToken, FilterID, ContentURI, StrippedStateEvent, Membership, - StateEvent, EventType, Filter, RoomFilter, RoomEventFilter) + StateEvent, EventType, Filter, RoomFilter, RoomEventFilter, EventFilter, + PresenceState, StateFilter) from mautrix.client import InternalEventType from .lib.store_proxy import ClientStoreProxy @@ -63,6 +64,7 @@ class Client: store=ClientStoreProxy(self.db_instance)) self.client.ignore_initial_sync = True self.client.ignore_first_sync = True + self.client.presence = PresenceState.ONLINE if self.online else PresenceState.OFFLINE if self.autojoin: self.client.add_event_handler(EventType.ROOM_MEMBER, self._handle_invite) self.client.add_event_handler(EventType.ROOM_TOMBSTONE, self._handle_tombstone) @@ -114,7 +116,14 @@ class Client: room=RoomFilter( timeline=RoomEventFilter( limit=50, + lazy_load_members=True, ), + state=StateFilter( + lazy_load_members=True, + ) + ), + presence=EventFilter( + not_types=[EventType.PRESENCE], ), ))) if self.displayname != "disable": @@ -169,6 +178,7 @@ class Client: "sync": self.sync, "sync_ok": self.sync_ok, "autojoin": self.autojoin, + "online": self.online, "displayname": self.displayname, "avatar_url": self.avatar_url, "remote_displayname": self.remote_displayname, @@ -308,6 +318,15 @@ class Client: self.client.remove_event_handler(EventType.ROOM_MEMBER, self._handle_invite) self.db_instance.autojoin = value + @property + def online(self) -> bool: + return self.db_instance.online + + @online.setter + def online(self, value: bool) -> None: + self.client.presence = PresenceState.ONLINE if value else PresenceState.OFFLINE + self.db_instance.online = value + @property def displayname(self) -> str: return self.db_instance.displayname diff --git a/maubot/db.py b/maubot/db.py index f06224b..a9928d2 100644 --- a/maubot/db.py +++ b/maubot/db.py @@ -60,6 +60,7 @@ class DBClient(Base): sync: bool = Column(Boolean, nullable=False, default=True) autojoin: bool = Column(Boolean, nullable=False, default=True) + online: bool = Column(Boolean, nullable=False, default=True) displayname: str = Column(String(255), nullable=False, default="") avatar_url: ContentURI = Column(String(255), nullable=False, default="") diff --git a/maubot/management/api/client.py b/maubot/management/api/client.py index e812bd9..0585d63 100644 --- a/maubot/management/api/client.py +++ b/maubot/management/api/client.py @@ -64,7 +64,7 @@ async def _create_client(user_id: Optional[UserID], data: dict) -> web.Response: db_instance = DBClient(id=mxid, homeserver=homeserver, access_token=access_token, enabled=data.get("enabled", True), next_batch=SyncToken(""), filter_id=FilterID(""), sync=data.get("sync", True), - autojoin=data.get("autojoin", True), + autojoin=data.get("autojoin", True), online=data.get("online", True), displayname=data.get("displayname", ""), avatar_url=data.get("avatar_url", "")) client = Client(db_instance) @@ -91,6 +91,7 @@ async def _update_client(client: Client, data: dict) -> web.Response: await client.update_started(data.get("started", None)) client.enabled = data.get("enabled", client.enabled) client.autojoin = data.get("autojoin", client.autojoin) + client.online = data.get("online", client.online) client.sync = data.get("sync", client.sync) return resp.updated(client.to_dict()) diff --git a/maubot/management/frontend/src/pages/dashboard/Client.js b/maubot/management/frontend/src/pages/dashboard/Client.js index 062d6ad..2048977 100644 --- a/maubot/management/frontend/src/pages/dashboard/Client.js +++ b/maubot/management/frontend/src/pages/dashboard/Client.js @@ -64,7 +64,7 @@ class Client extends BaseMainView { get entryKeys() { return ["id", "displayname", "homeserver", "avatar_url", "access_token", "sync", - "autojoin", "enabled", "started"] + "autojoin", "online", "enabled", "started"] } get initialState() { @@ -77,6 +77,7 @@ class Client extends BaseMainView { sync: true, autojoin: true, enabled: true, + online: true, started: false, instances: [], @@ -285,6 +286,9 @@ class Client extends BaseMainView { enabled, started: enabled && this.state.started, })}/> + this.setState({ online })} /> )