From 7936405b601b48e8d6502c0c0ab5b0878b5fa54c Mon Sep 17 00:00:00 2001 From: "aleksey.koryakin" Date: Tue, 12 Nov 2019 18:05:54 +0300 Subject: [PATCH 1/7] =?UTF-8?q?#ONECICD-211=20=D0=9F=D1=83=D0=B1=D0=BB?= =?UTF-8?q?=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B8=D0=B7=20=D1=84?= =?UTF-8?q?=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B0=20Markdown=20=D0=94=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BC=D0=B5=D1=82?= =?UTF-8?q?=D0=BE=D0=B4=D1=8B=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packagedef | 2 +- "src/\321\201onfluence.os" | 298 ++++++++++++++++++++++++++++++++----- 2 files changed, 259 insertions(+), 41 deletions(-) diff --git a/packagedef b/packagedef index 615753c..9b05dfe 100644 --- a/packagedef +++ b/packagedef @@ -1,6 +1,6 @@  Описание.Имя("confluence") - .Версия("1.0.5") + .Версия("1.1.0") .ЗависитОт("json") .ВерсияСреды("1.0.14") .ВключитьФайл("readme.md") diff --git "a/src/\321\201onfluence.os" "b/src/\321\201onfluence.os" index 586b8d3..1bee0a2 100644 --- "a/src/\321\201onfluence.os" +++ "b/src/\321\201onfluence.os" @@ -74,11 +74,8 @@ Иначе - ВызватьИсключение "Ошибка поиска страницы: " + КодПространства + "." + ИмяСтраницы + - "Запрос: " + URL + " - |КодСостояния: " + РезультатЗапроса.КодСостояния + " - |Ответ: " + РезультатЗапроса.Ответ; - + ВызватьИсключение "Ошибка поиска страницы: " + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); + КонецЕсли; Возврат Идентификатор; @@ -115,10 +112,7 @@ Иначе - ВызватьИсключение "Ошибка получения версии страницы:" + Идентификатор + - "Запрос: " + URL + " - |КодСостояния: " + РезультатЗапроса.КодСостояния + " - |Ответ: " + РезультатЗапроса.Ответ; + ВызватьИсключение "Ошибка получения версии страницы:" + Идентификатор + ТекстОшибки(РезультатЗапроса, URL); КонецЕсли; @@ -155,10 +149,7 @@ Иначе - ВызватьИсключение "Ошибка получения версии страницы:" + Идентификатор + - "Запрос: " + URL + " - |КодСостояния: " + РезультатЗапроса.КодСостояния + " - |Ответ: " + РезультатЗапроса.Ответ; + ВызватьИсключение "Ошибка получения версии страницы:" + Идентификатор + ТекстОшибки(РезультатЗапроса, URL); КонецЕсли; @@ -208,10 +199,7 @@ Иначе - ВызватьИсключение "Ошибка получения подчиненных страниц: " + Идентификатор + - "Запрос: " + URL + " - |КодСостояния: " + РезультатЗапроса.КодСостояния + " - |Ответ: " + РезультатЗапроса.Ответ; + ВызватьИсключение "Ошибка получения подчиненных страниц: " + Идентификатор + ТекстОшибки(РезультатЗапроса, URL); КонецЕсли; @@ -267,10 +255,7 @@ Иначе - ВызватьИсключение "Ошибка создания страницы:" + КодПространства + "." + ИмяСтраницы + "" - "Запрос: " + URL + " - |КодСостояния: " + РезультатЗапроса.КодСостояния + " - |Ответ: " + РезультатЗапроса.Ответ; + ВызватьИсключение "Ошибка создания страницы:" + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); КонецЕсли; @@ -358,10 +343,7 @@ Если РезультатЗапроса.КодСостояния <> 200 Тогда - ВызватьИсключение "Ошибка обновления страницы:" + КодПространства + "." + ИмяСтраницы + - "Запрос: " + URL + " - |КодСостояния: " + РезультатЗапроса.КодСостояния + " - |Ответ: " + РезультатЗапроса.Ответ; + ВызватьИсключение "Ошибка обновления страницы:" + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); КонецЕсли; @@ -447,10 +429,7 @@ РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "DELETE", URL); Если НЕ (РезультатЗапроса.КодСостояния = 200 И РезультатЗапроса.КодСостояния = 204) Тогда - ВызватьИсключение "Ошибка обновления страницы:" + КодПространства + "." + ИмяСтраницы + - "Запрос: " + URL + " - |КодСостояния: " + РезультатЗапроса.КодСостояния + " - |Ответ: " + РезультатЗапроса.Ответ; + ВызватьИсключение "Ошибка обновления страницы:" + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); КонецЕсли; @@ -480,10 +459,7 @@ Иначе - ВызватьИсключение "Ошибка прикрепления метки: - |Запрос: " + URL + " - |КодСостояния: " + РезультатЗапроса.КодСостояния + " - |Ответ: " + РезультатЗапроса.Ответ; + ВызватьИсключение "Ошибка прикрепления метки:" + ТекстОшибки(РезультатЗапроса, URL); Результат = Ложь; @@ -493,6 +469,220 @@ КонецФункции +Функция ПреобразоватьMarkdownToConfluence(ПараметрыПодключения, СодержимоеMarkdown) Экспорт + + Идентификатор = ""; + + URLОперации = "rest/tinymce/1/markdownxhtmlconverter"; + + ПараметрыОперации = Новый Структура(); + ПараметрыОперации.Вставить("wiki", СодержимоеMarkdown); + + Тело = СтрокаJSON(ПараметрыОперации); + РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "POST", URLОперации, Тело, "text/html; charset=UTF-8"); + + Если РезультатЗапроса.КодСостояния = 200 Тогда + + Возврат РезультатЗапроса.Ответ; + + Иначе + + ВызватьИсключение "Ошибка преобразования markdown → html" + ТекстОшибки(РезультатЗапроса, URLОперации); + + КонецЕсли; + + Возврат Идентификатор; + +КонецФункции + +Функция АдресСтраницы(КодПространства, ИмяСтраницы = "", Идентификатор = "", ИдентификаторРодителя = "") Экспорт + + Адрес = Новый Структура; + + Адрес.Вставить("КодПространства", КодПространства); + Адрес.Вставить("ИмяСтраницы", ИмяСтраницы); + Адрес.Вставить("Идентификатор", Идентификатор); + Адрес.Вставить("ИдентификаторРодителя", ИдентификаторРодителя); + + Возврат Адрес; + +КонецФункции + +Функция Создать(ПараметрыПодключения, АдресСтраницы, Содержимое = Неопределено) Экспорт + + HTTPМетод = "PUT"; + + ПараметрыКоманды = ПараметрыСозданияОбновления(ПараметрыПодключения, АдресСтраницы, Содержимое, , HTTPМетод); + + URL = ПолучитьURLОперации(); + + РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, HTTPМетод, URL, СтрокаJSON(ПараметрыКоманды)); + + Если РезультатЗапроса.КодСостояния = 200 Тогда + + ИдентификаторСтраницы = НайтиСтраницуПоИмени(ПараметрыПодключения, АдресСтраницы.КодПространства, АдресСтраницы.ИмяСтраницы); + + Иначе + + ВызватьИсключение СтрШаблон("Ошибка создания страницы: %1.%2%3", + АдресСтраницы.КодПространства, + АдресСтраницы.ИмяСтраницы, + ТекстОшибки(РезультатЗапроса, URL)); + + КонецЕсли; + + Возврат ИдентификаторСтраницы; + +КонецФункции + +Функция Обновить(ПараметрыПодключения, АдресСтраницы, Содержимое = Неопределено, ОбновитьПриИзмененииСодержимого = Ложь) Экспорт + + Если ПустаяСтрока(АдресСтраницы.ИмяСтраницы) И ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда + + ВызватьИсключение "Ошибка обновления страницы: " + АдресСтраницы.КодПространства + "." + АдресСтраницы.ИмяСтраницы + + "Ответ: не указаны имя страницы и идентификатор"; + + КонецЕсли; + + Если ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда + + АдресСтраницы.Идентификатор = НайтиСтраницуПоИмени(ПараметрыПодключения, АдресСтраницы.КодПространства, АдресСтраницы.ИмяСтраницы); + + Если ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда + + ВызватьИсключение "Ошибка обновления страницы: " + АдресСтраницы.КодПространства + "." + АдресСтраницы.ИмяСтраницы + + "Ответ: не найдена страница"; + + КонецЕсли; + + КонецЕсли; + + Если ОбновитьПриИзмененииСодержимого Тогда + + ТекущееСодержимое = СодержимоеСтраницыПоИдентификатору(ПараметрыПодключения, АдресСтраницы.Идентификатор); + Регексп = Новый РегулярноеВыражение("id=\\""([a-z0-9-]{36})\\""\ ac\:name"); // идентификаторы плагинов меняются + Регексп.Многострочный = Истина; + ТекущееСодержимое = Регексп.Заменить(ТекущееСодержимое, "NONE"); + ВрСодержимое = Регексп.Заменить(Содержимое, "NONE"); + Если СтрСравнить(СокрЛП(ТекущееСодержимое), СокрЛП(ВрСодержимое)) = 0 Тогда + + Возврат АдресСтраницы.Идентификатор; + + КонецЕсли; + + КонецЕсли; + + URL = ПолучитьURLОперации(, , АдресСтраницы.Идентификатор); + Версия = ВерсияСтраницыПоИдентификатору(ПараметрыПодключения, АдресСтраницы.Идентификатор); + Версия = Формат(Число(Версия) + 1, "ЧГ="); + + HTTPМетод = "PUT"; + + ПараметрыКоманды = ПараметрыСозданияОбновления(ПараметрыПодключения, АдресСтраницы, Содержимое, Версия, HTTPМетод); + + ТелоЗапроса = СтрокаJSON(ПараметрыКоманды); + + РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, HTTPМетод, URL, ТелоЗапроса); + + Если РезультатЗапроса.КодСостояния <> 200 Тогда + + ВызватьИсключение "Ошибка обновления страницы:" + АдресСтраницы.КодПространства + "." + АдресСтраницы.ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); + + КонецЕсли; + + Возврат АдресСтраницы.Идентификатор; + +КонецФункции // ОбновитьСтраницу() + +Функция ПараметрыСозданияОбновления(ПараметрыПодключения, Адрес, Содержимое, Версия = Неопределено, HTTPМетод = Неопределено) + + ПараметрыКоманды = Новый Структура(); + ПараметрыКоманды.Вставить("type", "page"); + ПараметрыКоманды.Вставить("title", Адрес.ИмяСтраницы); + ПараметрыКоманды.Вставить("space", Новый Структура("key", Адрес.КодПространства)); + + Если Версия <> Неопределено Тогда + + ПараметрыКоманды.Вставить("version", Новый Структура("number", Версия)); + + КонецЕсли; + + Если Не ПустаяСтрока(Адрес.ИдентификаторРодителя) Тогда + Родители = Новый Массив(); + Родители.Добавить(Новый Структура("id", Адрес.ИдентификаторРодителя)); + ПараметрыКоманды.Вставить("ancestors", Родители); + КонецЕсли; + + Если ТипЗнч(Содержимое) = Тип("Структура") И Содержимое.Свойство("Значение") Тогда + + Значение = Содержимое.Значение; + + Если Содержимое.Свойство("Формат") Тогда + Формат = Содержимое.Формат; + Иначе + Формат = "confluence"; + КонецЕсли; + + ИначеЕсли ЗначениеЗаполнено(Содержимое) Тогда + + Значение = Содержимое; + Формат = "confluence"; + + КонецЕсли; + + Если ЗначениеЗаполнено(Значение) Тогда + + Если Формат = "markdown" Тогда + + Значение = ПреобразоватьMarkdownToConfluence(ПараметрыПодключения, Значение); + ТелоСтраницы = Новый Структура("editor", Новый Структура("value, representation", Значение, "editor")); + + Если Версия = Неопределено Тогда + + HTTPМетод = "POST"; // Создание страниц в markdown через POST остальное PUT + + КонецЕсли; + + Иначе + + ТелоСтраницы = Новый Структура("storage", Новый Структура("value, representation", Значение, "storage")); + + КонецЕсли; + + ПараметрыКоманды.Вставить("body", ТелоСтраницы); + + КонецЕсли; + + Возврат ПараметрыКоманды; + +КонецФункции + +Функция СоздатьИлиОбновить(ПараметрыПодключения, АдресСтраницы, Содержимое, ОбновитьПриИзмененииСодержимого) Экспорт + + Если ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда + + АдресСтраницы.Идентификатор = НайтиСтраницуПоИмени(ПараметрыПодключения, АдресСтраницы.КодПространства, АдресСтраницы.ИмяСтраницы); + + КонецЕсли; + + Если Не ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда + + Идентификатор = Обновить( + ПараметрыПодключения, + АдресСтраницы, + Содержимое, + ОбновитьПриИзмененииСодержимого); + + Иначе + + АдресСтраницы.Идентификатор = Создать(ПараметрыПодключения, АдресСтраницы, Содержимое); + + КонецЕсли; + + Возврат АдресСтраницы.Идентификатор; + +КонецФункции + /////////////////////////////////////////////////////////////////// // СЛУЖЕБНЫЙ ФУНКЦИОНАЛ /////////////////////////////////////////////////////////////////// @@ -526,20 +716,26 @@ КонецФункции // ПолучитьURLОперации() -Функция ВыполнитьHTTPЗапрос(ПараметрыПодключения, Метод, URL, ТелоЗапроса = "") +Функция ВыполнитьHTTPЗапрос(ПараметрыПодключения, Метод, URL, ТелоЗапроса = "", Accept = "application/json; charset=UTF-8") HTTPЗапрос = Новый HTTPЗапрос; - HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json"); - HTTPЗапрос.Заголовки.Вставить("Accept", "application/json"); + HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json; charset=UTF-8"); + HTTPЗапрос.Заголовки.Вставить("Accept", Accept); HTTPЗапрос.АдресРесурса = URL; + Если Не ПустаяСтрока(ТелоЗапроса) Тогда - HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса); + HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8); КонецЕсли; - HTTP = Новый HTTPСоединение(ПараметрыПодключения.АдресСервера,, ПараметрыПодключения.Пользователь, ПараметрыПодключения.Пароль); + HTTP = Новый HTTPСоединение(ПараметрыПодключения.АдресСервера, , + ПараметрыПодключения.Пользователь, + ПараметрыПодключения.Пароль); + + Сообщить(СтрШаблон("%1: %2/%3", Метод, ПараметрыПодключения.АдресСервера, URL)); + Если СтрСравнить(Метод, "GET") = 0 Тогда Ответ = HTTP.Получить(HTTPЗапрос); @@ -558,10 +754,32 @@ Иначе - ВызватьИсключение "Неизвестный метод: '" + Метод + "'" + ВызватьИсключение СтрШаблон("Неизвестный метод: '%1'", Метод); КонецЕсли; - Возврат Новый Структура("Ответ, КодСостояния", Ответ.ПолучитьТелоКакСтроку(), Ответ.КодСостояния); + Возврат Новый Структура("Ответ, КодСостояния", Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8), Ответ.КодСостояния); КонецФункции // ВыполнитьHTTPЗапрос() + +Функция СтрокаJSON(Значение) + + ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(Ложь, , Истина, , , , , , Истина); + Запись = Новый ЗаписьJSON(); + Запись.УстановитьСтроку(); + + ЗаписатьJSON(Запись, Значение); + + Возврат Запись.Закрыть(); + +КонецФункции + +Функция ТекстОшибки(РезультатЗапроса, URL) + + Возврат СтрШаблон( + " + |Запрос: %1 + |КодСостояния: %2 + |Ответ: %3", URL, РезультатЗапроса.КодСостояния, РезультатЗапроса.Ответ); + +КонецФункции \ No newline at end of file From 77349f422b099972e4ab8885d430143432155659 Mon Sep 17 00:00:00 2001 From: "aleksey.koryakin" Date: Tue, 12 Nov 2019 18:15:02 +0300 Subject: [PATCH 2/7] =?UTF-8?q?#ONECICD-211=20=D0=A1=D0=BA=D1=80=D0=B8?= =?UTF-8?q?=D0=BF=D1=82=D1=8B=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + installlocalhost.bat | 12 ++++++++++++ installlocalhost.sh | 12 ++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 installlocalhost.bat create mode 100644 installlocalhost.sh diff --git a/.gitignore b/.gitignore index 4473662..b3d2ae7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.bak +*.ospx diff --git a/installlocalhost.bat b/installlocalhost.bat new file mode 100644 index 0000000..12a4e29 --- /dev/null +++ b/installlocalhost.bat @@ -0,0 +1,12 @@ +@echo off +call del "*.ospx" + +for /f %%i in ('"oscript -version"') do set result=%%i + +if %result%==1.0.19.105 ( + call opm build . -mf ./packagedef -out . +) else ( + call opm build -m ./packagedef -o . +) + +call opm install -f *.ospx \ No newline at end of file diff --git a/installlocalhost.sh b/installlocalhost.sh new file mode 100644 index 0000000..80cb5d1 --- /dev/null +++ b/installlocalhost.sh @@ -0,0 +1,12 @@ +#!/bin/bash +rm "*.ospx" + +result=$(oscript -version) + +if [[ $result = "1.0.19.105" ]]; then + opm build . -mf ./packagedef -out . +else + opm build -m ./packagedef -o . +fi + +opm install -f *.ospx From 0009bdd6fa37dee613934cdd9cd69a9f5571ea26 Mon Sep 17 00:00:00 2001 From: "aleksey.koryakin" Date: Wed, 13 Nov 2019 15:08:10 +0300 Subject: [PATCH 3/7] =?UTF-8?q?#ONECICD-211=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BC?= =?UTF-8?q?=D0=B5=D1=87=D0=B0=D0=BD=D0=B8=D0=B9=20IDE=20=D0=9E=D1=88=D0=B8?= =?UTF-8?q?=D0=B1=D0=BA=D0=B0=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "src/\321\201onfluence.os" | 49 ++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git "a/src/\321\201onfluence.os" "b/src/\321\201onfluence.os" index 1bee0a2..61b07a3 100644 --- "a/src/\321\201onfluence.os" +++ "b/src/\321\201onfluence.os" @@ -16,7 +16,7 @@ // // Параметры: // АдресСервера - Строка - Адрес (URL) сервера confluence. Например "https://conflunece.mydomain.ru" -// Пользователь - Строка - Имя пользователя для покдлючения +// Пользователь - Строка - Имя пользователя для подключения // Пароль - Строка - Пароль пользователя для подключения // // Возвращаемое значение: @@ -60,7 +60,7 @@ URL = ПолучитьURLОперации(КодПространства, ИмяСтраницы); РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "GET", URL); - Если РезультатЗапроса.КодСостояния = 200 Тогда + Если УспешныйЗапрос(РезультатЗапроса) Тогда ПарсерJSON = Новый ПарсерJSON; Ответ = ПарсерJSON.ПрочитатьJSON(РезультатЗапроса.Ответ); @@ -98,7 +98,7 @@ URL = ПолучитьURLОперации(,, Идентификатор); РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "GET", URL); - Если РезультатЗапроса.КодСостояния = 200 Тогда + Если УспешныйЗапрос(РезультатЗапроса) Тогда ПарсерJSON = Новый ПарсерJSON; @@ -136,7 +136,7 @@ URL = ПолучитьURLОперации(,, Идентификатор) + "&expand=body.storage"; РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "GET", URL); - Если РезультатЗапроса.КодСостояния = 200 Тогда + Если УспешныйЗапрос(РезультатЗапроса) Тогда Регексп = Новый РегулярноеВыражение("""body"":{""storage"":{""value"":""([\w\W]*?)"",""representation"":""storage"); Регексп.Многострочный = ИСТИНА; @@ -180,7 +180,7 @@ URL = ПолучитьURLОперации(,, Идентификатор, "child/page"); РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "GET", URL); - Если РезультатЗапроса.КодСостояния = 200 Тогда + Если УспешныйЗапрос(РезультатЗапроса) Тогда ПарсерJSON = Новый ПарсерJSON; Ответ = ПарсерJSON.ПрочитатьJSON(РезультатЗапроса.Ответ); @@ -249,7 +249,7 @@ ИдентификаторСтраницы = ""; РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "POST", URL, ТелоЗапроса); - Если РезультатЗапроса.КодСостояния = 200 Тогда + Если УспешныйЗапрос(РезультатЗапроса) Тогда ИдентификаторСтраницы = НайтиСтраницуПоИмени(ПараметрыПодключения, КодПространства, ИмяСтраницы); @@ -341,7 +341,7 @@ РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "PUT", URL, ТелоЗапроса); - Если РезультатЗапроса.КодСостояния <> 200 Тогда + Если НЕ УспешныйЗапрос(РезультатЗапроса) Тогда ВызватьИсключение "Ошибка обновления страницы:" + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); @@ -453,7 +453,7 @@ РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "POST", URL, ТелоЗапроса); - Если РезультатЗапроса.КодСостояния = 200 Тогда + Если УспешныйЗапрос(РезультатЗапроса) Тогда Результат = Истина; @@ -461,8 +461,6 @@ ВызватьИсключение "Ошибка прикрепления метки:" + ТекстОшибки(РезультатЗапроса, URL); - Результат = Ложь; - КонецЕсли; Возврат Результат; @@ -481,7 +479,7 @@ Тело = СтрокаJSON(ПараметрыОперации); РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "POST", URLОперации, Тело, "text/html; charset=UTF-8"); - Если РезультатЗапроса.КодСостояния = 200 Тогда + Если УспешныйЗапрос(РезультатЗапроса) Тогда Возврат РезультатЗапроса.Ответ; @@ -510,15 +508,15 @@ Функция Создать(ПараметрыПодключения, АдресСтраницы, Содержимое = Неопределено) Экспорт - HTTPМетод = "PUT"; + HTTPМетод = "POST"; - ПараметрыКоманды = ПараметрыСозданияОбновления(ПараметрыПодключения, АдресСтраницы, Содержимое, , HTTPМетод); + ПараметрыКоманды = ПараметрыСозданияОбновления(ПараметрыПодключения, АдресСтраницы, Содержимое); URL = ПолучитьURLОперации(); РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, HTTPМетод, URL, СтрокаJSON(ПараметрыКоманды)); - Если РезультатЗапроса.КодСостояния = 200 Тогда + Если УспешныйЗапрос(РезультатЗапроса) Тогда ИдентификаторСтраницы = НайтиСтраницуПоИмени(ПараметрыПодключения, АдресСтраницы.КодПространства, АдресСтраницы.ИмяСтраницы); @@ -578,13 +576,13 @@ HTTPМетод = "PUT"; - ПараметрыКоманды = ПараметрыСозданияОбновления(ПараметрыПодключения, АдресСтраницы, Содержимое, Версия, HTTPМетод); + ПараметрыКоманды = ПараметрыСозданияОбновления(ПараметрыПодключения, АдресСтраницы, Содержимое, Версия); ТелоЗапроса = СтрокаJSON(ПараметрыКоманды); РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, HTTPМетод, URL, ТелоЗапроса); - Если РезультатЗапроса.КодСостояния <> 200 Тогда + Если НЕ УспешныйЗапрос(РезультатЗапроса) Тогда ВызватьИсключение "Ошибка обновления страницы:" + АдресСтраницы.КодПространства + "." + АдресСтраницы.ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); @@ -594,7 +592,7 @@ КонецФункции // ОбновитьСтраницу() -Функция ПараметрыСозданияОбновления(ПараметрыПодключения, Адрес, Содержимое, Версия = Неопределено, HTTPМетод = Неопределено) +Функция ПараметрыСозданияОбновления(ПараметрыПодключения, Адрес, Содержимое, Версия = Неопределено) ПараметрыКоманды = Новый Структура(); ПараметрыКоманды.Вставить("type", "page"); @@ -636,13 +634,7 @@ Значение = ПреобразоватьMarkdownToConfluence(ПараметрыПодключения, Значение); ТелоСтраницы = Новый Структура("editor", Новый Структура("value, representation", Значение, "editor")); - - Если Версия = Неопределено Тогда - - HTTPМетод = "POST"; // Создание страниц в markdown через POST остальное PUT - - КонецЕсли; - + Иначе ТелоСтраницы = Новый Структура("storage", Новый Структура("value, representation", Значение, "storage")); @@ -734,8 +726,6 @@ ПараметрыПодключения.Пользователь, ПараметрыПодключения.Пароль); - Сообщить(СтрШаблон("%1: %2/%3", Метод, ПараметрыПодключения.АдресСервера, URL)); - Если СтрСравнить(Метод, "GET") = 0 Тогда Ответ = HTTP.Получить(HTTPЗапрос); @@ -762,6 +752,13 @@ КонецФункции // ВыполнитьHTTPЗапрос() +Функция УспешныйЗапрос(РезультатЗапроса) + + КодОтветаУспешно = 200; + Возврат РезультатЗапроса.КодСостояния = КодОтветаУспешно; + +КонецФункции + Функция СтрокаJSON(Значение) ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(Ложь, , Истина, , , , , , Истина); From 8bdb16cd9062b162423e295eb5fd350b8cc8b4e6 Mon Sep 17 00:00:00 2001 From: "aleksey.koryakin" Date: Wed, 13 Nov 2019 17:57:07 +0300 Subject: [PATCH 4/7] =?UTF-8?q?#ONECICD-211=20=D0=9E=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=81=D1=80=D0=B0=D0=B2=D0=BD=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D0=B9=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "src/\321\201onfluence.os" | 82 +++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git "a/src/\321\201onfluence.os" "b/src/\321\201onfluence.os" index 61b07a3..6b37cd3 100644 --- "a/src/\321\201onfluence.os" +++ "b/src/\321\201onfluence.os" @@ -74,7 +74,7 @@ Иначе - ВызватьИсключение "Ошибка поиска страницы: " + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); + ВызватьИсключение "Ошибка поиска страницы: " + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL, "GET"); КонецЕсли; @@ -112,7 +112,7 @@ Иначе - ВызватьИсключение "Ошибка получения версии страницы:" + Идентификатор + ТекстОшибки(РезультатЗапроса, URL); + ВызватьИсключение "Ошибка получения версии страницы:" + Идентификатор + ТекстОшибки(РезультатЗапроса, URL, "GET"); КонецЕсли; @@ -138,18 +138,13 @@ Если УспешныйЗапрос(РезультатЗапроса) Тогда - Регексп = Новый РегулярноеВыражение("""body"":{""storage"":{""value"":""([\w\W]*?)"",""representation"":""storage"); - Регексп.Многострочный = ИСТИНА; - Ответ = Регексп.НайтиСовпадения(РезультатЗапроса.Ответ); - Если Ответ.Количество() Тогда - - Тело = Ответ[0].Группы[1].Значение; - - КонецЕсли; + Данные = ЗначениеИзJSON(РезультатЗапроса.Ответ); + + Возврат Данные.body.storage.value; Иначе - ВызватьИсключение "Ошибка получения версии страницы:" + Идентификатор + ТекстОшибки(РезультатЗапроса, URL); + ВызватьИсключение "Ошибка получения версии страницы:" + Идентификатор + ТекстОшибки(РезультатЗапроса, URL, "GET"); КонецЕсли; @@ -199,7 +194,7 @@ Иначе - ВызватьИсключение "Ошибка получения подчиненных страниц: " + Идентификатор + ТекстОшибки(РезультатЗапроса, URL); + ВызватьИсключение "Ошибка получения подчиненных страниц: " + Идентификатор + ТекстОшибки(РезультатЗапроса, URL, "GET"); КонецЕсли; @@ -255,7 +250,7 @@ Иначе - ВызватьИсключение "Ошибка создания страницы:" + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); + ВызватьИсключение "Ошибка создания страницы:" + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL, "POST"); КонецЕсли; @@ -343,7 +338,7 @@ Если НЕ УспешныйЗапрос(РезультатЗапроса) Тогда - ВызватьИсключение "Ошибка обновления страницы:" + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); + ВызватьИсключение "Ошибка обновления страницы:" + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL, "PUT"); КонецЕсли; @@ -391,7 +386,7 @@ // КодПространства - Строка - Код пространства confluence // ИмяСтраницы - Строка - Наименование страницы (заголовок) // Идентификатор - Строка - Идентификатор страницы -// УдалятьПодчиненные - Булево - признак необходимости удаления подчиненых страниц. +// УдалятьПодчиненные - Булево - признак необходимости удаления подчиненных страниц. // Если данный параметр = ЛОЖЬ и есть подчиненные страницы, то удаление не будет выполнено // и будет вызвано исключение // @@ -427,9 +422,9 @@ URL = ПолучитьURLОперации(,, Идентификатор); РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "DELETE", URL); - Если НЕ (РезультатЗапроса.КодСостояния = 200 И РезультатЗапроса.КодСостояния = 204) Тогда + Если НЕ (УспешныйЗапрос(РезультатЗапроса) ИЛИ РезультатЗапроса.КодСостояния = 204) Тогда - ВызватьИсключение "Ошибка обновления страницы:" + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); + ВызватьИсключение "Ошибка удаления страницы:" + КодПространства + "." + ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL, "DELETE"); КонецЕсли; @@ -459,7 +454,7 @@ Иначе - ВызватьИсключение "Ошибка прикрепления метки:" + ТекстОшибки(РезультатЗапроса, URL); + ВызватьИсключение "Ошибка прикрепления метки:" + ТекстОшибки(РезультатЗапроса, URL, "POST"); КонецЕсли; @@ -485,7 +480,7 @@ Иначе - ВызватьИсключение "Ошибка преобразования markdown → html" + ТекстОшибки(РезультатЗапроса, URLОперации); + ВызватьИсключение "Ошибка преобразования markdown → html" + ТекстОшибки(РезультатЗапроса, URLОперации, "POST"); КонецЕсли; @@ -525,7 +520,7 @@ ВызватьИсключение СтрШаблон("Ошибка создания страницы: %1.%2%3", АдресСтраницы.КодПространства, АдресСтраницы.ИмяСтраницы, - ТекстОшибки(РезультатЗапроса, URL)); + ТекстОшибки(РезультатЗапроса, URL, HTTPМетод)); КонецЕсли; @@ -557,14 +552,15 @@ Если ОбновитьПриИзмененииСодержимого Тогда - ТекущееСодержимое = СодержимоеСтраницыПоИдентификатору(ПараметрыПодключения, АдресСтраницы.Идентификатор); - Регексп = Новый РегулярноеВыражение("id=\\""([a-z0-9-]{36})\\""\ ac\:name"); // идентификаторы плагинов меняются + СодержимоеConfluence = СодержимоеСтраницыПоИдентификатору(ПараметрыПодключения, АдресСтраницы.Идентификатор); + Регексп = Новый РегулярноеВыражение("ac\:macro-id=""[a-z0-9-]{36}"""); // идентификаторы плагинов меняются Регексп.Многострочный = Истина; - ТекущееСодержимое = Регексп.Заменить(ТекущееСодержимое, "NONE"); + СодержимоеConfluence = Регексп.Заменить(СодержимоеConfluence, "NONE"); ВрСодержимое = Регексп.Заменить(Содержимое, "NONE"); - Если СтрСравнить(СокрЛП(ТекущееСодержимое), СокрЛП(ВрСодержимое)) = 0 Тогда + + Если СтрСравнить(СокрЛП(СодержимоеConfluence), СокрЛП(ВрСодержимое)) = 0 Тогда - Возврат АдресСтраницы.Идентификатор; + Возврат Неопределено; КонецЕсли; @@ -584,7 +580,7 @@ Если НЕ УспешныйЗапрос(РезультатЗапроса) Тогда - ВызватьИсключение "Ошибка обновления страницы:" + АдресСтраницы.КодПространства + "." + АдресСтраницы.ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL); + ВызватьИсключение "Ошибка обновления страницы:" + АдресСтраницы.КодПространства + "." + АдресСтраницы.ИмяСтраницы + ТекстОшибки(РезультатЗапроса, URL, HTTPМетод); КонецЕсли; @@ -633,11 +629,13 @@ Если Формат = "markdown" Тогда Значение = ПреобразоватьMarkdownToConfluence(ПараметрыПодключения, Значение); - ТелоСтраницы = Новый Структура("editor", Новый Структура("value, representation", Значение, "editor")); + Хранение = Новый Структура("value, representation", Значение, "editor"); + ТелоСтраницы = Новый Структура("editor", Хранение); Иначе - ТелоСтраницы = Новый Структура("storage", Новый Структура("value, representation", Значение, "storage")); + Хранение = Новый Структура("value, representation", Значение, "storage"); + ТелоСтраницы = Новый Структура("storage", Хранение); КонецЕсли; @@ -651,6 +649,7 @@ Функция СоздатьИлиОбновить(ПараметрыПодключения, АдресСтраницы, Содержимое, ОбновитьПриИзмененииСодержимого) Экспорт + Результат = Новый Структура("Успешно, Действие"); Если ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда АдресСтраницы.Идентификатор = НайтиСтраницуПоИмени(ПараметрыПодключения, АдресСтраницы.КодПространства, АдресСтраницы.ИмяСтраницы); @@ -659,19 +658,26 @@ Если Не ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда - Идентификатор = Обновить( + РезультатОбновления = Обновить( ПараметрыПодключения, АдресСтраницы, Содержимое, ОбновитьПриИзмененииСодержимого); + Если РезультатОбновления <> Неопределено Тогда + Результат.Действие = "Обновление"; + КонецЕсли; + Иначе АдресСтраницы.Идентификатор = Создать(ПараметрыПодключения, АдресСтраницы, Содержимое); + Результат.Действие = "Создание"; КонецЕсли; - Возврат АдресСтраницы.Идентификатор; + Результат.Успешно = Истина; + + Возврат Результат; КонецФункции @@ -771,12 +777,22 @@ КонецФункции -Функция ТекстОшибки(РезультатЗапроса, URL) +Функция ЗначениеИзJSON(СтрокаJSON) + Чтение = Новый ЧтениеJSON(); + Чтение.УстановитьСтроку(СтрокаJSON); + Данные = ПрочитатьJSON(Чтение); + Чтение.Закрыть(); + + Возврат Данные; + +КонецФункции + +Функция ТекстОшибки(РезультатЗапроса, URL, HTTМетод) Возврат СтрШаблон( " - |Запрос: %1 + |Запрос: [%4] %1 |КодСостояния: %2 - |Ответ: %3", URL, РезультатЗапроса.КодСостояния, РезультатЗапроса.Ответ); + |Ответ: %3", URL, РезультатЗапроса.КодСостояния, РезультатЗапроса.Ответ, HTTМетод); КонецФункции \ No newline at end of file From 4b24c141a8eb07a01e14499ded00c595d4ef8067 Mon Sep 17 00:00:00 2001 From: "aleksey.koryakin" Date: Thu, 14 Nov 2019 13:23:12 +0300 Subject: [PATCH 5/7] =?UTF-8?q?#ONECICD-211=20=D0=9F=D1=83=D0=B1=D0=BB?= =?UTF-8?q?=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D1=8F=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=9F=D1=80=D0=B8=20=D1=81=D0=BE=D0=B7=D0=B4?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B8=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=86=D1=8B=20=D0=B0=D0=B4=D1=80=D0=B5=D1=81=20=D0=BD=D0=B5=20?= =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D1=8F=D0=BB=D1=81=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "src/\321\201onfluence.os" | 45 +++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git "a/src/\321\201onfluence.os" "b/src/\321\201onfluence.os" index 6b37cd3..bc49835 100644 --- "a/src/\321\201onfluence.os" +++ "b/src/\321\201onfluence.os" @@ -513,7 +513,7 @@ Если УспешныйЗапрос(РезультатЗапроса) Тогда - ИдентификаторСтраницы = НайтиСтраницуПоИмени(ПараметрыПодключения, АдресСтраницы.КодПространства, АдресСтраницы.ИмяСтраницы); + АдресСтраницы.Идентификатор = НайтиСтраницуПоИмени(ПараметрыПодключения, АдресСтраницы.КодПространства, АдресСтраницы.ИмяСтраницы); Иначе @@ -524,7 +524,7 @@ КонецЕсли; - Возврат ИдентификаторСтраницы; + Возврат АдресСтраницы.Идентификатор; КонецФункции @@ -607,28 +607,47 @@ ПараметрыКоманды.Вставить("ancestors", Родители); КонецЕсли; - Если ТипЗнч(Содержимое) = Тип("Структура") И Содержимое.Свойство("Значение") Тогда - - Значение = Содержимое.Значение; + ФорматПоУмолчанию = "confluence"; + Значение = ""; + Формат = ФорматПоУмолчанию; + + Если ТипЗнч(Содержимое) = Тип("Структура") Тогда + Если Содержимое.Свойство("Значение") Тогда + + Значение = Содержимое.Значение; + + ИначеЕсли Содержимое.Свойство("ИмяФайла") Тогда + + Значение = ТекстФайла(Содержимое.ИмяФайла); + + КонецЕсли; + Если Содержимое.Свойство("Формат") Тогда + Формат = Содержимое.Формат; - Иначе - Формат = "confluence"; + КонецЕсли; ИначеЕсли ЗначениеЗаполнено(Содержимое) Тогда Значение = Содержимое; - Формат = "confluence"; КонецЕсли; + Если ПустаяСтрока(Формат) Тогда + Формат = ФорматПоУмолчанию; + КонецЕсли; + + Если ЗначениеЗаполнено(Значение) Тогда Если Формат = "markdown" Тогда + Значение = СтрЗаменить(Значение, "\", "\\"); + Значение = ПреобразоватьMarkdownToConfluence(ПараметрыПодключения, Значение); + Хранение = Новый Структура("value, representation", Значение, "editor"); ТелоСтраницы = Новый Структура("editor", Хранение); @@ -795,4 +814,14 @@ |КодСостояния: %2 |Ответ: %3", URL, РезультатЗапроса.КодСостояния, РезультатЗапроса.Ответ, HTTМетод); +КонецФункции + +Функция ТекстФайла(ИмяФайла) + + Чтение = Новый ЧтениеТекста(ИмяФайла, КодировкаТекста.UTF8); + Содержимое = Чтение.Прочитать(); + Чтение.Закрыть(); + + Возврат Содержимое; + КонецФункции \ No newline at end of file From 153e09eba419418238eb24e179fe82815cbaa24f Mon Sep 17 00:00:00 2001 From: "aleksey.koryakin" Date: Thu, 14 Nov 2019 14:26:34 +0300 Subject: [PATCH 6/7] =?UTF-8?q?#ONECICD-211=20=D0=9E=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=81=D1=80=D0=B0=D0=B2=D0=BD=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=81=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D0=BC=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=B2=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82?= =?UTF-8?q?=D0=B5=20Markdown?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "src/\321\201onfluence.os" | 101 +++++++++++++++++++++++++++---------- 1 file changed, 75 insertions(+), 26 deletions(-) diff --git "a/src/\321\201onfluence.os" "b/src/\321\201onfluence.os" index bc49835..8358a38 100644 --- "a/src/\321\201onfluence.os" +++ "b/src/\321\201onfluence.os" @@ -10,6 +10,8 @@ /////////////////////////////////////////////////////////////////// +Перем ФорматыСодержимого Экспорт; + // ОписаниеПодключения // Создает структуру с набором параметров подключения. // Созданная структура в дальнейшем используется для всех операций @@ -505,7 +507,8 @@ HTTPМетод = "POST"; - ПараметрыКоманды = ПараметрыСозданияОбновления(ПараметрыПодключения, АдресСтраницы, Содержимое); + ОписаниеСодержимого = ПодготовитьСодержимое(ПараметрыПодключения, Содержимое); + ПараметрыКоманды = ПараметрыСозданияОбновления(АдресСтраницы, ОписаниеСодержимого); URL = ПолучитьURLОперации(); @@ -550,14 +553,27 @@ КонецЕсли; + ОписаниеСодержимого = ПодготовитьСодержимое(ПараметрыПодключения, Содержимое); + Если ОбновитьПриИзмененииСодержимого Тогда СодержимоеConfluence = СодержимоеСтраницыПоИдентификатору(ПараметрыПодключения, АдресСтраницы.Идентификатор); Регексп = Новый РегулярноеВыражение("ac\:macro-id=""[a-z0-9-]{36}"""); // идентификаторы плагинов меняются Регексп.Многострочный = Истина; СодержимоеConfluence = Регексп.Заменить(СодержимоеConfluence, "NONE"); - ВрСодержимое = Регексп.Заменить(Содержимое, "NONE"); + ВрСодержимое = Регексп.Заменить(ОписаниеСодержимого.Значение, "NONE"); + Если ОписаниеСодержимого.Формат = ФорматыСодержимого.MarkDown Тогда + + // TODO: Известные проблемы при сравнении MarkDown + // 1. Если в исходном файле есть "/", то для публикации его необходимо экранировать + // но до сравнения, тк от confluence он приходит в норм виде + // 2. Картинки (img) при конвертации тэк не закрытый, в confluence - закрытый + СодержимоеConfluence = СтрЗаменить(СодержимоеConfluence, "", ""); // Особенность конвертера Markdown → Confluence + + КонецЕсли; + + Если СтрСравнить(СокрЛП(СодержимоеConfluence), СокрЛП(ВрСодержимое)) = 0 Тогда Возврат Неопределено; @@ -572,7 +588,7 @@ HTTPМетод = "PUT"; - ПараметрыКоманды = ПараметрыСозданияОбновления(ПараметрыПодключения, АдресСтраницы, Содержимое, Версия); + ПараметрыКоманды = ПараметрыСозданияОбновления(АдресСтраницы, ОписаниеСодержимого, Версия); ТелоЗапроса = СтрокаJSON(ПараметрыКоманды); @@ -588,7 +604,7 @@ КонецФункции // ОбновитьСтраницу() -Функция ПараметрыСозданияОбновления(ПараметрыПодключения, Адрес, Содержимое, Версия = Неопределено) +Функция ПараметрыСозданияОбновления(Адрес, ОписаниеСодержимого, Версия = Неопределено) ПараметрыКоманды = Новый Структура(); ПараметрыКоманды.Вставить("type", "page"); @@ -607,6 +623,46 @@ ПараметрыКоманды.Вставить("ancestors", Родители); КонецЕсли; + ФорматПоУмолчанию = confluence.ФорматыСодержимого.Confluence; + Значение = ""; + Формат = ФорматПоУмолчанию; + + Если ТипЗнч(ОписаниеСодержимого) <> Тип("Структура") + ИЛИ НЕ ОписаниеСодержимого.Свойство("Формат") + ИЛИ НЕ ОписаниеСодержимого.Свойство("Значение") Тогда + + ВызватьИсключение "Передано не корректное описание содержимого"; + + КонецЕсли; + + Если ЗначениеЗаполнено(ОписаниеСодержимого.Значение) Тогда + + Если ОписаниеСодержимого.Формат = ФорматыСодержимого.MarkDown Тогда + + Значение = СтрЗаменить(ОписаниеСодержимого.Значение, "\", "\\"); + + Хранение = Новый Структура("value, representation", Значение, "editor"); + ТелоСтраницы = Новый Структура("editor", Хранение); + + Иначе + + Хранение = Новый Структура("value, representation", ОписаниеСодержимого.Значение, "storage"); + ТелоСтраницы = Новый Структура("storage", Хранение); + + КонецЕсли; + + ПараметрыКоманды.Вставить("body", ТелоСтраницы); + + КонецЕсли; + + Возврат ПараметрыКоманды; + +КонецФункции + +Функция ПодготовитьСодержимое(ПараметрыПодключения, Содержимое) + + ОписаниеСодержимого = Новый Структура("Значение, Формат"); + ФорматПоУмолчанию = "confluence"; Значение = ""; Формат = ФорматПоУмолчанию; @@ -634,35 +690,23 @@ Значение = Содержимое; КонецЕсли; - + Если ПустаяСтрока(Формат) Тогда + Формат = ФорматПоУмолчанию; - КонецЕсли; - - Если ЗначениеЗаполнено(Значение) Тогда - - Если Формат = "markdown" Тогда - - Значение = СтрЗаменить(Значение, "\", "\\"); + КонецЕсли; - Значение = ПреобразоватьMarkdownToConfluence(ПараметрыПодключения, Значение); - - Хранение = Новый Структура("value, representation", Значение, "editor"); - ТелоСтраницы = Новый Структура("editor", Хранение); + Если ЗначениеЗаполнено(Значение) И Формат = ФорматыСодержимого.MarkDown Тогда - Иначе - - Хранение = Новый Структура("value, representation", Значение, "storage"); - ТелоСтраницы = Новый Структура("storage", Хранение); - - КонецЕсли; + Значение = ПреобразоватьMarkdownToConfluence(ПараметрыПодключения, Значение); - ПараметрыКоманды.Вставить("body", ТелоСтраницы); - КонецЕсли; + + ОписаниеСодержимого.Формат = Формат; + ОписаниеСодержимого.Значение = Значение; - Возврат ПараметрыКоманды; + Возврат ОписаниеСодержимого; КонецФункции @@ -824,4 +868,9 @@ Возврат Содержимое; -КонецФункции \ No newline at end of file +КонецФункции + +ФорматыСодержимого = Новый Структура(); +ФорматыСодержимого.Вставить("Markdown", "markdown"); +ФорматыСодержимого.Вставить("Confluence", "confluence"); +ФорматыСодержимого.Вставить("HTML", "html"); \ No newline at end of file From e90a6035882662280808fe2bdd0202cdcdbba6d8 Mon Sep 17 00:00:00 2001 From: "aleksey.koryakin" Date: Mon, 9 Dec 2019 19:02:15 +0300 Subject: [PATCH 7/7] =?UTF-8?q?=D0=9E=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 34 +++++++ "src/\321\201onfluence.os" | 187 +++++++++++++++++++++++++------------ 2 files changed, 161 insertions(+), 60 deletions(-) diff --git a/readme.md b/readme.md index 2403a4f..324e068 100644 --- a/readme.md +++ b/readme.md @@ -32,3 +32,37 @@ #### Установка метки странице `Confluence.ПрикрепитьМеткуКСтранице(ПараметрыПодключения, ИдентификаторСтраницы, "Моя метка")` + +### Примеры нового API + +```bsl + +// Настройки подключения +Подключение = Confluence.ОписаниеПодключения("https://confluence.myserver.ru", "user", "password") + +// Получение идентификатора страницы +ИдентификаторРодителя = Confluence.НайтиСтраницуПоИмени(Подключение, "SpaceKey", "Корневая страница"); + +// Структура адреса страницы (Пространство, Наименование, Идентификатор, Родитель) +АдресСтраницы = Confluence.АдресСтраницы("SpaceKey", "Новая страница", , ИдентификаторРодителя); + +// Создадим новую страницу +Confluence.Создать(Подключение, АдресСтраницы, "Содержимое страницы"); +Сообщить("Идентификатор новой страницы: " + АдресСтраницы.Идентификатор) + +// Обновим содержимое +Confluence.Обновить(Подключение, АдресСтраницы, "Новое содержимое страницы", Истина); + +// Адрес второй страницы +АдресСтраницы = Confluence.АдресСтраницы("SpaceKey", "Вторая страница", , ИдентификаторРодителя); + +// Обновим если содержимое отличается, либо создадим если отсутствует +Confluence.СоздатьИлиОбновить(Подключение, АдресСтраницы, "Содержимое второй страницы"); + +// Опубликуем страницу в формате Markdown +АдресСтраницы = Confluence.АдресСтраницы("SpaceKey", "Третья страница Markdown", , ИдентификаторРодителя); +Содержимое = Новый Структура("Значение, Формат", "# Содержимое третьей страницы", confluence.ФорматыСодержимого.MarkDown); +Confluence.СоздатьИлиОбновить(Подключение, АдресСтраницы, Содержимое); + + +``` diff --git "a/src/\321\201onfluence.os" "b/src/\321\201onfluence.os" index 8358a38..5ec6288 100644 --- "a/src/\321\201onfluence.os" +++ "b/src/\321\201onfluence.os" @@ -140,7 +140,7 @@ Если УспешныйЗапрос(РезультатЗапроса) Тогда - Данные = ЗначениеИзJSON(РезультатЗапроса.Ответ); + Данные = ДесериализоватьJSON(РезультатЗапроса.Ответ); Возврат Данные.body.storage.value; @@ -464,32 +464,20 @@ КонецФункции -Функция ПреобразоватьMarkdownToConfluence(ПараметрыПодключения, СодержимоеMarkdown) Экспорт - - Идентификатор = ""; - - URLОперации = "rest/tinymce/1/markdownxhtmlconverter"; - - ПараметрыОперации = Новый Структура(); - ПараметрыОперации.Вставить("wiki", СодержимоеMarkdown); - - Тело = СтрокаJSON(ПараметрыОперации); - РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "POST", URLОперации, Тело, "text/html; charset=UTF-8"); - - Если УспешныйЗапрос(РезультатЗапроса) Тогда - - Возврат РезультатЗапроса.Ответ; - - Иначе - - ВызватьИсключение "Ошибка преобразования markdown → html" + ТекстОшибки(РезультатЗапроса, URLОперации, "POST"); - - КонецЕсли; - - Возврат Идентификатор; - -КонецФункции +#Область НовоеAPI +// АдресСтраницы +// Описание расположения страницы +// +// Параметры: +// КодПространства - Строка - Код пространства confluence +// ИмяСтраницы - Строка - имя страницы, должно быть уникально в пределах пространства +// Идентификатор - Строка - Идентификатор страницы confluence, может быть получен только поиском +// ИдентификаторРодителя - Строка - Идентификатор родителя страницы confluence, может быть получен только поиском +// +// Возвращаемое значение: +// Структура - Описание расположения страницы +// Функция АдресСтраницы(КодПространства, ИмяСтраницы = "", Идентификатор = "", ИдентификаторРодителя = "") Экспорт Адрес = Новый Структура; @@ -503,6 +491,19 @@ КонецФункции +// Создать +// Создает новую страницу в confluence и возвращает идентификатор новой страницы, также установив его в "АдресСтраницы" +// +// Параметры: +// ПараметрыПодключения - Структура - Описание подключения, см. confluence.ОписаниеПодключения +// АдресСтраницы - Структура - Описание расположения страницы, см. confluence.АдресСтраницы +// Содержимое - Строка, Структура - Содержимое новой страницы. +// либо строка содержимого в формате confluence +// либо структура с ключами Значение и Формат (Confluence, Markdown, HTML) +// +// Возвращаемое значение: +// Строка - Идентификатор созданной страницы +// Функция Создать(ПараметрыПодключения, АдресСтраницы, Содержимое = Неопределено) Экспорт HTTPМетод = "POST"; @@ -512,7 +513,7 @@ URL = ПолучитьURLОперации(); - РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, HTTPМетод, URL, СтрокаJSON(ПараметрыКоманды)); + РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, HTTPМетод, URL, СериализоватьJSON(ПараметрыКоманды)); Если УспешныйЗапрос(РезультатЗапроса) Тогда @@ -531,6 +532,23 @@ КонецФункции +// Обновить +// Выполняет обновление существующей страницы +// +// Параметры: +// ПараметрыПодключения - Структура - Описание подключения, см. confluence.ОписаниеПодключения +// АдресСтраницы - Структура - Описание расположения страницы, см. confluence.АдресСтраницы +// Содержимое - Строка, Структура - Содержимое новой страницы. +// либо строка содержимого в формате confluence +// либо структура с ключами Значение и Формат (Confluence, Markdown, HTML) +// +// ОбновитьПриИзмененииСодержимого - Булево - Выполнять только если содержимое изменено, +// Если установлено в Истина, но меняется только родитель или имя страницы - изменения не будут применены +// +// Возвращаемое значение: +// Неопределено, Строка - Когда обновление не требуется будет возвращено Неопределено, +// в других случаях - идентификатор страницы +// Функция Обновить(ПараметрыПодключения, АдресСтраницы, Содержимое = Неопределено, ОбновитьПриИзмененииСодержимого = Ложь) Экспорт Если ПустаяСтрока(АдресСтраницы.ИмяСтраницы) И ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда @@ -590,7 +608,7 @@ ПараметрыКоманды = ПараметрыСозданияОбновления(АдресСтраницы, ОписаниеСодержимого, Версия); - ТелоЗапроса = СтрокаJSON(ПараметрыКоманды); + ТелоЗапроса = СериализоватьJSON(ПараметрыКоманды); РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, HTTPМетод, URL, ТелоЗапроса); @@ -602,7 +620,66 @@ Возврат АдресСтраницы.Идентификатор; -КонецФункции // ОбновитьСтраницу() +КонецФункции + +// СоздатьИлиОбновить +// Создает новую страницу, либо обновление существующую +// +// Параметры: +// ПараметрыПодключения - Структура - Описание подключения, см. confluence.ОписаниеПодключения +// АдресСтраницы - Структура - Описание расположения страницы, см. confluence.АдресСтраницы +// Содержимое - Строка, Структура - Содержимое новой страницы. +// либо строка содержимого в формате confluence +// либо структура с ключами Значение и Формат (Confluence, Markdown, HTML) +// ОбновитьПриИзмененииСодержимого - Булево - Выполнять только если содержимое изменено, +// Если установлено в Истина, но меняется только родитель или имя страницы - изменения не будут применены +// +// Возвращаемое значение: +// Структура - Ключи: +// Успешно - Булево - не было ошибок +// Действие - Строка - "Создание", "Обновление", Неопределено +// +Функция СоздатьИлиОбновить(ПараметрыПодключения, АдресСтраницы, Содержимое, ОбновитьПриИзмененииСодержимого) Экспорт + + Результат = Новый Структура("Успешно, Действие"); + Если ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда + + АдресСтраницы.Идентификатор = НайтиСтраницуПоИмени(ПараметрыПодключения, АдресСтраницы.КодПространства, АдресСтраницы.ИмяСтраницы); + + КонецЕсли; + + Если Не ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда + + РезультатОбновления = Обновить( + ПараметрыПодключения, + АдресСтраницы, + Содержимое, + ОбновитьПриИзмененииСодержимого); + + Если РезультатОбновления <> Неопределено Тогда + Результат.Действие = "Обновление"; + КонецЕсли; + + Иначе + + АдресСтраницы.Идентификатор = Создать(ПараметрыПодключения, АдресСтраницы, Содержимое); + Результат.Действие = "Создание"; + + КонецЕсли; + + Результат.Успешно = Истина; + + Возврат Результат; + +КонецФункции + +#КонецОбласти + +/////////////////////////////////////////////////////////////////// +// СЛУЖЕБНЫЙ ФУНКЦИОНАЛ +/////////////////////////////////////////////////////////////////// + +#Область СлужебныеМетоды Функция ПараметрыСозданияОбновления(Адрес, ОписаниеСодержимого, Версия = Неопределено) @@ -710,44 +787,32 @@ КонецФункции -Функция СоздатьИлиОбновить(ПараметрыПодключения, АдресСтраницы, Содержимое, ОбновитьПриИзмененииСодержимого) Экспорт +Функция ПреобразоватьMarkdownToConfluence(ПараметрыПодключения, СодержимоеMarkdown) + + Идентификатор = ""; - Результат = Новый Структура("Успешно, Действие"); - Если ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда - - АдресСтраницы.Идентификатор = НайтиСтраницуПоИмени(ПараметрыПодключения, АдресСтраницы.КодПространства, АдресСтраницы.ИмяСтраницы); - - КонецЕсли; + URLОперации = "rest/tinymce/1/markdownxhtmlconverter"; + + ПараметрыОперации = Новый Структура(); + ПараметрыОперации.Вставить("wiki", СодержимоеMarkdown); - Если Не ПустаяСтрока(АдресСтраницы.Идентификатор) Тогда + Тело = СериализоватьJSON(ПараметрыОперации); + РезультатЗапроса = ВыполнитьHTTPЗапрос(ПараметрыПодключения, "POST", URLОперации, Тело, "text/html; charset=UTF-8"); + + Если УспешныйЗапрос(РезультатЗапроса) Тогда + + Возврат РезультатЗапроса.Ответ; - РезультатОбновления = Обновить( - ПараметрыПодключения, - АдресСтраницы, - Содержимое, - ОбновитьПриИзмененииСодержимого); - - Если РезультатОбновления <> Неопределено Тогда - Результат.Действие = "Обновление"; - КонецЕсли; - Иначе - - АдресСтраницы.Идентификатор = Создать(ПараметрыПодключения, АдресСтраницы, Содержимое); - Результат.Действие = "Создание"; + + ВызватьИсключение "Ошибка преобразования markdown → html" + ТекстОшибки(РезультатЗапроса, URLОперации, "POST"); КонецЕсли; - - Результат.Успешно = Истина; - - Возврат Результат; + + Возврат Идентификатор; КонецФункции -/////////////////////////////////////////////////////////////////// -// СЛУЖЕБНЫЙ ФУНКЦИОНАЛ -/////////////////////////////////////////////////////////////////// - Функция ПолучитьURLОперации(КодПространства = "", ИмяСтраницы = "", Идентификатор = "", Операция = "") URLОперации = "rest/api/content/"; @@ -828,7 +893,7 @@ КонецФункции -Функция СтрокаJSON(Значение) +Функция СериализоватьJSON(Значение) ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(Ложь, , Истина, , , , , , Истина); Запись = Новый ЗаписьJSON(); @@ -840,7 +905,7 @@ КонецФункции -Функция ЗначениеИзJSON(СтрокаJSON) +Функция ДесериализоватьJSON(СтрокаJSON) Чтение = Новый ЧтениеJSON(); Чтение.УстановитьСтроку(СтрокаJSON); Данные = ПрочитатьJSON(Чтение); @@ -870,6 +935,8 @@ КонецФункции +#КонецОбласти + ФорматыСодержимого = Новый Структура(); ФорматыСодержимого.Вставить("Markdown", "markdown"); ФорматыСодержимого.Вставить("Confluence", "confluence");