Функция-конвертер строки для отправки сообщений в Телеграмм

Здесь выкладываем скрипты
Правила форума
Уважаемые Пользователи форума, обратите внимание!
Ни при каких обстоятельствах, Администрация форума, не несёт ответственности за какой-либо, прямой или косвенный, ущерб причиненный в результате использования материалов, взятых на этом Сайте или на любом другом сайте, на который имеется гиперссылка с данного Сайта. Возникновение неисправностей, потерю программ или данных в Ваших устройствах, даже если Администрация будет явно поставлена в известность о возможности такого ущерба.
Просим Вас быть предельно осторожными и внимательными, в использовании материалов раздела. Учитывать не только Ваши пожелания, но и границы возможностей вашего оборудования.
Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Написал функцию-конвертер, позволяющую преобразовывать русские символы в строке в UTF-8 для корректной отправки в телеграмм. Функции можно подсовывать комбинированную русско-английскую строку, содержащую знаки препинания. На выходе функция формирует и собирает готовую строку для отправки в Телегу.

Код функции здесь (копировать и вставлять в реппозиторий в русской раскладке клавиатуры):


Код: Выделить всё

# Function Converter of Russian characters for sending in Telegram
# by Sertik 19/09/2020
# usage [$FuncStrToTele "Строка String .,!+"]
:global FuncStrToTele do={

:local string; :set $string $1;

#  table of the codes of Russian letters UTF8
:local rsimv [:toarray {"А"="D090"; "Б"="D091"; "В"="D092"; "Г"="D093"; "Д"="D094"; "Е"="D095"; "Ж"="D096"; "З"="D097"; "И"="D098"; "Й"="D099"; "К"="D09A"; "Л"="D09B"; "М"="D09C"; "Н"="D09D"; "О"="D09E"; "П"="D09F"; "Р"="D0A0"; "С"="D0A1"; "Т"="D0A2"; "У"="D0A3"; "Ф"="D0A4"; "Х"="D0A5"; "Ц"="D0A6"; "Ч"="D0A7"; "Ш"="D0A8"; "Щ"="D0A9"; "Ъ"="D0AA"; "Ы"="D0AB"; "Ь"="D0AC"; "Э"="D0AD"; "Ю"="D0AE"; "Я"="D0AF"; "а"="D0B0"; "б"="D0B1"; "в"="D0B2"; "г"="D0B3"; "д"="D0B4"; "е"="D0B5"; "ж"="D0B6"; "з"="D0B7"; "и"="D0B8"; "й"="D0B9"; "к"="D0BA"; "л"="D0BB"; "м"="D0BC"; "н"="D0BD"; "о"="D0BE"; "п"="D0BF"; "р"="D180"; "с"="D181"; "т"="D182"; "у"="D183"; "ф"="D184"; "х"="D185"; "ц"="D186"; "ч"="D187"; "ш"="D188"; "щ"="D189"; "ъ"="D18A"; "ы"="D18B"; "ь"="D18C"; "э"="D18D"; "ю"="D18E"; "я"="D18F"; "Ё"="D001"; "ё"="D191"; "№"="0023"; " "="0020"; "&"="0026"; "^"="005E"}]

# encoding of the symbols and аssembly line
:local StrTele ""; :local code "";
:for i from=0 to=([:len $string]-1) do={:local keys [:pick $string $i (1+$i)]; :local key ($rsimv->$keys); if ([:len $key]!=0) do={:set $code ("%"."$[:pick ($rsimv->$keys) 0 2]"."%"."$[:pick ($rsimv->$keys) 2 4]"); :if ([pick $code 0 3] ="%00") do={:set $code [:pick $code 3 6]}} else={:set $code $keys}; :set $StrTele ("$StrTele"."$code")}

:return $StrTele;
}
Пример использования :

:local botID "botXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXX" ;
:local myChatID "YYYYYY" ;
:global FuncStrToTele;
:local string [$FuncStrToTele "Привет от Sertik ! Работает функция-конвертер Russian alfabit для Telegramm"]
:tool fetch url=("https://api.telegram.org/$botID/sendmes ... xt=$string") keep-result=no

Проверяйте, у меня отлично работает. Теперь можно без всякого труда отправлять в Телегу сообщения на русском языке ! Замечания и дополнения приветствуются.

