mobilizon link in template (#80)
* added basic recap feature (no error handling) * introduced abstractpublication * extracted base reports * added error report to recap * added test * added docs * implemented publisher and formatter * fixed API for recap * removed redundant config validation * added config sample * added mobilizon link to templates * added link format to telegram * added mobilizon link to recap * fixed config and emoji
This commit is contained in:
parent
489d41179e
commit
8de70ef857
|
@ -5,6 +5,9 @@ telegram_validators = [
|
|||
Validator("publisher.telegram.chat_id", must_exist=True),
|
||||
Validator("publisher.telegram.msg_template_path", must_exist=True, default=None),
|
||||
Validator("publisher.telegram.recap_template_path", must_exist=True, default=None),
|
||||
Validator(
|
||||
"publisher.telegram.recap_header_template_path", must_exist=True, default=None
|
||||
),
|
||||
Validator("publisher.telegram.token", must_exist=True),
|
||||
Validator("publisher.telegram.username", must_exist=True),
|
||||
]
|
||||
|
@ -13,6 +16,9 @@ zulip_validators = [
|
|||
Validator("publisher.zulip.subject", must_exist=True),
|
||||
Validator("publisher.zulip.msg_template_path", must_exist=True, default=None),
|
||||
Validator("publisher.zulip.recap_template_path", must_exist=True, default=None),
|
||||
Validator(
|
||||
"publisher.zulip.recap_header_template_path", must_exist=True, default=None
|
||||
),
|
||||
Validator("publisher.zulip.bot_token", must_exist=True),
|
||||
Validator("publisher.zulip.bot_email", must_exist=True),
|
||||
]
|
||||
|
@ -20,6 +26,9 @@ mastodon_validators = []
|
|||
twitter_validators = [
|
||||
Validator("publisher.twitter.msg_template_path", must_exist=True, default=None),
|
||||
Validator("publisher.twitter.recap_template_path", must_exist=True, default=None),
|
||||
Validator(
|
||||
"publisher.twitter.recap_header_template_path", must_exist=True, default=None
|
||||
),
|
||||
Validator("publisher.twitter.api_key", must_exist=True),
|
||||
Validator("publisher.twitter.api_key_secret", must_exist=True),
|
||||
Validator("publisher.twitter.access_token", must_exist=True),
|
||||
|
|
|
@ -132,7 +132,7 @@ class AbstractEventFormatter(LoggerMixin, ConfLoaderMixin):
|
|||
"""
|
||||
return event
|
||||
|
||||
def get_message_from_event(self, event) -> str:
|
||||
def get_message_from_event(self, event: MobilizonEvent) -> str:
|
||||
"""
|
||||
Retrieves a message from the event itself.
|
||||
"""
|
||||
|
@ -147,6 +147,7 @@ class AbstractEventFormatter(LoggerMixin, ConfLoaderMixin):
|
|||
return JINJA_ENV.get_template(template_path)
|
||||
|
||||
def is_message_valid(self, event: MobilizonEvent) -> bool:
|
||||
# TODO: this thing swallows exception messages. It should be handled differently
|
||||
try:
|
||||
self.validate_message(self.get_message_from_event(event))
|
||||
except PublisherError:
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
class PublisherError(Exception):
|
||||
""" Generic publisher error """
|
||||
|
||||
def __init__(self, message):
|
||||
""" :param str message: exception message """
|
||||
super().__init__(message)
|
||||
pass
|
||||
|
||||
|
||||
class InvalidAttribute(PublisherError):
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import re
|
||||
|
||||
import pkg_resources
|
||||
import requests
|
||||
from requests import Response
|
||||
|
@ -30,17 +32,37 @@ class TelegramFormatter(AbstractEventFormatter):
|
|||
)
|
||||
|
||||
_conf = ("publisher", "telegram")
|
||||
_escape_characters = [
|
||||
"-",
|
||||
".",
|
||||
"(",
|
||||
"!",
|
||||
")",
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def restore_links(message: str) -> str:
|
||||
"""The escape_message function should ignore actually valid links that involve square brackets and parenthesis.
|
||||
This function de-escapes actual links without altering other escaped square brackets and parenthesis"""
|
||||
|
||||
def build_link(match):
|
||||
result = match.group(0)
|
||||
for character in TelegramFormatter._escape_characters:
|
||||
result = result.replace("\\" + character, character)
|
||||
return result
|
||||
|
||||
return re.sub(r"\[(\w*)]\\\(([\w\-/\\.:]*)\\\)", build_link, message,)
|
||||
|
||||
@staticmethod
|
||||
def escape_message(message: str) -> str:
|
||||
return (
|
||||
message.replace("-", r"\-")
|
||||
.replace(".", r"\.")
|
||||
.replace("(", r"\(")
|
||||
.replace("!", r"\!")
|
||||
.replace(")", r"\)")
|
||||
.replace("#", r"")
|
||||
)
|
||||
"""Escape message to comply with Telegram standards"""
|
||||
for character in TelegramFormatter._escape_characters:
|
||||
message = message.replace(character, "\\" + character)
|
||||
|
||||
# Telegram doesn't use headers so # can be removed
|
||||
message = message.replace("#", r"")
|
||||
|
||||
return TelegramFormatter.restore_links(message)
|
||||
|
||||
def validate_event(self, event: MobilizonEvent) -> None:
|
||||
description = event.description
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import pkg_resources
|
||||
from tweepy import OAuthHandler, API
|
||||
from tweepy import OAuthHandler, API, TweepyException
|
||||
from tweepy.models import Status
|
||||
|
||||
from mobilizon_reshare.event.event import MobilizonEvent
|
||||
|
@ -35,7 +35,9 @@ class TwitterFormatter(AbstractEventFormatter):
|
|||
self._log_error("No text was found", raise_error=InvalidEvent)
|
||||
|
||||
def validate_message(self, message) -> None:
|
||||
if len(message.encode("utf-8")) > 140:
|
||||
# TODO this is not precise. It should count the characters according to Twitter's logic but
|
||||
# Tweepy doesn't seem to support the validation client side
|
||||
if len(message.encode("utf-8")) > 280:
|
||||
raise PublisherError("Message is too long")
|
||||
|
||||
|
||||
|
@ -57,7 +59,10 @@ class TwitterPlatform(AbstractPlatform):
|
|||
return API(auth)
|
||||
|
||||
def _send(self, message: str) -> Status:
|
||||
return self._get_api().update_status(message)
|
||||
try:
|
||||
return self._get_api().update_status(message)
|
||||
except TweepyException as e:
|
||||
raise PublisherError from e
|
||||
|
||||
def validate_credentials(self):
|
||||
if not self._get_api().verify_credentials():
|
||||
|
|
|
@ -3,4 +3,6 @@
|
|||
🕒 {{ begin_datetime.format('DD MMMM, HH:mm') }} - {{ end_datetime.format('DD MMMM, HH:mm') }}
|
||||
{% if location %}📍 {{ location }}{% endif %}
|
||||
|
||||
{{ description }}
|
||||
{{ description }}
|
||||
|
||||
[Link]({{mobilizon_link}})
|
|
@ -2,3 +2,4 @@
|
|||
|
||||
🕒 {{ begin_datetime.format('DD MMMM, HH:mm') }} - {{ end_datetime.format('DD MMMM, HH:mm') }}
|
||||
{% if location %}📍 {{ location }}{% endif %}
|
||||
🔗 [Link]({{mobilizon_link}})
|
|
@ -5,4 +5,5 @@
|
|||
{% if location %}
|
||||
📍 {{ location }}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{{mobilizon_link}}
|
|
@ -2,4 +2,5 @@
|
|||
🕒 {{ begin_datetime.format('DD MMMM, HH:mm') }} - {{ end_datetime.format('DD MMMM, HH:mm') }}
|
||||
{% if location %}
|
||||
📍 {{ location }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
🔗 {{mobilizon_link}}
|
|
@ -6,4 +6,6 @@
|
|||
📍 {{ location }}
|
||||
|
||||
{% endif %}
|
||||
{{ description }}
|
||||
{{ description }}
|
||||
|
||||
[Link]({{mobilizon_link}})
|
|
@ -5,4 +5,5 @@
|
|||
{% if location %}
|
||||
📍 {{ location }}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
🔗 {{mobilizon_link}}
|
|
@ -30,6 +30,11 @@ def test_message_length_failure(event):
|
|||
["!", "\\!"],
|
||||
[")", "\\)"],
|
||||
[")!", "\\)\\!"],
|
||||
["[link](https://link.com)", "[link](https://link.com)"],
|
||||
[
|
||||
"[link](https://link.com) [link2](https://link.com)",
|
||||
"[link](https://link.com) [link2](https://link.com)",
|
||||
],
|
||||
],
|
||||
)
|
||||
def test_escape_message(message, result):
|
||||
|
|
Loading…
Reference in New Issue