diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..3afa3d4f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,38 @@ +image: docker:stable + +stages: +- build +- push + +default: + before_script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + +build: + stage: build + script: + - docker pull $CI_REGISTRY_IMAGE:latest || true + - docker build --pull --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA . + - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA + +push latest: + stage: push + only: + - master + variables: + GIT_STRATEGY: none + script: + - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA + - docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:latest + - docker push $CI_REGISTRY_IMAGE:latest + +push tag: + stage: push + variables: + GIT_STRATEGY: none + except: + - master + script: + - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA + - docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME + - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME diff --git a/README.md b/README.md index d575b2fc..deb960d4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,10 @@ # mautrix-telegram +![Languages](https://img.shields.io/github/languages/top/tulir/mautrix-telegram.svg) +[![License](https://img.shields.io/github/license/tulir/mautrix-telegram.svg)](LICENSE) +[![Release](https://img.shields.io/github/release/tulir/mautrix-telegram/all.svg)](https://github.com/tulir/mautrix-telegram/releases) +[![GitLab CI](https://mau.dev/tulir/mautrix-telegram/badges/master/pipeline.svg)](https://mau.dev/tulir/mautrix-telegram/container_registry) +[![Maintainability](https://img.shields.io/codeclimate/maintainability/tulir/mautrix-telegram.svg)](https://codeclimate.com/github/tulir/mautrix-telegram) + A Matrix-Telegram hybrid puppeting/relaybot bridge. ### [Wiki](https://github.com/tulir/mautrix-telegram/wiki) diff --git a/example-config.yaml b/example-config.yaml index 1c80967e..a07555e2 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -12,11 +12,11 @@ homeserver: # Changing these values requires regeneration of the registration. appservice: # The address that the homeserver can use to connect to this appservice. - address: http://localhost:8080 + address: http://localhost:29317 # The hostname and port where this appservice should listen. hostname: 0.0.0.0 - port: 8080 + port: 29317 # The maximum body size of appservice API requests (from the homeserver) in mebibytes # Usually 1 is enough, but on high-traffic bridges you might need to increase this to avoid 413s max_body_size: 1 diff --git a/mautrix_telegram/formatter/from_matrix/parser.py b/mautrix_telegram/formatter/from_matrix/parser.py index 16ee929a..3429126e 100644 --- a/mautrix_telegram/formatter/from_matrix/parser.py +++ b/mautrix_telegram/formatter/from_matrix/parser.py @@ -169,7 +169,9 @@ class MatrixParser: @classmethod def node_to_tmessage(cls, node: HTMLNode, ctx: RecursionContext) -> TelegramMessage: - if node.tag == "ol": + if node.tag == "mx-reply": + return TelegramMessage("") + elif node.tag == "ol": return cls.list_to_tmessage(node, ctx) elif node.tag == "ul": return cls.list_to_tmessage(node, ctx.enter_list()) diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index 4c1f5f13..d9f329e3 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -1033,7 +1033,6 @@ class Portal: orig_msg = DBMessage.get_by_mxid(relates_to.get("event_id", ""), self.mxid, space) if orig_msg and "m.new_content" in message: message = message["m.new_content"] - formatter.matrix_reply_to_telegram(message, space, room_id=self.mxid) response = await client.edit_message(self.peer, orig_msg.tgid, message, parse_mode=self._matrix_event_to_entities, link_preview=lp) diff --git a/mautrix_telegram/puppet.py b/mautrix_telegram/puppet.py index 8aaa2ad2..93e9abe7 100644 --- a/mautrix_telegram/puppet.py +++ b/mautrix_telegram/puppet.py @@ -170,14 +170,26 @@ class Puppet(CustomPuppetMixin): return int(round(similarity * 100)) @staticmethod - def get_displayname(info: User, enable_format: bool = True) -> str: + def _filter_name(name: str) -> str: + if not name: + return "" + whitespace = ("\ufeff", "\u3164", "\u2063", "\u200b", "\u180e", "\u034f", "\u2800", + "\u180e", "\u200b", "\u202f", "\u205f", "\u3000") + name = "".join(char for char in name if char not in whitespace) + name = name.strip() + return name + + @classmethod + def get_displayname(cls, info: User, enable_format: bool = True) -> str: + fn = cls._filter_name(info.first_name) + ln = cls._filter_name(info.last_name) data = { "phone number": info.phone if hasattr(info, "phone") else None, "username": info.username, - "full name": " ".join([info.first_name or "", info.last_name or ""]).strip(), - "full name reversed": " ".join([info.first_name or "", info.last_name or ""]).strip(), - "first name": info.first_name, - "last name": info.last_name, + "full name": " ".join([fn, ln]).strip(), + "full name reversed": " ".join([ln, fn]).strip(), + "first name": fn, + "last name": ln, } preferences = config["bridge.displayname_preference"] name = None @@ -189,7 +201,7 @@ class Puppet(CustomPuppetMixin): if isinstance(info, User) and info.deleted: name = f"Deleted account {info.id}" elif not name: - name = info.id + name = str(info.id) if not enable_format: return name