Застолбил также сие детище на Хабре. https://habr.com/ru/post/518534/ Надеюсь грубых ошибок нет. :-)
Последний раз редактировалось Sertik 19 сен 2021, 19:21, всего редактировалось 5 раз.


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
pepelxl
Сообщения: 161
Зарегистрирован: 23 июл 2013, 18:47

немножко по бубню.

Код: Выделить всё

:global string; :set $string $1;

1)Зачем два действия?
2) зачем глобал?

Код: Выделить всё

:local string $1

Код: Выделить всё

#  table of the codes of Russian letters UTF8
Вот тут грубая ошибка.
1) Во первых надо указывать, что это будет работать, ТОЛЬКО на винде, где языком для программ не используемых юникод - установлена кодировка win1251 На других локалях хоть обкопируйся - не заработает. (можно заменить имена аргументов на их hex аналог, тогда заработает на любой локале)
2) если создаёте массив - то в нём должно быть 128 символов. Иначе если в тексте будут такие символы "™€“" и тд. вы получите болт.

Код: Выделить всё

("%"."$[:pick ($rsimv->$keys) 0 2]"."%"."$[:pick ($rsimv->$keys) 2 4]")

Тут конечно вопрос читаемости, но я бы предпочёл избавится от конкатенации и просто записал таблицу сразу с % для ускорения сборки.

Код: Выделить всё

:set $string $StrTele
:return $string;
Какой сакральный смысл вводить дополнительное действие?????

Код: Выделить всё

:return  $StrTele


Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Вот тут грубая ошибка.
1) Во первых надо указывать, что это будет работать, ТОЛЬКО на винде, где языком для программ не используемых юникод - установлена кодировка win1251 На других локалях хоть обкопируйся - не заработает. (можно заменить имена аргументов на их hex аналог, тогда заработает на любой локале)
2) если создаёте массив - то в нём должно быть 128 символов. Иначе если в тексте будут такие символы "™€“" и тд. вы получите болт.
Хорошо, выложу еще в виде ".rsc". Вы думаете начинающим будет легче его вставить в реппозиторий ?

Насчет болта с особыми символами типа ™€ согласен - сообщение целиком не будет отображено в Мессенджере, но я и не писал поддержку таких символов (они не относятся к символам русского алфавита - Вы согласны ?)

Насчет :global и :set $string $1 и return $string - подстраховался, так как до сих пор честно не знаю куда происходит возврат при просто :return, и что возвращается (если не указать что возвращать), а также не знаю можно ли менять значения в процессе работы функции в $1, ведь она объявлена не была как переменная нигде, поэтому передал из параметра в глобал переменную. Подскажите если знаете, а чего бубнить то ... Локальную, согласен, лучше использовать чем глобальную.
Тут конечно вопрос читаемости, но я бы предпочёл избавится от конкатенации и просто записал таблицу сразу с % для ускорения сборки.
В таблицу заносить лишние %% сто пятьдесят раз не хотел - зачем память захламлять. Собирается и так быстро, на работе не сказывается. Наоборот изящно, так мне кажется.

Скрипт был написан "на скорую руку" (так получилось) ровно за 1 ч 13 минут с набивкой массива данных и отладкой. Главное результат - работает ведь :-)
Что забыл - вероятно нужно бы сделать также возможность отработки вставки символа перенос строки. Вставить его ключ в массив ясно не получиться, вероятно нужно бы для логичной совместимости использовать ключ "\n", как принято.

Ваши замечания осмыслил, поправил в функции пока на форуме.
Конструктивные замечания и дополнения только приветствуются.


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
pepelxl
Сообщения: 161
Зарегистрирован: 23 июл 2013, 18:47

Давай проведу аналогию с языком который умеет напрямую работать с подсистемой памяти OS, возьмём С\С++
В С/С++ аргументы в функцию можно передать по значению, по указателю, по ссылке.
При передаче по значению создаётся переменная и копируется побайтно содержимое. Эта операция довольно затратная для процессора.
При передачи по указателю, в функцию передаётся адрес ячейки памяти где лежат данные
При передачи по ссылке передаётся переменная которая хранит адрес ячейки памяти с содержимым.
Функции в С\С++ ни чего не знают про содержимое и по этому при написании функции всегда указывается тип и длинна аргументов.
Соответственно при передаче по значению, функция не изменяет изначальное значение аргумента, и изменяет, если идёт передача по указателю.
В С\С++ аргументы распадаются по-умолчанию в указатели когда передаётся массив, что бы не тратить время на копирование.
Строка в С\С++ считается массивом из байт.
Скриптовый язык ROS, наоборот, функция всегда знает тип и длину аргумента. Также массив знает тип и длинну каждого элемента.
Поэтому можно с уверенностью сказать, что скрипты ROS передают в функцию простые типы по значению (str ,bool, num и т.д.).
С массивами не всё так просто. При передачи массива в функцию, скриптовый интерпретатор пытается передать элементы массива по значению, но как только начинаются циклы и ветвления, всё превращается в указатели. При работе с массивами всегда стоит проверять какой из типов используется. Я многократно наступаю на эти грабли.
В вашем варианте, у вас простой тип и объявление string вообще не требуется, достаточно:

Код: Выделить всё

:for i from=0 to=([:len $1]-1) do={:local keys [:pick $1 $i];

Обратите внимание как сокращён :pick, при изъятии одного символа, указание размера не требуется.


Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Спасибо, познавательно.

Насчет укорочения в :pick при одном символе я знаю, видел вот тут (функция замены символа в строке):

:global replaceChar do={
:for i from=0 to=([:len $1] - 1) do={
:local char [:pick $1 $i]
:if ($char = $2) do={
:set $char $3
}
:set $output ($output . $char)
}
:return $output
}


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
pepelxl
Сообщения: 161
Зарегистрирован: 23 июл 2013, 18:47

Скрипт был написан "на скорую руку" (так получилось) ровно за 1 ч 13 минут с набивкой массива данных и отладкой. Главное результат - работает ведь :-)
Делать надо хорошо, плохо сделают другие.
Насчет болта с особыми символами типа ™€ согласен - сообщение целиком не будет отображено в Мессенджере, но я и не писал поддержку таких символов (они не относятся к символам русского алфавита - Вы согласны ?)
Нет не согласен. Если браться. то делать надо до конца, а не на пол шишки.
В чём сложность заполнить массив до конца https://ru.wikipedia.org/wiki/Windows-1251
Вообще надо заменить русские ключи на их HEX значения и тогда будет копироваться где угодно как надо, но сейчас проверил и оно не работает, чистый баг даже с asnii символами.
Хорошо, выложу еще в виде ".rsc". Вы думаете начинающим будет легче его вставить в реппозиторий ?
Скрипт хорош, когда работает на всех методах, а не в одном конкретном.


ВАШ КОСЯК: ваш массив содержит повторяющиеся символы(например А)


Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

А как у Вас дела со скриптом SMS PDU ? Вы его сделали до конца или "на пол шишки" ?

За "А" спасибо. Это был косяк в табличке данных, с которой я скопипастил коды символов русского алфавита в UTF-8. Повторная А это на самом деле буква "Ч". Поправил в скрипте.

А вот коды русских символов для UTF-8. https://i.voenmeh.ru/kafi5/Kam.loc/inform/UTF-8.htm

Остальные поддерживать мне не нужно. Кто хочет может дополнить массив по мере своих нужд, хоть смайликами ::yaz-yk:


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
pepelxl
Сообщения: 161
Зарегистрирован: 23 июл 2013, 18:47

А как у Вас дела со скриптом SMS PDU ? Вы его сделали до конца или "на пол шишки" ?
Он в статусе бета, и собирает образцы, так как без всевозможных образцов дописать функции не получится.
Но как минимум две функции пойдут под нож.
но сейчас проверил и оно не работает, чистый баг даже с asnii символами.

написал в службу поддержки, посмотрим что ответят.


Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

написал в службу поддержки, посмотрим что ответят.
Про что написали ? Вы и на Микротик накатить решили ? :-)

Напишите тогда уж им сразу чё они не поддерживают национальные языки нормально и отправку прием SMS с нелатинскими кодировками.
Мож они пофиксят свои баги и Вам не придётся мучаться с SMS PDU :hi_hi_hi:


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
pepelxl
Сообщения: 161
Зарегистрирован: 23 июл 2013, 18:47

Напишите тогда уж им сразу чё они не поддерживают национальные языки нормально и отправку прием SMS с нелатинскими кодировками.
Они явно дали понять, что свои хотелки принимаются только через ретейлеров , хомячки идут лесом.
А по поводу своего скрипта - так у меня два года всё работает. А люди не могут открыть букварь к своему модему и вызвать нужные команды. Мне что теперь покупать зоопарк модемов и делать код на все? Я вроде не коммерческий продукт создаю.


Ответить