風柳メモ

ソフトウェア・プログラミング関連の覚書が中心

【覚書】クロスドメインな画像を任意のファイル名でダウンロードするためのユーザースクリプトの記述方法

Twitter の原寸画像は、例えば「https://pbs.twimg.com/media/CYhLLnfU0AAbHun.jpg:orig」のようなURLとなっており、これを Windows のブラウザでダウンロードしようとすると、「CYhLLnfU0AAbHun.jpg-orig」のようなおかしな拡張子に変換されて保存されてしまうことがある*1

いちいち拡張子を修正するのが面倒だったため、
furyu.hatenablog.com
では、リンク(A)要素の download 属性で、ちゃんとした拡張子のファイル名(例えば、「CYhLLnfU0AAbHun-orig.jpg」)を指定してやり、リネームの手間を省こうとしたのだが……。
以前、
furyu.hatenablog.com
でも書いたように、クロスドメイン(クロスサイト)に於いては、download属性で指定したファイル名は無視されてしまう。

■例

<a href="https://pbs.twimg.com/media/CYhLLnfU0AAbHun.jpg:orig" download="<任意のファイル名>.jpg" id="download_link_sample_a">ダウンロードリンク-A</a>

これを何とかするための苦肉の策が以下のもの。
例によって、もっとスマートなやり方があればコメント願う。

ユーザースクリプトのサンプル

Cross-Domainなサイトの画像を任意のファイル名でダウンロードするユーザースクリプトのサンプル

このユーザースクリプトを Greasemonkey や Tampermonkey でインストールしてから、このページをリロードすると、↑の例のところに「ダウンロードリンク-B」というリンクが新たに表示されるはず。
これをクリックすると、「<任意のファイル名>.jpg」なるファイル名で画像がダウンロードできる……はず。
何をやっているかは、下記のソースコードを参照。また、このテスト以外には意味はないスクリプトなので、確認が終わったら削除しておくことを推奨。

// ==UserScript==
// @name            sample_download_link
// @namespace       http://furyu.hatenablog.com/
// @author          furyu
// @version         0.1.0.0
// @include         http://furyu.hatenablog.com/*
// @include         https://pbs.twimg.com/media/*
// @description     Cross-Domainなサイトの画像を任意のファイル名でダウンロードするユーザースクリプトのサンプル
// ==/UserScript==

( function () {

'use strict';

var SCRIPT_NAME = 'SAMPLE_DOWNLOAD_LINK',
    IFRAME_NAME = SCRIPT_NAME + '_download_frame',
    filename = '<任意のファイル名>.jpg',
    current_url = window.location.href;

if ( window !== window.parent ) {
    if ( window.name != IFRAME_NAME ) {
        return;
    }
    
    // 親 window から呼び出された画像用 IFRAME の処理
    var image_url = current_url,
        link = document.createElement( 'a' );
    
    link.href = image_url;
    link.download = filename;
    
    document.documentElement.appendChild( link );
    link.click(); // ダウンロード開始
    
    return;
}

// 親 window の処理

var source_image_link = document.querySelector( 'div#download_sample_image_container a#download_link_sample_a' );

if ( ! source_image_link ) {
    return;
}

var download_link = document.createElement( 'a' ),
    image_url = source_image_link.href;

download_link.href = image_url;
download_link.download = filename;
download_link.appendChild( document.createTextNode( 'ダウンロードリンク-B' ) );

download_link.addEventListener( 'click', function ( event ) {

    // リンクがクリックされたら、name を指定した隠し IFRAME を呼び出す
    
    event.stopPropagation();
    event.preventDefault();
    
    var iframe = document.createElement( 'iframe' ),
        iframe_style = iframe.style;
    
    iframe_style.width = '0';
    iframe_style.height = '0';
    iframe_style.visibility = 'hidden';
    
    iframe.src = image_url;
    iframe.name = IFRAME_NAME;
    
    document.documentElement.appendChild( iframe );
    
    return false;
}, false );

source_image_link.parentNode.appendChild( download_link );

} )()

