Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functions for ftp #108

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bsl-language-server.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"userWordsToIgnore": "пбп"
},
"LatinAndCyrillicSymbolInWord": {
"excludeWords": "ЧтениеXML, ЧтениеJSON, ЗаписьXML, ЗаписьJSON, ComОбъект, ФабрикаXDTO, ОбъектXDTO, СоединениеFTP, HTTPСоединение, HTTPЗапрос, HTTPСервисОтвет, SMSСообщение, WSПрокси, ИмяCOMОбъекта, ЭтоWindowsКлиент",
"excludeWords": "ЧтениеXML, ЧтениеJSON, ЗаписьXML, ЗаписьJSON, ComОбъект, ФабрикаXDTO, ОбъектXDTO, СоединениеFTP, HTTPСоединение, HTTPЗапрос, HTTPСервисОтвет, SMSСообщение, WSПрокси, ИмяCOMОбъекта, ЭтоWindowsКлиент, ВыполнитьПодключениеКFTPСерверуДляИнтеграционногоПотока",
"allowTrailingPartsInAnotherLanguage": true
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,21 @@
ЭлементНаследования = Справочники.пбп_ТипыИнтеграций
.ПолучитьПредопределенныйЭлементНаследованияНастроекТипаИнтеграции(РеквизитыОбъекта.ТипИнтеграции);
Если ЭлементНаследования = Справочники.пбп_ТипыИнтеграций.Каталог
Или ЭлементНаследования = Справочники.пбп_ТипыИнтеграций.FTPРесурсы
Или ЭлементНаследования = Справочники.пбп_ТипыИнтеграций.ПочтовыйКлиент Тогда
УстановитьВидимостьЭлементовДляТипаФайловыеОбмены();

пбп_ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
Элементы, "ПользовательскаяФункция", УстанавливаемоеСвойство,
Элементы, ПользовательскаяФункция, УстанавливаемоеСвойство,
РеквизитыОбъекта.ИспользоватьПользовательскиеФункции);
ИначеЕсли ЭлементНаследования = Справочники.пбп_ТипыИнтеграций.FTPРесурсы Тогда
Элементы.ТочкаВхода.Заголовок = НСтр("ru = 'Путь к каталогу на сервере'");

пбп_ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
Элементы, "ТочкаВхода", УстанавливаемоеСвойство, Истина);
пбп_ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
Элементы, "ПараметрыВхода", УстанавливаемоеСвойство, Ложь);
пбп_ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
Элементы, ПользовательскаяФункция, УстанавливаемоеСвойство,
РеквизитыОбъекта.ИспользоватьПользовательскиеФункции);
ИначеЕсли ЭлементНаследования = Справочники.пбп_ТипыИнтеграций.COM Тогда
Элементы.ТочкаВхода.Заголовок = НСтр("ru = 'Функция / запрос'");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@
пбп_ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
Элементы, СписокНастроекСтрока, УстанавливаемоеСвойство, Ложь);
ИначеЕсли ЭлементНаследования = Справочники.пбп_ТипыИнтеграций.FTPРесурсы Тогда
Элементы.СтрокаПодключения.Заголовок = НСтр("ru = 'Путь к каталогу'");
Элементы.СтрокаПодключения.Заголовок = НСтр("ru = 'Адрес сервера'");

УстановитьВидимостьЭлементовДляТипаФайловыеОбмены();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,236 @@

#КонецОбласти // REST

#Область FTP

// Параметры сообщения FTP
//
// Возвращаемое значение:
// Структура - содержит ключи для описания сообщения обмена
//
Функция ПараметрыСообщенияFTP() Экспорт

Результат = Новый Структура("Путь, ИмяФайла, Расширение, ДвоичныеДанные");
Возврат Результат;

КонецФункции

// Получить структуру параметров подключения к серверу FTP / SFTP
//
// Параметры:
// НастройкаИнтеграции - СправочникСсылка.пбп_НастройкиИнтеграции - настройка интеграции,
// для которой необходимо получить параметры
//
// Возвращаемое значение:
// Структура - Параметры соединения с сервером из настроек интеграции и безопасного хранилища
//
Функция ПолучитьПараметрыПодключенияFTPSFTP(НастройкаИнтеграции) Экспорт

