From 5f2c9b0ae519901c2218db8786935d4af285b9da Mon Sep 17 00:00:00 2001
From: Adimarantis <>
Date: Sun, 6 Feb 2022 14:21:21 +0000
Subject: [PATCH] 50_Signalbot: Added support for unicode textformatting and
emoticons
git-svn-id: https://svn.fhem.de/fhem/trunk@25638 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/CHANGED | 1 +
fhem/FHEM/50_Signalbot.pm | 43 +++-
fhem/MAINTAINER.txt | 1 +
fhem/lib/FHEM/Text/Unicode.pm | 402 +++++++++++++++++-----------------
4 files changed, 239 insertions(+), 208 deletions(-)
diff --git a/fhem/CHANGED b/fhem/CHANGED
index 358e2ef54..e33accc25 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
+ - feature: 50_Signalbot: text formatting and emoticons via unicode
- feature: 70_ESCVP21net.pm: toggle, TW7400, new Readings
- new: lib/FHEM/Text/Unicode: apply text styles in Unicode
- feature: 66_EseraMulti: added support for solar sensor Esera 11112
diff --git a/fhem/FHEM/50_Signalbot.pm b/fhem/FHEM/50_Signalbot.pm
index 8ae8c4360..5d1b052fe 100755
--- a/fhem/FHEM/50_Signalbot.pm
+++ b/fhem/FHEM/50_Signalbot.pm
@@ -1,6 +1,6 @@
##############################################
#$Id$
-my $Signalbot_VERSION="3.6";
+my $Signalbot_VERSION="3.7";
# Simple Interface to Signal CLI running as Dbus service
# Author: Adimarantis
# License: GPL
@@ -27,6 +27,9 @@ use HttpUtils;
eval "use Protocol::DBus;1";
eval "use Protocol::DBus::Client;1" or my $DBus_missing = "yes";
+require FHEM::Text::Unicode;
+use FHEM::Text::Unicode qw(:ALL);
+
#maybe really get introspective here instead of handwritten list
my %signatures = (
"setContactBlocked" => "sb",
@@ -104,6 +107,7 @@ sub Signalbot_Initialize($) {
"cmdFavorite ".
"favorites:textField-long ".
"autoJoin:yes,no ".
+ "formatting:none,html,markdown,both ".
"registerMethod:SMS,Voice ".
"$readingFnAttributes";
}
@@ -339,7 +343,7 @@ sub Signalbot_Set($@) { #
eval { $fullstring=decode_utf8($fullstring); };
Log3 $hash->{NAME}, 3 , $hash->{NAME}.": Error from decode" if $@;
- Log3 $hash->{NAME}, 3 , $hash->{NAME}.": Before parse:" . encode_utf8($fullstring) . ":";
+ Log3 $hash->{NAME}, 3 , $hash->{NAME}.": Before parse:" .$fullstring. ":";
my $tmpmessage = $fullstring =~ s/\\n/\x0a/rg;
my @args=parse_line(' ',0,$tmpmessage);
@@ -401,7 +405,7 @@ sub Signalbot_Set($@) { #
my @newatt;
foreach my $file (@attachments) {
if ( -e $file ) {
- if (! $file =~ /tmp\/signalbot/) {
+ if ($file=~/^\/tmp\/signalbot.*/ ne 1) {
$file =~ /^.*?\.([^.]*)?$/;
my $type = $1;
my $tmpfilename="/tmp/signalbot".gettimeofday().".".$type;
@@ -419,7 +423,11 @@ sub Signalbot_Set($@) { #
}
@attachments=@newatt;
}
-
+ #Convert html or markdown to unicode
+ my $format=AttrVal($hash->{NAME},"formatting","none");
+ my $convmsg=formatTextUnicode($format,$message);
+ $message=$convmsg if defined $convmsg;
+
#Send message to individuals (bulk)
if (@recipients > 0) {
Signalbot_sendMessage($hash,join(",",@recipients),join(",",@attachments),$message);
@@ -452,7 +460,7 @@ sub Signalbot_Get($@) {
my $account = ReadingsVal($name,"account","none");
if ($cmd eq "?") {
- my $gets="favorites:noArg accounts:noArg ";
+ my $gets="favorites:noArg accounts:noArg helpUnicode:noArg ";
$gets.="contacts:all,nonblocked ".
"groups:all,active,nonblocked " if $account ne "none";
return "Signalbot_Get: Unknown argument $cmd, choose one of ".$gets;
@@ -464,6 +472,8 @@ sub Signalbot_Get($@) {
if ($cmd eq "introspective") {
my $reply=Signalbot_CallS($hash,"org.freedesktop.DBus.Introspectable.Introspect");
return undef;
+ } elsif ($cmd eq "helpUnicode") {
+ return demoUnicodeHTML();
} elsif ($cmd eq "accounts") {
my $num=Signalbot_getAccounts($hash);
return "Error in listAccounts" if $num<0;
@@ -825,7 +835,7 @@ sub Signalbot_MessageReceived ($@) {
}
}
}
- Log3 $hash->{NAME}, 4, $hash->{NAME}.": Message from $sender : $message processed";
+ Log3 $hash->{NAME}, 4, $hash->{NAME}.": Message from $sender : ".decode_utf8($message)." processed";
} else {
Log3 $hash->{NAME}, 2, $hash->{NAME}.": Ignored message due to allowedPeer by $source:$message";
readingsSingleUpdate($hash, 'lastError', "Ignored message due to allowedPeer by $source:$message",1);
@@ -925,6 +935,8 @@ sub Signalbot_setup($@){
$hash->{STATE}="Connecting";
Signalbot_fetchFile($hash,"svn.fhem.de","/fhem/trunk/fhem/contrib/signal/signal_install.sh","www/signal/signal_install.sh");
chmod 0755, "www/signal/signal_install.sh";
+ #Make sure Logfile looks ok with Unicode characters and does not raise "Wide character"
+ binmode(LOG,"encoding(UTF-8)");
return undef;
}
@@ -1424,7 +1436,7 @@ sub Signalbot_refreshGroups($@) {
sub Signalbot_sendMessage($@) {
my ( $hash,$rec,$att,$mes ) = @_;
- Log3 $hash->{NAME}, 4, $hash->{NAME}.": sendMessage called for $rec:$att:".encode_utf8($mes);
+ Log3 $hash->{NAME}, 4, $hash->{NAME}.": sendMessage called for $rec:$att:".$mes;
my @recorg= split(/,/,$rec);
my @attach=split(/,/,$att);
@@ -2098,7 +2110,6 @@ sub Signalbot_OSRel() {
# -2 for Audio
# -3 for other media
# and extension without dot as 2nd list element
-
sub Signalbot_IdentifyStream($$) {
my ($hash, $msg) = @_;
@@ -2286,6 +2297,11 @@ For German documentation see Wiki<
Lists the defined favorites in the attribute "favorites" in a readable format
+
get helpUnicode
+
+ Opens a cheat sheet for all supported replacements to format text or add emoticons using html-like tags or markdown.
+ Note: This functionality needs to be enabled using the "formatting" attribute.
+
@@ -2367,6 +2383,17 @@ For German documentation see Wiki<
If send is used without a recipient, the message will send to this account or group(with #)
+ formatting
+
+ The "formatting" attribute has the following four options that allow highlighting in Unicode:
+
+ - none - no replacements
+ - html - replacements are enabled here with HTML-type tags (e.g. for bold <b> is bold </b>)
+ - markdown - replacements are enabled by markdown-like tags (e.g. __for italic__) as well as emotics
+ - both - both methods are possible here
+
+ To learn about the syntax how to use tags and markdown, use the get helpUnicode method. You can still also simply copy&paste Unicode text from other sources.
+
diff --git a/fhem/MAINTAINER.txt b/fhem/MAINTAINER.txt
index 4a8898287..875d5a0bf 100644
--- a/fhem/MAINTAINER.txt
+++ b/fhem/MAINTAINER.txt
@@ -626,6 +626,7 @@ lib/FHEM/Core/Timer/Register.pm Beta-User FHEM Development
lib/FHEM/SynoModules/API.pm DS_Starter Sonstiges
lib/FHEM/SynoModules/SMUtils.pm DS_Starter Sonstiges
lib/FHEM/SynoModules/ErrCodes.pm DS_Starter Sonstiges
+lib/FHEM/Text/Unicode.pm Adimarantis FHEM Development
contrib/sacha_gloor/* rudolfkoenig/orphan Sonstiges
contrib/70_ONKYO_AVR_PULL.pm loredo (deprecated)
diff --git a/fhem/lib/FHEM/Text/Unicode.pm b/fhem/lib/FHEM/Text/Unicode.pm
index e61a843a7..5ce8fc38b 100755
--- a/fhem/lib/FHEM/Text/Unicode.pm
+++ b/fhem/lib/FHEM/Text/Unicode.pm
@@ -1,200 +1,202 @@
-################################################################
-# $Id$
-# Maintainer: Adimarantis
-# Library to convert ASCII into formatted Unicode and apply styles like bold or emoticons
-#
-# This script 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 2 of the License, or
-# (at your option) any later version.
-#
-# The GNU General Public License can be found at
-# http://www.gnu.org/copyleft/gpl.html.
-# A copy is found in the textfile GPL.txt and important notices to the license
-# from the author is found in LICENSE.txt distributed with these scripts.
-#
-# This script 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.
-#
-################################################################
-
-package FHEM::Text::Unicode;
-use strict;
-use warnings;
-use Exporter 'import';
-our @EXPORT_OK = qw (formatTextUnicode formatStringUnicode demoUnicode demoUnicodeHTML);
-our %EXPORT_TAGS = (ALL => [@EXPORT_OK]);
-
-#define globally for demo
-#Emoticons
-my @mrep = (
- [":\\)","\x{1F600}"],
- [":-\\)","\x{1F600}"],
- [":\\(","\x{1F641}"],
- ["<3","\x{2665}"],
- [";-\\)","\x{1F609}"],
- [":\\+1:","\x{1F44D}"],
- [":smile:","\x{1F600}"],
- [":sad:","\x{1F641}"],
- [":heart:","\x{2665}"],
- [":wink:","\x{1F609}"],
- [":thumbsup:","\x{1F44D}"],
- );
-#html like styles
-my @htags = (
- ["bold" ,"",""],
- ["italic","",""],
- ["bold-italic","",""],
- ["mono","",""],
- ["mono","","
"],
- ["underline","",""],
- ["strikethrough","",""],
- ["fraktur","",""],
- ["script",""],
- ["square","",""],
-);
-#Single replacements in html mode
-my @hrep = (
- ["
","\n"],
-);
-#Markdown styles
-my @mtags = (
- ["italic","__","__"],
- ["strikethrough","~~","~~"],
- ["bold","\\*\\*","\\*\\*"],
- ["mono","``","``"],
-);
-
-#Convert text with Markdown/html to Unicode
-#Arguments:
-#$format:
-# html: Only apply HTML-like formatting like ....
-# markdown: Only apply Markdown formatting like __text__ and emoticon replacements
-# both: Apply both formatting styles
-#$msg: ASCII String that should be replaced
-#return: Unicode string with applied replacements
-#To display all replacements use the demoUnicode() pr demoUnicodeHTML() function
-sub formatTextUnicode($$) {
- my ($format,$msg) = @_;
- my @tags;
- my @reps;
-
- if ($format eq "markdown" || $format eq "both") {
- push @tags, @mtags;
- push @reps, @mrep;
- }
- if ($format eq "html" || $format eq "both") {
- push @tags, @htags;
- push @reps, @hrep;
- }
-
- #First pass, replace singe special characters
- foreach my $arr (@reps) {
- my @val=@$arr;
- $msg =~ s/$val[0]/$val[1]/sg;
- }
-
- my $found=1;
- my $matches=0;
- my $text;
- while ($found && $matches<100) {
- $matches++;
- $found=0;
- foreach my $arr (@tags) {
- my @val=@$arr;
- $msg =~ /$val[1](.*?)$val[2]/s;
- if (defined $1) {
- $text=formatStringUnicode($val[0],$1);
- if (defined $text) {
- $msg =~ s/$val[1].*?$val[2]/$text/s;
- $found=1;
- }
- }
- }
- }
- return $msg;
-}
-
-#Converts normal ASCII into unicode with a special font or style
-#$font: Style to be applied: underline, strikethrough, bold, italic, bold-italic, script, fraktur, square, mono
-#$str: ASCII String that should be converted
-#returns: Unicode String with style applied
-sub formatStringUnicode($$) {
- my ($font,$str) = @_;
-
- if ($font eq "underline") {
- $str =~ s/./$&\x{332}/g;
- return $str;
- }
- if ($font eq "strikethrough") {
- $str =~ s/./$&\x{336}/g;
- return $str;
- }
-
- my %uc = (
- "bold" => [0x1d41a,0x1d400,0x1d7ce],
- "italic" => [0x1d44e,0x1d434,0x30],
- "bold-italic" => [0x1d482,0x1d468,0x30],
- "script" => [0x1d4ea,0x1d4d0,0x30], #Using boldface since normal misses some letters
- "fraktur" => [0x1d586,0x1d56c,0x30],#Using boldface since normal misses some letters
- "square" => [0x1f130,0x1f130,0x30],
- "mono" => [0x1d68a,0x1d670,0x30],
- );
-
- return undef if (! defined $uc{$font});
-
- my $rep=chr($uc{$font}[0])."-".chr($uc{$font}[0]+25).chr($uc{$font}[1])."-".chr($uc{$font}[1]+25).chr($uc{$font}[2])."-".chr($uc{$font}[2]+9);
- $_=$str;
- eval "tr/a-zA-Z0-9/$rep/";
- return undef if $@;
-#Special handling for characters missing in some fonts
-# 0x1d455 => 0x1d629, #italic h -> italic sans-serif h or 0x210e (planck constant)
-# 0x1d4ba => 0x1d452, #script e -> serif e (not used -> using bold script charset which is complete
- $_ =~ tr/\x{1d455}\x{1d4ba}/\x{1d629}\x{1d452}/;
- return $_;
-}
-
-# Returns a String that is can be embedded in HTML (e.g. FHEM "get") and showcases all possible replacements and their syntax
-sub demoUnicodeHTML {
- my $str=demoUnicode();
- $str =~ s/</sg;
- $str =~ s/>/sg;
- $str =~ s/\n/
/sg;
- return $str;
-}
-
-# Returns a printable String that showcases all possible replacements and their syntax
-sub demoUnicode {
- my $str;
- $str.="HTML style formatting:\n";
- foreach my $arr (@htags) {
- my @val=@$arr;
- $str .= formatStringUnicode($val[0],$val[0]." TEXT 123").": $val[1]text$val[2]\n";
- }
- $str.="newline:
\n";
-
- $str.="\nMarkdown style formatting:\n";
- foreach my $arr (@mtags) {
- my @val=@$arr;
- my $md= formatStringUnicode($val[0],$val[0]." TEXT 123").": $val[1]text$val[2]\n";
- $md =~ s/\\//g;
- $str.=$md;
- }
- my $i=0;
- foreach my $arr (@mrep) {
- my @val=@$arr;
- my $emo=$val[0];
- $emo =~ s/\\//g;
- $str.="$val[1]=$emo ";
- $i++;
- if ($i>5) {
- $str.="\n";
- $i=0;
- }
- }
- return $str;
-}
-
-1;
\ No newline at end of file
+################################################################
+# $Id$
+# Maintainer: Adimarantis
+# Library to convert ASCII into formatted Unicode and apply styles like bold or emoticons
+#
+# This script 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 2 of the License, or
+# (at your option) any later version.
+#
+# The GNU General Public License can be found at
+# http://www.gnu.org/copyleft/gpl.html.
+# A copy is found in the textfile GPL.txt and important notices to the license
+# from the author is found in LICENSE.txt distributed with these scripts.
+#
+# This script 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.
+#
+################################################################
+
+package FHEM::Text::Unicode;
+use strict;
+use warnings;
+use Exporter 'import';
+our @EXPORT_OK = qw (formatTextUnicode formatStringUnicode demoUnicode demoUnicodeHTML);
+our %EXPORT_TAGS = (ALL => [@EXPORT_OK]);
+
+#define globally for demo
+#Emoticons
+my @mrep = (
+ [":\\)","\x{1F600}"],
+ [":-\\)","\x{1F600}"],
+ [":\\(","\x{1F641}"],
+ ["<3","\x{2665}"],
+ [";-\\)","\x{1F609}"],
+ [":\\+1:","\x{1F44D}"],
+ [":smile:","\x{1F600}"],
+ [":sad:","\x{1F641}"],
+ [":heart:","\x{2665}"],
+ [":wink:","\x{1F609}"],
+ [":thumbsup:","\x{1F44D}"],
+ );
+#html like styles
+my @htags = (
+ ["bold" ,"",""],
+ ["italic","",""],
+ ["bold-italic","",""],
+ ["mono","",""],
+ ["mono","","
"],
+ ["underline","",""],
+ ["strikethrough","",""],
+ ["fraktur","",""],
+ ["script",""],
+ ["square","",""],
+);
+#Single replacements in html mode
+my @hrep = (
+ ["
","\n"],
+);
+#Markdown styles
+my @mtags = (
+ ["italic","__","__"],
+ ["strikethrough","~~","~~"],
+ ["bold","\\*\\*","\\*\\*"],
+ ["mono","``","``"],
+);
+
+#Convert text with Markdown/html to Unicode
+#Arguments:
+#$format:
+# html: Only apply HTML-like formatting like ....
+# markdown: Only apply Markdown formatting like __text__ and emoticon replacements
+# both: Apply both formatting styles
+#$msg: ASCII String that should be replaced
+#returns: Unicode string with applied replacements
+#To display all replacements use the demoUnicode() or demoUnicodeHTML() function
+sub formatTextUnicode($$) {
+ my ($format,$msg) = @_;
+ my @tags;
+ my @reps;
+
+ if ($format eq "markdown" || $format eq "both") {
+ push @tags, @mtags;
+ push @reps, @mrep;
+ }
+ if ($format eq "html" || $format eq "both") {
+ push @tags, @htags;
+ push @reps, @hrep;
+ }
+
+ #First pass, replace singe special characters
+ foreach my $arr (@reps) {
+ my @val=@$arr;
+ $msg =~ s/$val[0]/$val[1]/sg;
+ }
+
+ my $found=1;
+ my $matches=0;
+ my $text;
+ while ($found && $matches<100) {
+ $matches++;
+ $found=0;
+ foreach my $arr (@tags) {
+ my @val=@$arr;
+ $msg =~ /$val[1](.*?)$val[2]/s;
+ if (defined $1) {
+ $text=formatStringUnicode($val[0],$1);
+ if (defined $text) {
+ $msg =~ s/$val[1].*?$val[2]/$text/s;
+ $found=1;
+ }
+ }
+ }
+ }
+ return $msg;
+}
+
+#Converts normal ASCII into unicode with a special font or style
+#$font: Style to be applied: underline, strikethrough, bold, italic, bold-italic, script, fraktur, square, mono
+#$str: ASCII String that should be converted
+#returns: Unicode String with style applied
+sub formatStringUnicode($$) {
+ my ($font,$str) = @_;
+
+ if ($font eq "underline") {
+ $str =~ s/./$&\x{332}/g;
+ return $str;
+ }
+ if ($font eq "strikethrough") {
+ $str =~ s/./$&\x{336}/g;
+ return $str;
+ }
+
+ my %uc = (
+ "bold" => [0x1d41a,0x1d400,0x1d7ce],
+ "italic" => [0x1d44e,0x1d434,0x30],
+ "bold-italic" => [0x1d482,0x1d468,0x30],
+ "script" => [0x1d4ea,0x1d4d0,0x30], #Using boldface since normal misses some letters
+ "fraktur" => [0x1d586,0x1d56c,0x30],#Using boldface since normal misses some letters
+ "square" => [0x1f130,0x1f130,0x30],
+ "mono" => [0x1d68a,0x1d670,0x30],
+ );
+
+ return undef if (! defined $uc{$font});
+
+ my $rep=chr($uc{$font}[0])."-".chr($uc{$font}[0]+25).chr($uc{$font}[1])."-".chr($uc{$font}[1]+25).chr($uc{$font}[2])."-".chr($uc{$font}[2]+9);
+ $_=$str;
+ #"no warnings" to prevent a bug in older Perl versions (seen in 5.28) that warns about
+ #"Replacement list is longer than search list" when using ASCII->Unicode replacements
+ eval "{no warnings; tr/a-zA-Z0-9/$rep/}";
+ return undef if $@;
+#Special handling for characters missing in some fonts
+# 0x1d455 => 0x1d629, #italic h -> italic sans-serif h or 0x210e (planck constant)
+# 0x1d4ba => 0x1d452, #script e -> serif e (not used -> using bold script charset which is complete
+ $_ =~ tr/\x{1d455}\x{1d4ba}/\x{1d629}\x{1d452}/;
+ return $_;
+}
+
+# Returns a String that is can be embedded in HTML (e.g. FHEM "get") and showcases all possible replacements and their syntax
+sub demoUnicodeHTML {
+ my $str=demoUnicode();
+ $str =~ s/</sg;
+ $str =~ s/>/sg;
+ $str =~ s/\n/
/sg;
+ return $str;
+}
+
+# Returns a printable String that showcases all possible replacements and their syntax
+sub demoUnicode {
+ my $str;
+ $str.="HTML style formatting:\n";
+ foreach my $arr (@htags) {
+ my @val=@$arr;
+ $str .= formatStringUnicode($val[0],$val[0]." TEXT 123").": $val[1]text$val[2]\n";
+ }
+ $str.="newline:
\n";
+
+ $str.="\nMarkdown style formatting:\n";
+ foreach my $arr (@mtags) {
+ my @val=@$arr;
+ my $md= formatStringUnicode($val[0],$val[0]." TEXT 123").": $val[1]text$val[2]\n";
+ $md =~ s/\\//g;
+ $str.=$md;
+ }
+ my $i=0;
+ foreach my $arr (@mrep) {
+ my @val=@$arr;
+ my $emo=$val[0];
+ $emo =~ s/\\//g;
+ $str.="$val[1]=$emo ";
+ $i++;
+ if ($i>5) {
+ $str.="\n";
+ $i=0;
+ }
+ }
+ return $str;
+}
+
+1;