注意

Google Chrome の拡張機能で上記の手法を使用するためには、manifest.json にて、

"content_scripts" : [
    {
        "matches" : [ "http://furyu.hatenablog.com/*", "https://pbs.twimg.com/media/*" ],
        "js" : [ "js/main.js" ],
        "run_at" : "document_end",
        "all_frames" : true
    }
]

のように、「 "all_frames" : true 」を指定して、IFRAME 内に対してもスクリプトが動作するように設定しておく必要がある。

*1:Firefoxだと、「CYhLLnfU0AAbHun.jpg orig.jpg」のようになるので、一応 JPEG としては解釈される

Google Chromeで、スクリプトが拡張機能として動作しているかどうかを判別するには?

furyu.hatenablog.com
等では、単体でユーザースクリプト(Greasemonkey/Tampermonkey)としても動作するスクリプトを、Google Chrome 拡張機能用として転用している。

このとき、

  • ユーザースクリプトとして動作する際には、スクリプト内で定義したデフォルト値を使用
  • 拡張機能として動作する際には、ユーザーが設定可能なオプション値を優先的に使用

という条件を満たさねばならず、そうすると、スクリプト自身が「今、自分はどちらとして動作しているか」を判別する必要が出てくる。

これをお手軽に知る方法はないか、検索をかけてみたのだけれど、探し方が悪いのか、なかなかしっくりくる方法が見つからない。
そこで、苦肉の策として以下のような方法を用いているのだが、もし読者の方でより簡便な方法をご存知の方がおられれば、ご教示願いたい。

1. manifest.json にて、初期化用スクリプトとメインスクリプトを、別々のタイミングで起動

"content_scripts" : [
    {
        "matches" : [ "https://twitter.com/*" ],
        "js" : [ "js/init.js" ],
        "run_at" : "document_start"
    },
    {
        "matches" : [ "https://twitter.com/*" ],
        "js" : [ "js/main.js" ],
        "run_at" : "document_end"
    }
],
"background" : {
    "scripts" : [ "js/background.js" ]
}

例の中の init.js が初期化用(document_start: DOM構築開始時に起動)で、main.js がユーザースクリプトを兼ねたメインスクリプト(document_end: DOM構築完了時に起動)。

なおバックグラウンドスクリプト(background.js)では、chrome.runtime.onMessage.addListener() で設定したリスナーにより、localStorageから取り出したユーザーオプション値を返す処理を定義しておく。

2. 初期化用スクリプト(init.js)内にて、ユーザーが設定したオプション値を取得する関数を定義

window.init_extension = function( callback ) {
    /* 任意の前処理 */
    chrome.runtime.sendMessage( {
        /* background.js で規定の処理を呼び出すためのパラメータ */
    }, function ( response ) {
        var user_options;
        /* response を解析して、ユーザーオプションを取得する処理 */
        callback( user_options );
    } );
};

background.js に対してchrome.runtime.sendMessage()にてメッセージを送信し、必要なユーザーオプションを取得した上で、コールバック関数に渡してやる関数を定義しておく。

3. メインスクリプト(main.js)内にて、2. の関数が定義されているかどうかで、処理を振り分け

if ( typeof window.init_extension == 'function' ) {
    // 拡張機能として動作
    window.init_extension( function( user_options ) {
        main( user_options ); // ユーザーオプションを設定
    } );
}
else {
    // ユーザースクリプトとして動作
    main(); // オプション未指定→デフォルト値を使用
}

2. で定義する関数が存在するかどうかにより、

  • 存在する場合: 拡張機能として動作しているとみなして当該関数を呼び出し、ユーザーオプションを取得して使用
  • 存在しない場合: ユーザースクリプトとして動作しているとみなし、デフォルト値を使用

Twitter 原寸びゅー:原寸画像を開く拡張機能&ユーザースクリプト(PC用Google Chrome・Firefox・Opera等対応)