СтруктураНастроек = ПолучитьСтруктуруНастроекИнтеграции(НастройкаИнтеграции);

ПараметрыСоединения = ПараметрыСоединенияFTP();
ПараметрыСоединения.Адрес = СтруктураНастроек.СтрокаПодключения;
ПараметрыСоединения.Порт = Число(СтруктураНастроек.Порт);

Если СтруктураНастроек.Свойство("Логин") Тогда
ПараметрыСоединения.ИмяПользователя = СтруктураНастроек.Логин.Значение;
Иначе
ПараметрыСоединения.ИмяПользователя = "";
КонецЕсли;

Если СтруктураНастроек.Свойство("Пароль") Тогда
ПараметрыСоединения.Пароль = СтруктураНастроек.Пароль.Значение;
Иначе
ПараметрыСоединения.Пароль = "";
КонецЕсли;

Возврат ПараметрыСоединения;

КонецФункции

// Выполнить подключение к FTP-серверу по настройке интеграции
//
// Параметры:
// ИнтеграционныйПоток - СправочникСсылка.пбп_ИнтеграционныеПотоки - интеграционный поток,
// для которого выполняется подключение к FTP-серверу
//
// Возвращаемое значение:
// FTPСоединение, Строка - возвращает FTP-соединение по указанным настройкам, либо строку с описанием ошибки
//
Функция ВыполнитьПодключениеКFTPСерверуДляИнтеграционногоПотока(ИнтеграционныйПоток) Экспорт
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid mixing Latin and Cyrillic characters in identifiers

The function name ВыполнитьПодключениеКFTPСерверуДляИнтеграционногоПотока mixes Latin letters ("FTP") with Cyrillic letters. This can lead to confusion and potential errors. Consider using consistent character sets in identifiers.

You can rename the function to use only Cyrillic characters:

- Функция ВыполнитьПодключениеКFTPСерверуДляИнтеграционногоПотока(ИнтеграционныйПоток) Экспорт
+ Функция ВыполнитьПодключениеКФТПСерверуДляИнтеграционногоПотока(ИнтеграционныйПоток) Экспорт
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Функция ВыполнитьПодключениеКFTPСерверуДляИнтеграционногоПотока(ИнтеграционныйПоток) Экспорт
Функция ВыполнитьПодключениеКФТПСерверуДляИнтеграционногоПотока(ИнтеграционныйПоток) Экспорт
Tools
GitHub Check: 1C: Project SubSystems Library Sonarqube Results

[warning] 532-532: src/cf/CommonModules/пбп_ИнтеграцииСервер/Ext/Module.bsl#L532
Нельзя использовать латинские и кириллические символы в одном идентификаторе


СтруктураРеквизитов = пбп_ОбщегоНазначенияСервер.ЗначенияРеквизитовОбъекта(
ИнтеграционныйПоток, "НастройкаИнтеграции, ТочкаВхода");

ПараметрыСоединения = ПолучитьПараметрыПодключенияFTPSFTP(СтруктураРеквизитов.НастройкаИнтеграции);

Порт = ?(Не ЗначениеЗаполнено(ПараметрыСоединения.Порт), 21, ПараметрыСоединения.Порт);

Таймаут = 60;

Попытка
FTPСоединение = Новый FTPСоединение(ПараметрыСоединения.Адрес,
Порт, ПараметрыСоединения.Логин, ПараметрыСоединения.Пароль, , , Таймаут);
Исключение
ЗаголовокОшибки = "Не удалось установить соединение с FTP-сервером. Подробно: ";
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
ЗаголовокОшибки, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);

Возврат СообщениеОбОшибке;
КонецПопытки;

КаталогИсходящие = СтруктураРеквизитов.ТочкаВхода;
КаталогИсходящие = СокрЛП(КаталогИсходящие);
Если Лев(КаталогИсходящие, 1) <> "/" Тогда
КаталогИсходящие = "/" + КаталогИсходящие;
КонецЕсли;

Если FTPСоединение.ТекущийКаталог() <> КаталогИсходящие Тогда
Попытка
FTPСоединение.УстановитьТекущийКаталог(КаталогИсходящие);
Исключение
ЗаголовокОшибки = "Не удалось установить каталог для исходящих на FTP-сервере. Подробно: ";
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
ЗаголовокОшибки, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);

Возврат СообщениеОбОшибке;
КонецПопытки;
КонецЕсли;

Возврат FTPСоединение;

КонецФункции

// Отправить сообщение FTP
//
// Параметры:
// ПодключениеКFTP - FTPСоединение- текущее соединение с FTP-сервером
// ПараметрыСообщения - Структура - параметры сообщения (см. ПараметрыСообщенияFTP)
//
// Возвращаемое значение:
// Строка - описание ошибки
//
Функция ОтправитьСообщениеFTP(ПодключениеКFTP, ПараметрыСообщения) Экспорт

ЗаголовокОшибки = "Файл не был создан. Подробно: ";
СообщениеОбОшибке = "";

Попытка
Если ПустаяСтрока(ПараметрыСообщения.Путь) Тогда
// BSLLS:MissingTemporaryFileDeletion-off
// Необходимо пропустить проверку, так как файл удаляется позже
НовыйФайл = ПолучитьИмяВременногоФайла(ПараметрыСообщения.Расширение);
// BSLLS:MissingTemporaryFileDeletion-on
ПараметрыСообщения.Данные.Записать(НовыйФайл);
ПараметрыСообщения.Путь = НовыйФайл;
КонецЕсли;

НовоеИмяФайлаНаСервере = СтрШаблон("%1.%2", ПараметрыСообщения.ИмяФайла, ПараметрыСообщения.Расширение);
ПодключениеКFTP.Записать(ПараметрыСообщения.Путь, НовоеИмяФайлаНаСервере);

// Повторно проверяем наличие записанного файла
КаталогИсходящие = ПодключениеКFTP.ТекущийКаталог();

Если Не ПроверитьФайлЕстьНаFTP(ПодключениеКFTP, НовоеИмяФайлаНаСервере, КаталогИсходящие) Тогда
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
ЗаголовокОшибки, "подробности уточните у администратора системы");
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
КонецЕсли;

УдалитьФайлы(НовыйФайл);

Check warning on line 614 in src/cf/CommonModules/пбп_ИнтеграцииСервер/Ext/Module.bsl

View check run for this annotation

sonar.openbsl.ru qa-bot / 1C: Project SubSystems Library Sonarqube Results

src/cf/CommonModules/пбп_ИнтеграцииСервер/Ext/Module.bsl#L614

Вместо синхронного метода `УдалитьФайлы` необходимо использовать `НачатьУдалениеФайлов`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use asynchronous file deletion to prevent blocking operations

Consider using НачатьУдалениеФайлов instead of the synchronous method УдалитьФайлы to delete files asynchronously. This will prevent blocking the main thread and improve performance.

Apply this diff to make the change:

-        УдалитьФайлы(НовыйФайл);
+        НачатьУдалениеФайлов(НовыйФайл);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
УдалитьФайлы(НовыйФайл);
НачатьУдалениеФайлов(НовыйФайл);
🧰 Tools
🪛 GitHub Check: 1C: Project SubSystems Library Sonarqube Results

[warning] 614-614: src/cf/CommonModules/пбп_ИнтеграцииСервер/Ext/Module.bsl#L614
Вместо синхронного метода УдалитьФайлы необходимо использовать НачатьУдалениеФайлов

Исключение
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
ЗаголовокОшибки, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
КонецПопытки;
Comment on lines +593 to +619
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure temporary files are deleted after exceptions to prevent resource leaks

If an exception occurs after creating the temporary file НовыйФайл, it may not be deleted, potentially leading to resource leaks. To ensure the temporary file is always cleaned up, add deletion of the file in the exception handling block.

