0%

movian-plugin-tips

URIMovian Plugin 的入口,本篇文章分析 URI 的实现

addURI

plugin object

addURI: function(re, callback) {
  var page = require('movian/page');
  return new page.Route(re, callback);
},

page

exports.Route = function(re, callback) {

  this.route = require('native/route').create(re, function(pageprop, sync, args) {

    try {

      // First, convert the raw page prop object into a proxied one
      pageprop = prop.makeProp(pageprop);

      // 将参数拆分出来,传入 fun 中执行
      // Prepend a Page object as first argument to callback
      args.unshift(new Page(pageprop, sync, false));


      callback.apply(null, args);
    } catch(e) {

      if(!prop.isZombie(pageprop)) {
        throw e;
      } else {
        console.log("Page at route " + re + " was closed, error supressed");
      }
    }
  });
}

URI 执行流程

Movian 输入 ted:start 之后的流程

11:15:19.974: navigator       [INFO ]: Opening search:ted:start
11:15:19.975: ted             [DEBUG]: Opening route ^ted:start
[prop directory {"persistent", "previous", "how", "close", "url", "parentUrl", "directClose", "eventSink", "bookmarked", "model", "glw"}]
false
[object Object]
11:15:19.975: HTTP            [INFO ]: Connect to www.ted.com:443
newest
Newest


11:30:06.881: navigator       [INFO ]: Opening ted:index:funny:Funny
11:30:06.881: ted             [DEBUG]: Opening route ^ted:index:(.*):(.*)
11:30:06.881: ted             [DEBUG]:   Page argument 1 : funny
11:30:06.881: ted             [DEBUG]:   Page argument 2 : Funny
[prop directory {"persistent", "previous", "how", "close", "url", "parentUrl", "directClose", "eventSink", "bookmarked", "model", "glw"}]
false
[object Object],funny,Funny

nav_open0 ->
nav_open_backend ->
nav_open_thread ->
backend_open ->
be_open ->
ecmascript_openuri 完成参数的解析,传入函数中执行

static backend_t be_ecmascript = {
  .be_flags  = BACKEND_OPEN_CHECKS_URI,
  .be_open   = ecmascript_openuri,
  .be_search = ecmascript_search,
};

BE_REGISTER(ecmascript);
void backend_register(backend_t *be)
{
  LIST_INSERT_HEAD(&backends, be, be_global_link);
}

#define BE_REGISTER(name)                                              \
INITIALIZER(backend_init_ ## name) {                                 \
  backend_register(&be_ ## name);                                    \
}

因此 be_ecmascript 注册到链表 be

搜索 URI ted:no locatedb_search

12:45:04.096: navigator       [INFO ]: Opening search:ted:nouri
12:45:04.097: FA              [DEBUG]: Searcher: ted:nouri: executing "locate -i -L -q -b 'ted:nouri'"
12:45:06.085: FA              [DEBUG]: Searcher: ted:nouri: Done
12:45:22.445: Callout         [DEBUG]: /data/OpenSourceCode/movian/src/upnp/upnp_event.c:150 executed for 1497161us
12:45:24.057: Callout         [DEBUG]: /data/OpenSourceCode/movian/src/upnp/upnp_event.c:150 executed for 1405651us
12:45:31.823: ted             [DEBUG]: Search for ted:no was closed, error supressed
12:45:31.823: rutracker       [DEBUG]: Search for ted:no was closed, error supressed

nav_open0 ->
nav_open_backend ->
nav_open_thread ->
backend_open ->
be_open ->
locatedb_search ->
fa_searcher ->

examples

plugin.addURI(plugin.getDescriptor().id + ":index:(.*):(.*)", function(page, sort, title) {
    setPageHeader(page, plugin.getDescriptor().title + ' - Sorted by: ' + decodeURIComponent(title));
    scraper(page, BASE_URL + '/talks?sort=' + sort);
});

plugin.addURI(plugin.getDescriptor().id + ":start", function(page) {
    setPageHeader(page, plugin.getDescriptor().title + ' - Sort by:');
    page.loading = true;
    var doc = showtime.httpReq(BASE_URL + '/talks').toString();
    page.loading = false;
    var sort = doc.match(/<optgroup label="Sort by([\s\S]*?)<\/optgroup>/)[1];
    // 1-uri component, 2-title
    var re = /<option value="([\s\S]*?)">([\s\S]*?)<\/option>/g;
    var match = re.exec(sort);
    while (match) {
        // sort: match[1]  title: encodeURIComponent(match[2])
        // 与上面的 URI re 是对应的 plugin.getDescriptor().id + ":index:(.*):(.*)"
        page.appendItem(plugin.getDescriptor().id + ':index:' + match[1] + ':' + encodeURIComponent(match[2]), "directory", {
            title: match[2]
        });
        match = re.exec(sort);
    }
});