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)
  1. {url}
  2. )} +
+
+ ; + 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