Web 版公式 Twitter上で、ツイートの画像を原寸*1で表示したり保存することが出来るようになるスクリプトです。
バージョン 0.1.5 以降、TweetDeck にも対応。
Chrome 拡張機能版(Google Chrome/Opera/Vivaldi対応)、Firefox Quantum アドオン版と、ユーザースクリプト版(Firefox/Google Chrome/Microsoft Edge/Opera対応)とがあります。
Windows 7 Professional SP1 Windows 10 Pro 上にて動作確認2016/01/16→2016/05/22→2017/01/02時点ソースコードはGitHub上にて公開しています。
また、ブックマークレット版も用意しました。こちらは保存関係の機能は使えませんが、一応 Internet Explorer 11や Microsoft Edge でも動作します。


動作イメージ

www.youtube.com
デモは Chrome 拡張機能版 0.1.4.500 のものです。
オプションの表示と変更・コンテキストメニュー(右クリック)からの保存は、拡張機能版でのみ動作します。

インストール

Chrome 拡張機能版(Google Chrome/Opera対応)

chrome.google.com
より追加。
「Twitter 原寸びゅー」のページに表示されている [+ CHROME に追加] ボタンを押してインストールして下さい。
Operaの場合、あらかじめ
https://addons.opera.com/ja/extensions/details/download-chrome-extension-9/?display=enを導入しておけば、同様にインストール可能。

Firefox Quantum アドオン版(WebExtensions)

addons.mozilla.org

より追加。
ページ上に表示されている [+ Firefox へ追加] ボタンを押してインストールして下さい。

ユーザースクリプト(Greasemonkey / Tampermonkey)版(Firefox/Google Chrome/Edge/Opera対応)

Firefox+Gresemonkey、Google Chrome+Tampermonkey、Microsoft Edge+Tampermonkey、あるいは Opera+Tampermonkeyの環境で、

Twitter 原寸びゅー・ユーザースクリプト版(twOpenOriginalImage.user.js)

GitHub - furyutei/twOpenOriginalImage: Twitter 原寸びゅー

をクリックし、指示に従ってインストール。

必要であれば、

Twitter 画像ダウンロードヘルパー(twImageDownloadHelper.user)

GitHub - furyutei/twOpenOriginalImage: Twitter 原寸びゅー

も同様にインストール。
バージョン 0.1.3.0 以降、画像ダウンロードヘルパーの機能は原寸びゅーに吸収したため、画像ダウンロードヘルパーのインストールは必要なくなりました。

ブックマークレット版(IE11/Edge/Google Chrome/Firefox/Opera対応)

Twitter 原寸びゅー

Twitter 原寸びゅー - Hatena::Let

2016年6月現在、Microsoft Edgeだと、ブックマークレットを登録するのがかなり面倒みたいですね……参考:[Windows 10]Microsoft Edgeでブックマークレットを使う。 | 初心者備忘録

使い方

基本的な使用方法

インストール後には、Web 版公式 Twitter上で、画像を含むツイートに対し、[原寸画像]ボタンが追加されるようになります。
ブックマークレット版の場合は、Twitterのタイムラインが表示された状態で、実行(ブックマークレットをクリック)してください。

このボタン(もしくはサムネイル)をクリックすることで、原寸の画像(URLの後ろに「:orig」がついたもの)を開くことができます。
タイムライン上であれば、[j][k]キーで移動後、[v]キーを押すことで、当該のツイートの画像を開くこともできます*2
デフォルトでは、

  • クリック → ひとつのページにまとめて開く
  • [Alt]+クリック → 複数画像がある場合、各画像毎にページが開く(twitter原寸ボタン互換動作)

となります。
動作を逆にしたい場合、拡張機能版ではオプション設定で変更可能です。
ユーザースクリプト版の場合は、インストール後にソースコードの一部変更が必要になります(「■ パラメータ」のところにある、「DISPLAY_ALL_IN_ONE_PAGE : true」の、true を false に書き換えます)。

