diff --git a/README.md b/README.md index 458a10e..7db3cf8 100644 --- a/README.md +++ b/README.md @@ -201,3 +201,13 @@ Please, fill `` of the Amazon SNS topic ``` Note the ```telegram/webhook``` url part + + + +(check last video sent) + ++ . Make the replies about log-in go directly to user from bot, rather than to channel. ++ . Slightly refactor my PR with notifcations to general channels about Goal, Idea, Plan,... +. Add links to inf.li, rather than to API items. ++ . Have a default language of the bot, and remove language tokens from text when showing on TG +. Prepend the language token when language of bot is known (e.g., like on web client.) less diff --git a/src/inftybot/authentication/intents/base.py b/src/inftybot/authentication/intents/base.py index dcc6c5f..ed8dc5e 100644 --- a/src/inftybot/authentication/intents/base.py +++ b/src/inftybot/authentication/intents/base.py @@ -51,4 +51,5 @@ def before_validate(self): self.set_api_authentication(self.current_user) if not self.is_authenticated: - raise AuthenticationError("Please, /login first") + message = "Please, talk to @{} to login".format(self.bot.username) + raise AuthenticationError(message) diff --git a/src/inftybot/authentication/tests/test_login.py b/src/inftybot/authentication/tests/test_login.py index b0f80a1..7cfaa9c 100644 --- a/src/inftybot/authentication/tests/test_login.py +++ b/src/inftybot/authentication/tests/test_login.py @@ -39,7 +39,9 @@ def test_call_intent_with_user_ensure_api_request_contains_token(self): except ValidationError: pass - self.assertEqual(intent.api.session.headers['authorization'], 'Token token') + store = getattr(intent.api.client, '_store') + session = store['session'] + self.assertEqual(session.headers['authorization'], 'Token token') def test_before_validate_sets_api_authentication(self): # todo test diff --git a/src/inftybot/comments/intents/comment.py b/src/inftybot/comments/intents/comment.py index a07bdeb..0017a3e 100644 --- a/src/inftybot/comments/intents/comment.py +++ b/src/inftybot/comments/intents/comment.py @@ -9,7 +9,9 @@ from telegram.ext import MessageHandler, BaseFilter from inftybot.authentication.intents.base import AuthenticatedMixin +from inftybot.comments.utils import prepare_comment from inftybot.core.intents.base import BaseMessageIntent +from inftybot.topics.utils import get_topic_id _ = gettext logger = logging.getLogger(__name__) @@ -69,11 +71,7 @@ def get_topic_url(self): def get_topic_id(self): topic_url = self.get_topic_url() - - try: - return int(topic_url.strip('/').rsplit('/', 1)[-1]) - except (IndexError, TypeError): - return None + return get_topic_id(topic_url) class TopicReplyFilter(BaseFilter): @@ -102,18 +100,19 @@ def handle(self, *args, **kwargs): original_message = self.update.message.reply_to_message parser = MessageParser(original_message.text) topic_url = parser.get_topic_url() + text = prepare_comment(self.update.message.text) data = { 'topic': topic_url, - 'text': self.update.message.text, + 'text': text.text, # 'languages': [], } try: - response = self.api.client.comments.post(data=data) + self.api.client.comments.post(data=data) except (HttpClientError, HttpServerError) as e: logger.error(e) else: self.bot.sendMessage( chat_id=self.update.message.chat_id, - text="Comment was created: {}".format(response.get('url', 'URL UNDEFINED')), + text="Comment was created", ) diff --git a/src/inftybot/comments/utils.py b/src/inftybot/comments/utils.py new file mode 100644 index 0000000..f74bf2e --- /dev/null +++ b/src/inftybot/comments/utils.py @@ -0,0 +1,10 @@ +# coding: utf-8 +from inftybot import config + + +def prepare_comment(comment): + comment = comment.strip() + if comment.startswith('.:'): + # language provided, bypass + return comment + return ".:{langcode}\n{comment}".format(langcode=config.DEFAULT_LANGUAGE, comment=comment) diff --git a/src/inftybot/config.py b/src/inftybot/config.py index d4fec9d..88dd284 100644 --- a/src/inftybot/config.py +++ b/src/inftybot/config.py @@ -14,6 +14,9 @@ SEARCH_PREVIEW_LENGTH = os.environ.get('SEARCH_PREVIEW_LENGTH', 200) INLINE_QUERY_CACHE_TIME = os.environ.get('INLINE_QUERY_CACHE_TIME', 0) +DEFAULT_LANGUAGE = os.environ.get('DEFAULT_LANGUAGE', 'en') + + INTENTS = [ 'inftybot.core.intents.start.StartCommandIntent', 'inftybot.core.intents.reset.ResetCommandIntent', @@ -37,3 +40,5 @@ JINJA_EXTENSIONS = [ 'inftybot.contrib.jinja2.ext.StringExtension', ] + +TOPIC_URL_TEMPLATE = 'https://inf.li/#/{INFTY_API_URL}:en/@/topic/{TOPIC_ID}' diff --git a/src/inftybot/core/intents/base.py b/src/inftybot/core/intents/base.py index c193c47..78499f8 100644 --- a/src/inftybot/core/intents/base.py +++ b/src/inftybot/core/intents/base.py @@ -128,7 +128,6 @@ def handle(self, *args, **kwargs): def handle_error(self, error): logger.error('Unhandled error in the intent {}: {}'.format(self.__class__, error)) - pass @classmethod def create_from_intent(cls, intent, **kwargs): @@ -159,7 +158,7 @@ def __init__(self, **kwargs): self.query = query def handle_error(self, error): - raise NotImplementedError + self.bot.send_message(chat_id=self.update.effective_chat.id, text=error.message) def parse_query(self): """ @@ -193,7 +192,7 @@ def get_handler(cls): ) def handle_error(self, error): - self.update.message.reply_text(error.message) + self.bot.send_message(chat_id=self.update.effective_chat.id, text=error.message) class BaseCommandIntent(BaseIntent): diff --git a/src/inftybot/core/intents/start.py b/src/inftybot/core/intents/start.py index 4abcaf6..ad526d1 100644 --- a/src/inftybot/core/intents/start.py +++ b/src/inftybot/core/intents/start.py @@ -13,4 +13,4 @@ def get_handler(cls): return CommandHandler("start", cls.as_callback(), pass_chat_data=True, pass_user_data=True) def handle(self, *args, **kwargs): - self.update.message.reply_text(_("Let's start")) + self.update.message.reply_text(_("Let's start. Use /login to begin.")) diff --git a/src/inftybot/search/intents/search.py b/src/inftybot/search/intents/search.py index bccc4f9..ecb873c 100644 --- a/src/inftybot/search/intents/search.py +++ b/src/inftybot/search/intents/search.py @@ -48,11 +48,8 @@ def handle(self): def process_result(result): description = result.get('body', '')[:config.SEARCH_PREVIEW_LENGTH] - topic = Topic() - topic.type = result.get('type') - topic.title = result.get('title') - topic.body = result.get('body') - topic.url = result.get('url') + attrs = {k: v for k, v in result.items() if hasattr(Topic, k)} + topic = Topic(**attrs) message_text = render_topic(topic) diff --git a/src/inftybot/topics/models.py b/src/inftybot/topics/models.py index 525e473..209b04d 100644 --- a/src/inftybot/topics/models.py +++ b/src/inftybot/topics/models.py @@ -1,8 +1,11 @@ # coding: utf-8 + from django.contrib.postgres.fields import ArrayField from django.db import models from django.utils.translation import gettext as _ +from inftybot.topics.utils import get_topic_id, get_topic_client_url + class Topic(models.Model): """Dummy topic model""" @@ -53,3 +56,9 @@ def categories_str(self): def categories_str(self, value): # NOQA pass + + def get_topic_id(self): + return get_topic_id(self.url) + + def get_client_url(self): + return get_topic_client_url(self) diff --git a/src/inftybot/topics/templates/topics/topic.md b/src/inftybot/topics/templates/topics/topic.md index ae59792..10b2258 100644 --- a/src/inftybot/topics/templates/topics/topic.md +++ b/src/inftybot/topics/templates/topics/topic.md @@ -1,10 +1,10 @@ -{% if object.categories_names %} -`Categories:` {{object.categories_names|join:','}} -{% endif %} +{% load langsplit_tags %} -`{{object.get_type_display}}:` *{{object.title}}* +{% if object.categories_names %}`Categories:` {{object.categories_names|select_language|join:', '}}{% endif %} -{{object.body}} +`{{object.get_type_display}}:` *{{object.title|select_language}}* -*URL:* {{object.url}} +{{object.body|select_language}} + +*URL:* {{object.get_client_url}} _Reply to this message to post a comment on Infinity._ \ No newline at end of file diff --git a/src/inftybot/topics/templatetags/__init__.py b/src/inftybot/topics/templatetags/__init__.py new file mode 100644 index 0000000..57d631c --- /dev/null +++ b/src/inftybot/topics/templatetags/__init__.py @@ -0,0 +1 @@ +# coding: utf-8 diff --git a/src/inftybot/topics/templatetags/langsplit_tags.py b/src/inftybot/topics/templatetags/langsplit_tags.py new file mode 100644 index 0000000..17786ac --- /dev/null +++ b/src/inftybot/topics/templatetags/langsplit_tags.py @@ -0,0 +1,18 @@ +# coding: utf-8 +from django import template +from langsplit import splitter + +from inftybot import config + +register = template.Library() + + +@register.filter +def select_language(value, langcode=None): + if isinstance(value, list): + return [select_language(v) for v in value] + langcode = langcode or config.DEFAULT_LANGUAGE + splitted = splitter.split(value) + if isinstance(splitted, dict): + return splitted.get(langcode, value) + return value diff --git a/src/inftybot/topics/tests/test_render_topic.py b/src/inftybot/topics/tests/test_render_topic.py new file mode 100644 index 0000000..e4d9cb3 --- /dev/null +++ b/src/inftybot/topics/tests/test_render_topic.py @@ -0,0 +1,17 @@ +# coding: utf-8 +from django.test import TestCase + +from inftybot.topics.models import Topic +from inftybot.topics.utils import render_topic + + +class RenderLangsplitTestCase(TestCase): + def test_default_language_renders_ok(self): + title = ".:en:Title" + body = """.:en + body + """ + + instance = Topic(title=title, body=body) + rendered = render_topic(instance) + self.assertNotIn('.:en', rendered) diff --git a/src/inftybot/topics/utils.py b/src/inftybot/topics/utils.py index 623dbab..a7ca213 100644 --- a/src/inftybot/topics/utils.py +++ b/src/inftybot/topics/utils.py @@ -1,6 +1,28 @@ # coding: utf-8 +from urllib.parse import urlparse + from django.template.loader import render_to_string +from inftybot import config + + +def get_topic_id(topic_url): + try: + return int(topic_url.strip('/').rsplit('/', 1)[-1]) + except (AttributeError, IndexError, TypeError): + return None + + +def get_topic_client_url(instance): + template = config.TOPIC_URL_TEMPLATE + url_object = urlparse(config.INFTY_API_URL) + topic_id = instance.get_topic_id() + context = { + 'INFTY_API_URL': url_object.netloc, + 'TOPIC_ID': topic_id, + } + return template.format(**context) + def render_topic(instance): return render_to_string('topics/topic.md', context={'object': instance})