From 696f2702f2b1479b0cc6db0b6f7df41e6017b7de Mon Sep 17 00:00:00 2001 From: Anton Titovets Date: Thu, 16 May 2024 08:50:58 +0300 Subject: [PATCH] =?UTF-8?q?DB:=20=D0=90=D0=B2=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B8=20=D0=B7=D0=B0=D0=B3?= =?UTF-8?q?=D1=80=D1=83=D0=B7=D0=BA=D0=B0=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D1=84=D0=B0=D0=B9=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OPI/src/CommonModules/OPI_Dropbox/Module.bsl | 164 +++++++++++++++++- .../CommonModules/OPI_Dropbox/OPI_Dropbox.mdo | 8 +- .../CommonModules/OPI_Инструменты/Module.bsl | 76 ++++---- .../OPI_ПолучениеДанныхТестов/Module.bsl | 1 + OPI/src/CommonModules/OPI_Тесты/Module.bsl | 37 +++- 5 files changed, 236 insertions(+), 50 deletions(-) diff --git a/OPI/src/CommonModules/OPI_Dropbox/Module.bsl b/OPI/src/CommonModules/OPI_Dropbox/Module.bsl index 2adc47fb9..9e69de3de 100644 --- a/OPI/src/CommonModules/OPI_Dropbox/Module.bsl +++ b/OPI/src/CommonModules/OPI_Dropbox/Module.bsl @@ -33,6 +33,91 @@ #Область ПрограммныйИнтерфейс +#Область Авторизация + +// Получить ссылку авторизации +// Генерирует ссылку авторизации для перехода в браузере +// +// Параметры: +// КлючПриложения - Строка - Ключ приложения - appkey +// +// Возвращаемое значение: +// Строка - URL для перехода в браузере +Функция ПолучитьСсылкуАвторизации(Знач КлючПриложения) Экспорт + + OPI_ПреобразованиеТипов.ПолучитьСтроку(КлючПриложения); + Возврат "https://www.dropbox.com/oauth2/authorize?client_id=" + + КлючПриложения + + "&response_type=code&token_access_type=offline"; + +КонецФункции + +// Получить токен +// Полеучает токен на основе кода со страницы ПолучитьСсылкуАвторизации +// +// Параметры: +// КлючПриложения - Строка - Ключ приложения - appkey +// СекретПриложения - Строка - Секрет приложения - appsecret +// Код - Строка - Код со страницы авторизации - code +// +// Возвращаемое значение: +// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Dropbox +Функция ПолучитьТокен(Знач КлючПриложения, Знач СекретПриложения, Знач Код) Экспорт + + URL = "https://api.dropbox.com/oauth2/token"; + ТипДанных = "application/x-www-form-urlencoded; charset=utf-8"; + + Параметры = Новый Структура; + OPI_Инструменты.ДобавитьПоле("code" , Код , "Строка", Параметры); + OPI_Инструменты.ДобавитьПоле("grant_type", "authorization_code", "Строка", Параметры); + + СтруктураURL = OPI_Инструменты.РазбитьURL(URL); + Сервер = СтруктураURL["Сервер"]; + Адрес = СтруктураURL["Адрес"]; + + Запрос = OPI_Инструменты.СоздатьЗапрос(Адрес, , ТипДанных); + Соединение = OPI_Инструменты.СоздатьСоединение(Сервер, КлючПриложения, СекретПриложения); + + СтрокаПараметров = OPI_Инструменты.ПараметрыЗапросаВСтроку(Параметры); + Данные = Прав(СтрокаПараметров, СтрДлина(СтрокаПараметров) - 1); + + Запрос.УстановитьТелоИзСтроки(Данные); + + Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос); + OPI_Инструменты.ОбработатьОтвет(Ответ); + + Возврат Ответ; + +КонецФункции + +// Обновить токен +// Получает новый токен на основе рефреш токена +// +// Параметры: +// КлючПриложения - Строка - Ключ приложения - appkey +// СекретПриложения - Строка - Секрет приложения - appsecret +// РефрешТокен - Строка - Рефреш токен - refresh +// +// Возвращаемое значение: +// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Dropbox +Функция ОбновитьТокен(Знач КлючПриложения, Знач СекретПриложения, Знач РефрешТокен) Экспорт + + URL = "https://api.dropbox.com/oauth2/token"; + + Параметры = Новый Структура; + OPI_Инструменты.ДобавитьПоле("refresh_token", РефрешТокен , "Строка", Параметры); + OPI_Инструменты.ДобавитьПоле("grant_type" , "refresh_token" , "Строка", Параметры); + OPI_Инструменты.ДобавитьПоле("client_id" , КлючПриложения , "Строка", Параметры); + OPI_Инструменты.ДобавитьПоле("client_secret", СекретПриложения, "Строка", Параметры); + + Ответ = OPI_Инструменты.Post(URL, Параметры, , Ложь); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти + #Область РаботаСФайлами // Загрузить файл @@ -45,7 +130,7 @@ // Перезаписывать - Булево - Перезаписывать файл или менять название - overwrite // // Возвращаемое значение: -// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Airtable +// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Dropbox Функция ЗагрузитьФайл(Знач Токен, Знач Файл, Знач Путь, Знач Перезаписывать = Ложь) Экспорт OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Файл); @@ -54,7 +139,7 @@ Режим = ?(Перезаписывать, "overwrite", "add"); Размер = Файл.Размер(); - Граница = 50000000; + Граница = 5000000; Если Размер > Граница Тогда Ответ = ЗагрузитьБольшойФайл(Токен, Файл, Путь, Режим); @@ -94,10 +179,50 @@ Функция ЗагрузитьБольшойФайл(Знач Токен, Знач Файл, Знач Путь, Знач Режим) - Заголовки = ПолучитьЗаголовкиЗапроса(Токен); + URL = "https://content.dropboxapi.com/2/files/upload_session/append_v2"; + + РазмерЧасти = 5000000; + ТекущаяПозиция = 0; + ПрочитаноБайт = 0; + ОбщийРазмер = Файл.Размер(); + Сессия = ОткрытьСессию(Токен); - Возврат ""; + Пока ПрочитаноБайт < ОбщийРазмер Цикл + + Отступ = ТекущаяПозиция; + Курсор = Новый Структура("offset,session_id", Отступ, Сессия); + + Параметры = Новый Структура("cursor", Курсор); + Заголовки = ПолучитьЗаголовкиЗапроса(Токен, Параметры); + + ЧтениеДанных = Новый ЧтениеДанных(Файл); + ПрочитаноБайт = ЧтениеДанных.Пропустить(ТекущаяПозиция); + Результат = ЧтениеДанных.Прочитать(РазмерЧасти); + ТекущиеДанные = Результат.ПолучитьДвоичныеДанные(); + РазмерТекущих = ТекущиеДанные.Размер(); + СледующаяПозиция = ТекущаяПозиция + РазмерТекущих; + + Если Не ЗначениеЗаполнено(ТекущиеДанные) Тогда + Прервать; + КонецЕсли; + + Ответ = OPI_Инструменты.PostBinary(URL, ТекущиеДанные, Заголовки); + + ТекущаяПозиция = СледующаяПозиция; + + // !OInt КБайт = 1024; + // !OInt МБайт = КБайт * КБайт; + // !OInt Сообщить(OPI_Инструменты.ИнформацияОПрогрессе(ТекущаяПозиция, ОбщийРазмер, "МБ", МБайт)); + + // !OInt ВыполнитьСборкуМусора(); + // !OInt ОсвободитьОбъект(ТекущиеДанные); + + КонецЦикла; + Ответ = ЗакрытьСессию(Токен, Путь, Режим, ОбщийРазмер, Сессия); + + Возврат Ответ; + КонецФункции Функция ЗагрузитьМалыйФайл(Знач Токен, Знач Файл, Знач Путь, Знач Режим) @@ -120,4 +245,35 @@ КонецФункции +Функция ОткрытьСессию(Знач Токен) + + SessionId = "session_id"; + URL = "https://content.dropboxapi.com/2/files/upload_session/start"; + Заголовки = ПолучитьЗаголовкиЗапроса(Токен); + + Ответ = OPI_Инструменты.PostBinary(URL, ПолучитьДвоичныеДанныеИзСтроки(""), Заголовки); + + Возврат Ответ[SessionId]; + +КонецФункции + +Функция ЗакрытьСессию(Знач Токен, Знач Путь, Знач Режим, Знач ОбщийРазмер, Знач Сессия) + + URL = "https://content.dropboxapi.com/2/files/upload_session/finish"; + + Коммит = Новый Структура(); + OPI_Инструменты.ДобавитьПоле("mode", Режим, "Строка", Коммит); + OPI_Инструменты.ДобавитьПоле("path", Путь, "Строка", Коммит); + + Курсор = Новый Структура("offset,session_id", ОбщийРазмер, Сессия); + + Параметры = Новый Структура("commit,cursor", Коммит, Курсор); + Заголовки = ПолучитьЗаголовкиЗапроса(Токен, Параметры); + + Ответ = OPI_Инструменты.PostBinary(URL, ПолучитьДвоичныеДанныеИзСтроки(""), Заголовки); + + Возврат Ответ; + +КонецФункции + #КонецОбласти \ No newline at end of file diff --git a/OPI/src/CommonModules/OPI_Dropbox/OPI_Dropbox.mdo b/OPI/src/CommonModules/OPI_Dropbox/OPI_Dropbox.mdo index 2d29f2935..7902731e7 100644 --- a/OPI/src/CommonModules/OPI_Dropbox/OPI_Dropbox.mdo +++ b/OPI/src/CommonModules/OPI_Dropbox/OPI_Dropbox.mdo @@ -1,14 +1,14 @@ OPI_Dropbox - - ru - Drop box - OPI dropbox + + ru + Drop box + true true true diff --git a/OPI/src/CommonModules/OPI_Инструменты/Module.bsl b/OPI/src/CommonModules/OPI_Инструменты/Module.bsl index cd95d4945..feb31fcd5 100644 --- a/OPI/src/CommonModules/OPI_Инструменты/Module.bsl +++ b/OPI/src/CommonModules/OPI_Инструменты/Module.bsl @@ -177,6 +177,43 @@ КонецПроцедуры +Функция СоздатьЗапрос(Знач Адрес, Знач ДопЗаголовки = "", Знач ТипДанных = "") Экспорт + + Заголовки = Новый Соответствие; + Заголовки.Вставить("Accept-Encoding", "gzip"); + Заголовки.Вставить("Accept" , "*/*"); + Заголовки.Вставить("Connection" , "keep-alive"); + Заголовки.Вставить("Accept-Charset" , "utf-8"); + + Если ЗначениеЗаполнено(ТипДанных) Тогда + Заголовки.Вставить("Content-Type", ТипДанных); + КонецЕсли; + + Если ТипЗнч(ДопЗаголовки) = Тип("Соответствие") Тогда + + Для Каждого Заголовок Из ДопЗаголовки Цикл + Заголовки.Вставить(Заголовок.Ключ, Заголовок.Значение); + КонецЦикла; + + КонецЕсли; + + НовыйЗапрос = Новый HTTPЗапрос(Адрес, Заголовки); + + Возврат НовыйЗапрос; + +КонецФункции + +Функция СоздатьСоединение(Знач Сервер, Знач Пользователь = "", Знач Пароль = "") Экспорт + + Попытка + SSL = Новый ЗащищенноеСоединениеOpenSSL; + Возврат Новый HTTPСоединение(Сервер, 443, Пользователь, Пароль, , 3000, SSL); + Исключение + Возврат Новый HTTPСоединение(Сервер, 443, Пользователь, Пароль, , 3000); + КонецПопытки; + +КонецФункции + #КонецОбласти #КонецОбласти @@ -265,7 +302,7 @@ ЗаписьJSON = Новый ЗаписьJSON; ЗаписьJSON.УстановитьСтроку(ПараметрыJSON); - ЗаписатьJSON(ЗаписьJSON, Данные); + ЗаписатьJSON(ЗаписьJSON, Данные,); Возврат ЗаписьJSON.Закрыть(); Исключение @@ -694,43 +731,6 @@ КонецФункции -Функция СоздатьЗапрос(Знач Адрес, Знач ДопЗаголовки = "", Знач ТипДанных = "") - - Заголовки = Новый Соответствие; - Заголовки.Вставить("Accept-Encoding", "gzip"); - Заголовки.Вставить("Accept" , "*/*"); - Заголовки.Вставить("Connection" , "keep-alive"); - Заголовки.Вставить("Accept-Charset" , "utf-8"); - - Если ЗначениеЗаполнено(ТипДанных) Тогда - Заголовки.Вставить("Content-Type", ТипДанных); - КонецЕсли; - - Если ТипЗнч(ДопЗаголовки) = Тип("Соответствие") Тогда - - Для Каждого Заголовок Из ДопЗаголовки Цикл - Заголовки.Вставить(Заголовок.Ключ, Заголовок.Значение); - КонецЦикла; - - КонецЕсли; - - НовыйЗапрос = Новый HTTPЗапрос(Адрес, Заголовки); - - Возврат НовыйЗапрос; - -КонецФункции - -Функция СоздатьСоединение(Знач Сервер) - - Попытка - SSL = Новый ЗащищенноеСоединениеOpenSSL; - Возврат Новый HTTPСоединение(Сервер, 443, , , , 3000, SSL); - Исключение - Возврат Новый HTTPСоединение(Сервер, 443, , , , 3000); - КонецПопытки; - -КонецФункции - Функция ЭтоПереадресация(Знач Ответ) Переадресация = 300; diff --git a/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl b/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl index dc6d359c0..ba81e7f4a 100644 --- a/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl +++ b/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl @@ -209,6 +209,7 @@ НовыйТест(ТаблицаТестов, "АТ_СоздатьУдалитьЗаписи" , "Создать/Удалить записи" , АирТ); НовыйТест(ТаблицаТестов, "ДропБокс_ЗагрузитьФайл" , "Загрузить файл" , ДропБокс); + НовыйТест(ТаблицаТестов, "ДропБокс_ПолучитьОбновитьТокен" , "Получить/Обновить токен" , ДропБокс); Возврат ТаблицаТестов; diff --git a/OPI/src/CommonModules/OPI_Тесты/Module.bsl b/OPI/src/CommonModules/OPI_Тесты/Module.bsl index ecf8d0d20..37fffe499 100644 --- a/OPI/src/CommonModules/OPI_Тесты/Module.bsl +++ b/OPI/src/CommonModules/OPI_Тесты/Module.bsl @@ -3745,15 +3745,44 @@ #Область Dropbox -Функция ДропБокс_ЗагрузитьФайл() Экспорт +Процедура ДропБокс_ПолучитьОбновитьТокен() Экспорт + + Ключ = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Dropbox_Appkey"); + Секрет = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Dropbox_Appsecret"); + + Результат = OPI_Dropbox.ПолучитьСсылкуАвторизации(Ключ); + + // !OInt OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьСсылкуАвторизации"); + + Код = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Dropbox_Code"); + + Результат = OPI_Dropbox.ПолучитьТокен(Ключ, Секрет, Код); + + Рефреш = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Dropbox_Refresh"); + + Результат = OPI_Dropbox.ОбновитьТокен(Ключ, Секрет, Рефреш); + + // !OInt OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ОбновитьТокен"); + + Токен = Результат["access_token"]; + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Токен).Заполнено(); + + OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Dropbox_Token", Токен); + +КонецПроцедуры + +Процедура ДропБокс_ЗагрузитьФайл() Экспорт Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Dropbox_Token"); - Файл = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Document"); - Путь = "/New/mydoc.docx"; + Файл = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Audio"); + Путь = "/New/Dogs.mp3"; Результат = OPI_Dropbox.ЗагрузитьФайл(Токен, Файл, Путь); -КонецФункции + // !OInt OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ЗагрузитьФайл"); + +КонецПроцедуры #КонецОбласти