0.1.4.1 以降、「ひとつのページにまとめて開く」操作をすると、別タブではなく、タイムラインと同じタブ上に、原寸画像をオーバーレイ(ポップアップ)表示するようになりました。
従来通りにしたい場合、拡張機能版ではオプション設定のオーバーレイを無効にしてください。
ユーザースクリプト版の場合、ソースコードの「■ パラメータ」のところにある、「DISPLAY_OVERLAY : true」の、true を false に書き換えます。

画像ダウンロードヘルパーが有効な場合*3、[ダウンロード]リンクが付きます。これを押すと、当該画像がダウンロードできます。
この際、ダウンロードするファイル名は、URLが例えば「…….jpg:orig」の場合には、「……-orig.jpg」に変換するようにしています……これまで、ダウンロード後に手動で拡張子を修正するのがわずらわしかったので…。

また、オーバーレイ(ポップアップ)表示時に[z]キーを押すことで、表示されている画像をまとめてZIP化したものをダウンロードできます*4

Chrome 拡張機能版のみの機能

拡張機能版の場合、オプションでデフォルト動作やボタンのテキスト等を変更できます。

また、画像を右クリックしてコンテキストメニューを開くと、直接「原寸画像を保存」もできます*5
この場合も、ダウンロードされるファイル名の拡張子は「…….jpg-orig」→「……-orig.jpg」のように書き換わります。

注意書き(不具合と対処方法等)

Chrome 拡張機能版で無効化される場合

バージョン:0.1.2以降、Twitter 画像ダウンロードヘルパーの機能を追加したため、対象となるドメインが増えています。
以前は twitter.com のみだったものに、pbs.twimg.com を追加。

バージョン:0.1.5以降では、TweetDeck対応のため、tweetdeck.twitter.com も追加されています。

バージョン:0.1.8.301以降では、「閲覧履歴の読み取り」権限を追加しています。

名称で警戒されるかもしれませんが、実際にはタブを操作するための権限であり、オプション変更時にTwitter/TweetDeckの全タブをリロードするためのものです。本拡張機能では、閲覧履歴は利用していません。

このため、それより前のバージョンで使用していて自動アップデートされた場合など、要求される権限の変更により、一時的に Google Chrome 側で無効化されてしまう(ツールバーからアイコンが消える)ことがあるようです。

この場合も、拡張機能の画面 chrome://extensions/ (「≡」(右上のハンバーガーメニュー)→「その他のツール(L)」→「拡張機能(E)」)を開き、「Twitter 原寸びゅー」を探して、「□ 有効にする」のチェックボックスにチェックを入れることで、再度有効にすることができます。

また、ダイアログが表示された場合には、[再度有効にする]([権限の許可])ボタンを押してください。


Chromeのバージョンによって、表示される画面や文言などが変更になっていることがあります。

[ダウンロード]ボタンが同じ画像に二つ表示されてしまう

Twitter 画像ダウンロードヘルパー(twImageDownloadHelper.user)をインストールしていませんか?
インストールしている場合には、これを削除しておいてください。
バージョン:0.1.3.0以降、拡張機能版・ユーザースクリプト版共に、Twitter 画像ダウンロードヘルパー(twImageDownloadHelper.user)の機能は Twitter 原寸びゅー側に吸収されたため、このスクリプトは不要となりました。

[ダウンロード]ボタンを押すと、タブが閉じられてしまう

リンクの target 属性を無効化する(target="_blank"等となっていても構わずに同一のタブに表示する)ような設定や拡張機能を入れている場合に、[ダウンロード]ボタンを押すと、画像がダウンロードされるとともに、そのタブが閉じてしまうといった現象が発生するようです。

当方の環境では、Firefox 43.0.4 にて、Tab Mix Plus 0.4.2.0 を入れている場合に発生しました。
この場合には、アドオンの設定画面 about:addons(「≡」(右上のハンバーガーメニュー)→「アドオン」)で、
「拡張機能」→(Tab Mix Plusの)[設定]→「リンク」タブ→「☑ ファイルをダウンロードするときに空白タブが開かないようにする」
のチェックを外して[適用]してやれば、タブが閉じられる現象は発生しなくなりました。
その代わりに他の動作で不都合があるかもしれませんが……。

画像の保存場所をその都度選択したい

画像のダウンロード時に保存場所を尋ねてくるかどうかは、ブラウザの設定に従います。
例えば Google Chrome であれば、
「≡」(右上のハンバーガーメニュー)→「設定(S)」→「詳細設定を表示...」→「ダウンロード」
にて、
「☑ ダウンロード前に各ファイルの保存場所を確認する」
にチェックがついていれば、ダウンロード時に保存場所が確認されます。

Firefox で ZIP ダウンロード時に警告が出る

Firefoxでは、ZIPファイルをダウンロードすると、「このファイルを開くのは危険です」という警告が表示される場合があります(危険なファイルなんて含んでいないんですが……)。
今のところ、対処方法が見つかっておりません……悪しからず。
一応、about:preferences#privacy(「≡」→「オプション」→「プライバシーとセキュリティ」)→「セキュリティ」→「フィッシング防護」→「☑不要な危険ソフトウェアを警告する」のチェックを外すと警告は出なくなりますが、その分他のサイトで危険が増すのでお勧めはできません。

開発の経緯

Twitterの画像は、縮小やトリミングがされていたりサムネイル状態だったりで、見難いことも多いです。
画像のURLの後ろに「:orig」と付けてやれば原寸画像を開くことはできますが、いちいちやるのは面倒で……と思っていたら、便利な拡張機能が公開されていることを知りました。

hogashi 氏(id:hogashi/[twitter:@hogextend])の、
hogashi.hatenablog.com
というものです。

大変便利でしたが、ひとつのツイートに複数の画像がある場合には複数のタブが開いてしまい、ちょっとわずらわしかったため、とりあえずブックマークレット
let.hatelabo.jp
などを作ったりしている内に、興が乗ってしまい、いちから実装してしまった次第です。
なお、ひととおり作って満足してしまったため、今後の更新を行うかどうか怪しいです(汗)。不安な方は
twitter原寸ボタンの方をインストールすることをお勧めします。

*1:画像のURLに『:orig』もしくは『name=orig』がついているものを便宜上『原寸』としています。実際には縮小されている場合もあります

*2:2016/02/01・0.1.3.1以降

*3:拡張機能版は0.1.2.0以降・ユーザースクリプト版は0.1.3.0以降。なお、ブックマークレット版では、画像ダウンロードヘルパー機能は未サポート。

*4:0.1.7.1 以降

*5:2016/02/02・0.1.3.101以降

ZIPファイルに日本語ファイル名が含まれる場合の文字化け予防方法(Windows7, CentOS 6)

他のシステムで作成されたZIPファイルを解凍した際に日本語ファイル名が文字化けする不具合への対処法をいくつか。



Windows7 の場合

標準の状態だと、Shift-JIS(CP932)以外でエンコードされていると、文字化けする。

これまでは

無料圧縮・解凍フリーソフト CubeICE - CubeSoft

などを使うことで対処していたが、日本語ファイル名が UTF-8 でエンコードされているものについては、Windows7・Windows Server 2008 R2 用 Hotfix を適用すれば解消される模様。

File names are corrupted after you decompress a .zip file in Windows 7 or in Windows Server 2008 R2

CentOS 6 の場合(unzip)

CentOS 6 系で yum を使ってインストールできる unzip (CentOS 6.6では現在 unzip-6.0-2.el6_6.x86_64) では、日本語ファイル名には未対応のため、エンコードに関わりなく文字化けしてしまう。

【UTF-8 エンコード時】

