メモ用サブブログ

子曰わく學びて時にこれを習う。

【Mac】Pythonで作成日が同時刻のファイルのタイムスタンプをインクリメントして一括変更するスクリプトを書いた

経緯と用途

自分は画像や動画等メディア系ファイルを保存した時に、名前のフォーマットがバラバラだと見た目が大変鬱陶しいので150124222459.jpgのようにファイル作成日の日付で揃えるようにしている。

リネームには「Name Mangler」というソフトを用いている。
中々優秀なソフトなのだが困ったことがひとつある。

タイムスタンプが同時刻だと名前が衝突してしまいリネームができなくなる。

Windowsでは「ファイル名変更君」というその名もズバリな素晴らしいソフトがあって、ファイル名変更君ではタイムスタンプを指定時刻から1秒ごとずらして変更するなど気の効いたこともでき、痒い所に手の届く丁寧な出来で重宝していた。

ところがMacには中々どうして、ファイル名変更君ほど優秀なソフトがない。Shupapanではタイムスタンプ変更ができるのだが、すべてのファイルが指定時刻に統一されてしまってこれでは使い物にならない。

そこでPythonでファイルのタイムスタンプを1秒づらしながら一括変更するスクリプトを書いた。

本当はシェルスクリプトでまかないたかったのだが未学者だし記法がクソすぎて学習コストが高いので慣れてるPythonで済ますことにした。(これだから永久にシェルスクリプトに手が回らない)

スクリプト

import os
import glob
import datetime

files = glob.glob('./*')
diffsec = 0
for file in files:
    diffsec += 1
    createdate_tap = datetime.datetime.now() + datetime.timedelta(seconds=diffsec)
    updatedate_tap = datetime.datetime.now() + datetime.timedelta(seconds=diffsec)
    times = (int(createdate_tap.strftime('%s')), int(updatedate_tap.strftime('%s')))
    os.utime(file, times)

使用方法と注意点

上のスクリプトをテキストファイルに貼り付け、適当な名前.pyで保存する。
タイムスタンプを変更したいファイルの入ったフォルダへこのファイルを置き、そのディレクトリでこのスクリプトを実行すると、そのディレクトリ内のすべてのファイルのタイムスタンプが現在時刻+差分秒へ置き換わる。

注意点としては、どうもMacでは、Pythonのos.utimeで作成日を変更しようとした時に実際の作成日より新しい日付には変更できないらしく、そのまま据え置きになってしまう。

なのでいつも作成日でファイル名を統一していた場合、更新日で変更することになる。

未検証だがMacのsettimeコマンドであれば、作成日より未来日付であっても変更が反映されるのかもしれない。(検証しろよ。)

参考

初めてのPython 第3版

初めてのPython 第3版

追記

どうせなので見なおしてコマンド化しました。 retasretas/tsinc

JavaScript callメソッド

Elastic SVG Elements | コリスというライブラリ(?なのか?これは)のソースを見ていたら次のようなコードを見つけた。

[].slice.call( document.querySelectorAll( 'button.button--effect-2' ) ).forEach( function( el ) {
                    new SVGButton( el, {
                        speed : { reset : 650, active : 650 },
                        easing : { reset : mina.elastic, active : mina.elastic }
                    } );
                } );

[].slice.call()ってなんだよ、と思って調べたらこういうことらしい。

applyとcallの使い方を丁寧に説明してみる - あと味

いやはやまったく知らなかった。JavaScriptの柔軟さもとい奇っ怪さはは深遠なり。

開眼!  JavaScript ―言語仕様から学ぶJavaScriptの本質

開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質

JavaScript逆引きレシピ jQuery対応 (PROGRAMMER’S RECiPE)

JavaScript逆引きレシピ jQuery対応 (PROGRAMMER’S RECiPE)

IEでクリッカブルマップ(イメージマップ)が効かない 意外な落とし穴

間違った例(動かない)

<img src="img.png" alt="aaa" usemap="foo">
<map name="foo">
    <area shape="rect" coords="73,68,117,85" href="hoge">
    <area shape="rect" coords="123,69,165,84" href="piyo">
</map>

正しい例(動く)

<img src="img.png" alt="aaa" usemap="#foo">
<map name="foo">
    <area shape="rect" coords="73,68,117,85" href="hoge">
    <area shape="rect" coords="123,69,165,84" href="piyo">
</map>

どこが違うのかわかったでしょうか。

正解はここです。

(正) usemap="#foo"
(誤) usemap="foo"

usemap属性にはシャープをつけないと正しく機能しない模様です。

ぐぐってもズバリ言ってる情報がなかったので、この罠にハマりました。

jekyll カテゴリをURLは英語のままに日本語化する方法

jekyllのカテゴリは不便なことにカテゴリ名がそのままURLになってしまう。
WordPressのようにURLとしてのカテゴリ名と表示名としてのカテゴリ名を分けることができない。

故に日本語でカテゴリを名づけたい時に困ったことになる。

Capistranoでデプロイを自動化しているのだが、手動でアップの時はいいのだがCapistranoを使ってSSHでアップしようとすると日本語のカテゴリが入ってるとうまく作動してくれない。

ということで、やはり日本語のカテゴリを使いたい場合でもURLは英語のままのほうが無難ということになる。

そこで根本的な解決ではないが以下のような方法を考えた。

フィルタで表示だけ日本語化してしまう対策。

# カテゴリを日本語にする
module CustomFilter
  def toja(input)
    patternes = {
        "test" => "テスト",
        "dogs" => "犬のこと",
        "money" => "お金のこと",
        "cats"  => "猫たち"
    }
    
    if patternes[input] != nil
        patternes[input]
    else
        input
    end
    
  end
end

Liquid::Template.register_filter(CustomFilter)

このようなファイルを作り適当な名前.rb_pluginsディレクトリ以下に配置する。

そしてVIEW側で

<h2>{{page.category | toja}}</h2>

のようにすれば無事、URLは英語のままにカテゴリ名を日本語化することに成功した。

patternesの対応表を増やして自分好みにアレンジしてくだされい。

参考

Liquid フィルタの書き方 - 情報と音楽

Ruby mapメソッドと省略表記

これらの条件から、フォローされているユーザーに対応するidの配列が必要であることがわかってきました。これを行う方法の1つは、Rubyのmapメソッドを使用することです。このメソッドはすべての "列挙可能 (enumerable)" オブジェクト (配列やハッシュなど、要素の集合で構成されるあらゆるオブジェクト11) で使用できます。このメソッドの使用法については4.3.2でも説明しました。以下のように使用します。

$ rails console
>> [1, 2, 3, 4].map { |i| i.to_s }
=> ["1", "2", "3", "4"]

上に示したような状況では、各要素に対して同じメソッド (この場合to_s) が実行されます。これは非常によく使われる方法であり、以下のようにアンパサンド &と、メソッドに対応するシンボルを使用した短縮表記も可能です12。この短縮表記なら変数iを使用せずに済みます。

>> [1, 2, 3, 4].map(&:to_s)
=> ["1", "2", "3", "4"]

Ruby on Rails チュートリアル:実例を使って Rails を学ぼう