Skip to content

Instantly share code, notes, and snippets.

@PlugFox
Last active January 27, 2021 15:11
Show Gist options
  • Save PlugFox/9967dcf5c3643fda5e41e577b3346485 to your computer and use it in GitHub Desktop.
Save PlugFox/9967dcf5c3643fda5e41e577b3346485 to your computer and use it in GitHub Desktop.
Журнал Регистрации ➜ Телеграмм
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Журнал регистрации</title>
<style>.container{margin:0 auto;width:100%}@media only screen and (min-width:601px){.container{width:95%}}@media only screen and (min-width:993px){.container{width:90%}}.deep-orange{background-color:#ff5722!important}table,th,td{border:0}table{width:100%;display:table;border-collapse:collapse;border-spacing:0}table.striped tr{border-bottom:0}table.striped>tbody>tr:nth-child(odd){background-color:rgba(242,242,242,0.5)}table.striped>tbody>tr>td{border-radius:0}table.highlight>tbody>tr{-webkit-transition:background-color .25s ease;transition:background-color .25s ease}table.highlight>tbody>tr:hover{background-color:rgba(255,87,34,0.5)}table.centered thead tr th{text-align:center}tr{border-bottom:1px solid rgba(0,0,0,0.12)}td,th{padding:15px 5px;display:table-cell;text-align:left;vertical-align:middle;border-radius:2px}@media only screen and (max-width:992px){table.responsive-table{width:100%;border-collapse:collapse;border-spacing:0;display:block;position:relative}table.responsive-table td:empty:before{content:'\00a0'}table.responsive-table th,table.responsive-table td{margin:0;vertical-align:top}table.responsive-table th{text-align:left}table.responsive-table thead{display:block;float:left}table.responsive-table thead tr{display:block;padding:0 10px 0 0}table.responsive-table thead tr th::before{content:"\00a0"}table.responsive-table tbody{display:block;width:auto;position:relative;overflow-x:auto;white-space:nowrap}table.responsive-table tbody tr{display:inline-block;vertical-align:top}table.responsive-table th{display:block;text-align:right}table.responsive-table td{display:block;min-height:1.25em;text-align:left}table.responsive-table tr{border-bottom:0;padding:0 10px}table.responsive-table thead{border:0;border-right:1px solid rgba(0,0,0,0.12)}table span.badge{display:inline-block;float:none;margin-left:auto}}h1,h2,h3,h4,h5,h6{font-weight:400;line-height:1.3}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit}h3{font-size:.75rem;line-height:75%;margin:1.9466666667rem 0 1.168rem 0}.right-align{text-align:right}.right{float:right!important}.tooltip{border-bottom:1px dotted #000;color:#000;outline:0;cursor:help;text-decoration:none;position:relative}.tooltip span{margin-left:-999em;position:absolute}.tooltip:hover span{font-family:Calibri,Tahoma,Geneva,sans-serif;position:absolute;left:1em;top:2em;z-index:99;margin-left:0;overflow-wrap:break-word;word-wrap:break-word;word-break:normal;line-break:auto;hyphens:manual;width:500px}.tooltip:hover img{border:0;margin:-10px 0 0 -55px;float:left;position:absolute}.tooltip:hover em{font-family:Candara,Tahoma,Geneva,sans-serif;font-size:1.2em;font-weight:bold;display:block;padding:.2em 0 .6em 0}.classic{padding:.8em 1em;border-radius:5px 5px;background:#ffa;border:1px solid #ffad33;-moz-border-radius:5px;-webkit-border-radius:5px;box-shadow:5px 5px 5px rgba(0,0,0,0.1);-webkit-box-shadow:5px 5px rgba(0,0,0,0.1);-moz-box-shadow:5px 5px rgba(0,0,0,0.1)}.custom{padding:.5em .8em .8em 2em}* html a:hover{background:transparent}</style>
</head>
<body>
<div class="container">
<h3 id="information">Информация</h3>
<table class="highlight striped centered" width="100%" height="100%">
<caption></caption>
<thead>
<tr>
<th scope="col" width="120px">Время</th>
<th scope="col">Компьютер / Приложение / Пользователь</th>
<th scope="col">Событие / Метаданные / Данные</th>
</tr>
</thead>
<tbody id="events">
</tbody>
</table>
</br>
<p style="padding:75px 0">&nbsp;</p>
</div>
</body>
</html>
//////////////////////////////////////////////////////////////
/// The MIT License (MIT)
///
/// Copyright (c) 2019 Plague Fox
///
/// Permission is hereby granted, free of charge, to any person obtaining
/// a copy of this software and associated documentation files (the
/// "Software"), to deal in the Software without restriction, including
/// without limitation the rights to use, copy, modify, merge, publish,
/// distribute, sublicense, and/or sell copies of the Software, and to
/// permit persons to whom the Software is furnished to do so, subject to
/// the following conditions:
///
/// The above copyright notice and this permission notice shall be included
/// in all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
/// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
/// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
/// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
/// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
/// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
#Область Объявление_констант
Перем Токен,ИдентификаторПолучателя; // Телеграм
Перем ДатаНачала,ДатаОкончания; // Отбор
Перем ПроксиПротокол,ПроксиСервер,ПроксиПорт,ПроксиПользователь,ПроксиПароль; // Прокси
#КонецОбласти
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
#Область Основная_информация_об_обработке
// <-- ОСНОВНАЯ ИНФОРМАЦИЯ НАЧАЛО
Функция ПолучитьИнформациюОбОбработке() Экспорт
Мета = Метаданные();
Инф = Новый Структура;
// Наименование обработки (имя для регистрации в справочнике внешних отчетов и обработок)
Инф.Вставить("Наименование", Мета.Синоним);
// Идентификатор без пробелов и знаков препинания
Инф.Вставить("Идентификатор", Мета.Имя);
// Дополнительная информация
Инф.Вставить("Информация", СтрЗаменить(СтрШаблон("%1 %2 (%3 г.)", Мета.Синоним, Мета.Комментарий, Формат(ТекущаяДата(), "ДФ='d MMM yyyy'")), " ", " "));
// Версия для удобства версирования (1.0, 1.1, и т.д.)
Инф.Вставить("Версия", Мета.Комментарий);
// Варианты: "ДополнительнаяОбработка", "ДополнительныйОтчет", "ЗаполнениеОбъекта", "Отчет", "ПечатнаяФорма", "СозданиеСвязанныхОбъектов"
Инф.Вставить("Вид", "ДополнительнаяОбработка"); // ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
// в безопасном режиме не доступна COM технология, загрузка внешних компонент, доступ к файловой системе, доступ к Интернету.
Инф.Вставить("БезопасныйРежим", Ложь);
// Использование. Варианты: "ОткрытиеФормы", "ВызовКлиентскогоМетода", "ВызовСерверногоМетода"
Инф.Вставить("Использование", "ВызовСерверногоМетода");
// Показывать оповещение. Варианты Истина, Ложь
Инф.Вставить("Оповещение", Истина);
// Модификатор
Инф.Вставить("Модификатор", "");
// Указываем назначение к которому делаем внешнюю печ. форму
МассивНазначений = Новый Массив;
Инф.Вставить("Назначение", МассивНазначений);
Возврат Инф;
КонецФункции // ПолучитьИнформациюОбОбработке()
// ОСНОВНАЯ ИНФОРМАЦИЯ КОНЕЦ -->
#КонецОбласти
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
#Область Подготовка_к_регистрации_и_печати
// <-- ПОДГОТОВКА РЕГИСТРАЦИИ ГЛОБАЛЬНОГО ОТЧЕТА НАЧАЛО
Функция СведенияОВнешнейОбработке() Экспорт
Инф = ПолучитьИнформациюОбОбработке();
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ПараметрыРегистрации = Новый Структура("Вид,Наименование,Версия,БезопасныйРежим,Информация,Назначение");
ЗаполнитьЗначенияСвойств(ПараметрыРегистрации, Инф);
ДобавитьКоманду(ТаблицаКоманд,
Инф.Наименование,
Инф.Идентификатор,
Инф.Использование,
Инф.Оповещение,
Инф.Модификатор);
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции // СведенияОВнешнейОбработке()
//************************************************************
Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции // ПолучитьТаблицуКоманд()
//************************************************************
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры // ДобавитьКоманду()
//************************************************************
Процедура ВыполнитьКоманду(ИдентификаторКоманды = "", ПараметрыВыполненияКоманды = Неопределено) Экспорт
НачатьВыполнениеРегламентногоЗадания();
КонецПроцедуры // ВыполнитьКоманду()
// ПОДГОТОВКА РЕГИСТРАЦИИ ГЛОБАЛЬНОГО ОТЧЕТА КОНЕЦ -->
#КонецОбласти
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
#Область Регламентное_задание
Процедура НачатьВыполнениеРегламентногоЗадания() Экспорт
Перем тзЖурнал,Сообщение,Вложение;
Попытка
// Получим таблицу значений из журнала
тзЖурнал = ПолучитьЖурнал();
Если Не тзЖурнал.Количество() Тогда Возврат КонецЕсли;
// Сформируем вложение
Вложение = СформироватьВложение(тзЖурнал);
// Сформируем текст сообщения
ЗаОдинДень = НачалоДня(тзЖурнал[0].Дата) = НачалоДня(тзЖурнал[тзЖурнал.Количество()-1].Дата);
Если ЗаОдинДень Тогда
Сообщение = СтрШаблон("%1 за <i>%2</i> в <pre>%3</pre>"
, СтрокаСЧислом(";<b>%1</b> ошибка;;<b>%1</b> ошибки;<b>%1</b> ошибок;<b>%1</b> ошибки", тзЖурнал.Количество(), ВидЧисловогоЗначения.Количественное, "Л=ru_RU")
, Формат(тзЖурнал[0].Дата, "ДФ='d MMM yyyy ''г.'''")
, СтрокаСоединенияИнформационнойБазы()
);
Иначе
Сообщение = СтрШаблон("%1 с <i>%2</i> по <i>%3</i> в <pre>%4</pre>"
, СтрокаСЧислом(";<b>%1</b> ошибка;;<b>%1</b> ошибки;<b>%1</b> ошибок;<b>%1</b> ошибки", тзЖурнал.Количество(), ВидЧисловогоЗначения.Количественное, "Л=ru_RU")
, Формат(тзЖурнал[0].Дата, "ДФ='d MMM yyyy ''г.'''")
, Формат(тзЖурнал[тзЖурнал.Количество()-1].Дата, "ДФ='d MMM yyyy ''г.'''")
, СтрокаСоединенияИнформационнойБазы()
);
КонецЕсли;
тзЖурнал = Неопределено;
// Отправим сообщение
ОтправитьСообщениеВТелеграм(Сообщение);
ОтправитьВложениеВТелеграм(Вложение);
Исключение
ОшибкаРегламентногоЗадания(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры // НачатьВыполнениеРегламентногоЗадания()
//============================================================
Функция ПолучитьЖурнал()
Отбор = Новый Структура("ДатаНачала,ДатаОкончания,Уровень"
, НачалоДня(ДатаНачала) // ДатаНачала
, КонецДня(ДатаОкончания) // ДатаОкончания
, УровеньЖурналаРегистрации.Ошибка // Уровень
);
Колонки = "ПредставлениеДанных,Данные,Комментарий,ПредставлениеМетаданных,Метаданные,Компьютер,ИмяПользователя,ПредставлениеСобытия,Событие,ПредставлениеПриложения,Дата";
тзЖурнал = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(тзЖурнал, Отбор, Колонки);
тзЖурнал.Сортировать("Дата Возр");
Возврат тзЖурнал;
КонецФункции // ПолучитьЖурнал()
//************************************************************
Функция СформироватьВложение(тзЖурнал)
Макет = ПреобразоватьТекстВДом(ПолучитьМакет("Макет").ПолучитьТекст());
ЗаОдинДень = НачалоДня(тзЖурнал[0].Дата) = НачалоДня(тзЖурнал[тзЖурнал.Количество()-1].Дата);
// Установим заголовок
Если ЗаОдинДень Тогда
Заголовок = СтрШаблон("Выгрузка ошибок из журнала регистрации за %1 для базы: %2"
, Формат(тзЖурнал[0].Дата, "ДФ='d MMM yyyy ''г.'''")
, СтрокаСоединенияИнформационнойБазы()
);
Иначе
Заголовок = СтрШаблон("Выгрузка ошибок из журнала регистрации с %1 по %2 для базы: %3"
, Формат(тзЖурнал[0].Дата, "ДФ='d MMM yyyy ''г.'''")
, Формат(тзЖурнал[тзЖурнал.Количество()-1].Дата, "ДФ='d MMM yyyy ''г.'''")
, СтрокаСоединенияИнформационнойБазы()
);
КонецЕсли;
Макет.Заголовок = Заголовок;
Макет.ПолучитьЭлементПоИдентификатору("information").ТекстовоеСодержимое
= Заголовок;
Макет.Нормализовать();
Вложение = ПреобразоватьДомВТекст(Макет);
ТелоТаблицы = "";
Для Каждого Строка Из тзЖурнал Цикл
ТелоТаблицы = ТелоТаблицы + СтрШаблон("
|<tr>
| <th scope=""row"">%1</td>
| <td class=""tooltip"">%2<span class=""classic"">%3</span></td>
| <td class=""tooltip"">%4<span class=""classic"">%5</span></td>
|</tr>"
, Формат(Строка.Дата, ?(ЗаОдинДень, "ДФ='H:mm:ss'", "ДФ='d MMM yyyy '' г.</br>''H:mm:ss'")) // Дата
, Строка.Компьютер + "</br>" + Строка.ПредставлениеПриложения + "</br>" + Строка.ИмяПользователя // Компьютер / ПредставлениеПриложения / ИмяПользователя
, СтрЗаменить(Строка.Комментарий, Символы.ПС, "</br>") // Комментарий
, Строка.ПредставлениеСобытия + "</br>" + Строка.ПредставлениеМетаданных + "</br>" + Строка.ПредставлениеДанных // ПредставлениеСобытия / ПредставлениеМетаданных / ПредставлениеДанных
, Строка.Событие + "</br>" + Строка.Метаданные + "</br>" + Строка.Данные // Событие / Метаданные / Данные
);
КонецЦикла;
Вложение = СтрЗаменить(Вложение, "<!--ТелоТаблицы-->", ТелоТаблицы);
Возврат Вложение;
КонецФункции // СформироватьВложение()
//************************************************************
Процедура ОтправитьСообщениеВТелеграм(Сообщение)
// Сформировать соединение и запрос
Соединение = ПолучитьСоединение();
Адрес = СтрШаблон("/bot%1/sendMessage?chat_id=%2&parse_mode=HTML&text=%3"
, Токен
, ИдентификаторПолучателя
, КодироватьСтроку(Сообщение, СпособКодированияСтроки.КодировкаURL, "UTF8"));
Заголовки = Новый Соответствие;
Запрос = Новый HTTPЗапрос(Адрес, Заголовки);
// GET
Ответ = Соединение.Получить(Запрос);
// Разбор ответа
Если Ответ.КодСостояния <> 200 Тогда
ВызватьИсключение СтрШаблон("Ошибка отправки сообщения в телеграм.
|Код состояния: %1
|Тело: %2"
, Ответ.КодСостояния
, Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8)
);
КонецЕсли;
КонецПроцедуры // ОтправитьСообщениеВТелеграм()
//************************************************************
Процедура ОтправитьВложениеВТелеграм(Знач Вложение)
// Сформировать тело запроса
Разделитель = "----" + Строка(Новый УникальныйИдентификатор());
Вложение = СтрШаблон(
"--%1
|Content-Disposition: form-data; name=""chat_id""
|
|%2
|--%1
|Content-Disposition: form-data; name=""document""; filename=""%3""
|
|%4
|--%1--
|"
, Разделитель // boundary
, ИдентификаторПолучателя // Получатель
, Формат(ДатаНачала, "ДФ='yyyyddMM''.html'''") // Имя файла
, Вложение // Тело файла
);
ПутьКФайлу = ПолучитьИмяВременногоФайла("post");
тд = Новый ТекстовыйДокумент;
тд.УстановитьТекст(Вложение);
тд.Записать(ПутьКФайлу, КодировкаТекста.UTF8);
// Сформировать соединение и запрос
Соединение = ПолучитьСоединение();
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Разделитель);
Адрес = СтрШаблон("/bot%1/sendDocument", Токен);
Запрос = Новый HTTPЗапрос(Адрес, Заголовки);
Запрос.УстановитьИмяФайлаТела(ПутьКФайлу);
// POST
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
// Разбор ответа
Если Ответ.КодСостояния <> 200 Тогда
ВызватьИсключение СтрШаблон("Ошибка отправки вложения в телеграм.
|Код состояния: %1
|Тело: %2"
, Ответ.КодСостояния
, Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8)
);
КонецЕсли;
УдалитьФайлы(ПутьКФайлу);
КонецПроцедуры // ОтправитьВложениеВТелеграм()
//************************************************************
Функция ПолучитьСоединение()
Прокси = Новый ИнтернетПрокси(Истина);
Если ТипЗнч(ПроксиПротокол) = Тип("Строка") И Не ПустаяСтрока(ПроксиПротокол) Тогда
Прокси.Установить(ПроксиПротокол, ПроксиСервер, ПроксиПорт, ПроксиПользователь, ПроксиПароль, Ложь);
КонецЕсли;
SSL = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("api.telegram.org", 443,,, Прокси, 15, SSL, Ложь);
Возврат Соединение;
КонецФункции // ПолучитьСоединение()
#КонецОбласти
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
#Область Вспомогательные_функции
Процедура ОшибкаРегламентногоЗадания(ОписаниеОшибки)
ОписаниеОшибки = СтрШаблон("Ошибка регламентной отправки журнала регистрации.
|Описание ошибки: %1", ОписаниеОшибки);
ЗаписьЖурналаРегистрации(Метаданные().Имя
, УровеньЖурналаРегистрации.Ошибка
, Неопределено
, Неопределено
, ОписаниеОшибки);
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = ОписаниеОшибки;
Сообщение.Сообщить();
ВызватьИсключение ОписаниеОшибки;
Возврат;
КонецПроцедуры // ОшибкаРегламентногоЗадания()
//************************************************************
Функция ПреобразоватьТекстВДом(Текст)
ЧтениеHTML = Новый ЧтениеHTML;
ЧтениеHTML.УстановитьСтроку(Текст);
ПостроительDOM = Новый ПостроительDOM;
Возврат ПостроительDOM.Прочитать(ЧтениеHTML);
КонецФункции // ПреобразоватьТекстВДом()
//************************************************************
Функция ПреобразоватьДомВТекст(ЭлементДом)
ЗаписьDOM = Новый ЗаписьDOM;
ЗаписьHTML = Новый ЗаписьHTML;
ЗаписьHTML.УстановитьСтроку();
ЗаписьDOM.Записать(ЭлементДом, ЗаписьHTML);
Возврат ЗаписьHTML.Закрыть();
КонецФункции // ПреобразоватьДомВТекст()
#КонецОбласти
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
#Область Заполняем_константы
// ТЕЛЕГРАМ +
Токен = "000000000:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // 000000000:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ИдентификаторПолучателя = "000000000"; // 000000000
// ТЕЛЕГРАМ -
// ОТБОР +
ДатаНачала = НачалоДня(ТекущаяДата() - 86400); // НачалоДня(ТекущаяДата() - 86400)
ДатаОкончания = КонецДня(ТекущаяДата() - 86400); // КонецДня(ТекущаяДата() - 86400)
// ОТБОР -
// ПРОКСИ +
ПроксиПротокол = "https"; // пустая строка или неопределено - прокси не используются, для socks5 - https
ПроксиСервер = "socks5://domain.tld"; // socks5://domain.tld
ПроксиПорт = 1080; // 1080
ПроксиПользователь = "user"; // user
ПроксиПароль = "password"; // password
// ПРОКСИ -
#КонецОбласти
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
#Область Комментарии
/// Author: Plague Fox
/// Site: pfx.pw
/// Infostart: https://infostart.ru/profile/PlugFox/
/// Telegram: @PlugFox
/// Email: [email protected]
/// Github: http://github.com/PlugFox
#КонецОбласти
//////////////////////////////////////////////////////////////
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment