diff --git a/OPI/src/CommonModules/OPI_YandexDisk/Module.bsl b/OPI/src/CommonModules/OPI_YandexDisk/Module.bsl index eaa5096786..d36006b39a 100644 --- a/OPI/src/CommonModules/OPI_YandexDisk/Module.bsl +++ b/OPI/src/CommonModules/OPI_YandexDisk/Module.bsl @@ -90,17 +90,19 @@ // Токен - Строка - Токен // Оригинал - Строка - Путь к оригинальному файлу или каталогу // Путь - Строка - Путь-назначение для копии +// Перезаписывать - Булево - Перезаписывать если файл с таким именем уже существует // // Возвращаемое значение: // Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex -Функция СоздатьКопиюОбъекта(Знач Токен, Знач Оригинал, Знач Путь) Экспорт +Функция СоздатьКопиюОбъекта(Знач Токен, Знач Оригинал, Знач Путь, Знач Перезаписывать = Ложь) Экспорт Заголовки = ЗаголовокАвторизации(Токен); URL = "https://cloud-api.yandex.net/v1/disk/resources/copy"; Параметры = Новый Структура; - Параметры.Вставить("from", Оригинал); - Параметры.Вставить("path", Путь); + Параметры.Вставить("from" , Оригинал); + Параметры.Вставить("path" , Путь); + Параметры.Вставить("overwrite" , Перезаписывать); Параметры = OPI_Инструменты.ПараметрыЗапросаВСтроку(Параметры); Ответ = OPI_Инструменты.Post(URL + Параметры, , Заголовки, Ложь); @@ -144,6 +146,7 @@ // // Возвращаемое значение: // Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex +//@skip-check method-too-many-params Функция ПолучитьСписокФайлов(Знач Токен , Знач Количество = 0 , Знач СмещениеОтНачала = 0 @@ -184,17 +187,19 @@ // Токен - Строка - Токен // Оригинал - Строка - Путь к оригинальному файлу или папке // Путь - Строка - Путь-назначение для перемещения +// Перезаписывать - Булево - Перезаписывать если файл с таким именем уже существует // // Возвращаемое значение: // Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex -Функция ПереместитьОбъект(Знач Токен, Знач Оригинал, Знач Путь) Экспорт +Функция ПереместитьОбъект(Знач Токен, Знач Оригинал, Знач Путь, Знач Перезаписывать = Ложь) Экспорт Заголовки = ЗаголовокАвторизации(Токен); URL = "https://cloud-api.yandex.net/v1/disk/resources/move"; Параметры = Новый Структура; - Параметры.Вставить("from", Оригинал); - Параметры.Вставить("path", Путь); + Параметры.Вставить("from" , Оригинал); + Параметры.Вставить("path" , Путь); + Параметры.Вставить("overwrite" , Перезаписывать); Параметры = OPI_Инструменты.ПараметрыЗапросаВСтроку(Параметры); Ответ = OPI_Инструменты.Post(URL + Параметры, , Заголовки, Ложь); @@ -203,6 +208,38 @@ КонецФункции +// Получить ссылку загрузки файла. +// +// Параметры: +// Токен - Строка - Токен +// Путь - Строка - Путь для сохранение файла на Диске +// Файл - Строка,ДвоичныеДанные - Файл для загрузки +// Перезаписывать - Булево - Перезаписывать, если файл с таким именем уже существует +// +// Возвращаемое значение: +// Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex +Функция ЗагрузитьФайл(Знач Токен, Знач Путь, Знач Файл, Знач Перезаписывать = Ложь) Экспорт + + Заголовки = ЗаголовокАвторизации(Токен); + + Если Не ТипЗнч(Файл) = Тип("ДвоичныеДанные") Тогда + Файл = Новый ДвоичныеДанные(Файл); + КонецЕсли; + + Файл = Новый Структура("file", Файл); + + Параметры = Новый Структура; + Параметры.Вставить("path" , Путь); + Параметры.Вставить("overwrite" , Перезаписывать); + + Ответ = OPI_Инструменты.Get("https://cloud-api.yandex.net/v1/disk/resources/upload", Параметры, Заголовки); + URL = Ответ["href"]; + Ответ = OPI_Инструменты.PutMultipart(URL, , Файл, "multipart", Заголовки); + + Возврат Ответ; + +КонецФункции + #КонецОбласти #Область УправлениеПубличнымДоступом diff --git a/OPI/src/CommonModules/OPI_Инструменты/Module.bsl b/OPI/src/CommonModules/OPI_Инструменты/Module.bsl index 75dca99b03..6565f741a6 100644 --- a/OPI/src/CommonModules/OPI_Инструменты/Module.bsl +++ b/OPI/src/CommonModules/OPI_Инструменты/Module.bsl @@ -49,112 +49,25 @@ Возврат ВыполнитьЗапросСТелом(URL, "PUT", Параметры, ДопЗаголовки, JSON); КонецФункции -// BSLLS:CognitiveComplexity-off +Функция PostMultipart(Знач URL + , Знач Параметры + , Знач Файлы = "" + , Знач ТипКонтента = "image/jpeg" + , Знач ДопЗаголовки = "") Экспорт -Функция PostMultipart(Знач URL, Знач Параметры, Знач Файлы = "", Знач ТипКонтента = "image/jpeg", - Знач ДопЗаголовки = "") Экспорт - - Если Не ЗначениеЗаполнено(Параметры) Тогда - Параметры = Новый Структура; - КонецЕсли; - - Если Не ЗначениеЗаполнено(Файлы) Тогда - Файлы = Новый Соответствие; - КонецЕсли; - - ЗаменаТочки = "___"; - GZip = "gzip"; - Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", ""); - СтруктураURL = РазбитьURL(URL); - - Заголовки = Новый Соответствие; - Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary); - Заголовки.Вставить("Accept-Encoding", GZip); - Заголовки.Вставить("Accept", "*/*"); - Заголовки.Вставить("Connection", "keep-alive"); - - Если ТипЗнч(ДопЗаголовки) = Тип("Соответствие") Тогда - - Для Каждого Заголовок Из ДопЗаголовки Цикл - Заголовки.Вставить(Заголовок.Ключ, Заголовок.Значение); - КонецЦикла; - - КонецЕсли; - - Соединение = Новый HTTPСоединение(СтруктураURL["Сервер"], 443, , , , 300, Новый ЗащищенноеСоединениеOpenSSL); - НовыйЗапрос = Новый HTTPЗапрос(СтруктураURL["Адрес"], Заголовки); - ТелоЗапроса = НовыйЗапрос.ПолучитьТелоКакПоток(); - ЗаписьТекста = Новый ЗаписьДанных(ТелоЗапроса, КодировкаТекста.UTF8, ПорядокБайтов.LittleEndian, "", "", Ложь); - - РазделительСтрок = Символы.ВК + Символы.ПС; - - Для Каждого Параметр Из Параметры Цикл - - ЗаписьТекста.ЗаписатьСтроку("--" + boundary + РазделительСтрок); - ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""" + Параметр.Ключ + """"); - ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); - ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); - - Если ТипЗнч(Параметр.Значение) = Тип("Строка") Тогда - ЗаписьТекста.ЗаписатьСтроку(Параметр.Значение); - Иначе - ЗаписьТекста.Записать(Параметр.Значение); - КонецЕсли; - - ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); - - КонецЦикла; - - Счетчик = 0; - Для Каждого Файл Из Файлы Цикл - - ПутьФайл = СтрЗаменить(Файл.Ключ, ЗаменаТочки, "."); - - Если ТипКонтента = "image/jpeg" Тогда - ИмяФайлаОтправки = "photo"; - Иначе - ИмяФайлаОтправки = СтрЗаменить(Файл.Ключ, ЗаменаТочки, "."); - ИмяФайлаОтправки = Лев(ИмяФайлаОтправки, СтрНайти(ИмяФайлаОтправки, ".") - 1); - ИмяФайлаОтправки = ?(ЗначениеЗаполнено(ИмяФайлаОтправки), ИмяФайлаОтправки, СтрЗаменить(Файл.Ключ, - ЗаменаТочки, ".")); - КонецЕсли; - - ЗаписьТекста.ЗаписатьСтроку("--" + boundary + РазделительСтрок); - ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""" - + ИмяФайлаОтправки - + """; filename=""" - + ПутьФайл - + """"); - ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); - ЗаписьТекста.ЗаписатьСтроку("Content-Type: " + ТипКонтента); - ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); - ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); - ЗаписьТекста.Записать(Файл.Значение); - ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); - - Счетчик = Счетчик + 1; - - КонецЦикла; - - ЗаписьТекста.ЗаписатьСтроку("--" + boundary + "--" + РазделительСтрок); - - ЗаписьТекста.Закрыть(); - - Ответ = Соединение.ВызватьHTTPМетод("POST", НовыйЗапрос); - - НужнаРаспаковка = Ответ.Заголовки.Получить("Content-Encoding") = GZip Или Ответ.Заголовки.Получить( - "content-encoding") = GZip; - - Если НужнаРаспаковка Тогда - Ответ = РаспаковатьОтвет(Ответ); - КонецЕсли; - - Возврат ?(ТипЗнч(Ответ) = Тип("ДвоичныеДанные"), JsonВСтруктуру(Ответ), JsonВСтруктуру( - Ответ.ПолучитьТелоКакДвоичныеДанные())); + Возврат ВыполнитьЗапросМультипарт(URL, "POST", Параметры, Файлы, ТипКонтента, ДопЗаголовки); КонецФункции -// BSLLS:CognitiveComplexity-on +Функция PutMultipart(Знач URL + , Знач Параметры + , Знач Файлы = "" + , Знач ТипКонтента = "image/jpeg" + , Знач ДопЗаголовки = "") Экспорт + + Возврат ВыполнитьЗапросМультипарт(URL, "PUT", Параметры, Файлы, ТипКонтента, ДопЗаголовки); + +КонецФункции Функция ПараметрыЗапросаВСоответствие(Знач СтрокаПараметров) Экспорт @@ -224,6 +137,8 @@ URL = СтрЗаменить(URL, "https://", ""); URL = СтрЗаменить(URL, "http://", ""); URL = СтрЗаменить(URL, "www.", ""); + URL = СтрЗаменить(URL, ":443", ""); + СтруктураВозврата = Новый Структура; СтруктураВозврата.Вставить("Сервер", Лев(URL, СтрНайти(URL, "/", НаправлениеПоиска.СНачала) - 1)); @@ -381,6 +296,116 @@ КонецФункции +// BSLLS:CognitiveComplexity-off +Функция ВыполнитьЗапросМультипарт(Знач URL + , Знач Вид + , Знач Параметры + , Знач Файлы = "" + , Знач ТипКонтента = "image/jpeg" + , Знач ДопЗаголовки = "") + + Если Не ЗначениеЗаполнено(Параметры) Тогда + Параметры = Новый Структура; + КонецЕсли; + + Если Не ЗначениеЗаполнено(Файлы) Тогда + Файлы = Новый Соответствие; + КонецЕсли; + + ЗаменаТочки = "___"; + GZip = "gzip"; + Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", ""); + СтруктураURL = РазбитьURL(URL); + + Заголовки = Новый Соответствие; + Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary); + Заголовки.Вставить("Accept-Encoding", GZip); + Заголовки.Вставить("Accept", "*/*"); + Заголовки.Вставить("Connection", "keep-alive"); + + Если ТипЗнч(ДопЗаголовки) = Тип("Соответствие") Тогда + + Для Каждого Заголовок Из ДопЗаголовки Цикл + Заголовки.Вставить(Заголовок.Ключ, Заголовок.Значение); + КонецЦикла; + + КонецЕсли; + + Соединение = Новый HTTPСоединение(СтруктураURL["Сервер"], 443, , , , 300, Новый ЗащищенноеСоединениеOpenSSL); + НовыйЗапрос = Новый HTTPЗапрос(СтруктураURL["Адрес"], Заголовки); + ТелоЗапроса = НовыйЗапрос.ПолучитьТелоКакПоток(); + ЗаписьТекста = Новый ЗаписьДанных(ТелоЗапроса, КодировкаТекста.UTF8, ПорядокБайтов.LittleEndian, "", "", Ложь); + + РазделительСтрок = Символы.ВК + Символы.ПС; + + Для Каждого Параметр Из Параметры Цикл + + ЗаписьТекста.ЗаписатьСтроку("--" + boundary + РазделительСтрок); + ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""" + Параметр.Ключ + """"); + ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); + ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); + + Если ТипЗнч(Параметр.Значение) = Тип("Строка") Тогда + ЗаписьТекста.ЗаписатьСтроку(Параметр.Значение); + Иначе + ЗаписьТекста.Записать(Параметр.Значение); + КонецЕсли; + + ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); + + КонецЦикла; + + Счетчик = 0; + Для Каждого Файл Из Файлы Цикл + + ПутьФайл = СтрЗаменить(Файл.Ключ, ЗаменаТочки, "."); + + Если ТипКонтента = "image/jpeg" Тогда + ИмяФайлаОтправки = "photo"; + Иначе + ИмяФайлаОтправки = СтрЗаменить(Файл.Ключ, ЗаменаТочки, "."); + ИмяФайлаОтправки = Лев(ИмяФайлаОтправки, СтрНайти(ИмяФайлаОтправки, ".") - 1); + ИмяФайлаОтправки = ?(ЗначениеЗаполнено(ИмяФайлаОтправки), ИмяФайлаОтправки, СтрЗаменить(Файл.Ключ, + ЗаменаТочки, ".")); + КонецЕсли; + + ЗаписьТекста.ЗаписатьСтроку("--" + boundary + РазделительСтрок); + ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""" + + ИмяФайлаОтправки + + """; filename=""" + + ПутьФайл + + """"); + ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); + ЗаписьТекста.ЗаписатьСтроку("Content-Type: " + ТипКонтента); + ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); + ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); + ЗаписьТекста.Записать(Файл.Значение); + ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок); + + Счетчик = Счетчик + 1; + + КонецЦикла; + + ЗаписьТекста.ЗаписатьСтроку("--" + boundary + "--" + РазделительСтрок); + + ЗаписьТекста.Закрыть(); + + Ответ = Соединение.ВызватьHTTPМетод(Вид, НовыйЗапрос); + + НужнаРаспаковка = Ответ.Заголовки.Получить("Content-Encoding") = GZip Или Ответ.Заголовки.Получить( + "content-encoding") = GZip; + + Если НужнаРаспаковка Тогда + Ответ = РаспаковатьОтвет(Ответ); + КонецЕсли; + + Возврат ?(ТипЗнч(Ответ) = Тип("ДвоичныеДанные") + , JsonВСтруктуру(Ответ) + , JsonВСтруктуру(Ответ.ПолучитьТелоКакДвоичныеДанные())); + +КонецФункции +// BSLLS:CognitiveComplexity-on + #Область GZip // Описание структур см. здесь https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT