Changes

Jump to navigation Jump to search
33,079 bytes added ,  04:48, 17 September 2016
Created page with "{{Stamp|2016-09-09|4.0.0|1.0.5}} Триггер это скрипт, который запускается при определенных действиях или собы..."
{{Stamp|2016-09-09|4.0.0|1.0.5}}

Триггер это скрипт, который запускается при определенных действиях или событиях. В качестве языка для написания скриптов используется '''[https://developer.mozilla.org/en-US/docs/Web/JavaScript JavaScript]'''. Результатом выполнения скрипта может быть изменение или создание записи, выполнение http-запроса, создание файла, валидация данных и другие действия.

== Создание триггера ==
Каждая библиотека может иметь несколько триггеров, чтобы открыть список триггеров зайдите в библиотеку, откройте меню и выберите пункт '''Триггеры'''.

Для создания триггера откройте список триггеров библиотеки и нажмите кнопку '''+'''. После этого необходимо выбрать момент запуска триггера и написать скрипт реализующий ваши потребности.

== Момент запуска триггера ==
Момент запуска триггера определяется двумя параметрами:
; Действие : это какая-либо выполняемая пользователем операция с записями.
; Фаза действия : определяет более точный момент срабатывания триггера. Для каждого типа Действия доступны свои фазы.

=== Выполнение скрипта ===
Фаза в которую запускается триггер также определяет то, как будет выполняться скрипт - синхронно или асинхронно.
; Синхронное выполнение скрипта : приложение приостановить взаимодействие с пользователем на время выполнения скрипта. Не рекомендуется в таких скриптах выполнять длительные операции.
; Асинхронное выполнение скрипта : скрипт запускается в фоновом режиме, приложение не приостанавливает взаимодействие с пользователем. Обычно асинхронно выполняются скрипты в последних фазах действия.

== Безопасность ==
Некоторые функции доступные из скриптов (операции с файлами, выполнение http-запросов, доступ к другим библиотекам) в целях безопасности требуют соответствующих разрешений.
Эти разрешения пользователь должен установить вручную для каждой библиотеки отдельно.

Чтобы открыть диалог установки разрешений для скриптов - откройте список триггеров библиотеки и нажмите кнопку '''Щит''' на тулбаре. Установка разрешений должна выполняться на каждом устройстве отдельно. Выбранные разрешения не синхронизируются между устройствами.

=== Разрешения для скриптов ===
; Libraries : Определяет какие библиотеки помимо родной будут доступны скрипту. Вы можете предоставить доступ ко всем библиотекам или выбрать определенные библиотеки. Данное разрешение требуется для функции libByName.
; Read files : Предоставляет скрипту доступ на чтение файлов с запоминающего устройства. Данное разрешение требуется для функции file.
; Write files : Предоставляет скрипту доступ на создание и изменение файлов в запоминающем устройстве. Данное разрешение требуется для функции file.
; Network : Предоставляет скрипту право выполнять http запросы. Данное разрешение требуется для функции http.

== Действия ==
{| class="wikitable"
|-
! Действие !! Фаза !! Выполнение
|-
| rowspan="3" | Создание записи
| открытие формы создания || синхронное
|-
| перед сохранением записи || синхронное
|-
| после сохранения записи || асинхронное
|-
| rowspan="3" | Изменение записи
| открытие формы изменения записи || синхронное
|-
| перед сохранением записи || синхронное
|-
|после сохранения записи || асинхронное
|-
| rowspan="2" | Удаление записи
| перед удалением записи || синхронное
|-
| после удаления записи || асинхронное
|-
| rowspan="2" | Открытие карточки записи
| перед отображением окна || синхронное
|-
| после отображения окна || асинхронное
|-
| rowspan="2" | Добавление записи в избранное
| перед операцией || синхронное
|-
| после операции || асинхронное
|-
| rowspan="2" | Удаление записи из избранного
| перед операцией || синхронное
|-
| после операции || асинхронное
|}

==Библиотеки и записи==
===Глобальные Функции===

====entry()====
:Получить запись в контексте которой происходит выполнение скрипта. Т.е. если скрипт выполняется на действие Изменение записи, то данная функция возвращает изменяемую запись.
:Функция доступа для всех действий и фаз выполнения, за исключением "Создание записи - открытие формы создания", для данного действия используйте функцию entryDefault.

:Результат: Объект Entry, текущая запись.

====entryDefault()====
:Получить объект для установки значений по умолчанию для еще не созданной записи. Функция доступна для действия ''Создание записи'' и фазы выполнения ''Открытие формы создания''.

:Результат: Объект DefaultEntry.

====lib()====
:Получить библиотеку в контексте которой происходит выполнение скрипта.

:Результат: Объект Library, текущая библиотека.

====libByName(name)====
:Найти библиотеку по имени. В настройках безопасности должно быть установлено разрешение на использование получаемой библиотеки.

:Результат: Объект Library, найденная библиотека.

===Объект Library===
Через этот объект осуществляется доступ к записям библиотеки. Можно работать с текущей библиотекой - ''lib()'' или с любой другой библиотекой в базе данных - ''libByName()''. Помимо функций получения записей данный объект предоставляет возможность создания новой записи.
====Методы====
=====entries()=====
:Получить все записи библиотеки.
:Результат: Array[Entry] Массив записей. Записи отсортированы по времени их создания - от новых к старым.

=====find(query)=====
:Поиск записей в библиотеки по значениям полей. Поиск аналогичен [[Working with library entries#EntrySearch|поиску через интерфейс]] программы.
:Параметры: query - строка поиска.
:Результат: Array[Entry] Массив найденных записей. Записи отсортированы по времени их создания - от новых к старым.

=====findByKey(name)=====
:Поиск записи в библиотеки по имени. Для библиотеки должен быть включен параметр ''Уникальные имена''.
:Параметры: name - имя записи.
:Результат: Объект Entry.

=====create(values)=====
:Создание новой записи в библиотеке.
:Параметры: values - объект класса [https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object'''Object'''] содержащий значения полей.
:Результат: Объект Entry, созданная запись.

====Свойства====
;title : Название библиотеки.

===Объект Entry===
Этот объект является записью библиотеки и предоставляет возможность получать и устанавливать значения полей.
====Методы====
=====set(name , value)=====
:Установить значение поля. После вызова метода сразу же происходит запись значения в базу данных.
:Параметры: name - имя поля, value - значение поля.

=====field(name)=====
:Получить значение поля
:Параметры: name - имя поля
:Результат: значение поля, тип результата зависит от типа поля.

====Свойства====
;title : Имя записи.
;description : Описание записи.
;favorites : Возвращает true - если запись находится в избранном
;deleted : Возвращает true - если запись удалена (находится в корзине).

===Объект DefaultEntry===
Шаблон со значениями по умолчанию для создания новой записи.
====Методы====
=====set(name , value)=====
:Установить значение поля.
:Параметры: name - имя поля, value - значение поля.

===Примеры===

====Валидация данных====
С помощью скриптов можно проверять корректность вводимых данных. Например для поля Целое число допустимы значения только от 0 до 200.
<source lang="javascript" line>
var num = entry().field("Number")
if (num < 0 || num > 200) {
message("Wrong range");
cancel();
}
</source>
#Получаем значение поля Number
#Проверяем значение на соответствие допустимому диапазону
#Если значение выходит за рамки диапазона то выводим сообщение ''Wrong range''.
#Отменяем операцию.
Данный скрипт следует использовать для действия ''Создание записи'' или ''Изменение записи'' и фазы ''Перед сохранением''.

====Установка значений по умолчанию====
Если стандартными средствами невозможно установить для поля требуемое значение по умолчанию то это можно сделать через скрипт.

=====Предыдущее значение из другого поля=====
Есть библиотека содержащая записи о дневном пробег автомобиля, велосипеда или ваших прогулках. В библиотеки есть поле StartingMileage и Mileage. При создании записи требуется в поле StartMileage заносить данные из поля Mileage предыдущей записи.
<source lang="javascript" line>
var entries = lib().entries();
if (entries.length > 0) {
prevMileage = entries[0].field("Mileage");
entryDefault().set("StartMileage" , prevMileage )
}
</source>
#Получаем текущую библиотеку lib() и список её записей entries()
#Проверяем, что список записей не пустой, иначе прекращаем выполнение скрипта, так как у нас нет предыдущей записи
#Список записей отсортирован от новых к старым, соответственно предыдущая запись находится в начале списка с индексом 0. Получаем значение поля Mileage из предыдущей записи.
#Устанавливаем значение поля Mileage из предыдущей записи как значение по умолчанию для поля StartMileage.
Скрипт должен быть установлен для действия Создание записи и фазы Открытие формы.

=====Начало следующего дня=====
Если требуется в поле дата/время при создании записи устанавливать начало следующего дня, то это может сделать следующий скрипт.
Для скрипта необходимо подключить JavaScript-библиотеку [http://momentjs.com/ moment.js]
<source lang="javascript" line>
var m = moment().add(1,'d')
m.hour(8).minute(0)
entryDefault().set("Date" , m.toDate().getTime())
</source>
#С помощью функции moment() библиотеки '''moment.js''' получаем текущее время и прибавляем 1 день.
#Устанавливаем время 8 часов и 0 минут.
#Записываем значение по умолчанию для поля Date.
Скрипт должен быть установлен для действия ''Создание записи'' и фазы ''Открытие формы''.

==Работа с файлами==
С помощью скриптов можно выполнять чтение или запись файлов расположенных во внутренней памяти устройства или на сд-карте.
Все операции с файлами производятся через объект File, который получается через вызов метода file().

Для работы с файлами для библиотеки должно быть установлено разрешение - на чтение и/или на запись файлов.
===Глобальные Функции===
====file(name)====
Открыть файл для операций чтения или записи.
:Параметр: name - имя и полный путь к файлу. Например, если файл расположен на sd-card, путь должен иметь вид /sdcard/example.txt.
:Результат: Объект File.

===Объект File===
Данный объект возвращается функцией file() и предоставляет доступ к запрошенному файлу. Если файл с указанным в функции file() именем ещё не существует, то но будет создан. После операций чтения или записи файл должен быть закрыть функцией close().
====Методы====
=====readAll()=====
:Reads all lines of the file, and then closes the file.
=====readLine()=====
:Read a line.
=====readLines()=====
:Read the remaining lines in the file and return them in an array.
=====readChar()=====
:Read a character.
=====write(text)=====
:Write strings. This function takes a variable number of arguments, converts each argument to a string, and writes that string to the file.
=====writeLine(text)=====
:Write strings and a newline.
=====close()=====
:Close the file. It may be reopened.
====Свойства====
; exists : true - if and only if the file denoted by this object exists; false otherwise
; length : The length, in bytes, of the file denoted by this object, or 0L if the file does not exist.
; getLineNumber : Get the current line number.

===Примеры===
====Запись и чтение из файла====
<source lang="javascript" line>
f= file("/sdcard/myfile.txt")
file.writeLine("one");
file.writeLine("two");
file.writeLine("three");
file.close();
var a = file.readLines();
</source>
<ol>
<li>Открываем файл myfile.txt на sdcard. Если файл еще не существует, то он будет создан.</li>
<li>Записываем в файл строку "one"</li>
</ol>
<ol start="5">
<li>Закрываем файл, только после этого файл сохраняется.</li>
<li>Считываем из файла все строки, в результате получаем массив строк в переменной a.</li>
</ol>

====Сохранить в файл запись====
Необходимо сохранить запись в формате xml. Запись имеет следующие поля: id , title , date.
<source lang="javascript" line>
var xml = '<record id="' + entry().field("id") + '">' +
'<title>' + entry().field("title") + '</title>' +
'<date>' + entry().field("date") + '</date>' +
'</record>';
f= file("/sdcard/" + entry().field("title") + ".xml");
f.write(xml);
f.close();
</source>
<ol><li>Формируем xml данные из значений полей для записи в файл.</li></ol>
<ol start="5">
<li>Открываем файл, имя файла будет таким же как и имя записи.</li>
<li>Сохраняем в файл xml-данные</li>
<li>Закрываем файл</li>
</ol>

==Выполнение http запросов==
С помощью скриптов можно выполнять http-запросы, что позволяет обмениваться информацией с веб-службами предоставляющими API. Также через http запросы вы можете интегрировать Memento со своей системой.
Все операции с файлами производятся через объект Http, который получается через вызов глобального метода http().

Http запросы доступны при соблюдении двух условий:
# Выполнение скрипта должно быть асинхронным (фоновым), так как обработка запроса по сети может занимать много времени. Таким образом выполнять http-запросы можно только в последних фазах действий.
# В библиотеки должно быть установлено разрешение - Network.
===Объект Http===
Интерфейс выполнения http запросов.
====Методы====
=====get(url)=====
:Выполнить get запрос.
:Параметры: url - http адрес, должен начинаться с http или https
:Результат: HttpResult - объект содержащий результат выполнения http запроса.

===Объект HttpResult===
Результат выполнения http запроса
====Свойства====
;code : http код ответа, если запрос выполнен успешно, то он обычно равен 200.
;body : тело ответа в виде текста.

===Примеры===
====Конвертация валюты====
Библиотека содержит два поля PriceUSD и PriceEUR. Пользователь заполняет только поле PriceUSD, требуется чтобы в поле PriceEUR записывалась цена в евро по текущему курсу.
Создадим триггер на действие ''Создание записи'', фаза выполнения будет ''После сохранения''.
<source lang="javascript" line>
result = http().get("http://api.fixer.io/latest?base=USD")
usdToEur = JSON.parse(result.body)["rates"]["Eur"]
entry().set("PriceEUR" , entry().field( "PriceUSD") * usdToEur )
</source>
#Для получения курсов валют пользуемся сервисом http://fixer.io/. Сервис по запросу http://api.fixer.io/latest?base=USD возвращает курсы валют в JSON формате.
#Воспользуется стандартным JavaScript объектом JSON чтобы распарсить ответ.
#Умножаем цену из поля PriceUSD на коэффициент конвертации валюты и устанавливаем полученное значение в поле PriceEUR.

====Создание задачи в приложении Todoist====
[https://todoist.com Todoist] — это веб-сервис и программа для управления задачами. Веб-сервис предоставляет возможность через [https://developer.todoist.com/ api] создавать задачи.
Приведем скрипт для создания задачи, текст задачи будет браться из записи.
<source lang="javascript" line>
var commands='[{"uuid":"' + guid() + '","temp_id":"' + guid() + '","type":"item_add","args":{"content":"' + entry().field("Task") + '"}}]'
result = http().get("https://todoist.com/API/v7/sync?token=15281e8e4d499dаff817af0b14112eac3176f9dc&commands=" + encodeURIComponent(commands))
if (result.code == 200) message('Task has been successfully created")
</source>
#Составляем команду в json формате для создания задачи в todoist, формат команды описан здесь: https://developer.todoist.com/#add-an-item. В команде должны присутствовать уникальные идентификаторы, для их получения используем глобальную функцию guid().
#Выполняем http запрос. Атрибут token используется для авторизации в todoist, его можно получить в Настройках Todoist вкладка Аккаунт. Так как текст задачи может содержать символы недопустимые в URL-запроса, то экранируем их с помощью стандартной функции encodeURIComponent().
#Выводим пользователю сообщение об успешно созданной задачи.

==Взаимодействие с системой==
===Глобальные Функции===
====message(text)====
:Отобразить пользователю небольшое всплывающее сообщение.
:Параметры: text - текст для отображения.

====cancel()====
:Отменить операцию вызвавшую данный триггер. Многие действия возникают при каких либо операциях с записями (создание, модификация, удаление и .д.). Если фаза действия предшествует операции, то возможно отменить эту операцию с помощью данной функции. Например, применять эту функцию можно при проверки корректности вводимых данных перед сохранением записи.

====system()====
:Получить информацию о системе.
:Результат: Объект System с информацией о системе.

====log(text)====
:Вывести строку в лог-файл выполнения скрипта. Функция будет полезна для отладки скриптов.
:Параметры: Text - текст который будет выведен в лог.

====guid()====
:Генерация случайного текстового идентификатора.
:Результат: Случайная строка-идентификатор.

====intent(action)====
:Создать объект обмена сообщениями - Intent. С помощью данного объекта можно передать данные другому приложению, или заставить другое приложение выполнить какое-либо действие.
:Функция доступна только для Android.
:Параметры: action - Строка, определяющая стандартное действие, которое требуется выполнить (например, view (просмотр) или pick (выбор)).
:Результат: Intent - объект обмена сообщениями.
:После получения объекта требуется добавить в него отправляемые данные и вызывать метод send().
:В Android есть множество встроенных действий, список и описание которых вы можете найти [https://developer.android.com/reference/android/content/Intent.html здесь].

===Объект System===
Данный объект содержит информацию о системе.
====Свойства====
;os : имя операционной системы на которой запущен скрипт.

===Объект Intent===
Объект обмена сообщениями. Объект создается с помощью вызова глобальной функции intent().
====Методы====
=====data(uri)=====
:Установить URI ссылающийся на данные.
:Параметры:uri - URI, ссылающийся на данные, с которыми будет выполняться действие. Это может быть идентификатор контакта, путь к файлу, номер телефона и т.д.
=====mimeType(mime)=====
:Установить MIME тип данных.
:Параметры:mime - MIME тип данных с которыми будет выполняться действие.
=====extra(key, value)=====
:Установить дополнительные данные в виде ключ-значение, которые необходимы для выполнения запрошенного действия. Точно так же, как некоторые действия используют определенные виды URI данных, некоторые действия используют определенные дополнительные данные.
:Параметры:
=====extraLong(key, value)=====
:Установить дополнительные данные в виде ключ-значение, где значение должно быть типом Long.
=====send()=====
:Отправить сообщение.

===Примеры===
====Скрипт открывающий окно набора номера====
В библиотеке должно быть поле Phone, содержащие номер телефона.
<source lang="javascript" line>
i = intent("android.intent.action.DIAL")
i.data("tel:"+entry().field("Phone"))
i.send()
</source>
# Создаем объект обмена сообщениями Intent и указываем действие которое откроет окно набора номера - android.intent.action.DIAL.
# В качестве данных требуется указать номер телефона в формате ''tel:номер''. Номер телефона берем из поля записи Phone.
# Отправляем сообщение.

====Скрипт открывающий приложение для отправки смс-сообщения====
Номер телефона будет определяться полем записи - Phone, а текст сообщения составляется из полей ContactName и Notes.
<source lang="javascript" line>
msg = "Dear, " + entry().field("ContactName") + "\n" + entry().field("Notes")
i = intent("android.intent.action.SENDTO")
i.data("smsto:"+entry().field("Phone"))
i.extra("sms_body" , msg)
i.send()
</source>
# Составляем сообщение из значений полей ContactName и Notes
# Создаем объект обмена сообщениями Intent и указываем действие которое откроет приложение для отправки сообщений- android.intent.action.SENDTO.
# В качестве данных требуется указать номер телефона в формате ''smsto:номер''. Номер телефона берем из поля записи Phone.
# Текст сообщение передаем в дополнительный параметр sms_body.
# Отправляем сообщение.

====Скрипт открывающий форму создания события в Гугл-Календаре.====
Время события и название события будут определяться полями записи.
<source lang="javascript" line>
i = intent("android.intent.action.INSERT")
i.data("content://com.android.calendar/events")
i.extra("title", entry().field("Title"))
i.extra("description" , entry().field("Description"))
i.extraLong("beginTime" , entry().field("Begin").getTime())
i.extraLong("endTime" , entry().field("End").getTime())
i.send()
</source>
# Создаем объект обмена сообщениями Intent и указываем действие которое требуется выполнить, а именно создание объекта - android.intent.action.INSERT.
# Для события android.intent.action.INSERT в data требуется передать базовый Uri создаваемого объекта. Событие в Google-календаре имеет базовый Uri - content://com.android.calendar/events.
# Устанавливаем название события, которое берем из поля Title.
# Устанавливаем описание события, которое берем из поля Description.
# Устанавливаем время начала события, которое берем из поля Begin. Поле Begin должно иметь тип Date/Time. Дополнительный параметр beginTime должен иметь тип Long, поэтому используется метод extraLong.
# Устанавливаем время окончания события, которое берем из поля End. Поле End должно иметь тип Date/Time. Дополнительный параметр endTime должен иметь тип Long, поэтому используется метод extraLong.
# Отправляем сообщение.

Navigation menu