Apply this diff to ensure the temporary file is deleted even when an exception occurs:

     УдалитьФайлы(НовыйФайл);
 Исключение
+    Если ФайлСуществует(НовыйФайл) Тогда
+        УдалитьФайлы(НовыйФайл);
+    КонецЕсли;
     ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
         ЗаголовокОшибки, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
     СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
 КонецПопытки;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Если ПустаяСтрока(ПараметрыСообщения.Путь) Тогда
// BSLLS:MissingTemporaryFileDeletion-off
// Необходимо пропустить проверку, так как файл удаляется позже
НовыйФайл = ПолучитьИмяВременногоФайла(ПараметрыСообщения.Расширение);
// BSLLS:MissingTemporaryFileDeletion-on
ПараметрыСообщения.Данные.Записать(НовыйФайл);
ПараметрыСообщения.Путь = НовыйФайл;
КонецЕсли;
НовоеИмяФайлаНаСервере = СтрШаблон("%1.%2", ПараметрыСообщения.ИмяФайла, ПараметрыСообщения.Расширение);
ПодключениеКFTP.Записать(ПараметрыСообщения.Путь, НовоеИмяФайлаНаСервере);
// Повторно проверяем наличие записанного файла
КаталогИсходящие = ПодключениеКFTP.ТекущийКаталог();
Если Не ПроверитьФайлЕстьНаFTP(ПодключениеКFTP, НовоеИмяФайлаНаСервере, КаталогИсходящие) Тогда
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
ЗаголовокОшибки, "подробности уточните у администратора системы");
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
КонецЕсли;
УдалитьФайлы(НовыйФайл);
Исключение
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
ЗаголовокОшибки, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
КонецПопытки;
Если ПустаяСтрока(ПараметрыСообщения.Путь) Тогда
// BSLLS:MissingTemporaryFileDeletion-off
// Необходимо пропустить проверку, так как файл удаляется позже
НовыйФайл = ПолучитьИмяВременногоФайла(ПараметрыСообщения.Расширение);
// BSLLS:MissingTemporaryFileDeletion-on
ПараметрыСообщения.Данные.Записать(НовыйФайл);
ПараметрыСообщения.Путь = НовыйФайл;
КонецЕсли;
НовоеИмяФайлаНаСервере = СтрШаблон("%1.%2", ПараметрыСообщения.ИмяФайла, ПараметрыСообщения.Расширение);
ПодключениеКFTP.Записать(ПараметрыСообщения.Путь, НовоеИмяФайлаНаСервере);
// Повторно проверяем наличие записанного файла
КаталогИсходящие = ПодключениеКFTP.ТекущийКаталог();
Если Не ПроверитьФайлЕстьНаFTP(ПодключениеКFTP, НовоеИмяФайлаНаСервере, КаталогИсходящие) Тогда
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
ЗаголовокОшибки, "подробности уточните у администратора системы");
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
КонецЕсли;
УдалитьФайлы(НовыйФайл);
Исключение
Если ФайлСуществует(НовыйФайл) Тогда
УдалитьФайлы(НовыйФайл);
КонецЕсли;
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
ЗаголовокОшибки, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
КонецПопытки;
🧰 Tools
🪛 GitHub Check: 1C: Project SubSystems Library Sonarqube Results

[warning] 614-614: src/cf/CommonModules/пбп_ИнтеграцииСервер/Ext/Module.bsl#L614
Вместо синхронного метода УдалитьФайлы необходимо использовать НачатьУдалениеФайлов


Возврат СообщениеОбОшибке;

КонецФункции

// Прочитать сообщение FTP
//
// Параметры:
// ПодключениеКFTP - FTPСоединение- текущее соединение с FTP-сервером
// ПараметрыСообщения - Структура - параметры сообщения (см. ПараметрыСообщенияFTP)
//
// Возвращаемое значение:
// Строка - описание ошибки
//
Функция ПрочитатьСообщениеFTP(ПодключениеКFTP, ПараметрыСообщения) Экспорт

