Compare commits

..

28 Commits

Author SHA1 Message Date
Tulir Asokan b4cf8cd451 Bump version to 0.7.1rc1 2020-01-11 20:08:47 +02:00
Tulir Asokan 80ff9d0f66 Precalculate list of channel IDs to get info for to fix #393 2020-01-11 20:07:21 +02:00
Tulir Asokan b0e60e60e4 Fix parameter name error in has_power_level call 2020-01-11 19:58:08 +02:00
Tulir Asokan c4b9a76931 Merge pull request #406 from Ma27/fix-tests
Fix several broken tests that were missing some required positional arguments
2019-12-28 14:56:21 +02:00
Maximilian Bosch fe52f0ad10 Fix several broken tests that were missing some required positional arguments 2019-12-28 13:00:39 +01:00
Tulir Asokan a9abf9a1af Bump version to 0.7.0 2019-12-28 01:29:38 +02:00
Tulir Asokan 815f9605f9 Bump version to 0.7.0rc4 2019-12-25 16:31:00 +02:00
Tulir Asokan 9a9d6fc0bb Fix handling m.emotes 2019-12-25 16:29:22 +02:00
Tulir Asokan 2f691bf1b8 Bump version to 0.7.0rc3 2019-12-25 16:01:39 +02:00
Tulir Asokan 50984dab14 Trust displaynames from non-contacts when syncing puppets 2019-12-25 15:49:35 +02:00
Tulir Asokan 6f6ce4bcc7 Try deleting sources in docker image 2019-12-23 19:44:44 +02:00
Tulir Asokan 119729393c Restore git for version info in CI builds 2019-12-23 19:30:55 +02:00
Tulir Asokan 9f3869e878 Try to fix version info in CI builds again 2019-12-23 19:15:36 +02:00
Tulir Asokan 9fb2a73ec5 Update mautrix-python to handle invites separately from leaves. Fixes #402 2019-12-21 21:02:41 +02:00
Tulir Asokan 64b3699b3c Only print stack traces for admins. Fixes #392 2019-12-21 20:46:49 +02:00
Tulir Asokan 76ad31a3bc Update to Alpine 3.11 and fix version info in CI builds 2019-12-21 20:45:02 +02:00
Tulir Asokan 71cdee5a4d Fix crash when login shared secret is not enabled 2019-12-15 19:04:43 +02:00
Tulir Asokan 2ae4b23528 Add option to log in to custom puppet with shared secret 2019-12-15 18:50:07 +02:00
Tulir Asokan 39927ac6c0 Try to fix cleaning up rooms
Not tested at all
2019-12-11 10:03:05 +02:00
Tulir Asokan 3e6e59db29 Add postgres password field to example helm chart values 2019-12-06 15:57:53 +02:00
Tulir Asokan 36e2c6f66f Bump version to 0.7.0rc2 2019-12-01 20:31:25 +02:00
Tulir Asokan 69d56f4632 Disable debug log when creating peer type chat portal. Fixes #389 2019-12-01 20:10:45 +02:00
Tulir Asokan af0f731a8a Ignore ChatForbidden when syncing dialogs. Fixes #390 2019-12-01 20:09:00 +02:00
Tulir Asokan cf8c05e1c5 Replace LEFT with LEAVE in mx_user_profile migration. Fixes #391 2019-12-01 20:07:54 +02:00
Tulir Asokan 7d5e307368 Allow room moderators to set room-specific configs 2019-11-30 21:38:33 +02:00
Tulir Asokan 701b28c33c Fix getting version in docker 2019-11-30 21:32:22 +02:00
Tulir Asokan a239ca439a Load version info from Git. Fixes #387 2019-11-30 20:54:54 +02:00
Tulir Asokan 578af19baa Use new forbidden default value system in mautrix-python. Fixes #388 2019-11-30 19:49:29 +02:00
24 changed files with 184 additions and 50 deletions
+5 -2
View File
@@ -18,7 +18,7 @@ RUN apk add --no-cache libpng libpng-dev zlib zlib-dev \
&& git checkout 543c1d23ac9322f4f03c7fb6612ea7d026d44ac0 \
&& make
FROM docker.io/alpine:3.10
FROM docker.io/alpine:3.11
ENV UID=1337 \
GID=1337 \
@@ -33,6 +33,7 @@ RUN apk add --no-cache --virtual .build-deps \
python3-dev \
libffi-dev \
build-base \
git \
&& apk add --no-cache \
py3-virtualenv \
py3-pillow \
@@ -51,7 +52,7 @@ RUN apk add --no-cache --virtual .build-deps \
py3-markupsafe \
#moviepy
py3-decorator \
#py3-tqdm \
py3-tqdm \
py3-requests \
#imageio
py3-numpy \
@@ -67,6 +68,8 @@ RUN apk add --no-cache --virtual .build-deps \
# lottieconverter
zlib libpng \
&& pip3 install .[speedups,hq_thumbnails,metrics] \
# pip installs the sources to /usr/lib/python3.8/site-packages, so we don't need them here
&& rm -rf /opt/mautrix-telegram/mautrix_telegram \
&& apk del .build-deps
VOLUME /data
@@ -18,6 +18,7 @@ depends_on = None
def upgrade():
conn = op.get_bind()
conn.execute("UPDATE mx_user_profile SET membership=UPPER(membership)")
conn.execute("UPDATE mx_user_profile SET membership='LEAVE' WHERE membership='LEFT'")
def downgrade():
+7 -1
View File
@@ -33,7 +33,7 @@ appservice:
# the HS database.
public:
# Whether or not the public-facing endpoints should be enabled.
enabled: true
enabled: false
# The prefix to use in the public-facing endpoints.
prefix: /public
# The base URL where the public-facing endpoints are available. The prefix is not added
@@ -154,6 +154,12 @@ bridge:
# Whether or not to use /sync to get presence, read receipts and typing notifications when using
# your own Matrix account as the Matrix puppet for your Telegram account.
sync_with_custom_puppets: true
# Shared secret for https://github.com/devture/matrix-synapse-shared-secret-auth
#
# If set, custom puppets will be enabled automatically for local users
# instead of users having to find an access token and run `login-matrix`
# manually.
login_shared_secret: null
# Set to false to disable link previews in messages sent to Telegram.
telegram_link_preview: true
# Use inline images instead of a separate message for the caption.
+1
View File
@@ -35,6 +35,7 @@ affinity: {}
postgresql:
enabled: true
postgresqlDatabase: mxtg
postgresqlPassword: SET TO RANDOM STRING
persistence:
size: 2Gi
resources:
+1 -1
View File
@@ -1,2 +1,2 @@
__version__ = "0.7.0rc1"
__version__ = "0.7.1rc1"
__author__ = "Tulir Asokan <tulir@maunium.net>"
+4 -2
View File
@@ -35,7 +35,7 @@ from .portal import 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 . import __version__
from .version import version, linkified_version
try:
import prometheus_client as prometheus
@@ -47,8 +47,10 @@ class TelegramBridge(Bridge):
name = "mautrix-telegram"
command = "python -m mautrix-telegram"
description = "A Matrix-Telegram puppeting bridge."
repo_url = "https://github.com/tulir/mautrix-telegram"
real_user_content_key = "net.maunium.telegram.puppet"
version = __version__
version = version
markdown_version = linkified_version
config_class = Config
matrix_class = MatrixHandler
state_store_class = SQLStateStore
+2 -2
View File
@@ -108,9 +108,9 @@ class Bot(AbstractUser):
if isinstance(chat, ChatForbidden) or chat.left or chat.deactivated:
self.remove_chat(TelegramID(chat.id))
channel_ids = (InputChannel(chat_id, 0)
channel_ids = [InputChannel(chat_id, 0)
for chat_id, chat_type in self.chats.items()
if chat_type == "channel")
if chat_type == "channel"]
for channel_id in channel_ids:
try:
await self.client(GetChannelsRequest([channel_id]))
+1 -1
View File
@@ -169,7 +169,7 @@ async def execute_room_cleanup(evt, rooms_to_clean: List[Union[po.Portal, RoomID
await room.cleanup_and_delete()
cleaned += 1
else:
await po.Portal.cleanup_room(evt.az.intent, room, message="Room deleted")
await po.Portal.cleanup_room(evt.az.intent, room, "Room deleted")
cleaned += 1
evt.sender.command_status = None
await evt.reply(f"{cleaned} rooms cleaned up successfully.")
+5 -1
View File
@@ -51,6 +51,10 @@ class CommandEvent(BaseCommandEvent):
self.config = processor.config
self.public_website = processor.public_website
@property
def print_error_traceback(self) -> bool:
return self.sender.is_admin
async def get_help_key(self) -> HelpCacheKey:
return HelpCacheKey(self.is_management, self.is_portal, self.sender.puppet_whitelisted,
self.sender.matrix_puppet_whitelisted, self.sender.is_admin,
@@ -112,7 +116,7 @@ def command_handler(_func: Optional[CommandHandlerFunc] = None, *, needs_auth: b
class CommandProcessor(BaseCommandProcessor):
def __init__(self, context: c.Context) -> None:
super().__init__(az=context.az, config=context.config, event_class=CommandEvent,
loop=context.loop)
loop=context.loop, bridge=context.bridge)
self.tgbot = context.bot
self.bridge = context.bridge
self.az, self.config, self.loop, self.tgbot = context.core
+3 -5
View File
@@ -113,12 +113,10 @@ async def cleanup_old_portal_while_bridging(evt: CommandEvent, portal: "po.Porta
"Continuing without touching previous Matrix room...")
return True, None
elif evt.args[0] == "delete-and-continue":
return True, portal.cleanup_room(portal.main_intent, portal.mxid,
message="Portal deleted (moving to another room)")
return True, portal.cleanup_portal("Portal deleted (moving to another room)")
elif evt.args[0] == "unbridge-and-continue":
return True, portal.cleanup_room(portal.main_intent, portal.mxid,
message="Room unbridged (portal moving to another room)",
puppets_only=True)
return True, portal.cleanup_portal("Room unbridged (portal moving to another room)",
puppets_only=True)
else:
await evt.reply(
"The chat you were trying to bridge already has a Matrix portal room.\n\n"
+5 -1
View File
@@ -23,7 +23,7 @@ from ... import portal as po, util
from .. import command_handler, CommandEvent, SECTION_PORTAL_MANAGEMENT
@command_handler(help_section=SECTION_PORTAL_MANAGEMENT,
@command_handler(needs_auth=False, help_section=SECTION_PORTAL_MANAGEMENT,
help_text="View or change per-portal settings.",
help_args="<`help`|_subcommand_> [...]")
async def config(evt: CommandEvent) -> None:
@@ -43,6 +43,10 @@ async def config(evt: CommandEvent) -> None:
await config_view(evt, portal)
return
if not await portal.can_user_perform(evt.sender, "config"):
await evt.reply("You do not have the permissions to configure this room.")
return
key = evt.args[1] if len(evt.args) > 1 else None
value = yaml.load(" ".join(evt.args[2:])) if len(evt.args) > 2 else None
if cmd == "set":
+6 -3
View File
@@ -20,7 +20,8 @@ from telethon.errors import ( # isort: skip
AccessTokenExpiredError, AccessTokenInvalidError, FirstNameInvalidError, FloodWaitError,
PasswordHashInvalidError, PhoneCodeExpiredError, PhoneCodeInvalidError,
PhoneNumberAppSignupForbiddenError, PhoneNumberBannedError, PhoneNumberFloodError,
PhoneNumberOccupiedError, PhoneNumberUnoccupiedError, SessionPasswordNeededError)
PhoneNumberOccupiedError, PhoneNumberUnoccupiedError, SessionPasswordNeededError,
PhoneNumberInvalidError)
from mautrix.types import EventID
@@ -84,7 +85,7 @@ async def enter_code_register(evt: CommandEvent) -> EventID:
await evt.sender.ensure_started(even_if_no_session=True)
first_name, last_name = evt.sender.command_status["full_name"]
user = await evt.sender.client.sign_up(evt.args[0], first_name, last_name)
asyncio.ensure_future(evt.sender.post_login(user), loop=evt.loop)
asyncio.ensure_future(evt.sender.post_login(user, first_login=True), loop=evt.loop)
evt.sender.command_status = None
return await evt.reply(f"Successfully registered to Telegram.")
except PhoneNumberOccupiedError:
@@ -166,6 +167,8 @@ async def _request_code(evt: CommandEvent, phone_number: str, next_status: Dict[
except PhoneNumberUnoccupiedError:
return await evt.reply("That phone number has not been registered. "
"Please register with `$cmdprefix+sp register <phone>`.")
except PhoneNumberInvalidError:
return await evt.reply("That phone number is not valid.")
except Exception:
evt.log.exception("Error requesting phone code")
return await evt.reply("Unhandled exception while requesting code. "
@@ -244,7 +247,7 @@ async def _sign_in(evt: CommandEvent, **sign_in_info) -> EventID:
await evt.reply(f"[{existing_user.displayname}]"
f"(https://matrix.to/#/{existing_user.mxid})"
" was logged out from the account.")
asyncio.ensure_future(evt.sender.post_login(user), loop=evt.loop)
asyncio.ensure_future(evt.sender.post_login(user, first_login=True), loop=evt.loop)
evt.sender.command_status = None
name = f"@{user.username}" if user.username else f"+{user.phone}"
return await evt.reply(f"Successfully logged in as {name}")
+14 -1
View File
@@ -19,7 +19,8 @@ import os
from mautrix.types import UserID
from mautrix.client import Client
from mautrix.bridge.config import BaseBridgeConfig, ConfigUpdateHelper
from mautrix.bridge.config import (BaseBridgeConfig, ConfigUpdateHelper, ForbiddenKey,
ForbiddenDefault)
Permissions = NamedTuple("Permissions", relaybot=bool, user=bool, puppeting=bool,
matrix_puppeting=bool, admin=bool, level=str)
@@ -32,6 +33,17 @@ class Config(BaseBridgeConfig):
except KeyError:
return super().__getitem__(key)
@property
def forbidden_defaults(self) -> List[ForbiddenDefault]:
return [
*super().forbidden_defaults,
ForbiddenDefault("appservice.public.external", "https://example.com/public",
condition="appservice.public.enabled"),
ForbiddenDefault("bridge.permissions", ForbiddenKey("example.com")),
ForbiddenDefault("telegram.api_id", 12345),
ForbiddenDefault("telegram.api_hash", "tjyd5yge35lbodk1xwzw2jstp90k55qz"),
]
def do_update(self, helper: ConfigUpdateHelper) -> None:
copy, copy_dict, base = helper
@@ -97,6 +109,7 @@ class Config(BaseBridgeConfig):
copy("bridge.plaintext_highlights")
copy("bridge.public_portals")
copy("bridge.sync_with_custom_puppets")
copy("bridge.login_shared_secret")
copy("bridge.telegram_link_preview")
copy("bridge.inline_images")
copy("bridge.image_as_file_size")
+49
View File
@@ -0,0 +1,49 @@
import subprocess
import shutil
import os
from . import __version__
cmd_env = {
"PATH": os.environ["PATH"],
"HOME": os.environ["HOME"],
"LANG": "C",
"LC_ALL": "C",
}
def run(cmd):
return subprocess.check_output(cmd, stderr=subprocess.DEVNULL, env=cmd_env)
if os.path.exists(".git") and shutil.which("git"):
try:
git_revision = run(["git", "rev-parse", "HEAD"]).strip().decode("ascii")
git_revision_url = f"https://github.com/tulir/mautrix-telegram/commit/{git_revision}"
git_revision = git_revision[:8]
except (subprocess.SubprocessError, OSError):
git_revision = "unknown"
git_revision_url = None
try:
git_tag = run(["git", "describe", "--exact-match", "--tags"]).strip().decode("ascii")
except (subprocess.SubprocessError, OSError):
git_tag = None
else:
git_revision = "unknown"
git_revision_url = None
git_tag = None
git_tag_url = (f"https://github.com/tulir/mautrix-telegram/releases/tag/{git_tag}"
if git_tag else None)
if git_tag and __version__ == git_tag[1:].replace("-", ""):
version = __version__
linkified_version = f"[{version}]({git_tag_url})"
else:
if not __version__.endswith("+dev"):
__version__ += "+dev"
version = f"{__version__}.{git_revision}"
if git_revision_url:
linkified_version = f"{__version__}.[{git_revision}]({git_revision_url})"
else:
linkified_version = version
+5
View File
@@ -215,6 +215,11 @@ class MatrixHandler(BaseMatrixHandler):
event_id: EventID) -> None:
await self.handle_kick_ban(False, room_id, user_id, kicked_by, reason, event_id)
async def handle_unban(self, room_id: RoomID, user_id: UserID, unbanned_by: UserID,
reason: str, event_id: EventID) -> None:
# TODO handle unbans properly instead of handling it as a kick
await self.handle_kick_ban(False, room_id, user_id, unbanned_by, reason, event_id)
async def handle_ban(self, room_id: RoomID, user_id: UserID, banned_by: UserID, reason: str,
event_id: EventID) -> None:
await self.handle_kick_ban(True, room_id, user_id, banned_by, reason, event_id)
+19 -13
View File
@@ -222,7 +222,7 @@ class BasePortal(ABC):
return False
evt_type = EventType.find(f"net.maunium.telegram.{event}")
evt_type.t_class = EventType.Class.STATE
return self.main_intent.state_store.has_power_level(self.mxid, user.mxid, event=evt_type)
return 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]]:
@@ -273,17 +273,13 @@ class BasePortal(ABC):
authenticated.append(user)
return authenticated
async def cleanup_room(self, intent: IntentAPI, room_id: RoomID,
message: str = "Portal deleted", puppets_only: bool = False) -> None:
@staticmethod
async def cleanup_room(intent: IntentAPI, room_id: RoomID, message: str,
puppets_only: bool = False) -> None:
try:
members = await intent.get_room_members(room_id)
except MatrixRequestError:
members = []
if self.username:
try:
await intent.remove_room_alias(self.alias_localpart)
except (MatrixRequestError, IntentError):
self.log.warning("Failed to remove alias when cleaning up room", exc_info=True)
for user in members:
puppet = p.Puppet.get_by_mxid(UserID(user), create=False)
if user != intent.mxid and (not puppets_only or puppet):
@@ -299,12 +295,20 @@ class BasePortal(ABC):
except (MatrixRequestError, IntentError):
self.log.warning("Failed to leave room when cleaning up room", exc_info=True)
async def cleanup_portal(self, message: str, puppets_only: bool = False) -> None:
if self.username:
try:
await self.main_intent.remove_room_alias(self.alias_localpart)
except (MatrixRequestError, IntentError):
self.log.warning("Failed to remove alias when cleaning up room", exc_info=True)
await self.cleanup_room(self.main_intent, self.mxid, message, puppets_only)
async def unbridge(self) -> None:
await self.cleanup_room(self.main_intent, self.mxid, "Room unbridged", puppets_only=True)
await self.cleanup_portal("Room unbridged", puppets_only=True)
self.delete()
async def cleanup_and_delete(self) -> None:
await self.cleanup_room(self.main_intent, self.mxid)
await self.cleanup_portal("Portal deleted")
self.delete()
# endregion
@@ -401,9 +405,11 @@ class BasePortal(ABC):
if peer_type:
cls.log.info(f"Creating portal for {peer_type} {tgid} (receiver {tg_receiver})")
if peer_type == "chat":
import traceback
cls.log.info("Chat portal stack trace:\n" + "".join(traceback.format_stack()))
# TODO enable this for non-release builds
# (or add better wrong peer type error handling)
# if peer_type == "chat":
# import traceback
# cls.log.info("Chat portal stack trace:\n" + "".join(traceback.format_stack()))
portal = cls(tgid, peer_type=peer_type, tg_receiver=tg_receiver)
portal.db_instance.insert()
return portal
+1 -1
View File
@@ -367,7 +367,7 @@ class PortalMatrix(BasePortal, MautrixBasePortal, ABC):
if not bridge_notices and not excepted:
return
if content.msgtype in (MessageType.TEXT, MessageType.NOTICE):
if content.msgtype in (MessageType.TEXT, MessageType.EMOTE, MessageType.NOTICE):
await self._pre_process_matrix_message(sender, not logged_in, content)
await self._handle_matrix_text(sender_id, event_id, space, client, content, reply_to)
elif content.msgtype == MessageType.LOCATION:
+6
View File
@@ -258,6 +258,8 @@ class Puppet(CustomPuppetMixin):
return False
allow_source = (source.is_relaybot
or self.displayname_source == source.tgid
# User is not a contact, so there's no custom name
or not info.contact
# No displayname source, so just trust anything
or self.displayname_source is None)
if not allow_source:
@@ -424,4 +426,8 @@ def init(context: 'Context') -> Iterable[Awaitable[Any]]:
Puppet.displayname_template = SimpleTemplate(config["bridge.displayname_template"],
"displayname")
secret = config["bridge.login_shared_secret"]
Puppet.login_shared_secret = secret.encode("utf-8") if secret else None
Puppet.login_device_name = "Telegram Bridge"
return (puppet.try_start() for puppet in Puppet.all_with_custom_mxid())
+22 -6
View File
@@ -19,7 +19,8 @@ import logging
import asyncio
from telethon.tl.types import (TypeUpdate, UpdateNewMessage, UpdateNewChannelMessage, PeerUser,
UpdateShortChatMessage, UpdateShortMessage, User as TLUser, Chat)
UpdateShortChatMessage, UpdateShortMessage, User as TLUser, Chat,
ChatForbidden)
from telethon.tl.types.contacts import ContactsNotModified
from telethon.tl.functions.contacts import GetContactsRequest, SearchRequest
from telethon.tl.functions.account import UpdateStatusRequest
@@ -198,14 +199,27 @@ class User(AbstractUser, BaseUser):
self.client.session.delete()
return self
async def post_login(self, info: TLUser = None) -> None:
async def post_login(self, info: TLUser = None, first_login: bool = False) -> None:
try:
await self.update_info(info)
if not self.is_bot and config["bridge.startup_sync"]:
except Exception:
self.log.exception("Failed to update telegram account info")
return
try:
puppet = pu.Puppet.get(self.tgid)
if puppet.custom_mxid != self.mxid and puppet.can_auto_login(self.mxid):
self.log.info(f"Automatically enabling custom puppet")
await puppet.switch_mxid(access_token="auto", mxid=self.mxid)
except Exception:
self.log.exception("Failed to automatically enable custom puppet")
if not self.is_bot and config["bridge.startup_sync"]:
try:
await self.sync_dialogs()
await self.sync_contacts()
except Exception:
self.log.exception("Failed to run post-login functions for %s", self.mxid)
except Exception:
self.log.exception("Failed to run post-login sync")
async def update(self, update: TypeUpdate) -> bool:
if not self.is_bot:
@@ -327,7 +341,9 @@ class User(AbstractUser, BaseUser):
async for dialog in self.client.iter_dialogs(limit=limit, ignore_migrated=True,
archived=False):
entity = dialog.entity
if isinstance(entity, Chat) and (entity.deactivated or entity.left):
if isinstance(entity, ChatForbidden):
self.log.warning(f"Ignoring forbidden chat {entity} while syncing")
elif isinstance(entity, Chat) and (entity.deactivated or entity.left):
self.log.warning(f"Ignoring deactivated or left chat {entity} while syncing")
continue
elif isinstance(entity, TLUser) and not config["bridge.sync_direct_chats"]:
+1
View File
@@ -0,0 +1 @@
from .get_version import git_tag, git_revision, version, linkified_version
+1 -1
View File
@@ -119,7 +119,7 @@ class AuthAPI(abc.ABC):
existing_user = User.get_by_tgid(user_info.id)
if existing_user and existing_user != user:
await existing_user.log_out()
asyncio.ensure_future(user.post_login(user_info), loop=self.loop)
asyncio.ensure_future(user.post_login(user_info, first_login=True), loop=self.loop)
if user.command_status and user.command_status["action"] == "Login":
user.command_status = None
@@ -149,11 +149,9 @@ class ProvisioningAPI(AuthAPI):
force = request.query.get("force", None)
if force in ("delete", "unbridge"):
delete = force == "delete"
await portal.cleanup_room(portal.main_intent, portal.mxid, puppets_only=not delete,
message=("Portal deleted (moving to another room)"
if delete
else "Room unbridged (portal moving to another "
"room)"))
await portal.cleanup_portal("Portal deleted (moving to another room)" if delete
else "Room unbridged (portal moving to another room)",
puppets_only=not delete)
else:
return self.get_error_response(409, "chat_already_bridged",
"Telegram chat is already bridged to another "
+13 -3
View File
@@ -1,6 +1,7 @@
import setuptools
import glob
import mautrix_telegram
from mautrix_telegram.get_version import git_tag, git_revision, version, linkified_version
extras = {
"speedups": ["cryptg>=0.1,<0.3", "cchardet", "aiodns", "Brotli"],
@@ -16,9 +17,18 @@ try:
except IOError:
long_desc = "Failed to read README.md"
with open("mautrix_telegram/version.py", "w") as version_file:
version_file.write(f"""# Generated in setup.py
git_tag = {git_tag!r}
git_revision = {git_revision!r}
version = {version!r}
linkified_version = {linkified_version!r}
""")
setuptools.setup(
name="mautrix-telegram",
version=mautrix_telegram.__version__,
version=version,
url="https://github.com/tulir/mautrix-telegram",
author="Tulir Asokan",
@@ -32,7 +42,7 @@ setuptools.setup(
install_requires=[
"aiohttp>=3.0.1,<4",
"mautrix>=0.4.0rc1,<0.5",
"mautrix>=0.4.0,<0.5",
"SQLAlchemy>=1.2.3,<2",
"alembic>=1.0.0,<2",
"commonmark>=0.8.1,<0.10",
+9 -1
View File
@@ -26,7 +26,7 @@ def context(request: FixtureRequest) -> Context:
"""
# Config(path, registration_path, base_path)
config = getattr(request.cls, 'config', Config("", "", ""))
return Context(az=Mock(), config=config, loop=Mock(), session_container=Mock(), bot=Mock())
return Context(az=Mock(), config=config, loop=Mock(), session_container=Mock(), bridge=Mock(), bot=Mock())
@pytest.fixture
@@ -52,6 +52,7 @@ class TestCommandEvent:
sender=u.User(UserID("@sender:example.org")),
command="help",
args=[],
content=Mock(),
is_management=True,
is_portal=False,
)
@@ -107,6 +108,7 @@ class TestCommandEvent:
sender=u.User(UserID("@sender:example.org")),
command="help",
args=[],
content=Mock(),
is_management=False,
is_portal=False,
)
@@ -133,6 +135,7 @@ class TestCommandEvent:
sender=u.User(UserID("@sender:example.org")),
command="help",
args=[],
content=Mock(),
is_management=True,
is_portal=False,
)
@@ -209,6 +212,7 @@ class TestCommandHandler:
sender=sender,
command=command,
args=[],
content=Mock(),
is_management=False,
is_portal=boolean,
)
@@ -271,6 +275,7 @@ class TestCommandHandler:
sender=sender,
command=command,
args=[],
content=Mock(),
is_management=is_management,
is_portal=boolean,
)
@@ -307,6 +312,7 @@ class TestCommandProcessor:
sender=sender,
command="hElp",
args=[],
content=Mock(),
is_management=boolean2[0],
is_portal=boolean2[1])
@@ -333,6 +339,7 @@ class TestCommandProcessor:
sender=sender,
command="foo",
args=[],
content=Mock(),
is_management=boolean2[0],
is_portal=boolean2[1],
)
@@ -361,6 +368,7 @@ class TestCommandProcessor:
sender=sender, # u.User
command="foo",
args=[],
content=Mock(),
is_management=boolean2[0],
is_portal=boolean2[1]
)