commit 6f05952dca52adb111978566a82b2815e1d0bcdb Author: Arthur Bols Date: Wed May 19 18:37:14 2021 +0200 Initial commit diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..a849cff --- /dev/null +++ b/__init__.py @@ -0,0 +1 @@ +from .ascii_emoji import AsciiEmojiPlugin diff --git a/ascii_emoji.png b/ascii_emoji.png new file mode 100644 index 0000000..cc50091 Binary files /dev/null and b/ascii_emoji.png differ diff --git a/ascii_emoji.py b/ascii_emoji.py new file mode 100644 index 0000000..0140c3a --- /dev/null +++ b/ascii_emoji.py @@ -0,0 +1,65 @@ +# This file is part of Ascii Emoji. +# +# Copyright (C) 2021 Arthur Bols +# +# Ascii Emoji is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ascii Emoji is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ascii Emoji. If not, see . + +import re + +from ascii_emoji.ascii_emoticons_data import ascii_emoticons_data +from gajim.common import ged +from gajim.plugins import GajimPlugin +from gajim.plugins.helpers import log_calls +from gajim.plugins.plugins_i18n import _ + + +class AsciiEmojiPlugin(GajimPlugin): + + @log_calls('AsciiEmojiPlugin') + def init(self): + self.description = _('Replaces ascii emoticons with emoji.') + self.config_dialog = None + + self.events_handlers = { + 'decrypted-message-received': (ged.PREGUI1, + self._decrypted_message_received), + 'gc-message-received': (ged.PREGUI1, self._gc_message_received), + } + + self.emoticon_regex = re.compile(ascii_emoticons_data.get_regex()) + + @log_calls('AsciiEmojiPlugin') + def _replace(self, obj): + if not obj.msgtxt: + return + iterator = self.emoticon_regex.finditer(obj.msgtxt) + new_msgtxt = '' + prev_repl = 0 + for match in iterator: + start, end = match.span() + ascii_text = obj.msgtxt[start:end] + emoji = ascii_emoticons_data.get(ascii_text, None) + + if emoji is not None: + new_msgtxt += obj.msgtxt[prev_repl:start] + emoji + prev_repl = end + obj.msgtxt = new_msgtxt + obj.msgtxt[prev_repl:] + + @log_calls('AsciiEmojiPlugin') + def _decrypted_message_received(self, obj): + self._replace(obj) + + @log_calls('AsciiEmojiPlugin') + def _gc_message_received(self, obj): + self._replace(obj) diff --git a/ascii_emoticons_data.py b/ascii_emoticons_data.py new file mode 100644 index 0000000..86f63a4 --- /dev/null +++ b/ascii_emoticons_data.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- + +# This file is part of Ascii Emoji. +# +# Copyright (C) 2021 Arthur Bols +# +# Ascii Emoji is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ascii Emoji is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ascii Emoji. If not, see . + +import re + + +class AsciiEmoticonsData(dict): + def get_regex(self): + # When an emoticon is bordered by an alphanumeric character it + # is NOT expanded. e.g., foo:) NO, foo :) YES, (BRB) NO, + # (:)) YES, etc. We still allow multiple emoticons + # side-by-side like :P:P:P + + keys = sorted(self.keys(), key=len, reverse=True) + pre_pattern = '' + post_pattern = '' + emoticon_length = 0 + emoticons_pattern = '' + for emoticon in keys: + # escape regexp metachars + emoticon_escaped = re.escape(emoticon) + emoticons_pattern += emoticon_escaped + '|' + if emoticon_length != len(emoticon): + # Build up expressions to match emoticons next to others + pre_pattern = pre_pattern[:-1] + ')|(?<=' + post_pattern = post_pattern[:-1] + ')|(?=' + emoticon_length = len(emoticon) + pre_pattern += emoticon_escaped + '|' + post_pattern += emoticon_escaped + '|' + # We match from our list of emoticons, but they must either have + # whitespace, or another emoticon next to it to match successfully + # [\w.] alphanumeric and dot (for not matching 8) in (2.8)) + emoticons_pattern = r'(?:(?:P', '\U0001F61c'), + ('X-P', '\U0001F61c'), + (':(', '\U0001F61e'), + (':-(', '\U0001F61e'), + (':-[', '\U0001F61e'), + (':[', '\U0001F61e'), + ('=(', '\U0001F61e'), + ('>:[', '\U0001F61e'), + (':-O', '\U0001F62e'), + (':O', '\U0001F62e'), + ('>:O', '\U0001F62e'), + ('O_O', '\U0001F62e'), + (':)', '\U0001F606'), + ('>:-)', '\U0001F606'), + ('>;)', '\U0001F606'), + ('>=)', '\U0001F606'), + ('x-D', '\U0001F606'), + ('X-D', '\U0001F606'), + ('xD', '\U0001F606'), + ('XD', '\U0001F606'), + ('0:)', '\U0001F607'), + ('0:-)', '\U0001F607'), + ('0:-3', '\U0001F607'), + ('0:3', '\U0001F607'), + ('0;-)', '\U0001F607'), + ('0;^)', '\U0001F607'), + ('O:)', '\U0001F607'), + ('O:-)', '\U0001F607'), + ('O:-3', '\U0001F607'), + ('O:3', '\U0001F607'), + ('O;-)', '\U0001F607'), + ('O=)', '\U0001F607'), + ('*)', '\U0001F609'), + ('*-)', '\U0001F609'), + (';)', '\U0001F609'), + (';-)', '\U0001F609'), + (';-]', '\U0001F609'), + (';]', '\U0001F609'), + (';^)', '\U0001F609'), + (';D', '\U0001F609'), + ('-_-', '\U0001F611'), + ('-__-', '\U0001F611'), + ('-___-', '\U0001F611'), + ("':(", '\U0001F613'), + ("':-(", '\U0001F613'), + ("'=(", '\U0001F613'), + (':-.', '\U0001F615'), + (':-/', '\U0001F615'), + (':/', '\U0001F615'), + (':\\', '\U0001F615'), + (':L', '\U0001F615'), + ('=/', '\U0001F615'), + ('=\\', '\U0001F615'), + ('=L', '\U0001F615'), + ('>:/', '\U0001F615'), + ('>:\\', '\U0001F615'), + (':*', '\U0001F618'), + (':-*', '\U0001F618'), + (':^*', '\U0001F618'), + ('=*', '\U0001F618'), + (':@', '\U0001F620'), + ('>:(', '\U0001F620'), + ('>:-(', '\U0001F620'), + (":'(", '\U0001F622'), + (":'-(", '\U0001F622'), + (';(', '\U0001F622'), + (';-(', '\U0001F622'), + ('>.<', '\U0001F623'), + ('D:', '\U0001F628'), + (':$', '\U0001F633'), + ('=$', '\U0001F633'), + ('#)', '\U0001F635'), + ('#-)', '\U0001F635'), + ('%)', '\U0001F635'), + ('%-)', '\U0001F635'), + ('X)', '\U0001F635'), + ('X-)', '\U0001F635'), + (':#', '\U0001F636'), + (':-#', '\U0001F636'), + (':-X', '\U0001F636'), + (':X', '\U0001F636'), + ('=#', '\U0001F636'), + ('=X', '\U0001F636'), + (':)', '\U0001F642'), + (':-)', '\U0001F642'), + (':]', '\U0001F642'), + ('=)', '\U0001F642'), + ('=]', '\U0001F642'), + ('*\\0/*', '\U0001F646'), + ('*\\O/*', '\U0001F646'), + ('\\0/', '\U0001F646'), + ('\\O/', '\U0001F646'), + ('<3', '\U00002764\U0000FE0F'), +]) diff --git a/manifest.ini b/manifest.ini new file mode 100644 index 0000000..3a90615 --- /dev/null +++ b/manifest.ini @@ -0,0 +1,9 @@ +[info] +name: Ascii Emoji +short_name: ascii_emoji +version: 1.0.0 +description: Replaces ascii emoticons with emoji. +authors: Arthur Bols +homepage: +min_gajim_version: 1.2.91 +max_gajim_version: 1.3.90