Add sync state indicator and support for clearing cache
This commit is contained in:
parent
13065451f5
commit
d557a5b02a
15 changed files with 157 additions and 35 deletions
|
@ -1 +1 @@
|
||||||
__version__ = "0.1.0.dev22"
|
__version__ = "0.1.0.dev23"
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
from typing import Dict, List, Optional, Set, TYPE_CHECKING
|
from typing import Dict, List, Optional, Set, Callable, Any, Awaitable, TYPE_CHECKING
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ from aiohttp import ClientSession
|
||||||
from mautrix.errors import MatrixInvalidToken, MatrixRequestError
|
from mautrix.errors import MatrixInvalidToken, MatrixRequestError
|
||||||
from mautrix.types import (UserID, SyncToken, FilterID, ContentURI, StrippedStateEvent, Membership,
|
from mautrix.types import (UserID, SyncToken, FilterID, ContentURI, StrippedStateEvent, Membership,
|
||||||
EventType, Filter, RoomFilter, RoomEventFilter)
|
EventType, Filter, RoomFilter, RoomEventFilter)
|
||||||
|
from mautrix.client import InternalEventType
|
||||||
|
|
||||||
from .db import DBClient
|
from .db import DBClient
|
||||||
from .matrix import MaubotMatrixClient
|
from .matrix import MaubotMatrixClient
|
||||||
|
@ -51,11 +52,22 @@ class Client:
|
||||||
self.log = log.getChild(self.id)
|
self.log = log.getChild(self.id)
|
||||||
self.references = set()
|
self.references = set()
|
||||||
self.started = False
|
self.started = False
|
||||||
|
self.sync_ok = True
|
||||||
self.client = MaubotMatrixClient(mxid=self.id, base_url=self.homeserver,
|
self.client = MaubotMatrixClient(mxid=self.id, base_url=self.homeserver,
|
||||||
token=self.access_token, client_session=self.http_client,
|
token=self.access_token, client_session=self.http_client,
|
||||||
log=self.log, loop=self.loop, store=self.db_instance)
|
log=self.log, loop=self.loop, store=self.db_instance)
|
||||||
|
self.client.ignore_initial_sync = True
|
||||||
|
self.client.ignore_first_sync = True
|
||||||
if self.autojoin:
|
if self.autojoin:
|
||||||
self.client.add_event_handler(EventType.ROOM_MEMBER, self._handle_invite)
|
self.client.add_event_handler(EventType.ROOM_MEMBER, self._handle_invite)
|
||||||
|
self.client.add_event_handler(InternalEventType.SYNC_ERRORED, self._set_sync_ok(False))
|
||||||
|
self.client.add_event_handler(InternalEventType.SYNC_SUCCESSFUL, self._set_sync_ok(True))
|
||||||
|
|
||||||
|
def _set_sync_ok(self, ok: bool) -> Callable[[Dict[str, Any]], Awaitable[None]]:
|
||||||
|
async def handler(data: Dict[str, Any]) -> None:
|
||||||
|
self.sync_ok = ok
|
||||||
|
|
||||||
|
return handler
|
||||||
|
|
||||||
async def start(self, try_n: Optional[int] = 0) -> None:
|
async def start(self, try_n: Optional[int] = 0) -> None:
|
||||||
try:
|
try:
|
||||||
|
@ -128,6 +140,13 @@ class Client:
|
||||||
await self.stop_plugins()
|
await self.stop_plugins()
|
||||||
self.stop_sync()
|
self.stop_sync()
|
||||||
|
|
||||||
|
def clear_cache(self) -> None:
|
||||||
|
self.stop_sync()
|
||||||
|
self.db_instance.filter_id = ""
|
||||||
|
self.db_instance.next_batch = ""
|
||||||
|
self.db.commit()
|
||||||
|
self.start_sync()
|
||||||
|
|
||||||
def delete(self) -> None:
|
def delete(self) -> None:
|
||||||
try:
|
try:
|
||||||
del self.cache[self.id]
|
del self.cache[self.id]
|
||||||
|
@ -144,6 +163,7 @@ class Client:
|
||||||
"enabled": self.enabled,
|
"enabled": self.enabled,
|
||||||
"started": self.started,
|
"started": self.started,
|
||||||
"sync": self.sync,
|
"sync": self.sync,
|
||||||
|
"sync_ok": self.sync_ok,
|
||||||
"autojoin": self.autojoin,
|
"autojoin": self.autojoin,
|
||||||
"displayname": self.displayname,
|
"displayname": self.displayname,
|
||||||
"avatar_url": self.avatar_url,
|
"avatar_url": self.avatar_url,
|
||||||
|
|
|
@ -130,3 +130,13 @@ async def delete_client(request: web.Request) -> web.Response:
|
||||||
await client.stop()
|
await client.stop()
|
||||||
client.delete()
|
client.delete()
|
||||||
return resp.deleted
|
return resp.deleted
|
||||||
|
|
||||||
|
|
||||||
|
@routes.post("/client/{id}/clearcache")
|
||||||
|
async def clear_client_cache(request: web.Request) -> web.Response:
|
||||||
|
user_id = request.match_info.get("id", None)
|
||||||
|
client = Client.get(user_id, None)
|
||||||
|
if not client:
|
||||||
|
return resp.client_not_found
|
||||||
|
client.clear_cache()
|
||||||
|
return resp.ok
|
||||||
|
|
|
@ -36,6 +36,7 @@ async def proxy(request: web.Request) -> web.StreamResponse:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
headers = request.headers.copy()
|
headers = request.headers.copy()
|
||||||
|
del headers["Host"]
|
||||||
headers["Authorization"] = f"Bearer {client.access_token}"
|
headers["Authorization"] = f"Bearer {client.access_token}"
|
||||||
if "X-Forwarded-For" not in headers:
|
if "X-Forwarded-For" not in headers:
|
||||||
peer = request.transport.get_extra_info("peername")
|
peer = request.transport.get_extra_info("peername")
|
||||||
|
|
|
@ -399,6 +399,32 @@ paths:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Error'
|
$ref: '#/components/schemas/Error'
|
||||||
|
'/client/{id}/clearcache':
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
description: The Matrix user ID of the client to change
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
put:
|
||||||
|
operationId: clear_client_cache
|
||||||
|
summary: Clear the sync/state cache of a Matrix client
|
||||||
|
tags: [Clients]
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Cache cleared
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
success:
|
||||||
|
type: boolean
|
||||||
|
401:
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
404:
|
||||||
|
$ref: '#/components/responses/ClientNotFound'
|
||||||
/client/auth/servers:
|
/client/auth/servers:
|
||||||
get:
|
get:
|
||||||
operationId: get_client_auth_servers
|
operationId: get_client_auth_servers
|
||||||
|
@ -607,29 +633,42 @@ components:
|
||||||
type: string
|
type: string
|
||||||
example: '@putkiteippi:maunium.net'
|
example: '@putkiteippi:maunium.net'
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
description: The Matrix user ID of this client.
|
||||||
homeserver:
|
homeserver:
|
||||||
type: string
|
type: string
|
||||||
example: 'https://maunium.net'
|
example: 'https://maunium.net'
|
||||||
|
description: The homeserver URL for this client.
|
||||||
access_token:
|
access_token:
|
||||||
type: string
|
type: string
|
||||||
|
description: The Matrix access token for this client.
|
||||||
enabled:
|
enabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
example: true
|
example: true
|
||||||
|
description: Whether or not this client is enabled.
|
||||||
started:
|
started:
|
||||||
type: boolean
|
type: boolean
|
||||||
example: true
|
example: true
|
||||||
|
description: Whether or not this client and its instances have been started.
|
||||||
sync:
|
sync:
|
||||||
type: boolean
|
type: boolean
|
||||||
example: true
|
example: true
|
||||||
|
description: Whether or not syncing is enabled on this client.
|
||||||
|
sync_ok:
|
||||||
|
type: boolean
|
||||||
|
example: true
|
||||||
|
description: Whether or not the previous sync was successful on this client.
|
||||||
autojoin:
|
autojoin:
|
||||||
type: boolean
|
type: boolean
|
||||||
example: true
|
example: true
|
||||||
|
description: Whether or not this client should automatically join rooms when invited.
|
||||||
displayname:
|
displayname:
|
||||||
type: string
|
type: string
|
||||||
example: J. E. Saarinen
|
example: J. E. Saarinen
|
||||||
|
description: The display name for this client.
|
||||||
avatar_url:
|
avatar_url:
|
||||||
type: string
|
type: string
|
||||||
example: 'mxc://maunium.net/FsPQQTntCCqhJMFtwArmJdaU'
|
example: 'mxc://maunium.net/FsPQQTntCCqhJMFtwArmJdaU'
|
||||||
|
description: The content URI of the avatar for this client.
|
||||||
instances:
|
instances:
|
||||||
type: array
|
type: array
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
|
|
@ -37,7 +37,7 @@ async function defaultDelete(type, id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function defaultPut(type, entry, id = undefined, suffix = undefined) {
|
async function defaultPut(type, entry, id = undefined, suffix = undefined) {
|
||||||
const resp = await fetch(`${BASE_PATH}/${type}/${id || entry.id}${suffix || ''}`, {
|
const resp = await fetch(`${BASE_PATH}/${type}/${id || entry.id}${suffix || ""}`, {
|
||||||
headers: getHeaders(),
|
headers: getHeaders(),
|
||||||
body: JSON.stringify(entry),
|
body: JSON.stringify(entry),
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
|
@ -221,6 +221,14 @@ export function getAvatarURL({ id, avatar_url }) {
|
||||||
export const putClient = client => defaultPut("client", client)
|
export const putClient = client => defaultPut("client", client)
|
||||||
export const deleteClient = id => defaultDelete("client", id)
|
export const deleteClient = id => defaultDelete("client", id)
|
||||||
|
|
||||||
|
export async function clearClientCache(id) {
|
||||||
|
const resp = await fetch(`${BASE_PATH}/client/${id}/clearcache`, {
|
||||||
|
headers: getHeaders(),
|
||||||
|
method: "POST",
|
||||||
|
})
|
||||||
|
return await resp.json()
|
||||||
|
}
|
||||||
|
|
||||||
export const getClientAuthServers = () => defaultGet("/client/auth/servers")
|
export const getClientAuthServers = () => defaultGet("/client/auth/servers")
|
||||||
|
|
||||||
export async function doClientAuth(server, type, username, password) {
|
export async function doClientAuth(server, type, username, password) {
|
||||||
|
@ -240,6 +248,6 @@ export default {
|
||||||
getInstances, getInstance, putInstance, deleteInstance,
|
getInstances, getInstance, putInstance, deleteInstance,
|
||||||
getInstanceDatabase, queryInstanceDatabase,
|
getInstanceDatabase, queryInstanceDatabase,
|
||||||
getPlugins, getPlugin, uploadPlugin, deletePlugin,
|
getPlugins, getPlugin, uploadPlugin, deletePlugin,
|
||||||
getClients, getClient, uploadAvatar, getAvatarURL, putClient, deleteClient,
|
getClients, getClient, uploadAvatar, getAvatarURL, putClient, deleteClient, clearClientCache,
|
||||||
getClientAuthServers, doClientAuth
|
getClientAuthServers, doClientAuth,
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ class Client extends BaseMainView {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
this.deleteFunc = api.deleteClient
|
this.deleteFunc = api.deleteClient
|
||||||
|
this.homeserverOptions = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
get entryKeys() {
|
get entryKeys() {
|
||||||
|
@ -69,6 +70,7 @@ class Client extends BaseMainView {
|
||||||
saving: false,
|
saving: false,
|
||||||
deleting: false,
|
deleting: false,
|
||||||
startingOrStopping: false,
|
startingOrStopping: false,
|
||||||
|
clearingCache: false,
|
||||||
error: "",
|
error: "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,6 +81,7 @@ class Client extends BaseMainView {
|
||||||
delete client.saving
|
delete client.saving
|
||||||
delete client.deleting
|
delete client.deleting
|
||||||
delete client.startingOrStopping
|
delete client.startingOrStopping
|
||||||
|
delete client.clearingCache
|
||||||
delete client.error
|
delete client.error
|
||||||
delete client.instances
|
delete client.instances
|
||||||
return client
|
return client
|
||||||
|
@ -88,7 +91,7 @@ class Client extends BaseMainView {
|
||||||
return this.state.homeserver
|
return this.state.homeserver
|
||||||
? this.homeserverEntry([this.props.ctx.homeserversByURL[this.state.homeserver],
|
? this.homeserverEntry([this.props.ctx.homeserversByURL[this.state.homeserver],
|
||||||
this.state.homeserver])
|
this.state.homeserver])
|
||||||
: {}
|
: this.homeserverOptions[0] || {}
|
||||||
}
|
}
|
||||||
|
|
||||||
homeserverEntry = ([serverName, serverURL]) => serverURL && {
|
homeserverEntry = ([serverName, serverURL]) => serverURL && {
|
||||||
|
@ -156,8 +159,39 @@ class Client extends BaseMainView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearCache = async () => {
|
||||||
|
this.setState({ clearingCache: true })
|
||||||
|
const resp = await api.clearClientCache(this.props.entry.id)
|
||||||
|
if (resp.success) {
|
||||||
|
this.setState({ clearingCache: false, error: "" })
|
||||||
|
} else {
|
||||||
|
this.setState({ clearingCache: false, error: resp.error })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get loading() {
|
get loading() {
|
||||||
return this.state.saving || this.state.startingOrStopping || this.state.deleting
|
return this.state.saving || this.state.startingOrStopping || this.clearingCache || this.state.deleting
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStartedContainer = () => {
|
||||||
|
let text
|
||||||
|
if (this.props.entry.started) {
|
||||||
|
if (this.props.entry.sync_ok) {
|
||||||
|
text = "Started"
|
||||||
|
} else {
|
||||||
|
text = "Erroring"
|
||||||
|
}
|
||||||
|
} else if (this.props.entry.enabled) {
|
||||||
|
text = "Stopped"
|
||||||
|
} else {
|
||||||
|
text = "Disabled"
|
||||||
|
}
|
||||||
|
return <div className="started-container">
|
||||||
|
<span className={`started ${this.props.entry.started}
|
||||||
|
${this.props.entry.sync_ok ? "sync_ok" : "sync_error"}
|
||||||
|
${this.props.entry.enabled ? "" : "disabled"}`}/>
|
||||||
|
<span className="text">{text}</span>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSidebar = () => !this.isNew && (
|
renderSidebar = () => !this.isNew && (
|
||||||
|
@ -172,20 +206,16 @@ class Client extends BaseMainView {
|
||||||
onDragLeave={evt => evt.target.parentElement.classList.remove("drag")}/>
|
onDragLeave={evt => evt.target.parentElement.classList.remove("drag")}/>
|
||||||
{this.state.uploadingAvatar && <Spinner/>}
|
{this.state.uploadingAvatar && <Spinner/>}
|
||||||
</div>
|
</div>
|
||||||
<div className="started-container">
|
{this.renderStartedContainer()}
|
||||||
<span className={`started ${this.props.entry.started}
|
{(this.props.entry.started || this.props.entry.enabled) && <>
|
||||||
${this.props.entry.enabled ? "" : "disabled"}`}/>
|
|
||||||
<span className="text">
|
|
||||||
{this.props.entry.started ? "Started" :
|
|
||||||
(this.props.entry.enabled ? "Stopped" : "Disabled")}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{(this.props.entry.started || this.props.entry.enabled) && (
|
|
||||||
<button className="save" onClick={this.startOrStop} disabled={this.loading}>
|
<button className="save" onClick={this.startOrStop} disabled={this.loading}>
|
||||||
{this.state.startingOrStopping ? <Spinner/>
|
{this.state.startingOrStopping ? <Spinner/>
|
||||||
: (this.props.entry.started ? "Stop" : "Start")}
|
: (this.props.entry.started ? "Stop" : "Start")}
|
||||||
</button>
|
</button>
|
||||||
)}
|
<button className="clearcache" onClick={this.clearCache} disabled={this.loading}>
|
||||||
|
{this.state.clearingCache ? <Spinner/> : "Clear cache"}
|
||||||
|
</button>
|
||||||
|
</>}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -195,10 +225,17 @@ class Client extends BaseMainView {
|
||||||
name={this.isNew ? "id" : ""} className="id"
|
name={this.isNew ? "id" : ""} className="id"
|
||||||
value={this.state.id} origValue={this.props.entry.id}
|
value={this.state.id} origValue={this.props.entry.id}
|
||||||
placeholder="@fancybot:example.com" onChange={this.inputChange}/>
|
placeholder="@fancybot:example.com" onChange={this.inputChange}/>
|
||||||
<PrefSelect rowName="Homeserver" options={this.homeserverOptions} isSearchable={true}
|
{api.getFeatures().client_auth ? (
|
||||||
value={this.selectedHomeserver} origValue={this.props.entry.homeserver}
|
<PrefSelect rowName="Homeserver" options={this.homeserverOptions}
|
||||||
onChange={({ id }) => this.setState({ homeserver: id })}
|
isSearchable={true} value={this.selectedHomeserver}
|
||||||
creatable={true} isValidNewOption={this.isValidHomeserver}/>
|
origValue={this.props.entry.homeserver}
|
||||||
|
onChange={({ value }) => this.setState({ homeserver: value })}
|
||||||
|
creatable={true} isValidNewOption={this.isValidHomeserver}/>
|
||||||
|
) : (
|
||||||
|
<PrefInput rowName="Homeserver" type="text" name="homeserver"
|
||||||
|
value={this.state.homeserver} origValue={this.props.entry.homeserver}
|
||||||
|
placeholder="https://example.com" onChange={this.inputChange}/>
|
||||||
|
)}
|
||||||
<PrefInput rowName="Access token" type="text" name="access_token"
|
<PrefInput rowName="Access token" type="text" name="access_token"
|
||||||
value={this.state.access_token} origValue={this.props.entry.access_token}
|
value={this.state.access_token} origValue={this.props.entry.access_token}
|
||||||
placeholder="MDAxYWxvY2F0aW9uIG1hdHJpeC5sb2NhbAowMDEzaWRlbnRpZmllc"
|
placeholder="MDAxYWxvY2F0aW9uIG1hdHJpeC5sb2NhbAowMDEzaWRlbnRpZmllc"
|
||||||
|
|
|
@ -75,10 +75,11 @@ class Dashboard extends Component {
|
||||||
}
|
}
|
||||||
const homeserversByName = homeservers
|
const homeserversByName = homeservers
|
||||||
const homeserversByURL = {}
|
const homeserversByURL = {}
|
||||||
for (const [key, value] of Object.entries(homeservers)) {
|
if (api.getFeatures().client_auth) {
|
||||||
homeserversByURL[value] = key
|
for (const [key, value] of Object.entries(homeservers)) {
|
||||||
|
homeserversByURL[value] = key
|
||||||
|
}
|
||||||
}
|
}
|
||||||
console.log(homeserversByName, homeserversByURL)
|
|
||||||
this.setState({ instances, clients, plugins, homeserversByName, homeserversByURL })
|
this.setState({ instances, clients, plugins, homeserversByName, homeserversByURL })
|
||||||
|
|
||||||
await this.enableLogs()
|
await this.enableLogs()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const proxy = require("http-proxy-middleware")
|
const proxy = require("http-proxy-middleware")
|
||||||
|
|
||||||
module.exports = function(app) {
|
module.exports = function(app) {
|
||||||
app.use(proxy("/_matrix/maubot/v1", { target: "http://localhost:29316" }))
|
app.use(proxy("/_matrix/maubot/v1", { target: process.env.PROXY || "http://localhost:29316" }))
|
||||||
app.use(proxy("/_matrix/maubot/v1/logs", { target: "http://localhost:29316", ws: true }))
|
app.use(proxy("/_matrix/maubot/v1/logs", { target: process.env.PROXY || "http://localhost:29316", ws: true }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ $secondary-light: #62EBFF
|
||||||
$error: #B71C1C
|
$error: #B71C1C
|
||||||
$error-dark: #7F0000
|
$error-dark: #7F0000
|
||||||
$error-light: #F05545
|
$error-light: #F05545
|
||||||
|
$warning: orange
|
||||||
|
|
||||||
$border-color: #DDD
|
$border-color: #DDD
|
||||||
$text-color: #212121
|
$text-color: #212121
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
width: 8rem
|
width: 8rem
|
||||||
margin-right: 1rem
|
margin-right: 1rem
|
||||||
|
|
||||||
> div
|
> *
|
||||||
margin-bottom: 1rem
|
margin-bottom: 1rem
|
||||||
|
|
||||||
@import avatar
|
@import avatar
|
||||||
|
|
|
@ -25,8 +25,13 @@
|
||||||
margin: .5rem
|
margin: .5rem
|
||||||
|
|
||||||
&.true
|
&.true
|
||||||
background-color: $primary
|
&.sync_ok
|
||||||
box-shadow: 0 0 .75rem .75rem $primary
|
background-color: $primary
|
||||||
|
box-shadow: 0 0 .75rem .75rem $primary
|
||||||
|
|
||||||
|
&.sync_error
|
||||||
|
background-color: $warning
|
||||||
|
box-shadow: 0 0 .75rem .75rem $warning
|
||||||
|
|
||||||
&.false
|
&.false
|
||||||
background-color: $error-light
|
background-color: $error-light
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
&:hover
|
&:hover
|
||||||
background-color: $error !important
|
background-color: $error !important
|
||||||
|
|
||||||
button.save, button.delete
|
button.save, button.clearcache, button.delete
|
||||||
+button
|
+button
|
||||||
+main-color-button
|
+main-color-button
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|
|
@ -18,7 +18,7 @@ from markdown.extensions import Extension
|
||||||
import markdown as md
|
import markdown as md
|
||||||
import attr
|
import attr
|
||||||
|
|
||||||
from mautrix.client import Client as MatrixClient
|
from mautrix.client import Client as MatrixClient, SyncStream
|
||||||
from mautrix.util.formatter import parse_html
|
from mautrix.util.formatter import parse_html
|
||||||
from mautrix.types import (EventType, MessageEvent, Event, EventID, RoomID, MessageEventContent,
|
from mautrix.types import (EventType, MessageEvent, Event, EventID, RoomID, MessageEventContent,
|
||||||
MessageType, TextMessageEventContent, Format, RelatesTo)
|
MessageType, TextMessageEventContent, Format, RelatesTo)
|
||||||
|
@ -83,12 +83,12 @@ class MaubotMatrixClient(MatrixClient):
|
||||||
content.relates_to = relates_to
|
content.relates_to = relates_to
|
||||||
return self.send_message(room_id, content, **kwargs)
|
return self.send_message(room_id, content, **kwargs)
|
||||||
|
|
||||||
async def call_handlers(self, event: Event, source) -> None:
|
async def dispatch_event(self, event: Event, source: SyncStream = SyncStream.INTERNAL) -> None:
|
||||||
if isinstance(event, MessageEvent):
|
if isinstance(event, MessageEvent):
|
||||||
event = MaubotMessageEvent(event, self)
|
event = MaubotMessageEvent(event, self)
|
||||||
else:
|
elif source != SyncStream.INTERNAL:
|
||||||
event.client = self
|
event.client = self
|
||||||
return await super().call_handlers(event, source)
|
return await super().dispatch_event(event, source)
|
||||||
|
|
||||||
async def get_event(self, room_id: RoomID, event_id: EventID) -> Event:
|
async def get_event(self, room_id: RoomID, event_id: EventID) -> Event:
|
||||||
event = await super().get_event(room_id, event_id)
|
event = await super().get_event(room_id, event_id)
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -21,7 +21,7 @@ setuptools.setup(
|
||||||
packages=setuptools.find_packages(),
|
packages=setuptools.find_packages(),
|
||||||
|
|
||||||
install_requires=[
|
install_requires=[
|
||||||
"mautrix>=0.4.dev46,<0.5",
|
"mautrix>=0.4.dev47,<0.5",
|
||||||
"aiohttp>=3.0.1,<4",
|
"aiohttp>=3.0.1,<4",
|
||||||
"SQLAlchemy>=1.2.3,<2",
|
"SQLAlchemy>=1.2.3,<2",
|
||||||
"alembic>=1.0.0,<2",
|
"alembic>=1.0.0,<2",
|
||||||
|
|
Loading…
Reference in a new issue