1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2026-05-16 09:38:28 +02:00

Приведение модулей и тестов к виду КлиентСервер

This commit is contained in:
Anton Titovets
2026-05-12 13:08:44 +03:00
parent 3160d19970
commit eb8c0ff067
88 changed files with 1038 additions and 696 deletions
+12
View File
@@ -6,6 +6,18 @@
"summary_en": "Methods of working with ZeroMQ",
"image": "media/Covers/ZeroMQ.png",
"changes": [
{
"lib": "All",
"icon": "media/HTTP.png",
"description_ru": "Оптимизирована загрузка по частям в HTTP-клиенте",
"description_en": ""
},
{
"lib": "All",
"icon": "media/logo.png",
"description_ru": "Все основные модули библиотек в 1С теперь `КлиентСервер`",
"description_en": ""
},
{
"lib": "All",
"icon": "media/logo.png",
@@ -0,0 +1,8 @@
{
"version": 1,
"settings": {
"common-module-name-client-server": {
"enabled": false
}
}
}
@@ -0,0 +1,2 @@
disableMassiveChecks=false
eclipse.preferences.version=1
@@ -0,0 +1,17 @@
alwaysEndWithSemicolon=true
autowrapBinary=indent_on_wrap
autowrapInvocation=indent_on_wrap
autowrapMethodParameters=indent_on_wrap
creatorEmptyBrackets=never brackets
defaultValuesInitialized=true
eclipse.preferences.version=1
formattingOn=true
indentMethodInternal=true
invocationEmptyParamsDelimited=true
keywordStandard=CamelCase
noindent_preprocessor=true
projectSpecificSettingsInited=true
showWhitespaceCharacters=false
softFormatassignmentStatement=true
spacesForTabs=false
whitespaceMethodParamsDelimited=true
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
topObjects=false
@@ -0,0 +1,3 @@
addModuleStrictTypesAnnotation=false
createModuleStructure=false
eclipse.preferences.version=1
@@ -0,0 +1,3 @@
commonChecks=true
eclipse.preferences.version=1
standardChecks=true
@@ -10,6 +10,7 @@
<value>Airtable (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Airtable из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>Bitrix24 (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Bitrix24 из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>Build hash (ОПИ</value>
</synonym>
<comment>Служебный модуль, помогающий определить актуальность проекта исходному коду</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>CDEK (ОПИ)</value>
</synonym>
<comment>Модуль для работы со СДЭК из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -5,6 +5,7 @@
<key>ru</key>
<value>ClickHouse</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -10,6 +10,7 @@
<value>Dropbox (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Dropbox из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -721,7 +721,11 @@
// BSLLS:MissingTemporaryFileDeletion-off
//@skip-check missing-temporary-file-deletion
ИВФ = ПолучитьИмяВременногоФайла();
#Если ВебКлиент Тогда
ИВФ = OPI_Инструменты.ПолучитьИмяВременногоФайлаНаСервере();
#Иначе
ИВФ = ПолучитьИмяВременногоФайла();
#КонецЕсли
// BSLLS:MissingTemporaryFileDeletion-on
@@ -852,7 +856,11 @@
// BSLLS:MissingTemporaryFileDeletion-off
//@skip-check missing-temporary-file-deletion
ИВФ = ПолучитьИмяВременногоФайла();
#Если ВебКлиент Тогда
ИВФ = OPI_Инструменты.ПолучитьИмяВременногоФайлаНаСервере();
#Иначе
ИВФ = ПолучитьИмяВременногоФайла();
#КонецЕсли
// BSLLS:MissingTemporaryFileDeletion-on
@@ -6,6 +6,7 @@
<value>FTP (ОПИ)</value>
</synonym>
<comment>Модуль для работы с FTP из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>gRPC (ОПИ)</value>
</synonym>
<comment>Модуль для работы с gRPC из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -10,6 +10,7 @@
<value>Google Calendar (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Google Calendar из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -10,6 +10,7 @@
<value>Google Drive (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Google Drive из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -10,6 +10,7 @@
<value>Google Sheets (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Google Sheets из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -179,7 +179,7 @@
КлючПодписи = Данные["private_key"];
URL = Данные["token_uri"];
ТекущаяДата = ТекущаяУниверсальнаяДата();
ТекущаяДата = OPI_Инструменты.ПолучитьТекущуюУниверсальнуюДату();
ДатаСгорания = ТекущаяДата + ВремяЖизни;
UnixTime = OPI_Инструменты.UnixTime(ТекущаяДата);
@@ -10,6 +10,7 @@
<value>Google Workspace (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Google Workspace из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>Green API (ОПИ)</value>
</synonym>
<comment>Модуль для работы с WhatsApp через GreenAPI из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>GreenAPI Max (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Max через GreenAPI из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>MS SQL (ОПИ)</value>
</synonym>
<comment>Модуль для работы с базами MSSQL из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>MongoDB (ОПИ)</value>
</synonym>
<comment>Модуль для работы с базами MongoDB из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>MySQL (ОПИ)</value>
</synonym>
<comment>Модуль для работы с базами MySQL из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -95,30 +95,17 @@
OPI_ПреобразованиеТипов.ПолучитьСтроку(Логин);
OPI_ПреобразованиеТипов.ПолучитьСтроку(Пароль);
URL = "https://neocities.org/api/key";
Результат = OPI_ЗапросыHTTP.НовыйЗапрос()
.Инициализировать()
.УстановитьURL(URL)
.ДобавитьBasicАвторизацию(Логин, Пароль)
.ОбработатьЗапрос("GET")
.ВернутьОтветКакJSONКоллекцию();
URL = "neocities.org";
Таймаут = 120;
Попытка
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
БезопасноеСоединение = Новый HTTPСоединение(URL, 443, Логин, Пароль, , Таймаут, ЗащищенноеСоединение);
Исключение
URL = "https://" + URL;
БезопасноеСоединение = Новый HTTPСоединение(URL, 443, Логин, Пароль, , Таймаут);
КонецПопытки;
Ответ = БезопасноеСоединение.Получить(Новый HTTPЗапрос("/api/key"));
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
Ответ = ПрочитатьJSON(ЧтениеJSON);
Возврат Ответ;
Возврат Результат;
КонецФункции
@@ -6,6 +6,7 @@
<value>Neocities (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Neocities из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>Notion (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Notion из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -646,7 +646,7 @@
ДополнитьURL(URL, "api/blobs/sha256:%1");
Хеш = OPI_Криптография.Хеш(Данные, ХешФункция.SHA256);
Хеш = OPI_Криптография.Хеш(Данные, "SHA256");
Хеш = нРег(ПолучитьHexСтрокуИзДвоичныхДанных(Хеш));
URL = СтрШаблон(URL, Хеш);
@@ -6,6 +6,7 @@
<value>Ollama (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Ollama из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>Open AI (ОПИ)</value>
</synonym>
<comment>Модуль для работы с OpenAI API из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>PostgreSQL (ОПИ)</value>
</synonym>
<comment>Модуль для работы с базами PostgreSQL из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>RCON (ОПИ)</value>
</synonym>
<comment>Модуль для работы с RCON из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -69,41 +69,11 @@
, Знач Элементы
, Знач ДатаОбновления = Неопределено) Экспорт
ДатаОбновления = ?(ДатаОбновления = Неопределено
, OPI_Инструменты.ПолучитьТекущуюДату()
, ДатаОбновления);
OPI_ПреобразованиеТипов.ПолучитьСтроку(НазваниеКанала);
OPI_ПреобразованиеТипов.ПолучитьСтроку(ОписаниеКанала);
OPI_ПреобразованиеТипов.ПолучитьСтроку(СсылкаКанала);
OPI_ПреобразованиеТипов.ПолучитьМассив(Элементы);
OPI_ПреобразованиеТипов.ПолучитьДату(ДатаОбновления);
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("rss");
ЗаписьXML.ЗаписатьАтрибут("version", "2.0");
ЗаписьXML.ЗаписатьНачалоЭлемента("channel");
ЗаписатьЭлементXML(ЗаписьXML, "title" , НазваниеКанала);
ЗаписатьЭлементXML(ЗаписьXML, "link" , СсылкаКанала);
ЗаписатьЭлементXML(ЗаписьXML, "description", ОписаниеКанала);
ДатаRFC822 = OPI_Инструменты.ДатаRFC822(ДатаОбновления);
ЗаписатьЭлементXML(ЗаписьXML, "lastBuildDate", ДатаRFC822);
Для Каждого Элемент Из Элементы Цикл
ЗаписатьЭлементФида(ЗаписьXML, Элемент);
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.ЗаписатьКонецЭлемента();
Фид = ЗаписьXML.Закрыть();
Возврат Фид;
Возврат OPI_ФункцииБиблиотекВызовСервера.СоздатьФидRSS(НазваниеКанала
, ОписаниеКанала
, СсылкаКанала
, Элементы
, ДатаОбновления);
КонецФункции
@@ -153,29 +123,7 @@
// Структура Из КлючИЗначение - Структура канала
Функция РазобратьФидRSS(Знач ТекстXML) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекстXML, Истина);
Канал = Новый Структура;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекстXML);
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Если ЧтениеXML.Имя = "channel" Тогда
Канал = ПрочитатьКаналRSS(ЧтениеXML);
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЧтениеXML.Закрыть();
Возврат Канал;
Возврат OPI_ФункцииБиблиотекВызовСервера.РазобратьФидRSS(ТекстXML);
КонецФункции
@@ -201,43 +149,11 @@
, Знач Элементы
, Знач ДатаОбновления = Неопределено) Экспорт
ДатаОбновления = ?(ДатаОбновления = Неопределено
, OPI_Инструменты.ПолучитьТекущуюДату()
, ДатаОбновления);
OPI_ПреобразованиеТипов.ПолучитьСтроку(НазваниеФида);
OPI_ПреобразованиеТипов.ПолучитьСтроку(СсылкаФида);
OPI_ПреобразованиеТипов.ПолучитьСтроку(IDФида);
OPI_ПреобразованиеТипов.ПолучитьМассив(Элементы);
OPI_ПреобразованиеТипов.ПолучитьДату(ДатаОбновления);
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("feed");
ЗаписьXML.ЗаписатьАтрибут("xmlns", "http://www.w3.org/2005/Atom");
ЗаписатьЭлементXML(ЗаписьXML, "title", НазваниеФида);
ЗаписатьЭлементXML(ЗаписьXML, "id" , IDФида);
ЗаписьXML.ЗаписатьНачалоЭлемента("link");
ЗаписьXML.ЗаписатьАтрибут("href", СсылкаФида);
ЗаписьXML.ЗаписатьАтрибут("rel" , "alternate");
ЗаписьXML.ЗаписатьКонецЭлемента();
ДатаISO8601 = OPI_Инструменты.ДатаISO8601(ДатаОбновления);
ЗаписатьЭлементXML(ЗаписьXML, "updated", ДатаISO8601);
Для Каждого Элемент Из Элементы Цикл
ЗаписатьЭлементФидаAtom(ЗаписьXML, Элемент);
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента(); // feed
Фид = ЗаписьXML.Закрыть();
Возврат Фид;
Возврат OPI_ФункцииБиблиотекВызовСервера.СоздатьФидAtom(НазваниеФида
, СсылкаФида
, IDФида
, Элементы
, ДатаОбновления);
КонецФункции
@@ -289,29 +205,7 @@
// Структура Из КлючИЗначение - Структура фида
Функция РазобратьФидAtom(Знач ТекстXML) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекстXML, Истина);
Фид = Новый Структура;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекстXML);
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Если ЧтениеXML.Имя = "feed" Тогда
Фид = ПрочитатьФидAtom(ЧтениеXML);
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЧтениеXML.Закрыть();
Возврат Фид;
Возврат OPI_ФункцииБиблиотекВызовСервера.РазобратьФидAtom(ТекстXML);
КонецФункции
@@ -319,245 +213,3 @@
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Процедура ЗаписатьЭлементXML(ЗаписьXML, ИмяЭлемента, Значение)
Если ЗначениеЗаполнено(Значение) Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента(ИмяЭлемента);
ЗаписьXML.ЗаписатьТекст(Значение);
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЕсли;
КонецПроцедуры
Процедура ЗаписатьЭлементФида(ЗаписьXML, Элемент)
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(Элемент);
ЗаписьXML.ЗаписатьНачалоЭлемента("item");
Для Каждого ПолеДанных Из Элемент Цикл
ТекущийКлюч = ПолеДанных.Ключ;
ТекущееЗначение = ПолеДанных.Значение;
Если ТипЗнч(ТекущееЗначение) = Тип("Дата") Тогда
ТекущееЗначение = OPI_Инструменты.ДатаRFC822(ТекущееЗначение);
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущееЗначение, Ложь);
КонецЕсли;
Если ТекущийКлюч = "guid" Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("guid");
ЗаписьXML.ЗаписатьАтрибут("isPermaLink", "false");
ЗаписьXML.ЗаписатьТекст(ТекущееЗначение);
ЗаписьXML.ЗаписатьКонецЭлемента();
Иначе
ЗаписатьЭлементXML(ЗаписьXML, ТекущийКлюч, ТекущееЗначение);
КонецЕсли;
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецПроцедуры
Функция ПрочитатьКаналRSS(ЧтениеXML)
Канал = Новый Структура;
Элементы = Новый Массив;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяЭлемента = ЧтениеXML.Имя;
Если ИмяЭлемента = "item" Тогда
Элемент = ПрочитатьЭлементRSS(ЧтениеXML);
Элементы.Добавить(Элемент);
Иначе
ЧтениеXML.Прочитать();
Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
Канал.Вставить(ИмяЭлемента, ЧтениеXML.Значение);
КонецЕсли;
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "channel" Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Канал.Вставить("items", Элементы);
Возврат Канал;
КонецФункции
Функция ПрочитатьЭлементRSS(ЧтениеXML)
Элемент = Новый Структура;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяЭлемента = ЧтениеXML.Имя;
ЧтениеXML.Прочитать();
Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
Элемент.Вставить(ИмяЭлемента, ЧтениеXML.Значение);
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "item" Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Возврат Элемент;
КонецФункции
Процедура ЗаписатьЭлементФидаAtom(ЗаписьXML, Элемент)
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(Элемент);
ЗаписьXML.ЗаписатьНачалоЭлемента("entry");
Для Каждого ПолеДанных Из Элемент Цикл
ТекущийКлюч = ПолеДанных.Ключ;
ТекущееЗначение = ПолеДанных.Значение;
Если ТипЗнч(ТекущееЗначение) = Тип("Дата") Тогда
ТекущееЗначение = OPI_Инструменты.ДатаISO8601(ТекущееЗначение);
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущееЗначение, Ложь);
КонецЕсли;
Если ТекущийКлюч = "link" Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("link");
ЗаписьXML.ЗаписатьАтрибут("href", ТекущееЗначение);
ЗаписьXML.ЗаписатьАтрибут("rel" , "alternate");
ЗаписьXML.ЗаписатьКонецЭлемента();
ИначеЕсли ТекущийКлюч = "author" Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("author");
ЗаписатьЭлементXML(ЗаписьXML, "name" , ТекущееЗначение);
ЗаписьXML.ЗаписатьКонецЭлемента();
ИначеЕсли ТекущийКлюч = "content" Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("content");
ЗаписьXML.ЗаписатьАтрибут("type", "html");
ЗаписьXML.ЗаписатьТекст(ТекущееЗначение);
ЗаписьXML.ЗаписатьКонецЭлемента();
Иначе
ЗаписатьЭлементXML(ЗаписьXML, ТекущийКлюч, ТекущееЗначение);
КонецЕсли;
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента(); // entry
КонецПроцедуры
Функция ПрочитатьФидAtom(ЧтениеXML)
Фид = Новый Структура;
Элементы = Новый Массив;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяЭлемента = ЧтениеXML.Имя;
Если ИмяЭлемента = "entry" Тогда
Элемент = ПрочитатьЭлементAtom(ЧтениеXML);
Элементы.Добавить(Элемент);
ИначеЕсли ИмяЭлемента = "link" Тогда
Фид.Вставить("link", ЧтениеXML.ПолучитьАтрибут("href"));
Иначе
ЧтениеXML.Прочитать();
Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
Фид.Вставить(ИмяЭлемента, ЧтениеXML.Значение);
КонецЕсли;
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "feed" Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Фид.Вставить("entries", Элементы);
Возврат Фид;
КонецФункции
Функция ПрочитатьЭлементAtom(ЧтениеXML)
Элемент = Новый Структура;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяЭлемента = ЧтениеXML.Имя;
Если ИмяЭлемента = "link" Тогда
Элемент.Вставить("link" , ЧтениеXML.ПолучитьАтрибут("href"));
ИначеЕсли ИмяЭлемента = "author" Тогда
ИмяАвтора = ПрочитатьАвтораAtom(ЧтениеXML);
Элемент.Вставить("author", ИмяАвтора);
Иначе
ЧтениеXML.Прочитать();
Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
Элемент.Вставить(ИмяЭлемента, ЧтениеXML.Значение);
КонецЕсли;
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "entry" Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Возврат Элемент;
КонецФункции
Функция ПрочитатьАвтораAtom(ЧтениеXML)
ИмяАвтора = "";
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеXML.Имя = "name" Тогда
ЧтениеXML.Прочитать();
Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
ИмяАвтора = ЧтениеXML.Значение;
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "author" Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Возврат ИмяАвтора;
КонецФункции
#КонецОбласти
@@ -6,6 +6,7 @@
<value>RSS (ОПИ)</value>
</synonym>
<comment>Модуль для работы с RSS из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>ReportPortal (ОПИ)</value>
</synonym>
<comment>Модуль для работы с ReportPortal из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -1298,11 +1298,7 @@
Функция СоздатьПодписьURL(Знач СтруктураДанных, Знач Метод, Знач ВремяЖизни, Знач Заголовки)
AccessKey = СтруктураДанных["AccessKey"];
SecretKey = СтруктураДанных["SecretKey"];
Region = СтруктураДанных["Region"];
Service = СтруктураДанных["Service"];
URL = СтруктураДанных["URL"];
URL = СтруктураДанных["URL"];
РазбитыйURL = OPI_Инструменты.РазбитьURL(URL);
@@ -1311,165 +1307,10 @@
ДопЗаголовки = Новый Структура("Host", Домен);
ДобавитьДополнительныеЗаголовки(Заголовки, ДопЗаголовки);
ТекущаяДата = ТекущаяУниверсальнаяДата();
КлючПодписи = ПолучитьКлючПодписи(SecretKey, Region, Service, ТекущаяДата);
Скоуп = СоздатьСкоуп(Region, Service, ТекущаяДата);
ВременнаяМетка = OPI_Инструменты.ВременнаяМеткаISO(ТекущаяДата);
КлючиЗаголовков = ПолучитьСтрокуКлючейЗаголовков(Заголовки);
Основа = КодироватьСтроку(AccessKey + "/" + Скоуп, СпособКодированияСтроки.КодировкаURL);
СтрокаЗаголовков = ПолучитьСтрокуЗаголовков(Заголовки);
СтрокаХеша = "UNSIGNED-PAYLOAD";
ПараметрыURL = Новый ТаблицаЗначений;
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-Algorithm" , "AWS4-HMAC-SHA256");
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-Credential" , Основа);
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-Date" , ВременнаяМетка);
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-Expires" , ВремяЖизни);
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-SignedHeaders", КлючиЗаголовков);
ПараметрыСтрокой = OPI_Инструменты.ПараметрыЗапросаВСтроку(ПараметрыURL);
ПараметрыСтрокой = Прав(ПараметрыСтрокой, СтрДлина(ПараметрыСтрокой) - 1);
ШаблонЗапроса = "";
ЧислоЧастей = 6;
Для Н = 1 По ЧислоЧастей Цикл
ШаблонЗапроса = ШаблонЗапроса + "%" + Строка(Н) + ?(Н = ЧислоЧастей, "", Символы.ПС);
КонецЦикла;
КаноническийЗапрос = СтрШаблон(ШаблонЗапроса
, Метод
, Адрес
, ПараметрыСтрокой
, СтрокаЗаголовков
, КлючиЗаголовков
, СтрокаХеша);
СтрокаДляПодписи = СоздатьСтрокуПодписи(КаноническийЗапрос, Скоуп, ТекущаяДата);
Сигнатура = OPI_Криптография.HMAC(КлючПодписи, СтрокаДляПодписи, "SHA256");
Сигнатура = нРег(ПолучитьHexСтрокуИзДвоичныхДанных(Сигнатура));
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-Signature", Сигнатура);
ПодписьURL = OPI_Инструменты.ПараметрыЗапросаВСтроку(ПараметрыURL);
Возврат ПодписьURL;
КонецФункции
Функция ПолучитьКлючПодписи(Знач СекретныйКлюч, Знач Регион, Знач Сервис, Знач ТекущаяДата)
СекретныйКлюч = ПолучитьДвоичныеДанныеИзСтроки("AWS4" + СекретныйКлюч);
ДанныеДата = ПолучитьДвоичныеДанныеИзСтроки(Формат(ТекущаяДата, "ДФ=yyyyMMdd;"));
Регион = ПолучитьДвоичныеДанныеИзСтроки(Регион);
Сервис = ПолучитьДвоичныеДанныеИзСтроки(Сервис);
AWSЗапрос = ПолучитьДвоичныеДанныеИзСтроки("aws4_request");
Sha256_ = "SHA256";
КлючДанных = OPI_Криптография.HMAC(СекретныйКлюч, ДанныеДата, Sha256_);
КлючРегиона = OPI_Криптография.HMAC(КлючДанных, Регион, Sha256_);
КлючСервиса = OPI_Криптография.HMAC(КлючРегиона, Сервис, Sha256_);
ФинальныйКлюч = OPI_Криптография.HMAC(КлючСервиса, AWSЗапрос, Sha256_);
Возврат ФинальныйКлюч;
КонецФункции
Функция СоздатьСкоуп(Знач Регион, Знач Сервис, Знач ТекущаяДата)
ДатаОбычная = Формат(ТекущаяДата, "ДФ=yyyyMMdd;");
Скоуп = Новый Массив;
Скоуп.Добавить(ДатаОбычная);
Скоуп.Добавить(Регион);
Скоуп.Добавить(Сервис);
Скоуп.Добавить("aws4_request");
СкоупСтрокой = СтрСоединить(Скоуп, "/");
Возврат СкоупСтрокой;
КонецФункции
Функция СоздатьСтрокуПодписи(Знач КаноническийЗапрос, Знач Скоуп, Знач ТекущаяДата)
ШаблонСтроки = "";
Алгоритм = "AWS4-HMAC-SHA256";
ДатаISO = OPI_Инструменты.ВременнаяМеткаISO(ТекущаяДата);
ЧислоЧастей = 4;
КаноническийЗапрос = ПолучитьДвоичныеДанныеИзСтроки(КаноническийЗапрос);
КаноническийЗапрос = OPI_Криптография.Хеш(КаноническийЗапрос, ХешФункция.SHA256);
КаноническийЗапрос = нРег(ПолучитьHexСтрокуИзДвоичныхДанных(КаноническийЗапрос));
Для Н = 1 По ЧислоЧастей Цикл
ШаблонСтроки = ШаблонСтроки + "%" + Строка(Н) + ?(Н = ЧислоЧастей, "", Символы.ПС);
КонецЦикла;
СтрокаПодписи = СтрШаблон(ШаблонСтроки, Алгоритм, ДатаISO, Скоуп, КаноническийЗапрос);
СтрокаПодписи = ПолучитьДвоичныеДанныеИзСтроки(СтрокаПодписи);
Возврат СтрокаПодписи;
КонецФункции
Функция ПолучитьСтрокуЗаголовков(Знач Заголовки)
СписокЗаголовков = Новый СписокЗначений;
Для Каждого Заголовок Из Заголовки Цикл
ТекущийКлюч = Заголовок.Ключ;
ТекущийКлючН = нРег(ТекущийКлюч);
Если Не СтрНачинаетсяС(ТекущийКлючН, "host") И Не СтрНачинаетсяС(ТекущийКлючН, "x-amz") Тогда
Продолжить;
КонецЕсли;
СтрокаЗаголовка = нРег(ТекущийКлюч) + ":" + Заголовок.Значение;
СписокЗаголовков.Добавить(СтрокаЗаголовка);
КонецЦикла;
СписокЗаголовков.СортироватьПоЗначению();
СтрокаЗаголовков = СтрСоединить(СписокЗаголовков.ВыгрузитьЗначения(), Символы.ПС);
СтрокаЗаголовков = СтрокаЗаголовков + Символы.ПС;
Возврат СтрокаЗаголовков;
КонецФункции
Функция ПолучитьСтрокуКлючейЗаголовков(Знач Заголовки)
СписокЗаголовков = Новый СписокЗначений;
Для Каждого Заголовок Из Заголовки Цикл
ТекущийКлюч = Заголовок.Ключ;
ТекущийКлючН = нРег(ТекущийКлюч);
Если Не СтрНачинаетсяС(ТекущийКлючН, "host") И Не СтрНачинаетсяС(ТекущийКлючН, "x-amz") Тогда
Продолжить;
КонецЕсли;
СтрокаЗаголовка = нРег(ТекущийКлюч);
СписокЗаголовков.Добавить(СтрокаЗаголовка);
КонецЦикла;
СписокЗаголовков.СортироватьПоЗначению();
СтрокаЗаголовков = СтрСоединить(СписокЗаголовков.ВыгрузитьЗначения(), ";");
Возврат СтрокаЗаголовков;
ПодписьURL = OPI_Инструменты.СгенерироватьПодписьAWS(СтруктураДанных, Адрес, Метод, Заголовки, ВремяЖизни);
Возврат ПодписьURL;
КонецФункции
@@ -6,6 +6,7 @@
<value>S3 (ОПИ)</value>
</synonym>
<comment>Модуль для работы с S3 хранилищами из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -443,7 +443,11 @@
// BSLLS:MissingTemporaryFileDeletion-off
//@skip-check missing-temporary-file-deletion
ИВФ = ПолучитьИмяВременногоФайла();
#Если ВебКлиент Тогда
ИВФ = OPI_Инструменты.ПолучитьИмяВременногоФайлаНаСервере();
#Иначе
ИВФ = ПолучитьИмяВременногоФайла();
#КонецЕсли
// BSLLS:MissingTemporaryFileDeletion-on
@@ -565,7 +569,11 @@
// BSLLS:MissingTemporaryFileDeletion-off
//@skip-check missing-temporary-file-deletion
ИВФ = ПолучитьИмяВременногоФайла();
#Если ВебКлиент Тогда
ИВФ = OPI_Инструменты.ПолучитьИмяВременногоФайлаНаСервере();
#Иначе
ИВФ = ПолучитьИмяВременногоФайла();
#КонецЕсли
// BSLLS:MissingTemporaryFileDeletion-on
@@ -6,6 +6,7 @@
<value>SFTP (ОПИ)</value>
</synonym>
<comment>Модуль для работы с SFTP из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -10,6 +10,7 @@
<value>SQLite (ОПИ)</value>
</synonym>
<comment>Модуль для работы с базами SQLite из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>SSH (ОПИ)</value>
</synonym>
<comment>Модуль для работы с SSH из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>Slack (ОПИ)</value>
</synonym>
<comment>Модуль для работы со Slack из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>TCP (ОПИ)</value>
</synonym>
<comment>Модуль для работы с TCP из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -234,8 +234,8 @@
Для Каждого ЭлементДанных Из КодированныеДанные Цикл
ТекущийКлюч = РаскодироватьСтроку(ЭлементДанных.Ключ, СпособКодированияСтроки.КодировкаURL);
ТекущееЗначение = РаскодироватьСтроку(ЭлементДанных.Значение, СпособКодированияСтроки.КодировкаURL);
ТекущийКлюч = OPI_Инструменты.ПолучитьРаскодированнуюСтроку(ЭлементДанных.Ключ, "КодировкаURL");
ТекущееЗначение = OPI_Инструменты.ПолучитьРаскодированнуюСтроку(ЭлементДанных.Значение, "КодировкаURL");
СтруктураДанных.Вставить(ТекущийКлюч, ТекущееЗначение);
@@ -245,26 +245,13 @@
Хеш = "";
КлючДвоичные = ПолучитьДвоичныеДанныеИзСтроки(КлючСтрокой);
Результат = OPI_Криптография.HMAC(КлючДвоичные, ПолучитьДвоичныеДанныеИзСтроки(Токен), "SHA256");
ТЗнач = Новый ТаблицаЗначений;
ТЗнач.Колонки.Добавить("Ключ");
ТЗнач.Колонки.Добавить("Значение");
Для Каждого Данные Из СтруктураДанных Цикл
НоваяСтрока = ТЗнач.Добавить();
НоваяСтрока.Ключ = Данные.Ключ;
НоваяСтрока.Значение = Данные.Значение;
КонецЦикла;
ТЗнач.Сортировать("Ключ");
Результат = OPI_Криптография.HMAC(КлючДвоичные, ПолучитьДвоичныеДанныеИзСтроки(Токен), "SHA256");
СтруктураДанных = OPI_Инструменты.СортироватьСтруктуруПоКлючу(СтруктураДанных);
СоответствиеВозврата = Новый Соответствие;
DCS = "";
Для Каждого СтрокаТЗ Из ТЗнач Цикл
Для Каждого СтрокаТЗ Из СтруктураДанных Цикл
Если СтрокаТЗ.Ключ <> "hash" И СтрокаТЗ.Ключ <> "cookie" Тогда
DCS = DCS + СтрокаТЗ.Ключ + "=" + СтрокаТЗ.Значение + Символы.ПС;
@@ -1577,7 +1564,7 @@
OPI_ПреобразованиеТипов.ПолучитьСтроку(Текст);
ЗаменитьСпецСимволы(Текст, Разметка);
Текст = РаскодироватьСтроку(Текст, СпособКодированияСтроки.URLВКодировкеURL);
Текст = OPI_Инструменты.ПолучитьРаскодированнуюСтроку(Текст, "URLВКодировкеURL");
КонецПроцедуры
@@ -6,6 +6,7 @@
<value>Telegram (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Telegram Bot API из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>VK (ОПИ)</value>
</synonym>
<comment>Модуль для работы с VK из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="cba61dc6-38eb-4bff-83cd-34dbc233f294">
<name>OPI_VKTeams</name>
<comment>Модуль для работы с VK Teams из набора ОПИ</comment>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
<synonym>
<key>ru</key>
<value>VK Teams (ОПИ)</value>
</synonym>
<comment>Модуль для работы с VK Teams из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>
@@ -6,6 +6,7 @@
<value>Viber (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Viber из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -5,6 +5,7 @@
<key>ru</key>
<value>WebSocket (ОПИ)</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -515,8 +515,10 @@
Заголовки = OPI_YandexID.ПолучитьЗаголовокАвторизации(Токен);
URL = "https://cloud-api.yandex.net/v1/disk/resources/upload";
КодированныйURL = OPI_Инструменты.ПолучитьКодированнуюСтроку(Адрес, "КодировкаURL");
Параметры = Новый Структура;
Параметры.Вставить("url" , КодироватьСтроку(Адрес, СпособКодированияСтроки.КодировкаURL));
Параметры.Вставить("url" , КодированныйURL);
Параметры.Вставить("path", Путь);
Параметры = OPI_Инструменты.ПараметрыЗапросаВСтроку(Параметры);
@@ -683,7 +685,7 @@
Href = "href";
Параметры = Новый Структура;
Параметры.Вставить("public_key", КодироватьСтроку(URL, СпособКодированияСтроки.КодировкаURL));
Параметры.Вставить("public_key", OPI_Инструменты.ПолучитьКодированнуюСтроку(URL, "КодировкаURL"));
Если ЗначениеЗаполнено(Откуда) Тогда
Параметры.Вставить("path", Откуда);
@@ -6,6 +6,7 @@
<value>Yandex.Disk (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Yandex.Disk из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>YandexID (ОПИ)</value>
</synonym>
<comment>Модуль для работы с YandexID из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>Yandex Metrika (ОПИ)</value>
</synonym>
<comment>Модуль для работы с Yandex Metrika из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>ZeroMQ (ОПИ)</value>
</synonym>
<comment>Модуль для работы с ZeroMQ из набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -7,6 +7,5 @@
</synonym>
<comment>Служебный модуль работы с HTTP набора ОПИ</comment>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
<serverCall>true</serverCall>
</mdclass:CommonModule>
@@ -1193,9 +1193,18 @@
// BSLLS:MissingTemporaryFileDeletion-off
//@skip-check missing-temporary-file-deletion
ПутьЗаготовок = ПолучитьИмяВременногоФайла();
#Если ВебКлиент Тогда
ПутьЗаготовок = OPI_Инструменты.ПолучитьИмяВременногоФайлаНаСервере();
#Иначе
ПутьЗаготовок = ПолучитьИмяВременногоФайла();
#КонецЕсли
//@skip-check missing-temporary-file-deletion
ПутьКлючей = ПолучитьИмяВременногоФайла();
#Если ВебКлиент Тогда
ПутьКлючей = OPI_Инструменты.ПолучитьИмяВременногоФайлаНаСервере();
#Иначе
ПутьКлючей = ПолучитьИмяВременногоФайла();
#КонецЕсли
// BSLLS:MissingTemporaryFileDeletion-on
@@ -1775,7 +1784,11 @@
// BSLLS:MissingTemporaryFileDeletion-off
//@skip-check missing-temporary-file-deletion
ИВФ = ПолучитьИмяВременногоФайла();
#Если ВебКлиент Тогда
ИВФ = OPI_Инструменты.ПолучитьИмяВременногоФайлаНаСервере();
#Иначе
ИВФ = ПолучитьИмяВременногоФайла();
#КонецЕсли
// BSLLS:MissingTemporaryFileDeletion-on
@@ -1803,7 +1816,11 @@
// BSLLS:MissingTemporaryFileDeletion-off
//@skip-check missing-temporary-file-deletion
ИВФ = ПолучитьИмяВременногоФайла();
#Если ВебКлиент Тогда
ИВФ = OPI_Инструменты.ПолучитьИмяВременногоФайлаНаСервере();
#Иначе
ИВФ = ПолучитьИмяВременногоФайла();
#КонецЕсли
// BSLLS:MissingTemporaryFileDeletion-on
@@ -1849,7 +1866,11 @@
// BSLLS:MissingTemporaryFileDeletion-off
//@skip-check missing-temporary-file-deletion
ИВФ = ПолучитьИмяВременногоФайла();
#Если ВебКлиент Тогда
ИВФ = OPI_Инструменты.ПолучитьИмяВременногоФайлаНаСервере();
#Иначе
ИВФ = ПолучитьИмяВременногоФайла();
#КонецЕсли
// BSLLS:MissingTemporaryFileDeletion-on
@@ -6,6 +6,7 @@
<value>SQL (служебный, ОПИ)</value>
</synonym>
<comment>Общий модуль инструментов работы с SQL набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -6,6 +6,7 @@
<value>SSH (служебный, ОПИ)</value>
</synonym>
<comment>Общий модуль инструментов работы с SSH набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -188,6 +188,30 @@
КонецФункции
Функция ПолучитьРаскодированнуюСтроку(Знач Значение, Знач Способ) Экспорт
Если ТипЗнч(Способ) = Тип("Строка") Тогда
СпособКодировки = СпособКодированияСтроки[Способ];
Иначе
СпособКодировки = Способ;
КонецЕсли;
Возврат РаскодироватьСтроку(Значение, СпособКодировки);
КонецФункции
Функция ПолучитьКодированнуюСтроку(Знач Значение, Знач Способ) Экспорт
Если ТипЗнч(Способ) = Тип("Строка") Тогда
СпособКодировки = СпособКодированияСтроки[Способ];
Иначе
СпособКодировки = Способ;
КонецЕсли;
Возврат КодироватьСтроку(Значение, СпособКодировки);
КонецФункции
#КонецОбласти
#Область JSON
@@ -716,6 +740,57 @@
КонецФункции
Функция СортироватьСтруктуруПоКлючу(Знач Значение) Экспорт
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Ключ");
Таблица.Колонки.Добавить("Значение");
Для Каждого Данные Из Значение Цикл
НоваяСтрока = Таблица.Добавить();
НоваяСтрока.Ключ = Данные.Ключ;
НоваяСтрока.Значение = Данные.Значение;
КонецЦикла;
Таблица.Сортировать("Ключ");
ВозвращаемаяСтруктура = Новый Структура;
Для Каждого СтрокаТаблицы Из Таблица Цикл
ВозвращаемаяСтруктура.Вставить(СтрокаТаблицы.Ключ, СтрокаТаблицы.Значение);
КонецЦикла;
Возврат ВозвращаемаяСтруктура;
КонецФункции
Функция ТаблицаЗначенийВМассив(Знач ТаблицаЗначений) Экспорт
МассивВозврата = Новый Массив;
МассивКолонок = Новый Массив;
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
МассивКолонок.Добавить(Колонка.Имя);
КонецЦикла;
СтрокаКолонок = СтрСоединить(МассивКолонок, ",");
Для Каждого Строка Из ТаблицаЗначений Цикл
НоваяСтрока = Новый Структура(СтрокаКолонок);
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
МассивВозврата.Добавить(НоваяСтрока);
КонецЦикла;
Возврат МассивВозврата;
КонецФункции
#КонецОбласти
#Область РаботаСДатой
@@ -738,6 +813,10 @@
КонецФункции
Функция ПолучитьТекущуюУниверсальнуюДату() Экспорт
Возврат ТекущаяУниверсальнаяДата();
КонецФункции
Функция UNIXTime(Знач Дата) Экспорт
ОТД = Новый ОписаниеТипов("Дата");
@@ -1134,6 +1213,10 @@
КонецФункции
Функция ПолучитьИмяВременногоФайлаНаСервере(Знач Расширение = Неопределено) Экспорт
Возврат ПолучитьИмяВременногоФайла(Расширение);
КонецФункции
Функция ВерсияОПИ() Экспорт
Возврат "2.1.0";
КонецФункции
@@ -7,6 +7,5 @@
</synonym>
<comment>Основной модуль инструментов набора ОПИ</comment>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
<serverCall>true</serverCall>
</mdclass:CommonModule>
@@ -6,6 +6,7 @@
<value>Компоненты (служебный, ОПИ)</value>
</synonym>
<comment>Модуль работы с внешними компонентами набора ОПИ</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -177,7 +177,13 @@
Функция Хеш(ДвоичныеДанные, Тип) Экспорт
Хеширование = Новый ХешированиеДанных(Тип);
Если ТипЗнч(Тип) = Тип("Строка") Тогда
ТипХеша = ХешФункция[Тип];
Иначе
ТипХеша = Тип;
КонецЕсли;
Хеширование = Новый ХешированиеДанных(ТипХеша);
Хеширование.Добавить(ДвоичныеДанные);
Возврат Хеширование.ХешСумма;
@@ -7,6 +7,5 @@
</synonym>
<comment>Модуль работы с криптографией набора ОПИ</comment>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
<serverCall>true</serverCall>
</mdclass:CommonModule>
@@ -7,6 +7,5 @@
</synonym>
<comment>Модуль приведения типов набора ОПИ</comment>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
<serverCall>true</serverCall>
</mdclass:CommonModule>
@@ -7,6 +7,5 @@
</synonym>
<comment>Модуль для вызова методов с расширенным набором параметров</comment>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
<serverCall>true</serverCall>
</mdclass:CommonModule>
@@ -6,6 +6,7 @@
<value>Универсальный сервер (служебный, ОПИ)</value>
</synonym>
<comment>Универсальные методы для разных видов серверов</comment>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -0,0 +1,622 @@
// OneScript: ./OInt/tools/main/Modules/OPI_ФункцииБиблиотекВызовСервера.os
// MIT License
// Copyright (c) 2023-2026 Anton Tsitavets
// 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.
// https://github.com/Bayselonarrend/OpenIntegrations
// BSLLS:Typo-off
// BSLLS:LatinAndCyrillicSymbolInWord-off
// BSLLS:IncorrectLineBreak-off
// BSLLS:NumberOfOptionalParams-off
// BSLLS:UsingServiceTag-off
// BSLLS:LineLength-off
// BSLLS:QueryParseError-off
// BSLLS:AssignAliasFieldsInQuery-off
// BSLLS:NumberOfParams-off
// BSLLS:UsingSynchronousCalls-off
// BSLLS:MagicNumber-off
//@skip-check module-structure-top-region
//@skip-check module-structure-method-in-regions
//@skip-check wrong-string-literal-content
//@skip-check method-too-many-params
//@skip-check constructor-function-return-section
// #Использовать "./internal"
#Область СлужебныйПрограммныйИнтерфейс
#Область S3
Функция СгенерироватьПодписьAWS(Знач СтруктураДанных, Знач Адрес, Знач Метод, Знач Заголовки, Знач ВремяЖизни) Экспорт
AccessKey = СтруктураДанных["AccessKey"];
SecretKey = СтруктураДанных["SecretKey"];
Region = СтруктураДанных["Region"];
Service = СтруктураДанных["Service"];
СтрокаХеша = "UNSIGNED-PAYLOAD";
ТекущаяДата = OPI_Инструменты.ПолучитьТекущуюУниверсальнуюДату();
ВременнаяМетка = OPI_Инструменты.ВременнаяМеткаISO(ТекущаяДата);
КлючПодписи = ПолучитьКлючПодписи(SecretKey, Region, Service, ТекущаяДата);
Скоуп = СоздатьСкоуп(Region, Service, ТекущаяДата);
КлючиЗаголовков = ПолучитьСтрокуКлючейЗаголовков(Заголовки);
СтрокаЗаголовков = ПолучитьСтрокуЗаголовков(Заголовки);
Основа = OPI_Инструменты.ПолучитьКодированнуюСтроку(AccessKey + "/" + Скоуп, "КодировкаURL");
ПараметрыURL = Новый ТаблицаЗначений;
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-Algorithm" , "AWS4-HMAC-SHA256");
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-Credential" , Основа);
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-Date" , ВременнаяМетка);
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-Expires" , ВремяЖизни);
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-SignedHeaders", КлючиЗаголовков);
ПараметрыСтрокой = OPI_Инструменты.ПараметрыЗапросаВСтроку(ПараметрыURL);
ПараметрыСтрокой = Прав(ПараметрыСтрокой, СтрДлина(ПараметрыСтрокой) - 1);
ШаблонЗапроса = "";
ЧислоЧастей = 6;
Для Н = 1 По ЧислоЧастей Цикл
ШаблонЗапроса = ШаблонЗапроса + "%" + Строка(Н) + ?(Н = ЧислоЧастей, "", Символы.ПС);
КонецЦикла;
КаноническийЗапрос = СтрШаблон(ШаблонЗапроса
, Метод
, Адрес
, ПараметрыСтрокой
, СтрокаЗаголовков
, КлючиЗаголовков
, СтрокаХеша);
СтрокаДляПодписи = СоздатьСтрокуПодписи(КаноническийЗапрос, Скоуп, ТекущаяДата);
Сигнатура = OPI_Криптография.HMAC(КлючПодписи, СтрокаДляПодписи, "SHA256");
Сигнатура = нРег(ПолучитьHexСтрокуИзДвоичныхДанных(Сигнатура));
OPI_Инструменты.ДобавитьКлючЗначение(ПараметрыURL, "X-Amz-Signature", Сигнатура);
ПодписьURL = OPI_Инструменты.ПараметрыЗапросаВСтроку(ПараметрыURL);
Возврат ПодписьURL;
КонецФункции
#КонецОбласти
#Область RSS
Функция СоздатьФидRSS(Знач НазваниеКанала
, Знач ОписаниеКанала
, Знач СсылкаКанала
, Знач Элементы
, Знач ДатаОбновления = Неопределено) Экспорт
ДатаОбновления = ?(ДатаОбновления = Неопределено
, OPI_Инструменты.ПолучитьТекущуюДату()
, ДатаОбновления);
OPI_ПреобразованиеТипов.ПолучитьСтроку(НазваниеКанала);
OPI_ПреобразованиеТипов.ПолучитьСтроку(ОписаниеКанала);
OPI_ПреобразованиеТипов.ПолучитьСтроку(СсылкаКанала);
OPI_ПреобразованиеТипов.ПолучитьМассив(Элементы);
OPI_ПреобразованиеТипов.ПолучитьДату(ДатаОбновления);
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("rss");
ЗаписьXML.ЗаписатьАтрибут("version", "2.0");
ЗаписьXML.ЗаписатьНачалоЭлемента("channel");
ЗаписатьЭлементXML(ЗаписьXML, "title" , НазваниеКанала);
ЗаписатьЭлементXML(ЗаписьXML, "link" , СсылкаКанала);
ЗаписатьЭлементXML(ЗаписьXML, "description", ОписаниеКанала);
ДатаRFC822 = OPI_Инструменты.ДатаRFC822(ДатаОбновления);
ЗаписатьЭлементXML(ЗаписьXML, "lastBuildDate", ДатаRFC822);
Для Каждого Элемент Из Элементы Цикл
ЗаписатьЭлементФида(ЗаписьXML, Элемент);
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.ЗаписатьКонецЭлемента();
Фид = ЗаписьXML.Закрыть();
Возврат Фид;
КонецФункции
Функция РазобратьФидRSS(Знач ТекстXML) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекстXML, Истина);
Канал = Новый Структура;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекстXML);
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Если ЧтениеXML.Имя = "channel" Тогда
Канал = ПрочитатьКаналRSS(ЧтениеXML);
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЧтениеXML.Закрыть();
Возврат Канал;
КонецФункции
Функция СоздатьФидAtom(Знач НазваниеФида
, Знач СсылкаФида
, Знач IDФида
, Знач Элементы
, Знач ДатаОбновления = Неопределено) Экспорт
ДатаОбновления = ?(ДатаОбновления = Неопределено
, OPI_Инструменты.ПолучитьТекущуюДату()
, ДатаОбновления);
OPI_ПреобразованиеТипов.ПолучитьСтроку(НазваниеФида);
OPI_ПреобразованиеТипов.ПолучитьСтроку(СсылкаФида);
OPI_ПреобразованиеТипов.ПолучитьСтроку(IDФида);
OPI_ПреобразованиеТипов.ПолучитьМассив(Элементы);
OPI_ПреобразованиеТипов.ПолучитьДату(ДатаОбновления);
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("feed");
ЗаписьXML.ЗаписатьАтрибут("xmlns", "http://www.w3.org/2005/Atom");
ЗаписатьЭлементXML(ЗаписьXML, "title", НазваниеФида);
ЗаписатьЭлементXML(ЗаписьXML, "id" , IDФида);
ЗаписьXML.ЗаписатьНачалоЭлемента("link");
ЗаписьXML.ЗаписатьАтрибут("href", СсылкаФида);
ЗаписьXML.ЗаписатьАтрибут("rel" , "alternate");
ЗаписьXML.ЗаписатьКонецЭлемента();
ДатаISO8601 = OPI_Инструменты.ДатаISO8601(ДатаОбновления);
ЗаписатьЭлементXML(ЗаписьXML, "updated", ДатаISO8601);
Для Каждого Элемент Из Элементы Цикл
ЗаписатьЭлементФидаAtom(ЗаписьXML, Элемент);
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента(); // feed
Фид = ЗаписьXML.Закрыть();
Возврат Фид;
КонецФункции
Функция РазобратьФидAtom(Знач ТекстXML) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекстXML, Истина);
Фид = Новый Структура;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекстXML);
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Если ЧтениеXML.Имя = "feed" Тогда
Фид = ПрочитатьФидAtom(ЧтениеXML);
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЧтениеXML.Закрыть();
Возврат Фид;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
#Область S3
Функция СоздатьСтрокуПодписи(Знач КаноническийЗапрос, Знач Скоуп, Знач ТекущаяДата)
ШаблонСтроки = "";
Алгоритм = "AWS4-HMAC-SHA256";
ДатаISO = OPI_Инструменты.ВременнаяМеткаISO(ТекущаяДата);
ЧислоЧастей = 4;
КаноническийЗапрос = ПолучитьДвоичныеДанныеИзСтроки(КаноническийЗапрос);
КаноническийЗапрос = OPI_Криптография.Хеш(КаноническийЗапрос, "SHA256");
КаноническийЗапрос = нРег(ПолучитьHexСтрокуИзДвоичныхДанных(КаноническийЗапрос));
Для Н = 1 По ЧислоЧастей Цикл
ШаблонСтроки = ШаблонСтроки + "%" + Строка(Н) + ?(Н = ЧислоЧастей, "", Символы.ПС);
КонецЦикла;
СтрокаПодписи = СтрШаблон(ШаблонСтроки, Алгоритм, ДатаISO, Скоуп, КаноническийЗапрос);
СтрокаПодписи = ПолучитьДвоичныеДанныеИзСтроки(СтрокаПодписи);
Возврат СтрокаПодписи;
КонецФункции
Функция ПолучитьКлючПодписи(Знач СекретныйКлюч, Знач Регион, Знач Сервис, Знач ТекущаяДата)
СекретныйКлюч = ПолучитьДвоичныеДанныеИзСтроки("AWS4" + СекретныйКлюч);
ДанныеДата = ПолучитьДвоичныеДанныеИзСтроки(Формат(ТекущаяДата, "ДФ=yyyyMMdd;"));
Регион = ПолучитьДвоичныеДанныеИзСтроки(Регион);
Сервис = ПолучитьДвоичныеДанныеИзСтроки(Сервис);
AWSЗапрос = ПолучитьДвоичныеДанныеИзСтроки("aws4_request");
Sha256_ = "SHA256";
КлючДанных = OPI_Криптография.HMAC(СекретныйКлюч, ДанныеДата, Sha256_);
КлючРегиона = OPI_Криптография.HMAC(КлючДанных, Регион, Sha256_);
КлючСервиса = OPI_Криптография.HMAC(КлючРегиона, Сервис, Sha256_);
ФинальныйКлюч = OPI_Криптография.HMAC(КлючСервиса, AWSЗапрос, Sha256_);
Возврат ФинальныйКлюч;
КонецФункции
Функция СоздатьСкоуп(Знач Регион, Знач Сервис, Знач ТекущаяДата)
ДатаОбычная = Формат(ТекущаяДата, "ДФ=yyyyMMdd;");
Скоуп = Новый Массив;
Скоуп.Добавить(ДатаОбычная);
Скоуп.Добавить(Регион);
Скоуп.Добавить(Сервис);
Скоуп.Добавить("aws4_request");
СкоупСтрокой = СтрСоединить(Скоуп, "/");
Возврат СкоупСтрокой;
КонецФункции
Функция ПолучитьСтрокуЗаголовков(Знач Заголовки)
СписокЗаголовков = Новый СписокЗначений;
Для Каждого Заголовок Из Заголовки Цикл
ТекущийКлюч = Заголовок.Ключ;
ТекущийКлючН = нРег(ТекущийКлюч);
Если Не СтрНачинаетсяС(ТекущийКлючН, "host") И Не СтрНачинаетсяС(ТекущийКлючН, "x-amz") Тогда
Продолжить;
КонецЕсли;
СтрокаЗаголовка = нРег(ТекущийКлюч) + ":" + Заголовок.Значение;
СписокЗаголовков.Добавить(СтрокаЗаголовка);
КонецЦикла;
СписокЗаголовков.СортироватьПоЗначению();
СтрокаЗаголовков = СтрСоединить(СписокЗаголовков.ВыгрузитьЗначения(), Символы.ПС);
СтрокаЗаголовков = СтрокаЗаголовков + Символы.ПС;
Возврат СтрокаЗаголовков;
КонецФункции
Функция ПолучитьСтрокуКлючейЗаголовков(Знач Заголовки)
СписокЗаголовков = Новый СписокЗначений;
Для Каждого Заголовок Из Заголовки Цикл
ТекущийКлюч = Заголовок.Ключ;
ТекущийКлючН = нРег(ТекущийКлюч);
Если Не СтрНачинаетсяС(ТекущийКлючН, "host") И Не СтрНачинаетсяС(ТекущийКлючН, "x-amz") Тогда
Продолжить;
КонецЕсли;
СтрокаЗаголовка = нРег(ТекущийКлюч);
СписокЗаголовков.Добавить(СтрокаЗаголовка);
КонецЦикла;
СписокЗаголовков.СортироватьПоЗначению();
СтрокаЗаголовков = СтрСоединить(СписокЗаголовков.ВыгрузитьЗначения(), ";");
Возврат СтрокаЗаголовков;
КонецФункции
#КонецОбласти
#Область RSS
Процедура ЗаписатьЭлементXML(ЗаписьXML, ИмяЭлемента, Значение)
Если ЗначениеЗаполнено(Значение) Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента(ИмяЭлемента);
ЗаписьXML.ЗаписатьТекст(Значение);
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЕсли;
КонецПроцедуры
Процедура ЗаписатьЭлементФида(ЗаписьXML, Элемент)
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(Элемент);
ЗаписьXML.ЗаписатьНачалоЭлемента("item");
Для Каждого ПолеДанных Из Элемент Цикл
ТекущийКлюч = ПолеДанных.Ключ;
ТекущееЗначение = ПолеДанных.Значение;
Если ТипЗнч(ТекущееЗначение) = Тип("Дата") Тогда
ТекущееЗначение = OPI_Инструменты.ДатаRFC822(ТекущееЗначение);
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущееЗначение, Ложь);
КонецЕсли;
Если ТекущийКлюч = "guid" Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("guid");
ЗаписьXML.ЗаписатьАтрибут("isPermaLink", "false");
ЗаписьXML.ЗаписатьТекст(ТекущееЗначение);
ЗаписьXML.ЗаписатьКонецЭлемента();
Иначе
ЗаписатьЭлементXML(ЗаписьXML, ТекущийКлюч, ТекущееЗначение);
КонецЕсли;
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецПроцедуры
Функция ПрочитатьКаналRSS(ЧтениеXML)
Канал = Новый Структура;
Элементы = Новый Массив;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяЭлемента = ЧтениеXML.Имя;
Если ИмяЭлемента = "item" Тогда
Элемент = ПрочитатьЭлементRSS(ЧтениеXML);
Элементы.Добавить(Элемент);
Иначе
ЧтениеXML.Прочитать();
Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
Канал.Вставить(ИмяЭлемента, ЧтениеXML.Значение);
КонецЕсли;
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "channel" Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Канал.Вставить("items", Элементы);
Возврат Канал;
КонецФункции
Функция ПрочитатьЭлементRSS(ЧтениеXML)
Элемент = Новый Структура;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяЭлемента = ЧтениеXML.Имя;
ЧтениеXML.Прочитать();
Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
Элемент.Вставить(ИмяЭлемента, ЧтениеXML.Значение);
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "item" Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Возврат Элемент;
КонецФункции
Процедура ЗаписатьЭлементФидаAtom(ЗаписьXML, Элемент)
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(Элемент);
ЗаписьXML.ЗаписатьНачалоЭлемента("entry");
Для Каждого ПолеДанных Из Элемент Цикл
ТекущийКлюч = ПолеДанных.Ключ;
ТекущееЗначение = ПолеДанных.Значение;
Если ТипЗнч(ТекущееЗначение) = Тип("Дата") Тогда
ТекущееЗначение = OPI_Инструменты.ДатаISO8601(ТекущееЗначение);
Иначе
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущееЗначение, Ложь);
КонецЕсли;
Если ТекущийКлюч = "link" Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("link");
ЗаписьXML.ЗаписатьАтрибут("href", ТекущееЗначение);
ЗаписьXML.ЗаписатьАтрибут("rel" , "alternate");
ЗаписьXML.ЗаписатьКонецЭлемента();
ИначеЕсли ТекущийКлюч = "author" Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("author");
ЗаписатьЭлементXML(ЗаписьXML, "name" , ТекущееЗначение);
ЗаписьXML.ЗаписатьКонецЭлемента();
ИначеЕсли ТекущийКлюч = "content" Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("content");
ЗаписьXML.ЗаписатьАтрибут("type", "html");
ЗаписьXML.ЗаписатьТекст(ТекущееЗначение);
ЗаписьXML.ЗаписатьКонецЭлемента();
Иначе
ЗаписатьЭлементXML(ЗаписьXML, ТекущийКлюч, ТекущееЗначение);
КонецЕсли;
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента(); // entry
КонецПроцедуры
Функция ПрочитатьФидAtom(ЧтениеXML)
Фид = Новый Структура;
Элементы = Новый Массив;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяЭлемента = ЧтениеXML.Имя;
Если ИмяЭлемента = "entry" Тогда
Элемент = ПрочитатьЭлементAtom(ЧтениеXML);
Элементы.Добавить(Элемент);
ИначеЕсли ИмяЭлемента = "link" Тогда
Фид.Вставить("link", ЧтениеXML.ПолучитьАтрибут("href"));
Иначе
ЧтениеXML.Прочитать();
Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
Фид.Вставить(ИмяЭлемента, ЧтениеXML.Значение);
КонецЕсли;
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "feed" Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Фид.Вставить("entries", Элементы);
Возврат Фид;
КонецФункции
Функция ПрочитатьЭлементAtom(ЧтениеXML)
Элемент = Новый Структура;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ИмяЭлемента = ЧтениеXML.Имя;
Если ИмяЭлемента = "link" Тогда
Элемент.Вставить("link" , ЧтениеXML.ПолучитьАтрибут("href"));
ИначеЕсли ИмяЭлемента = "author" Тогда
ИмяАвтора = ПрочитатьАвтораAtom(ЧтениеXML);
Элемент.Вставить("author", ИмяАвтора);
Иначе
ЧтениеXML.Прочитать();
Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
Элемент.Вставить(ИмяЭлемента, ЧтениеXML.Значение);
КонецЕсли;
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "entry" Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Возврат Элемент;
КонецФункции
Функция ПрочитатьАвтораAtom(ЧтениеXML)
ИмяАвтора = "";
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеXML.Имя = "name" Тогда
ЧтениеXML.Прочитать();
Если ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
ИмяАвтора = ЧтениеXML.Значение;
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "author" Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Возврат ИмяАвтора;
КонецФункции
#КонецОбласти
#КонецОбласти
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="9bbe0d01-567a-49ca-ae09-d55148424279">
<name>OPI_ФункцииБиблиотекВызовСервера</name>
<synonym>
<key>ru</key>
<value>Функции библиотек (ОПИ, вызов сервера)</value>
</synonym>
<comment>Отдельные функции библиотек, которые невозможно реализовать на клиенте</comment>
<server>true</server>
<serverCall>true</serverCall>
</mdclass:CommonModule>
@@ -113,6 +113,7 @@
<commonModules>CommonModule.OPI_ПреобразованиеТипов</commonModules>
<commonModules>CommonModule.OPI_РасширенныйВызов</commonModules>
<commonModules>CommonModule.OPI_УниверсальныйСервер</commonModules>
<commonModules>CommonModule.OPI_ФункцииБиблиотекВызовСервера</commonModules>
<commonModules>CommonModule.OPI_BuildHash</commonModules>
<dataProcessors>DataProcessor.OPI_HTTPКлиент</dataProcessors>
</mdclass:Configuration>
@@ -122,55 +122,7 @@
КонецФункции
Функция ПолучитьСоответствиеРазделовТестирования() Экспорт
Разделы = Новый Структура;
Разделы.Вставить("Core" , 1);
Разделы.Вставить("Telegram" , 5);
Разделы.Вставить("VK" , 5);
Разделы.Вставить("Viber" , 5);
Разделы.Вставить("FTP" , 5);
Разделы.Вставить("SSH" , 5);
Разделы.Вставить("SFTP" , 5);
Разделы.Вставить("PostgreSQL" , 5);
Разделы.Вставить("MySQL" , 5);
Разделы.Вставить("MSSQL" , 5);
Разделы.Вставить("SQLite" , 5);
Разделы.Вставить("MongoDB" , 5);
Разделы.Вставить("RCON" , 5);
Разделы.Вставить("YandexDisk" , 5);
Разделы.Вставить("GoogleWorkspace", 2);
Разделы.Вставить("GoogleCalendar" , 5);
Разделы.Вставить("GoogleDrive" , 5);
Разделы.Вставить("GoogleSheets" , 5);
Разделы.Вставить("Notion" , 5);
Разделы.Вставить("Slack" , 5);
Разделы.Вставить("Airtable" , 5);
Разделы.Вставить("Dropbox" , 5);
Разделы.Вставить("Bitrix24" , 5);
Разделы.Вставить("VKTeams" , 5);
Разделы.Вставить("Neocities" , 5);
Разделы.Вставить("CDEK" , 5);
Разделы.Вставить("YandexMetrika" , 5);
Разделы.Вставить("S3" , 5);
Разделы.Вставить("TCP" , 5);
Разделы.Вставить("WebSocket" , 5);
Разделы.Вставить("ZeroMQ" , 5);
Разделы.Вставить("GreenAPI" , 5);
Разделы.Вставить("GreenMax" , 5);
Разделы.Вставить("Ollama" , 5);
Разделы.Вставить("HTTP" , 5);
Разделы.Вставить("OpenAI" , 5);
Разделы.Вставить("ReportPortal" , 5);
Разделы.Вставить("GRPC" , 5);
Разделы.Вставить("ClickHouse" , 5);
Разделы.Вставить("RSS" , 5);
Возврат Разделы;
КонецФункции
Функция ПолучитьТаблицуТестов(Знач МодульТестов = "") Экспорт
Функция ПолучитьТаблицуТестов(Знач МодульТестов = "", Знач КакМассив = Ложь) Экспорт
Телеграм = "Telegram";
ВКонтакте = "VK";
@@ -414,6 +366,10 @@
ТаблицаТестов = ТаблицаТестов.Скопировать(Отбор);
КонецЕсли;
Если КакМассив Тогда
ТаблицаТестов = OPI_Инструменты.ТаблицаЗначенийВМассив(ТаблицаТестов);
КонецЕсли;
Возврат ТаблицаТестов;
@@ -433,24 +389,15 @@
КонецФункции
Функция СформироватьТестыЯкс(Знач МодульТестов = "") Экспорт
Функция СформироватьТестыЯкс(Знач МодульТестов) Экспорт
Модуль = ПолучитьОбщийМодуль("ЮТТесты");
Разделы = ПолучитьСоответствиеРазделовТестирования();
ТаблицаТестов = ПолучитьТаблицуТестов(МодульТестов);
Для Каждого Раздел Из Разделы Цикл
ТекущийРаздел = Раздел.Ключ;
Отбор = Новый Структура("Раздел", ТекущийРаздел);
ТестыРаздела = ТаблицаТестов.НайтиСтроки(Отбор);
Набор = Модуль.ДобавитьТестовыйНабор(ТекущийРаздел);
Для Каждого Тест Из ТестыРаздела Цикл
Набор.ДобавитьСерверныйТест(Тест.Метод, Тест.Синоним);
КонецЦикла;
Набор = Модуль.ДобавитьТестовыйНабор(МодульТестов);
Для Каждого Тест Из ТаблицаТестов Цикл
Набор.ДобавитьСерверныйТест(Тест.Метод, Тест.Синоним);
КонецЦикла;
Возврат "";
@@ -473,22 +420,12 @@
Функция СформироватьТестыЯксCLI(Знач МодульТестов = "") Экспорт
Модуль = ПолучитьОбщийМодуль("ЮТТесты");
Разделы = ПолучитьСоответствиеРазделовТестирования();
ТаблицаТестов = ПолучитьТаблицуТестов(МодульТестов);
Для Каждого Раздел Из Разделы Цикл
ТекущийРаздел = Раздел.Ключ;
Отбор = Новый Структура("Раздел", ТекущийРаздел);
ТестыРаздела = ТаблицаТестов.НайтиСтроки(Отбор);
Набор = Модуль.ДобавитьТестовыйНабор(ТекущийРаздел + " (CLI)");
Для Каждого Тест Из ТестыРаздела Цикл
Набор.ДобавитьСерверныйТест(Тест.Метод, Тест.Синоним);
КонецЦикла;
Набор = Модуль.ДобавитьТестовыйНабор(МодульТестов + " (CLI)");
Для Каждого Тест Из ТаблицаТестов Цикл
Набор.ДобавитьТест(Тест.Метод, Тест.Синоним);
КонецЦикла;
Возврат "";
@@ -497,22 +434,11 @@
Функция СформироватьТестыАссертсCLI(Знач МодульТестов = "") Экспорт
МассивТестов = Новый Массив;
Разделы = ПолучитьСоответствиеРазделовТестирования();
ТаблицаТестов = ПолучитьТаблицуТестов(МодульТестов);
МассивТестов = Новый Массив;
Для Каждого Раздел Из Разделы Цикл
ТекущийРаздел = Раздел.Ключ;
Отбор = Новый Структура("Раздел", ТекущийРаздел);
ТестыРаздела = ТаблицаТестов.НайтиСтроки(Отбор);
Для Каждого Тест Из ТестыРаздела Цикл
МассивТестов.Добавить(Тест.Метод);
КонецЦикла;
Для Каждого Тест Из ТаблицаТестов Цикл
МассивТестов.Добавить(Тест.Метод);
КонецЦикла;
Возврат МассивТестов;
@@ -3,9 +3,8 @@
<name>OPI_ПолучениеДанныхТестов</name>
<synonym>
<key>ru</key>
<value>ПолучениеДанныхТестов</value>
<value>Получение данных тестов</value>
</synonym>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
<serverCall>true</serverCall>
</mdclass:CommonModule>
@@ -0,0 +1,84 @@
// MIT License
// Copyright (c) 2023-2026 Anton Tsitavets
// 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.
// https://github.com/Bayselonarrend/OpenIntegrations
// BSLLS:LatinAndCyrillicSymbolInWord-off
// BSLLS:IncorrectLineBreak-off
// BSLLS:UsingHardcodePath-off
// BSLLS:Typo-off
// BSLLS:DeprecatedMessage-off
// BSLLS:UsingServiceTag-off
// BSLLS:ExecuteExternalCodeInCommonModule-off
// BSLLS:DuplicateStringLiteral-off
// BSLLS:MagicNumber-off
// BSLLS:UsingHardcodeNetworkAddress-off
// BSLLS:UsingSynchronousCalls-off
// BSLLS:UnusedLocalMethod-off
// BSLLS:MissingTemporaryFileDeletion-off
// BSLLS:MethodSize-off
// BSLLS:IfElseIfEndsWithElse-off
// BSLLS:CognitiveComplexity-off
// BSLLS:NumberOfOptionalParams-off
// BSLLS:CommentedCode-off
// BSLLS:CyclomaticComplexity-off
// BSLLS:LineLength-off
// BSLLS:NestedStatements-off
// BSLLS:IfElseDuplicatedCodeBlock-off
//@skip-check use-non-recommended-method
//@skip-check module-structure-top-region
//@skip-check module-structure-method-in-regions
//@skip-check undefined-function-or-procedure
//@skip-check wrong-string-literal-content
//@skip-check module-unused-method
//@skip-check missing-temporary-file-deletion
//@skip-check method-too-many-params
//@skip-check bsl-legacy-check-for-each-statetement-collection
//@skip-check bsl-legacy-check-string-literal
//@skip-check bsl-legacy-check-expression-type
//@skip-check undefined-variable
// #Использовать "../../../../tools/main"
// #Использовать "../../../../tools/http"
// #Использовать "../../../../api/openai"
// #Использовать "../../../../api/rportal"
// #Использовать asserts
#Область СлужебныйПрограммныйИнтерфейс
Функция СформироватьТестыЯкс(Знач МодульТестов) Экспорт
ТаблицаТестов = OPI_ПолучениеДанныхТестов.ПолучитьТаблицуТестов(МодульТестов, Истина);
Набор = ЮТТесты.ДобавитьТестовыйНабор(МодульТестов);
Для Каждого Тест Из ТаблицаТестов Цикл
Набор.ДобавитьКлиентскийТест(Тест.Метод, Тест.Синоним);
Набор.ДобавитьСерверныйТест(Тест.Метод, Тест.Синоним);
КонецЦикла;
Возврат "";
КонецФункции
#КонецОбласти
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="f01aa0bc-1c16-4217-a6a5-6b142084d945">
<name>OPI_СписокТестовКлиентСервер</name>
<synonym>
<key>ru</key>
<value>Генерация списка тестов YaxUnit (клиент/сервер)</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>
@@ -76,7 +76,7 @@
Процедура ИсполняемыеСценарии() Экспорт
OPI_ПолучениеДанныхТестов.СформироватьТестыЯкс("Bitrix24");
OPI_СписокТестовКлиентСервер.СформироватьТестыЯкс("Bitrix24");
КонецПроцедуры
@@ -4386,8 +4386,8 @@
СтруктураСобытия.Вставить("type" , "user");
СтруктураСобытия.Вставить("ownerId" , 1);
СтруктураСобытия.Вставить("from" , XMLСтрока(Завтра));
СтруктураСобытия.Вставить("to" , XMLСтрока(Завтра + Час));
СтруктураСобытия.Вставить("from" , (Завтра));
СтруктураСобытия.Вставить("to" , (Завтра + Час));
СтруктураСобытия.Вставить("section" , IDКалендаря);
СтруктураСобытия.Вставить("name" , "Новое событие");
СтруктураСобытия.Вставить("skip_time" , "N");
@@ -4410,7 +4410,7 @@
МассивДней.Добавить("MO");
СтруктураПовторяемости.Вставить("BYDAY", МассивДней);
СтруктураПовторяемости.Вставить("UNTIL", XMLСтрока(Завтра + Час * 24 * 10));
СтруктураПовторяемости.Вставить("UNTIL", (Завтра + Час * 24 * 10));
СтруктураСобытия.Вставить("rrule" , СтруктураПовторяемости);
СтруктураСобытия.Вставить("is_meeting", "Y");
@@ -5,6 +5,7 @@
<key>ru</key>
<value>Bitrix24</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
+1 -1
View File
@@ -76,7 +76,7 @@
Процедура ИсполняемыеСценарии() Экспорт
OPI_ПолучениеДанныхТестов.СформироватьТестыЯкс("CDEK");
OPI_СписокТестовКлиентСервер.СформироватьТестыЯкс("CDEK");
КонецПроцедуры
@@ -5,6 +5,7 @@
<key>ru</key>
<value>CDEK</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -76,7 +76,7 @@
Процедура ИсполняемыеСценарии() Экспорт
OPI_ПолучениеДанныхТестов.СформироватьТестыЯкс("ClickHouse");
OPI_СписокТестовКлиентСервер.СформироватьТестыЯкс("ClickHouse");
КонецПроцедуры
@@ -5,6 +5,7 @@
<key>ru</key>
<value>ClickHouse</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
+1 -1
View File
@@ -71,7 +71,7 @@
Процедура ИсполняемыеСценарии() Экспорт
OPI_ПолучениеДанныхТестов.СформироватьТестыЯкс("Core");
OPI_СписокТестовКлиентСервер.СформироватьТестыЯкс("Core");
КонецПроцедуры
@@ -5,6 +5,7 @@
<key>ru</key>
<value>Core tests</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
+1 -1
View File
@@ -76,7 +76,7 @@
Процедура ИсполняемыеСценарии() Экспорт
OPI_ПолучениеДанныхТестов.СформироватьТестыЯкс("Dropbox");
OPI_СписокТестовКлиентСервер.СформироватьТестыЯкс("Dropbox");
КонецПроцедуры
@@ -5,6 +5,7 @@
<key>ru</key>
<value>Dropbox</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
+1 -1
View File
@@ -76,7 +76,7 @@
Процедура ИсполняемыеСценарии() Экспорт
OPI_ПолучениеДанныхТестов.СформироватьТестыЯкс("FTP");
OPI_СписокТестовКлиентСервер.СформироватьТестыЯкс("FTP");
КонецПроцедуры
@@ -5,6 +5,7 @@
<key>ru</key>
<value>FTP</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
@@ -20,6 +20,7 @@
<configurationExtensionPurpose>Customization</configurationExtensionPurpose>
<scriptVariant>Russian</scriptVariant>
<commonModules>CommonModule.OPI_ПолучениеДанныхТестов</commonModules>
<commonModules>CommonModule.OPI_СписокТестовКлиентСервер</commonModules>
<commonModules>CommonModule.OPIt_Airtable</commonModules>
<commonModules>CommonModule.OPIt_Bitrix24</commonModules>
<commonModules>CommonModule.OPIt_CDEK</commonModules>