ServiceFork Tizen: различия между версиями

Материал из Браузер Fork - Wiki
Перейти к навигации Перейти к поиску
FXML all_*: channel overrides global
FXML all_*: channel overrides global
 
Строка 1: Строка 1:
{{DISPLAYTITLE:ServiceFork — локальные парсеры (Tizen)}}
{{DISPLAYTITLE:ServiceFork — локальные парсеры (Tizen, webOS)}}


<div class="toccolours" style="width:100%; max-width:920px; padding:12px 16px; line-height:1.55;">
<div class="toccolours" style="width:100%; max-width:920px; padding:12px 16px; line-height:1.55;">
На <b>Samsung Tizen</b> Fork browser запускает фоновый HTTP-сервис '''ServiceFork''' (порт '''8092'''): в нём '''Node.js''' парсит сайты и отдаёт страницы в формате '''FXML (JSON)''' с <code>http://127.0.0.1:8092/</code> — без PHP на хостинге.
'''ServiceFork''' — локальные парсеры в Fork browser на <b>Samsung Tizen</b> и <b>LG webOS</b>: фоновый HTTP на порту '''8092''', внутри '''Node.js''' парсит сайты и отдаёт '''FXML (JSON)''' с <code>http://127.0.0.1:8092/</code> — без PHP на хостинге.


Каждый файл-плагин в <code>service/plugins/</code> — отдельный локальный парсер. Если задана функция <code>home()</code>, плитка парсера появляется на домашней странице Fork browser в секции '''Локально'''.
Один каталог <code>service/plugins/</code> и одно ядро <code>service/index.js</code> используются в обеих сборках. Плитки парсеров с <code>home()</code> попадают на домашнюю страницу в секцию '''Локально'''.
 
'''Версия виджета:''' локальные парсеры ServiceFork — начиная с '''1.3.0''' (Tizen .wgt и webOS .ipk). В более старых сборках секция «Локально» без этих плиток.