$ /usr/bin/unzip -l ./AmazonMusicDownload.zip
Archive:  ./AmazonMusicDownload.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
  8381815  10-11-2015 01:53   ?????????????(???????????????)/Cherish you/01 - Cherish you.mp3
  9099388  10-11-2015 01:53   ?????????????+?????????????????/?????????????+????????????????? ??????????????+??+????????+???????????????/01
- Blooming Lily.mp3
  8447415  10-11-2015 01:54   ?????????????+?????????????????/?????????????+????????????????? ??????????????+??+????????+???????????????/03
- ???????????????????????????.mp3
---------                     -------
 25928618                     3 files

【Shift-JIS エンコード時】

$ /usr/bin/unzip -l ./sjis-sample.zip
Archive:  ./sjis-sample.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  10-11-2015 10:59   ?????+???????????-????/?????+???????????-???? ?L?????N?^?[?C???[?W?\???O?W/
  9099388  10-11-2015 01:53   ?????+???????????-????/?????+???????????-???? ?L?????N?^?[?C???[?W?\???O?W/01 - Blooming Lily.mp3
  8447415  10-11-2015 01:54   ?????+???????????-????/?????+???????????-???? ?L?????N?^?[?C???[?W?\???O?W/03 - ?`???X?L?????_???X.mp3
        0  10-11-2015 10:59   ?X?????q??(???????F??)/Cherish you/
  8381815  10-11-2015 01:53   ?X?????q??(???????F??)/Cherish you/01 - Cherish you.mp3
---------                     -------
 25928618                     5 files


そこで、unzip 6.0 Shift-JIS対応版 をインストールすることで対応してみることに。

unzip 6.0 Shift-JIS対応版のインストール方法
$ git clone https://github.com/ted-n/unzip.git
$ cd unzip/unzip60
$ make -f unix/Makefile LOCAL_UNZIP="-D_FILE_OFFSET_BITS=64 -DNO_LCHMOD -D_MBCS -DNO_WORKING_ISPRINT" generic_gcc
$ sudo make -f unix/Makefile install

これで、/usr/local/bin 下にパッチの当たった unzip がインストールされる。
一行目を修正("git clone git@github.com:ted-n/unzip.git"としていたが、これは予めSSH Keyの設定が必要なため)

【UTF-8 エンコード時】

$ /usr/local/bin/unzip -l ./AmazonMusicDownload.zip
Archive:  ./AmazonMusicDownload.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
  8381815  10-11-2015 01:53   氷堂美智留(矢作紗友里)/Cherish you/01 - Cherish you.mp3
  9099388  10-11-2015 01:53   冴えない彼女の育てかた/冴えない彼女の育てかた キャラクターイメージソング集/01 - Blooming Lily.mp3
  8447415  10-11-2015 01:54   冴えない彼女の育てかた/冴えない彼女の育てかた キャラクターイメージソング集/03 - 饒舌スキャンダラス.mp3
---------                     -------
 25928618                     3 files

【Shift-JIS エンコード時】

$ /usr/local/bin/unzip -l ./sjis-sample.zip
Archive:  ./sjis-sample.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  10-11-2015 10:59   冴えない彼女の育てかた/冴えない彼女の育てかた キャラクターイメージソング集/
  9099388  10-11-2015 01:53   冴えない彼女の育てかた/冴えない彼女の育てかた キャラクターイメージソング集/01 - Blooming Lily.mp3
  8447415  10-11-2015 01:54   冴えない彼女の育てかた/冴えない彼女の育てかた キャラクターイメージソング集/03 - 饒舌スキャンダラス.mp3
        0  10-11-2015 10:59   氷堂美智留(矢作紗友里)/Cherish you/
  8381815  10-11-2015 01:53   氷堂美智留(矢作紗友里)/Cherish you/01 - Cherish you.mp3
---------                     -------
 25928618                     5 files
Python で Shift-JIS エンコードしたファイル名で圧縮する場合の注意

自分はこれまで、Linux(CentOS) 上の Python で日本語ファイル名を含んだ ZIP ファイルを作成する場合でも、Windows で扱いやすくするために Shift-JIS(CP932) でエンコードしたファイル名で圧縮していたのだが、こうして作成したファイルを上記のパッチ済みの unzip で表示すると、なぜか文字化けしてしまった。

【オリジナルの unzip 6.0 使用時】

$ /usr/bin/unzip -l ./test.zip
Archive:  ./test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      400  10-11-2015 15:57   ???{????f?B???N?g??/???{???t?@?C????.txt
---------                     -------
      400                     1 file

【パッチ済みの unzip 使用時】

$ /usr/local/bin/unzip -l ./test.zip
Archive:  ./test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      400  10-11-2015 15:57   傔
                                ・fB
                                    Ng
                                      /傔
                                         黎@C
                                             シ.txt
---------                     -------
      400                     1 file

調べてみると、どうも ZIP ファイルヘッダの version(ZipInfo.create_system) が 3 (Unix) になっているとこの現象が発生するようなので、これを考慮して Python スクリプトを作成する必要がある模様。
zipfile.py の class ZipInfo の定義を見てみると、sys.platform が 'win32' のときは self.create_system に 0 が、それ以外は 3 がデフォルトで設定されている。

【例】

import czipfile as zipfile
import datetime

zip = zipfile.ZipFile( 'test.zip', 'w' )
timestamp = datetime.datetime.now()
dir_filename = u'日本語のディレクトリ/日本語ファイル名.txt'
content = 'test' * 100

zipinfo = zipfile.ZipInfo(
  filename = dir_filename.encode( 'cp932', 'replace' ),
  date_time = ( timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute, timestamp.second )
)
zipinfo.compress_type = zipfile.ZIP_DEFLATED
zipinfo.create_system = 0 # 0 - MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems), 3 - UNIX (https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)

zip.writestr( zipinfo, content )
zip.close()
$ /usr/local/bin/unzip -l ./test.zip
Archive:  ./test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      400  10-11-2015 15:59   日本語のディレクトリ/日本語ファイル名.txt
---------                     -------
      400                     1 file

追記(2015/10/26)

【覚書】はてなブログのレスポンシブWebデザイン対応

ほんとうに今更ながら、はてなブログはテーマ(テンプレート)によってはレスポンシブWebデザインに対応していることに気付く。
スマートフォンでアクセスする際に「PCのときとURLが変わってしまうのは不便だなー」と思っていたことだし、本ブログも対応してみることに。

手順1:レスポンシブ対応のテーマをインストール

テーマ ストアでレスポンシブ対応のテーマを探してインストール。
なお現状、レスポンシブ対応のテーマを探す機能などはないので、自力で探すしかない。

自分は、たまたま目についたシンプルな

Simple Gray - テーマ ストア - はてなブログ

をインストールしてベースにさせていただいた。


今気が付いたが、レスポンシブ対応テーマを探すには、

はてなブログのレスポンシブデザイン対応のテーマ集24個【随時更新】(スマホでもPCとほぼ同じ表示になるテンプレート) - 広汎性発達障害の女が毒を吐くブログ

の記事が便利そう。

手順2:CSS等の調整

デザイン設定で、CSSを適当に(好みに合わせて)調整。
自分の場合、はてなダイアリーのときに使用していたテーマの色合いが気に入っていたので、それに近い感じにしてみた。

また、ヘッダの下に検索フォームを設置し、画面の横幅が 1150px 以下のときには表示されるようにしておいた。
サイドバーが下に落ちて、検索フォームにアクセスしづらくなったときの代用。

手順3:レスポンシブ(スマートフォン)対応設定

デザインCSS先頭に、

/*
  Responsive: yes
 */

のようなコメントを追加したのち、スマートフォン→詳細設定にて、☑ レスポンシブデザインにチェックを入れる。

参考

レスポンシブデザインのテーマを作成する際の注意点

デザインCSSに Responsive: yes のコメントを入れるのは、忘れやすいので注意。