From c532dbebf0eb99679374c0345cf318bc9ed31fef Mon Sep 17 00:00:00 2001
From: teramako
Date: Mon, 23 Nov 2009 10:49:12 +0000
Subject: ZIPでダウンロードするお
git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@35973 d0d07461-0603-4401-acd4-de1884942a52
---
zip-de-download.js | 282 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 282 insertions(+)
create mode 100644 zip-de-download.js
(limited to 'zip-de-download.js')
diff --git a/zip-de-download.js b/zip-de-download.js
new file mode 100644
index 0000000..3798388
--- /dev/null
+++ b/zip-de-download.js
@@ -0,0 +1,282 @@
+let INFO =
+
+ teramako
+ MIT
+
+
+ 特定ページの画像とかのURLを取ってきて一気にZIPにしてダウンロードするお
+
+
+ -
+ :zipd :zipdownload
+ :zipdownload -list dawonloadPath
+
+
+ downloadPathへZIPでアーカイブする。
+ downloadPathがディレクトリの場合、"ページタイトル.zip"となる。
+ 省略された場合、以下の順に値を見て、そのディレクトリへダウンロードされる。
+
+ - g:zipDownloadDir (liberator.globalVariables.zipDownloadDir)
+ - browser.download.lastDir (Preference)
+ - ホームディレクトリ
+
+
+
+ -listオプションを指定すると、ダウンロードされるURLをリストする。
+ (ダウンロードはされない)
+
+
+
+ -
+ g:zipDownloadDir
+ g:zipDownloadDir
+ liberator.globalVariables.zipDownloadDir
+
+
ダウンロード先ディレクトリ。downloadPathを省略した場合に、使用される。
+ 例
+ :let g:zipDownloadDir=~/downloads
+
+
+
+ -
+ plugins.zipDeDownload.SITE_INFO
+ plugins.zipDeDownload.SITE_INFO
+
+
+ ページ毎の設定。詳細はコードを見よ。(見れば分かると思う)
+
+
+
+;
+
+// FIXME: 将来的には、storageに入れるべき
+// FIXME: あと、それぞれダウンロード先を指定できた方が良い(?)
+// XXX: WeData化してもOK
+let SITE_INFO = [
+ {
+ label: "みんくちゃんねる",
+ site: "http://minkch\\.com/archives/.*\\.html",
+ xpath: '//a[img[@class="pict"]]|//div/img[@class="pict"]',
+ filter: "\\.(jpe?g|gif|png)$"
+ }, {
+ label: "カナ速",
+ site: "http://kanasoku\\.blog82\\.fc2\\.com/blog-entry-.*\\.html",
+ xpath: '//div[@class="entry_body"]//a[img]',
+ filter: "\\.(jpe?g|gif|png)$"
+ }, {
+ label: "がぞう~速報",
+ site: "http://stalker\\.livedoor\\.biz/archives/.*\\.html",
+ xpath: '//div[@class="main" or @class="mainmore"]//a/img[@class="pict"]/..',
+ filter: "\\.(jpe?g|gif|png)$"
+ }, {
+ label: "ギャルゲーブログ",
+ site: "http://suiseisekisuisui\\.blog107\\.fc2\\.com/blog-entry-.*.html",
+ xpath: '//div[@class="ently_text"]/a[img]',
+ filter: "\\.(jpe?g|gif|png)$"
+ }, {
+ label: "わくてか速報",
+ site: "http://blog\\.livedoor\\.jp/wakusoku/archives/.*\\.html",
+ xpath: '//div[@class="article-body-inner" or @class="article-body-more"]//a[//img[@class="pict"]]',
+ filter: "\\.(jpe?g|gif|png)$"
+ }, {
+ label: "らばQ",
+ site: "http://labaq\\.com/archives/.*\\.html",
+ xpath: '//img[@class="pict"]',
+ }, {
+ labe: "【2ch】ニュー速クオリティ",
+ site: "http://news4vip\\.livedoor\\.biz/archives/.*\\.html",
+ xpath: '//a[img[@class="pict"]] | //div/img[@class="pict"]',
+ filter: "\\.(jpe?g|gif|png)$"
+ }, {
+ label: "ねとねた",
+ site: "http://vitaminabcdefg\\.blog6\\.fc2\\.com/blog-entry-.*\\.html",
+ xpath: '//div[@class="mainEntryBody" or @class="mainEntryMore"]//a[img]',
+ filter: "\\.(jpe?g|gif|png)$"
+ }, {
+ label: "PINK速報",
+ site: "http://pinkimg\\.blog57\\.fc2\\.com/blog-entry-.*\\.html",
+ xpath: '//div[@class="entry_text"]/a[img]',
+ filter: "\\.(jpe?g|gif|png)$"
+ }
+];
+
+__proto__ = (function(){
+ // nsIZipWriter#open io-flags
+ const PR_RDONLY = 0x01;
+ const PR_WRONLY = 0x02;
+ const PR_RDWR = 0x04;
+ const PR_CREATE_FILE = 0x08;
+ const PR_APPEND = 0x10;
+ const PR_TRUNCATE = 0x20;
+ const PR_SYNC = 0x40;
+ const PR_EXCL = 0x80;
+
+ const mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
+ const zipWriter = Components.Constructor("@mozilla.org/zipwriter;1", "nsIZipWriter");
+
+ function getFile(aFile){
+ return liberator.modules.io.File(aFile);
+ }
+ function createChannel(url){
+ return liberator.modules.services.get("io").newChannel(url, "UTF-8", null);
+ }
+ function getEntryName(uri, mimeType){
+ let mime;
+ try {
+ mime = mimeService.getTypeFromURI(uri);
+ } catch(e) {
+ liberator.reportError(e);
+ };
+ let ext = mimeService.getPrimaryExtension(mime ? mime : mimeType, null)
+ let name = uri.path.split("/").pop();
+ name = (name ? name : "index") + (mime ? "" : "."+ext);
+ return name;
+ }
+ function getDownloadDirectory(){
+ let path = liberator.globalVariables.zipDownloadDir ||
+ liberator.modules.options.getPref("browser.download.lastDir", null) ||
+ liberator.modules.services.get("directory").get("Home", Ci.nsIFile).path;
+ return getFile(path);
+ }
+ let self = {
+ downloadZip: function(path, urls, comment, isAppend){
+ let zipW = new zipWriter();
+ let urls = [url for each(url in urls)];
+ liberator.assert(urls.length < 1, "None of URLs");
+
+ if ((/\.zip$/i).test(path)){
+ path += ".zip";
+ }
+ let zipFile = getFile(path);
+ if (isAppend && zipFile.exists()){
+ zipW.open(zipFile, PR_RDWR | PR_APPEND);
+ } else {
+ zipW.open(zipFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
+ }
+
+ if (comment)
+ zipW.comment = comment;
+
+ let i = 0;
+ for each(let url in urls){
+ let ch = createChannel(url);
+ let stream = ch.open();
+ let entryName = ("000" + ++i).slice(-3) +"-"+ getEntryName(ch.URI, ch.contentType);
+ liberator.echomsg("zip: " + url + " to " + entryName, 3);
+ zipW.addEntryStream(entryName, Date.now() * 1000, Ci.nsIZipWriter.COMPRESSION_DEFAULT, stream, false);
+ }
+ zipW.close();
+ return zipFile;
+ },
+ getInfoFromBuffer: function(){
+ for each(data in SITE_INFO){
+ let reg = new RegExp(data.site);
+ if (reg.test(liberator.modules.buffer.URL)){
+ return data;
+ }
+ }
+ return null;
+ },
+ getURLs: function(info){
+ let filter = new RegExp(info.filter ? info.filter : ".");
+ let i = 0;
+ for (let elm in liberator.modules.util.evaluateXPath(info.xpath, content.document)){
+ let url;
+ if (elm instanceof Ci.nsIDOMHTMLAnchorElement)
+ url = elm.href;
+ else if (elm instanceof Ci.nsIDOMHTMLImageElement)
+ url = elm.src;
+ else
+ continue;
+
+ if (filter.test(url))
+ yield url;
+ }
+ },
+ download: function(zipPath, listOnly, option){
+ let info = this.getInfoFromBuffer() || {};
+ if (option){
+ let infoBuf = {};
+ for (let key in info){
+ infoBuf[key] = info[key];
+ }
+ for (let key in option){
+ infoBuf[key] = option[key];
+ }
+ info = infoBuf;
+ }
+ liberator.assert(info.xpath, "not registered in SITE_IFO");
+
+ let urls = this.getURLs(info);
+ let title = liberator.modules.buffer.title;
+ let comment = [title, liberator.modules.buffer.URL].join("\n");
+ let file;
+ if (!zipPath){
+ file = getDownloadDirectory();
+ file.append(title + ".zip");
+ } else {
+ file = getFile(zipPath);
+ if (file.exists() && file.isDirectory()){
+ file.append(title + ".zip");
+ }
+ }
+ if (listOnly){
+ return [file, urls, comment];
+ }
+ return this.downloadZip(file.path, urls, comment, info.append);
+ }
+ };
+
+ // ---------------------------------------------------
+ // Commands
+ // ---------------------------------------------------
+ liberator.modules.commands.addUserCommand(
+ ["zipd[ownload]"], "download and archive to ZIP",
+ function (arg){
+ let option = {}
+ option.append = ("-append" in arg);
+ if ("-xpath" in arg){
+ option.xpath = arg["-xpath"];
+ }
+ if ("-list" in arg){
+ let [file, urls, comment] = self.download(arg[0], true, option);
+ let xml = <>
+ Download :{file.path}
+ {comment}
+
+ {liberator.modules.template.map(urls, function(url) - {url}
)}
+
+
+ >;
+ liberator.echo(xml, true);
+ return;
+ }
+ let zipFile = self.download(arg[0], false, option);
+ liberator.echo("Completed DownloadZip: " + zipFile.path);
+ }, {
+ argCount: "?",
+ literal: true,
+ options: [
+ [["-list","-l"], liberator.modules.commands.OPTION_NOARG],
+ [["-append","-a"], liberator.modules.commands.OPTION_NOARG],
+ [["-xpath","-x"], liberator.modules.commands.OPTION_STRING],
+ ],
+ completer: liberator.modules.completion.file
+ }, true);
+
+ return self;
+})();
+// vim: sw=2 ts=2 et:
--
cgit v1.2.3