См. также: [[FXML|Спецификация FXML]] · [https://appfxml.com/ Репозиторий Fork browser]
См. также: [[FXML|Спецификация FXML]] · [https://appfxml.com/ Репозиторий Fork browser]
Строка 11: Строка 13:
== Назначение ==
== Назначение ==


* '''Локальные парсеры''' — каталоги, поиск, просмотр: логика выполняется на TV в Tizen background service (Node.js).
* '''Локальные парсеры''' — каталоги, поиск, просмотр: логика на TV (Node.js в background / JS service).
* Ответ — тот же JSON, что у веб-портала: <code>title</code>, <code>channels[]</code>, глобальные поля (<code>css</code>, <code>typeList</code>, <code>icon</code> …) — см. [[FXML#3. Термины и модель данных|модель FXML]].
* Контракт как у веб-портала: <code>title</code>, <code>channels[]</code>, глобальные поля — см. [[FXML#3. Термины и модель данных|модель FXML]].
* Один файл <code>service/plugins/&lt;id&gt;.js</code> = один парсер с URL <code>http://127.0.0.1:8092/&lt;id&gt;</code>.
* Файл <code>service/plugins/&lt;id&gt;.js</code> → URL <code>http://127.0.0.1:8092/&lt;id&gt;</code> (имя без <code>.js</code>).


== Домашняя страница: секция «Локально» ==
== Домашняя страница: секция «Локально» ==


При старте Fork browser (Tizen) запрашивает <code>http://127.0.0.1:8092/status</code>. ServiceFork собирает массив <code>services</code> из функций <code>home()</code> всех загруженных плагинов (<code>homeServices</code> в <code>service/index.js</code>) и отдаёт плитки в формате FXML-channel (<code>source: service</code>, <code>playlist_url</code>, иконка, меню).
При старте приложение будит ServiceFork и опрашивает <code>http://127.0.0.1:8092/status</code>. В JSON поле '''<code>services</code>''' — плитки из <code>home()</code> всех плагинов (<code>homeServices</code> в <code>service/index.js</code>): FXML-channel с <code>source: service</code>, <code>playlist_url</code>, иконкой.


Клиент добавляет эти плитки в блок <code>ch.service</code> стартовой страницы — в интерфейсе это секция '''Локально''' (рядом с USB, играми и другими локальными пунктами).
Клиент кладёт их в <code>ch.service</code> стартовой страницы — в UI это блок '''Локально'''.


'''Важно:''' без <code>home()</code> парсер доступен только по прямому URL (<code>/&lt;id&gt;</code> или ссылка <code>playlist_url</code> в другом портале), на домашний экран он не попадёт.
'''Важно:''' без <code>home()</code> парсер доступен только по прямому URL или через <code>playlist_url</code> в другом портале, на домашний экран не попадёт.


== Архитектура ==
== Общая архитектура (Tizen и webOS) ==


{| class="wikitable" style="width:100%;"
{| class="wikitable" style="width:100%;"
! Компонент !! Описание
! Компонент !! Описание
|-
|-
| <code>service/index.js</code> || Ядро ServiceFork: HTTP '''8092''', загрузка плагинов, <code>createApi</code>, маршрутизация, <code>/status</code> → <code>services</code>.
| <code>service/index.js</code> || Ядро: HTTP '''8092''', загрузка плагинов, <code>createApi</code>, маршруты, <code>/status</code> → <code>services</code>.
|-
|-
| <code>service/plugins/&lt;id&gt;.js</code> || Модуль парсера: <code>routes</code> (страницы FXML), опционально <code>home()</code> (плитка «Локально»), <code>matchUrl</code> / <code>handleUrl</code> для перехвата внешних ссылок.
| <code>service/plugins/&lt;id&gt;.js</code> || Парсер: <code>routes</code>, <code>home()</code>, опционально <code>matchUrl</code> / <code>handleUrl</code>.
|-
|-
| Fork browser (UI) || Открывает <code>playlist_url</code> плитки или любой <code>http://127.0.0.1:8092/…</code> и рисует JSON как обычную FXML-страницу.
| <code>service/plugins/&lt;id&gt;.png</code> || Иконка плитки (локальный URL на том же порту).
|-
| Fork browser (UI) || <code>playlist_url</code> → <code>127.0.0.1:8092/…</code>, отображение JSON как FXML.
|}
|}


'''Tizen:''' background service приложения (<code>config.xml</code>, пакет <code>&lt;packageId&gt;.servicefork</code>), точки входа <code>onStart</code> / <code>onRequest</code> в <code>service/index.js</code>.
'''Служебные URL''' (одинаково на обеих платформах):
 
'''Служебные URL:'''


{| class="wikitable"
{| class="wikitable"
! Путь !! Ответ
! Путь !! Ответ
|-
|-
| <code>/status</code> || JSON: <code>ok</code>, версия, список плагинов, '''<code>services</code>''' — плитки для секции «Локально»
| <code>/status</code> || JSON: версия, список плагинов, '''<code>services</code>''' для «Локально»
|-
|-
| <code>/</code>, <code>/plugins</code> || Список парсеров (FXML или JSON)
| <code>/</code>, <code>/plugins</code> || Список парсеров
|-
|-
| <code>/logs</code> || Логи service (FXML-страница)
| <code>/logs</code> || Логи (FXML-страница)
|}
|}


Зарезервированные id: <code>status</code>, <code>plugins</code>, <code>logs</code>.
Зарезервированные id: <code>status</code>, <code>plugins</code>, <code>logs</code>.
== Samsung Tizen ==
{| class="wikitable" style="width:100%;"
! !!
|-
| Запуск || Background service в <code>config.xml</code>, пакет <code>&lt;packageId&gt;.servicefork</code>, <code>onStart</code> / <code>onRequest</code> в <code>service/index.js</code>.
|-
| Проект || Tizen Studio, например <code>workspace/Forkbrowser/service/</code>.
|-
| Сборка || .wgt с приложением и service, см. [[Браузер Fork - Wiki:Установить браузер Fork#Samsung Smart TV|установка Tizen]].
|-
| Логи в UI || MessagePort <code>servicefork-log</code> (Tizen).
|}
== LG webOS ==
С '''1.3.0''' webOS использует то же ядро и те же плагины, что Tizen; отличается только обёртка платформы.
{| class="wikitable" style="width:100%;"
! !!
|-
| Luna service || <code>com.forkplayer.tv.service</code> — каталог <code>usr/palm/services/com.forkplayer.tv.service/</code> в IPK.
|-
| Обёртка || <code>service/service.js</code> (<code>webos-service</code>): подключает <code>index.js</code>, держит HTTP :8092 через activity / keepAlive (важно на эмуляторе 3.0, иначе процесс завершается и <code>/rezka</code>, <code>/logs</code> дают «connection refused»).
|-
| Старт из приложения || <code>luna://com.forkplayer.tv.service/start</code> (subscribe) из <code>js/load.js</code>, затем опрос <code>/status</code> → <code>window.servicefork</code>.
|-
| Проект || <code>ForkPlayer_webOS</code>: UI в корне, <code>service/</code> — копия Tizen service + <code>services.json</code>, <code>package.json</code>.
|-
| Сборка IPK || Только через '''ares-package''' (app + service в одном пакете). Ручной <code>tar</code>-IPK на эмуляторе 3.0 даёт «Failed to extract package».
|-
| Пример файла || <code>com.forkplayer.tv_1.3.0_all.ipk</code> — приложение + service в <code>packageinfo</code>.
|}
'''Структура IPK (упрощённо):'''
<pre>usr/palm/applications/com.forkplayer.tv/    ← UI (Fork browser)
usr/palm/services/com.forkplayer.tv.service/ ← ServiceFork :8092 + plugins
usr/palm/packages/com.forkplayer.tv/        ← packageinfo со списком services[]</pre>
Адрес '''127.0.0.1:8092''' на webOS TV и эмуляторе корректен: запросы идут к JS service на том же устройстве. Если плитки есть, а страница парсера не открывается — сервис уже завершился; обновите виджет '''≥ 1.3.0''' с исправленным keep-alive.


== Быстрый старт: свой парсер ==
== Быстрый старт: свой парсер ==


# В Tizen Studio (<code>workspace/Forkbrowser/service/plugins/</code>) скопируйте <code>_template.js</code> → <code>myparser.js</code> (файлы с <code>_</code> в начале имени не загружаются).
# Скопируйте <code>service/plugins/_template.js</code> → <code>myparser.js</code> (файлы <code>_*.js</code> не загружаются).
# Опишите парсер: <code>name</code>, <code>version</code>, маршруты в <code>routes</code> (<code>''</code> — главная, <code>search</code>, <code>list</code> …).
# Задайте <code>name</code>, <code>version</code>, <code>routes</code>; реализуйте <code>home(base)</code> → <code>api.homeTile({…})</code>.
# Реализуйте '''<code>home(base)</code>''' и верните <code>api.homeTile({…})</code> — так парсер появится в '''Локально''' после установки .wgt.
# Положите <code>myparser.png</code> рядом с .js.
# Соберите виджет и установите на TV. Парсер: <code>http://127.0.0.1:8092/myparser</code>
# Соберите виджет '''≥ 1.3.0''' (Tizen .wgt или webOS .ipk) и установите на TV.
# Иконка: положите <code>service/plugins/myparser.png</code> рядом с .js — подставится в плитку.
# Проверка: <code>http://127.0.0.1:8092/status</code>, плитка в «Локально», вход <code>/myparser</code>.
 
Плагины правят в Tizen-проекте и синхронизируют в <code>ForkPlayer_webOS/service/plugins/</code> (или наоборот — ядро общее).


'''Минимальный каркас:'''
'''Минимальный каркас:'''
Строка 89: Строка 135:
};</pre>
};</pre>


При необходимости парсер можно вызывать и с удалённого портала — укажите в JSON <code>"playlist_url": "http://127.0.0.1:8092/myparser"</code> (актуально только на устройстве, где запущен ServiceFork).
Удалённый портал может ссылаться на <code>http://127.0.0.1:8092/myparser</code> — работает только на устройстве с запущенным ServiceFork.


== API ядра (кратко) ==
== API ядра (кратко) ==


Плагин получает объект <code>api</code> из <code>createApi</code> (<code>service/index.js</code>).
Плагин получает <code>api</code> из <code>createApi</code> (<code>service/index.js</code>).


{| class="wikitable"
{| class="wikitable"
! Метод !! Назначение
! Метод !! Назначение
|-
|-
| <code>api.page(title, channels, extra)</code> || FXML-страница (<code>css</code>, <code>typeList</code>, <code>icon</code> в <code>extra</code>)
| <code>api.page(title, channels, extra)</code> || FXML-страница
|-
|-
| <code>api.folder(title, url, opts)</code> || Элемент с <code>playlist_url</code>
| <code>api.folder / api.stream / api.htmlChannel</code> || Элементы списка
|-
|-
| <code>api.stream(title, url, opts)</code> || Элемент с <code>stream_url</code>, опционально <code>parser</code>
| <code>api.homeTile(cfg)</code> || Плитка «Локально»
|-
|-
| <code>api.htmlChannel(cfg)</code> || Channel с <code>position: html</code>, шаблон, меню, поиск
| <code>api.cardChannels</code>, <code>api.getTextCached</code> || Сетки и HTTP
|-
|-
| <code>api.homeTile(cfg)</code> || Плитка для секции «Локально» (<code>source: service</code>)
| <code>api.pluginUrl(base, id, route, params)</code> || URL маршрута
|-
|-
| <code>api.cardChannels(items, base, opts)</code> || Сетка карточек
| <code>api.log.info / warn / error</code> || Логи → <code>/logs</code>
|-
| <code>api.getText / api.getTextCached</code> || HTTP GET HTML
|-
| <code>api.pluginUrl(base, id, route, params)</code> || URL маршрута парсера
|-
| <code>api.log.info / warn / error</code> || Логи → <code>/logs</code> и UI Fork
|}
|}


'''Маршруты:''' ключ — путь после <code>/&lt;pluginId&gt;/</code>; обработчик <code>(ctx, cb)</code>, <code>cb(err, fxmlObject)</code>.
'''Маршруты:''' ключ — путь после <code>/&lt;pluginId&gt;/</code>; <code>cb(err, fxmlObject)</code>.


'''Внешние ссылки:''' <code>matchUrl</code> + <code>handleUrl</code> — перехват полного <code>http(s)://…</code> в адресной строке Fork (см. <code>rezka.js</code>, <code>kinogo.js</code>).
'''Внешние URL:''' <code>matchUrl</code> + <code>handleUrl</code> (см. <code>rezka.js</code>, <code>kinogo.js</code>).


== Иконки и оформление ==
== Иконки и оформление ==


* <code>service/plugins/&lt;id&gt;.png</code> (или .jpg) → <code>http://127.0.0.1:8092/&lt;id&gt;.png</code>
* <code>service/plugins/&lt;id&gt;.png</code> → <code>http://127.0.0.1:8092/&lt;id&gt;.png</code>
* CSS страницы: <code>api.page(..., { css: '...' })</code>
* CSS: <code>api.page(..., { css: '...' })</code>
* Шаблоны карточек: <code>api.htmlChannel({ template: '...' })</code> — плейсхолдеры как в [[FXML#6. Оформление и вёрстка элементов|§6 FXML]]
* Шаблоны: [[FXML#6. Оформление и вёрстка элементов|§6 FXML]]


== Отладка ==
== Отладка ==


# <code>http://127.0.0.1:8092/status</code> — версия, список плагинов, массив <code>services</code> (то, что уходит в «Локально»).
# <code>http://127.0.0.1:8092/status</code> — плагины и массив <code>services</code>.
# <code>http://127.0.0.1:8092/logs</code> — логи; ошибки плагина с префиксом <code>[pluginId]</code>.
# <code>http://127.0.0.1:8092/logs</code> — FXML-логи; <code>?format=raw</code>, <code>?clear=1</code>.
# В Fork логи service также приходят через MessagePort (<code>servicefork-log</code>).
# Tizen: MessagePort <code>servicefork-log</code>.
# webOS: ответ Luna <code>start</code> (поле <code>log</code> в <code>service.js</code>), консоль JS service на TV / эмуляторе.


== Связь с FXML ==
== Связь с FXML ==


{| class="wikitable"
JSON с ServiceFork неотличим от PHP-портала для клиента Fork; парсинг выполняется локально на TV.
! PHP-портал !! ServiceFork (Tizen)
|-
| <code>$_PL</code> / <code>$_CH</code> || <code>api.page()</code>
|-
| <code>json_encode</code> || <code>sendJson</code> в HTTP-ответе
|-
| Ссылки на свой домен || <code>api.pluginUrl</code> → <code>127.0.0.1:8092</code>
|}
 
Для пользователя JSON выглядит одинаково; разница только в том, что парсер крутится локально на TV.


== Примеры в проекте ==
== Примеры ==


* <code>service/plugins/_template.js</code> — шаблон парсера с <code>home()</code> и <code>routes</code>
* <code>service/plugins/_template.js</code>
* <code>service/plugins/rezka.js</code>, <code>kinogo.js</code> — полные парсеры (меню, поиск, <code>matchUrl</code>)
* <code>service/plugins/rezka.js</code>, <code>kinogo.js</code>


== Установка приложения с ServiceFork ==
== Установка ==


Сборка .wgt и установка на Samsung Tizen — [[Браузер Fork - Wiki:Установить браузер Fork#Samsung Smart TV|инструкции по установке]] ([https://appfxml.com/ Apps2Tizen], ForkTizenInstall).
* '''Samsung Tizen''' — [[Браузер Fork - Wiki:Установить браузер Fork#Samsung Smart TV|Apps2Tizen / .wgt]], версия '''≥ 1.3.0''' для ServiceFork.
* '''LG webOS''' — [[Браузер Fork - Wiki:Установить браузер Fork|установка webOS]] (.ipk через Dev Manager / ares-install), пакет '''≥ 1.3.0''' с service в составе IPK.


[[Category:FXML]]
[[Category:FXML]]



Текущая версия от 23:24, 28 октября 2026


ServiceFork — локальные парсеры в Fork browser на Samsung Tizen и LG webOS: фоновый HTTP на порту 8092, внутри Node.js парсит сайты и отдаёт FXML (JSON) с http://127.0.0.1:8092/ — без PHP на хостинге.

Один каталог service/plugins/ и одно ядро service/index.js используются в обеих сборках. Плитки парсеров с home() попадают на домашнюю страницу в секцию Локально.

Версия виджета: локальные парсеры ServiceFork — начиная с 1.3.0 (Tizen .wgt и webOS .ipk). В более старых сборках секция «Локально» без этих плиток.

См. также: Спецификация FXML · Репозиторий Fork browser

Назначение

  • Локальные парсеры — каталоги, поиск, просмотр: логика на TV (Node.js в background / JS service).
  • Контракт как у веб-портала: title, channels[], глобальные поля — см. модель FXML.
  • Файл service/plugins/<id>.js → URL http://127.0.0.1:8092/<id> (имя без .js).

Домашняя страница: секция «Локально»

При старте приложение будит ServiceFork и опрашивает http://127.0.0.1:8092/status. В JSON поле services — плитки из home() всех плагинов (homeServices в service/index.js): FXML-channel с source: service, playlist_url, иконкой.

Клиент кладёт их в ch.service стартовой страницы — в UI это блок Локально.

Важно: без home() парсер доступен только по прямому URL или через playlist_url в другом портале, на домашний экран не попадёт.

Общая архитектура (Tizen и webOS)

Компонент Описание
service/index.js Ядро: HTTP 8092, загрузка плагинов, createApi, маршруты, /status → services.
service/plugins/<id>.js Парсер: routes, home(), опционально matchUrl / handleUrl.
service/plugins/<id>.png Иконка плитки (локальный URL на том же порту).
Fork browser (UI) playlist_url → 127.0.0.1:8092/…, отображение JSON как FXML.

Служебные URL (одинаково на обеих платформах):

Путь Ответ
/status JSON: версия, список плагинов, services для «Локально»
/, /plugins Список парсеров
/logs Логи (FXML-страница)

Зарезервированные id: status, plugins, logs.

Samsung Tizen

Запуск Background service в config.xml, пакет <packageId>.servicefork, onStart / onRequest в service/index.js.
Проект Tizen Studio, например workspace/Forkbrowser/service/.
Сборка .wgt с приложением и service, см. установка Tizen.
Логи в UI MessagePort servicefork-log (Tizen).

LG webOS

С 1.3.0 webOS использует то же ядро и те же плагины, что Tizen; отличается только обёртка платформы.

Luna service com.forkplayer.tv.service — каталог usr/palm/services/com.forkplayer.tv.service/ в IPK.
Обёртка service/service.js (webos-service): подключает index.js, держит HTTP :8092 через activity / keepAlive (важно на эмуляторе 3.0, иначе процесс завершается и /rezka, /logs дают «connection refused»).
Старт из приложения luna://com.forkplayer.tv.service/start (subscribe) из js/load.js, затем опрос /status → window.servicefork.
Проект ForkPlayer_webOS: UI в корне, service/ — копия Tizen service + services.json, package.json.
Сборка IPK Только через ares-package (app + service в одном пакете). Ручной tar-IPK на эмуляторе 3.0 даёт «Failed to extract package».
Пример файла com.forkplayer.tv_1.3.0_all.ipk — приложение + service в packageinfo.

Структура IPK (упрощённо):

usr/palm/applications/com.forkplayer.tv/     ← UI (Fork browser)
usr/palm/services/com.forkplayer.tv.service/ ← ServiceFork :8092 + plugins
usr/palm/packages/com.forkplayer.tv/         ← packageinfo со списком services[]

Адрес 127.0.0.1:8092 на webOS TV и эмуляторе корректен: запросы идут к JS service на том же устройстве. Если плитки есть, а страница парсера не открывается — сервис уже завершился; обновите виджет ≥ 1.3.0 с исправленным keep-alive.

Быстрый старт: свой парсер

  1. Скопируйте service/plugins/_template.js → myparser.js (файлы _*.js не загружаются).
  2. Задайте name, version, routes; реализуйте home(base) → api.homeTile({…}).
  3. Положите myparser.png рядом с .js.
  4. Соберите виджет ≥ 1.3.0 (Tizen .wgt или webOS .ipk) и установите на TV.
  5. Проверка: http://127.0.0.1:8092/status, плитка в «Локально», вход /myparser.

Плагины правят в Tizen-проекте и синхронизируют в ForkPlayer_webOS/service/plugins/ (или наоборот — ядро общее).

Минимальный каркас:

module.exports = function (api) {
  var id = 'myparser';
  return {
    name: 'My Parser',
    version: '1.0.0',
    home: function (base) {
      return api.homeTile({
        id: id,
        base: base,
        title: 'My Parser',
        playlist_url: api.pluginUrl(base, id)
      });
    },
    routes: {
      '': function (ctx, cb) {
        cb(null, api.page('My Parser', [
          api.folder('Раздел', api.pluginUrl(ctx.base, id, 'list'))
        ]));
      },
      list: function (ctx, cb) {
        cb(null, api.page('Список', [
          api.stream('Пример', 'http://example.com/video.m3u8')
        ]));
      }
    }
  };
};

Удалённый портал может ссылаться на http://127.0.0.1:8092/myparser — работает только на устройстве с запущенным ServiceFork.

API ядра (кратко)

Плагин получает api из createApi (service/index.js).

Метод Назначение
api.page(title, channels, extra) FXML-страница
api.folder / api.stream / api.htmlChannel Элементы списка
api.homeTile(cfg) Плитка «Локально»
api.cardChannels, api.getTextCached Сетки и HTTP
api.pluginUrl(base, id, route, params) URL маршрута
api.log.info / warn / error Логи → /logs

Маршруты: ключ — путь после /<pluginId>/; cb(err, fxmlObject).

Внешние URL: matchUrl + handleUrl (см. rezka.js, kinogo.js).

Иконки и оформление

Отладка

  1. http://127.0.0.1:8092/status — плагины и массив services.
  2. http://127.0.0.1:8092/logs — FXML-логи; ?format=raw, ?clear=1.
  3. Tizen: MessagePort servicefork-log.
  4. webOS: ответ Luna start (поле log в service.js), консоль JS service на TV / эмуляторе.

Связь с FXML

JSON с ServiceFork неотличим от PHP-портала для клиента Fork; парсинг выполняется локально на TV.

Примеры

  • service/plugins/_template.js
  • service/plugins/rezka.js, kinogo.js

Установка

  • Samsung Tizen — Apps2Tizen / .wgt, версия ≥ 1.3.0 для ServiceFork.
  • LG webOS — установка webOS (.ipk через Dev Manager / ares-install), пакет ≥ 1.3.0 с service в составе IPK.