diff options
-rw-r--r-- | zip-de-download.js | 282 |
1 files changed, 282 insertions, 0 deletions
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 = +<plugin name="zip-de-download" version="0.5" + href="" + summary="ZIPでダウンロードするお" + xmlns="http://vimperator.org/namespaces/liberator"> + <author email="teramako@gmail.com">teramako</author> + <license href="http://opensource.org/licenses/mit-license.php">MIT</license> + <project name="Vimperator" minVersion="2.3"/> + <p xmlns={XHTML}> + 特定ページの画像とかのURLを取ってきて一気にZIPにしてダウンロードするお + <code style='font-family: sans-serif !important;'><![CDATA[ + /) + ///) + /,.=゙''"/ + / i f ,.r='"-‐'つ____ こまけぇこたぁいいんだよ!! + / / _,.-‐'~/⌒ ⌒\ + / ,i ,二ニ⊃( ●). (●)\ + / ノ il゙フ::::::⌒(__人__)⌒::::: \ + ,イ「ト、 ,!,!| |r┬-| | + / iトヾヽ_/ィ"\ `ー'´ / + ]]></code> + </p> + <item> + <tags>:zipd :zipdownload</tags> + <spec>:zipd<oa>ownload</oa> <oa>-l<oa>ist</oa></oa> <a>dawonloadPath</a></spec> + <description> + <p> + <a>downloadPath</a>へZIPでアーカイブする。 + <a>downloadPath</a>がディレクトリの場合、"ページタイトル.zip"となる。 + 省略された場合、以下の順に値を見て、そのディレクトリへダウンロードされる。 + <ul> + <li>g:zipDownloadDir (liberator.globalVariables.zipDownloadDir)</li> + <li>browser.download.lastDir (Preference)</li> + <li>ホームディレクトリ</li> + </ul> + </p> + <p> + <oa>-l<oa>ist</oa></oa>オプションを指定すると、ダウンロードされるURLをリストする。 + (ダウンロードはされない) + </p> + </description> + </item> + <item> + <tags>g:zipDownloadDir</tags> + <spec><oa>g:</oa>zipDownloadDir</spec> + <spec>liberator.globalVariables.zipDownloadDir</spec> + <description> + <p>ダウンロード先ディレクトリ。<a>downloadPath</a>を省略した場合に、使用される。</p> + <p>例 + <code><ex>:let g:zipDownloadDir=~/downloads</ex></code> + </p> + </description> + </item> + <item> + <tags>plugins.zipDeDownload.SITE_INFO</tags> + <spec>plugins.zipDeDownload.SITE_INFO</spec> + <description> + <p> + ページ毎の設定。詳細はコードを見よ。(見れば分かると思う) + </p> + </description> + </item> +</plugin>; + +// 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 = <> + <h1><span>Download :</span><span>{file.path}</span></h1> + <p>{comment}</p> + <ol> + {liberator.modules.template.map(urls, function(url) <li>{url}</li>)} + </ol> + <br/> + </>; + 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: |