aboutsummaryrefslogtreecommitdiffstats
path: root/notifier/subject_weather_yahoo.js
blob: 72bcaa0f9b9e61b9c0118c2ce3912d6e3f863770 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*** BEGIN LICENSE BLOCK {{{
  Copyright (c) 2008 suVene<suvene@zeromemory.info>

  distributable under the terms of an MIT-style license.
  http://www.opensource.jp/licenses/mit-license.html
}}}  END LICENSE BLOCK ***/
// PLUGIN_INFO//{{
var PLUGIN_INFO =
<VimperatorPlugin>
  <name>{NAME}</name>
  <description>Yahoo! Weather forecast notice.</description>
  <description lang="ja">Yahoo!天気予報通知</description>
  <author mail="suvene@zeromemory.info" homepage="http://zeromemory.sblo.jp/">suVene</author>
  <version>0.1.3</version>
  <license>MIT</license>
  <minVersion>2.0pre</minVersion>
  <maxVersion>2.0pre</maxVersion>
  <updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/notifier/subject_weather_yahoo.js</updateURL>
  <detail><![CDATA[
== Options ==
>||
liberator.globalVariables.subject_weather_yahoo_urls = [url1, url2,]
||<
- @see http://weather.yahoo.co.jp/weather/
  ]]></detail>
</VimperatorPlugin>;
//}}}
(function() {

var notifier = liberator.plugins.notifier;
if (!notifier) return;

var libly = notifier.libly;
var $U = libly.$U;
var logger = $U.getLogger("subject_weather_yahoo");

var URLs = liberator.globalVariables.subject_weather_yahoo_urls || [
  "http://weather.yahoo.co.jp/weather/jp/27/6200/27127/5300001.html",
  "http://weather.yahoo.co.jp/weather/jp/13/4410/13113/1500001.html"
];

URLs.forEach(function(url) {
  notifier.subject.register(notifier.SubjectHttp, {
    interval: 10,
    options: {
      url: url,
      headers: null,
      extra: { encoding: "euc-jp" }
    },
    parse: function(res) {
      var parsed = res.getHTMLDocument(
                      'id("cat-pass yjw_pinpoint_today yjw_pinpoint_tomorrow")'
                   );
      if (!parsed.length) return;

      var now = new Date();
      var hours = now.getHours();
      var start = Math.floor(hours / 3) + 1;
      var yahooToday = $U.getFirstNodeFromXPath("descendant::h3/span/text()", parsed[1]);
      yahooToday = yahooToday.textContent.replace(/.*\u6708(\d+)\u65E5.*/, "$1"); // 月($1)日
      var source, cloneTable;


      if (yahooToday == now.getDate()) {
          source = parsed[1];
      } else {
          source = parsed[2];
      }

      var table = $U.getFirstNodeFromXPath("descendant::table", source);
      table.style.width = "95%";
      table.style.color = "#222";
      var cloneTable = table.cloneNode(false);
      this.cloneTable(cloneTable, table, start, start + 3, true);

      // concat tommorow
      if (start > 6)
          this.cloneTable(cloneTable,
                  $U.getFirstNodeFromXPath("descendant::table", parsed[2]),
                  1, (3 - (8 - start)), false);

      var df = window.content.document.createDocumentFragment();
      df.appendChild(parsed[0]);
      df.appendChild(cloneTable);

      var next = new Date();
      next.setHours(now.getHours() + 1)
      next.setMinutes(0);
      next.setSeconds(30);
      this.interval = (next.getTime() - now.getTime()) / 1000;

      return df;
    },
    cloneTable: function(source, table, start, end, withHead) {
      var rows = table.getElementsByTagName("tr");
      for (let r = 0, len = rows.length; r < len; r++) {
          let row = withHead ? rows[r].cloneNode(false) : source.getElementsByTagName("tr")[r];
          let cols = rows[r].getElementsByTagName("td");
          if (withHead)
              source.appendChild(row);
          for (let c = 0, len2 = cols.length; c < len2; c++) {
              if ((withHead && c == 0) || (start <= c && c < end)) {
                  row.appendChild(cols[c].cloneNode(true));
              }
          }
      }
      return source;
    },
    buildMessages: function(diff)
      new notifier.Message("Weather forecast by Yahoo!", $U.xmlSerialize(diff), url)
  });
});

})();
// vim: set fdm=marker sw=2 ts=2 sts=0 et:

an>) d.callback.ok = fun; d.canceller = function () { try { clearTimeout(id) } catch (e) {} }; return d; }; Deferred.wait = function (n) { var d = new Deferred(), t = new Date(); var id = setTimeout(function () { d.call((new Date).getTime() - t.getTime()); }, n * 1000); d.canceller = function () { clearTimeout(id) }; return d; }; function http (opts) { var d = Deferred(); var req = new XMLHttpRequest(); req.open(opts.method, opts.url, true, opts.user || null, opts.password || null); if (opts.headers) { for (var k in opts.headers) if (opts.headers.hasOwnProperty(k)) { req.setRequestHeader(k, opts.headers[k]); } } req.onreadystatechange = function () { if (req.readyState == 4) d.call(req); }; req.send(opts.data || null); d.xhr = req; return d; } http.get = function (url) http({method:"get", url:url}); http.post = function (url, data) http({method:"post", url:url, data:data, headers:{"Content-Type":"application/x-www-form-urlencoded"}}); Deferred.Deferred = Deferred; Deferred.http = http; // copied from AutoPagerize (c) id:swdyh function getElementsByXPath(xpath, node){ node = node || document; var nodesSnapshot = (node.ownerDocument || node).evaluate(xpath, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var data = []; for(var i = 0, l = nodesSnapshot.snapshotLength; i < l; data.push(nodesSnapshot.snapshotItem(i++))); return (data.length > 0) ? data : null; } function getFirstElementByXPath(xpath, node){ node = node || document; var result = (node.ownerDocument || node).evaluate(xpath, node, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); return result.singleNodeValue ? result.singleNodeValue : null; } // copied from Pagerization (c) id:ofk function parseHTML(str, ignoreTags) { var exp = "^[\\s\\S]*?<html(?:\\s[^>]*)?>|</html\\s*>[\\S\\s]*$"; if (ignoreTags) { if (typeof ignoreTags == "string") ignoreTags = [ignoreTags]; var stripTags = []; ignoreTags = ignoreTags.filter(function(tag) tag[tag.length - 1] == "/" || !stripTags.push(tag)) .map(function(tag) tag.replace(/\/$/, "")); if (stripTags.length > 0) { stripTags = stripTags.length > 1 ? "(?:" + stripTags.join("|") + ")" : String(stripTags); exp += "|<" + stripTags + "(?:\\s[^>]*|/)?>|</" + stripTags + "\\s*>"; } } str = str.replace(new RegExp(exp, "ig"), ""); var res = document.implementation.createDocument(null, "html", null); var range = document.createRange(); range.setStartAfter(window.content.document.body); res.documentElement.appendChild(res.importNode(range.createContextualFragment(str), true)); if (ignoreTags) ignoreTags.forEach(function(tag) { var elements = res.getElementsByTagName(tag); for (var i = elements.length, el; el = elements.item(--i); el.parentNode.removeChild(el)); }); return res; } var DownloadManager = Cc['@mozilla.org/download-manager;1'] .getService(Ci.nsIDownloadManager); const nicoApiEndPoint = 'http://www.nicovideo.jp/api/getflv?v='; const nicoWatchEndPoint = 'http://www.nicovideo.jp/watch/'; var groupId = liberator.globalVariables.nicovideo_mylist || ''; function NiconicoFlvHandler(url, title) { let videoId = url.match(/\w{2}\d+/)[0]; let fileName = title.replace(/[?\\*\/:<>|"]/g, '_') + '.flv'; Deferred.http.get(nicoApiEndPoint + videoId).next(function(apiResult){ let flvUrl = decodeURIComponent(apiResult.responseText.match(/url=(.*?)&/)[1]); return Deferred.http.get(nicoWatchEndPoint + videoId).next(function(watchPage){ let WebBrowserPersist = Cc['@mozilla.org/embedding/browser/nsWebBrowserPersist;1'] .createInstance(Ci.nsIWebBrowserPersist); let sourceUri = makeURI(flvUrl, null, null); let file = DownloadManager.userDownloadsDirectory; file.appendRelativePath(fileName); let fileUri = makeFileURI(file); let download = DownloadManager.addDownload( 0, sourceUri, fileUri, fileName, null, null, null, null, WebBrowserPersist ); WebBrowserPersist.progressListener = download; WebBrowserPersist.saveURI(sourceUri, null, null, null, null, file); }); }).error(function(e){ log(e); liberator.echoerr(e); }); } var count = 0; function NiconicoMylistHandler(url, title){ let videoId = url.match(/\w{2}\d+/)[0]; Deferred.wait(count++ * 5).next(function(est){ return Deferred.http.get(nicoWatchEndPoint + videoId).next(function(watchResult){ var html = parseHTML(watchResult.responseText, ['img', 'script']); var csrfToken = getElementsByXPath('//input[@name="csrf_token"]', html)[0].value; var mylists = getElementsByXPath('id("mylist_add_group_id")/option', html).map(function(element) [element.innerHTML, element.value]); var params = [['ajax', '1'], ['mylist', 'add'], ['mylist_add', '�o�^'], ['csrf_token', csrfToken], ['group_id', groupId]].map(function(p) p[0] + "=" + encodeURIComponent(p[1])).join("&"); return Deferred.wait(count++ * 5).next(function(est){ return Deferred.http.post(nicoWatchEndPoint + videoId, params).next(function(mylistResult){ liberator.log(mylistResult.responseText); }); }); }); }).error(function(e){ log(e); liberator.echoerr(e); }); } function setupLDRizeCooperationNiconicoFlvFetcher() { let NiconicoFlvFetcher = { pattern: 'http://www.nicovideo.jp/watch/*', handler: { download: NiconicoFlvHandler, mylist: NiconicoMylistHandler }, wait: 5000, }; this.convertHandlerInfo([NiconicoFlvFetcher]); this.handlerInfo.unshift(NiconicoFlvFetcher); } if (liberator.plugins.LDRizeCooperation === undefined) { liberator.plugins.LDRizeCooperationPlugins = liberator.plugins.LDRizeCooperationPlugins || []; liberator.plugins.LDRizeCooperationPlugins.push(setupLDRizeCooperationNiconicoFlvFetcher); } else { setupLDRizeCooperationNiconicoFlvFetcher.apply(liberator.plugins.LDRizeCooperation); } function httpGET(uri, callback) { let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) callback.call(this,xhr.responseText); else throw new Error(xhr.statusText) } }; xhr.open('GET', uri, true); xhr.send(null); } liberator.modules.commands.addUserCommand( ['fetchflv'], 'Download flv file from Nicovideo', function (arg) { httpGET( arg.string || liberator.modules.buffer.URL, function (responseText) { let [, title] = responseText.match(/<title(?:[ \t\r\n][^>]*)?>([^<]*)<\/title[ \t\n\r]*>/i); liberator.log(title); NiconicoFlvHandler(arg.string || liberator.modules.buffer.URL, title); } ); }, {} ); liberator.modules.commands.addUserCommand( ['nicomylist'], 'Select Nicovideo mylist', function (arg) { groupId = arg.string; }, { completer: function(context,arg){ Deferred.http.get(nicoWatchEndPoint + "sm2757983").next(function(watchResult){ var html = parseHTML(watchResult.responseText, ['img', 'script']); var mylists = getElementsByXPath('id("mylist_add_group_id")/option', html).map(function(element) [element.value, element.innerHTML]); context.title = ['ID', 'Name']; context.advance = mylists.length; context.completions = mylists; }).error(function(e){ log(e); liberator.echoerr(e); }); } }); })();