ЗаголовокОшибки = "Файл не был получен. Подробно: ";
СообщениеОбОшибке = "";

Попытка
ИмяФайлаНаСервере = СтрШаблон("%1.%2", ПараметрыСообщения.ИмяФайла, ПараметрыСообщения.Расширение);

// Проверяем наличие получаемого файла
КаталогВходящие = ПодключениеКFTP.ТекущийКаталог();

Если Не ПроверитьФайлЕстьНаFTP(ПодключениеКFTP, ИмяФайлаНаСервере, КаталогВходящие) Тогда
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
ЗаголовокОшибки, "искомый файл отсутствует на FTP-сервере");
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
Возврат СообщениеОбОшибке;
КонецЕсли;

Если ПустаяСтрока(ПараметрыСообщения.Путь) Тогда
// BSLLS:MissingTemporaryFileDeletion-off
// Необходимо пропустить проверку, так как полученный файл должен храниться до его обработки
ПараметрыСообщения.Путь = ПолучитьИмяВременногоФайла(ПараметрыСообщения.Расширение);
// BSLLS:MissingTemporaryFileDeletion-on
КонецЕсли;

ПодключениеКFTP.Получить(ИмяФайлаНаСервере, ПараметрыСообщения.Путь);
Исключение
ПолноеОписаниеОшибки = СтрШаблон("ru = '%1%2'",
ЗаголовокОшибки, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
СообщениеОбОшибке = НСтр(ПолноеОписаниеОшибки);
КонецПопытки;

Возврат СообщениеОбОшибке;

КонецФункции

// Проверяет наличие файла на FTP
//
// Параметры:
// FTPСоединение - FTPСоединение - текущее соединение с FTP-сервером
// ИмяФайла - Строка - имя искомого файла
// КаталогПоиска - Строка - каталог поиска файла на FTP-сервере
// ПоТочномуСовпадению - Булево - если Истина, то поиск на равенство, если Ложь - по вхождению
//
// Возвращаемое значение:
// Булево - файл найден
//
Функция ПроверитьФайлЕстьНаFTP(FTPСоединение, ИмяФайла, КаталогПоиска = "/", ПоТочномуСовпадению = Истина) Экспорт

Результат = Ложь;

ФайлыНаРесурсе = FTPСоединение.НайтиФайлы(КаталогПоиска);
Для Каждого ФайлНаСервере Из ФайлыНаРесурсе Цикл
Если ПоТочномуСовпадению Тогда
Если ВРег(ФайлНаСервере) = ВРег(ИмяФайла) Тогда
Результат = Истина;
Прервать;
КонецЕсли;
Иначе
Если СтрНайти(ВРег(ФайлНаСервере), ВРег(ИмяФайла), НаправлениеПоиска.СНачала) > 0 Тогда
Результат = Истина;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Comment on lines +685 to +698
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Optimize file existence check to improve performance

Currently, the method retrieves the entire list of files from the directory and iterates over them to find the desired file. This approach can lead to performance issues if the directory contains a large number of files.

Consider using a method that checks for the existence of a specific file directly, if available in the FTPСоединение class, such as a СуществуетФайл method. This would improve performance by avoiding unnecessary retrieval and iteration over all files.


Comment on lines +685 to +699
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optimize file search on FTP server

The method ПроверитьФайлЕстьНаFTP retrieves the entire list of files in the directory and iterates over them to find the desired file. This may lead to performance issues if the directory contains a large number of files.

Consider using a method that checks for the existence of a file directly, if available, or optimizes the search to prevent performance degradation.

Возврат Результат;

КонецФункции

#КонецОбласти // FTP

#КонецОбласти

#Область СлужебныеПроцедурыИФункции
Expand Down Expand Up @@ -560,4 +790,11 @@

КонецФункции

Функция ПараметрыСоединенияFTP()

Результат = Новый Структура("Адрес, Порт, Логин, Пароль, КаталогВходящие, КаталогИсходящие");
Возврат Результат;

КонецФункции

#КонецОбласти // СлужебныеПроцедурыИФункции
Loading
Loading