root/lang/javascript/vimperator-plugins/trunk/subscldr.js

Revision 36891, 8.1 kB (checked in by anekos, 6 months ago)

feed が取れなかったときのエラーなどを echoerr するようにした

Line 
1//
2// subscldr.js
3//
4// LICENSE: {{{
5//   Copyright (c) 2009 snaka<snaka.gml@gmail.com>
6//
7//     Distributable under the terms of an MIT-style license.
8//     http://www.opensource.jp/licenses/mit-license.html
9// }}}
10//
11// PLUGIN INFO: {{{
12var PLUGIN_INFO =
13<VimperatorPlugin>
14  <name>{NAME}</name>
15  <description>Adds subscriptions to livedoor Reader/Fastladder in place.</description>
16  <description lang="ja">ページ遷移なしでlivedoor ReaderやFastladderにフィードを登録します。</description>
17  <minVersion>2.0pre</minVersion>
18  <maxVersion>2.3</maxVersion>
19  <require type="plugin">_libly.js</require>
20  <updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/subscldr.js</updateURL>
21  <author mail="snaka.gml@gmail.com" homepage="http://vimperator.g.hatena.ne.jp/snaka72/">snaka</author>
22  <license>MIT style license</license>
23  <version>0.2.2</version>
24  <detail><![CDATA[
25    == Subject ==
26    Adds subscriptions to livedoor Reader/Fastladder in place.
27
28    == Commands ==
29    >||
30    :subscldr
31    :subscfl
32    ||<
33
34  ]]></detail>
35
36  <detail lang="ja"><![CDATA[
37    == 概要 ==
38    ページ遷移すること無しにlivedoor ReaderやFastladderへのフィードの登録を行います。
39
40    == コマンド ==
41    >||
42    :subscldr
43    :subscfl
44    ||<
45
46  ]]></detail>
47</VimperatorPlugin>;
48// }}}
49
50liberator.plugins.subscldr = (function() {
51  // PUBLIC {{{
52  var PUBLICS = {
53    // TODO:Provide API function.
54
55    // for DEBUG {{{
56    //getSubscription: getSubscription,
57    //postSubscription: postSubscription,
58    //selectFeed: selectFeed
59    // }}}
60  };
61
62  // }}}
63  // COMMAND {{{
64  addCommand(
65    ["subscldr", "subscrldr"],
66    "livedoor Reader",
67    "http://reader.livedoor.com/subscribe/"
68  );
69
70  addCommand(
71    ["subscfl", "subscrfl"],
72    "Fastladder",
73    "http://fastladder.com/subscribe/"
74  );
75  // }}}
76  // PRIVATE {{{
77  function addCommand (command, servicename, endpoint) {
78
79    function handleFeedRequest(opts, redirectUrl, force) {
80        var subscribeInfo = getSubscription(redirectUrl);
81        var availableLinks = subscribeInfo.feedlinks.filter(function(info) info[1]);
82        var alreadySubscribed = availableLinks.length != subscribeInfo.feedlinks.length;
83
84        if (alreadySubscribed && !force) {
85          liberator.echo("This site has already been subscribed. Are you sure to want to add subscription?");
86          commandline.input("Add? [y/N]:",
87            function(ans) {
88              if (ans.toLowerCase().indexOf("y") == 0) // /^y(?:es)?$/.test(ans.toLowerCase())
89                handleFeedRequest(opts, null, true);
90              else
91                liberator.echo("Canceled.");
92              commandline.close();
93            }
94          );
95          return;
96        }
97
98        switch (availableLinks.length) {
99        case 0:
100          if (alreadySubscribed)
101            liberator.echo("The feed of this site has already been subscribed.");
102          else
103            // Maybe never reach here.
104            liberator.echoerr("SITE FEED NOT AVAILABLE!!!");
105          break;
106        case 1:
107          liberator.log("FEED ONLY ONE!!");
108          subscribeInfo.feedlinks = [availableLinks[0][0], true];
109          postSubscription(subscribeInfo, opts);
110          break;
111        default:
112          liberator.log("SOME FEED AVAILABLE");
113          selectFeed( availableLinks.map(function(i) [i[0], i[2]]),
114            function(sel) {
115              liberator.log("SELECTED FEED:" + sel);
116              liberator.echo("Redirected ...");
117              var redirectUrl = endpoint + "?url=" + encodeURIComponent(sel);
118              handleFeedRequest(opts, redirectUrl);
119            }
120          );
121        }
122    }
123
124    function getSubscription(target) {
125      liberator.echo("Please wait ...");
126      var subscribeInfo;
127
128      var uri = target || endpoint + buffer.URL;
129
130      var req = new libly.Request(uri, null, {asynchronous: false});
131      req.addEventListener("onSuccess", function(res) {
132        liberator.log(res.responseText);
133        res.getHTMLDocument();
134        subscribeInfo = getSubscribeInfo(res.doc);
135        liberator.log(subscribeInfo.toSource());
136      });
137      req.get();
138
139      return subscribeInfo;
140    }
141
142    function postSubscription(info, opts) {
143      liberator.log("subscribe:" + info.toSource());
144
145      var postBody= "url=" + encodeURIComponent(info.target_url) +
146                    "&folder_id=0" +
147                    "&rate=" + (opts.rate || "0") +
148                    "&register=1" +
149                    "&feedlink=" + encodeURIComponent(info.feedlinks[0]) +
150                    "&public=1" +
151                    "&ApiKey=" + info.apiKey;
152
153      liberator.log("POST DATA:" + postBody);
154      var req = new libly.Request(
155        endpoint,
156        null,
157        {
158          asyncronus: false,
159          postBody: postBody
160        }
161      );
162      req.addEventListener("onSuccess", function(data) {
163        liberator.log("Post status: " + data.responseText);
164        liberator.echo("Subscribe feed succeed.");
165      });
166      req.addEventListener("onFailure", function(data) {
167        liberator.log("POST FAILURE: " + data.responseText);
168        liberator.echoerr("POST FAILURE: " + data.statusText);
169      });
170
171      req.post();
172    }
173
174    commands.addUserCommand(
175      command,
176      "Register feed subscriptions to " + servicename + ".",
177      function(args) {
178        try {
179          handleFeedRequest({rate: args["-rate"]});
180        } catch (e) {
181          liberator.echoerr(e);
182        }
183      },
184      {
185        options: [
186          [["-rate", "-r"], commands.OPTION_INT]
187        ]
188      },
189      true  // Use in DEVELOP
190    );
191
192  }
193
194  function getSubscribeInfo(htmldoc) {
195    var subscribeInfo = {
196       target_url: null,
197       register: 1,
198       apiKey: null,
199       feedlinks: []
200    };
201
202    $LXs('id("feed_candidates")/xhtml:li', htmldoc).forEach( function(item) {
203      var feedlink = $LX('./xhtml:a[@class="feedlink"]', item);
204      var title = $LX('./xhtml:a[@class="subscribe_list"]', item);
205      var users = $LX('./xhtml:span[@class="subscriber_count"]/xhtml:a', item);
206      var yet = $LX('./xhtml:input[@name="feedlink"]', item);
207      liberator.log("input:" + feedlink.href);
208      subscribeInfo.feedlinks.push([feedlink.href, (yet != null), (title ? title.textContent : '' ) + ' / ' + (users ? users.textContent :  '0 user')]);
209    });
210
211    var target_url = $LX('id("target_url")', htmldoc);
212    if (!target_url) throw "Cannot find subscribe info about this page!";
213    subscribeInfo.target_url = target_url.value;
214    liberator.log("target_url:" + subscribeInfo.target_url);
215
216    subscribeInfo.apiKey = $LX('//*[@name="ApiKey"]', htmldoc).value;
217    if (!subscribeInfo.apiKey) throw "Can't get API key for subscription!";
218    return subscribeInfo;
219  }
220
221  function selectFeed(links, next) {
222    liberator.log(links.toSource());
223    liberator.echo("Following feeds were found on this site. Which are you subscribe?");
224    commandline.input("Select or input feed URL ", function(selected) {
225      liberator.echo("You select " + selected + ".");
226      commandline.close();
227      if (next && typeof next == "function")
228        next(selected);
229      else
230        liberator.echoerr("Your selected no is invalid.");
231    },{
232      completer: function(context) {
233        context.title = ["Available feeds", "Title / users"];
234        context.completions = links;
235      }
236    });
237    // Open candidates list forcibly
238    events.feedkeys("<TAB>");
239  }
240
241  // For convenience
242  //function $LXs(a,b) libly.$U.getNodesFromXPath(a,b);
243  //function $LX(a,b)  libly.$U.getFirstNodeFromXPath(a,b);
244
245  function nsResolver(prefix) {
246    var ns = { 'xhtml': 'http://www.w3.org/1999/xhtml' };
247    return ns[prefix] || null;
248  }
249
250  function $LXs(a, b) {
251    var ret = [];
252    var res = (b.ownerDocument || b).evaluate(a, b, nsResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
253    for (var i = 0; i < res.snapshotLength; i++) {
254      ret.push(res.snapshotItem(i));
255    }
256    return ret;
257  }
258
259  function $LX(a, b) {
260    var res = (b.ownerDocument || b).evaluate(a, b, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
261    return res.singleNodeValue || null;
262  }
263
264  // }}}
265  return PUBLICS;
266})();
267
268// vim:sw=2 ts=2 et si fdm=marker:
Note: See TracBrowser for help on using the browser.