古い写真のアルバムをスマホで見るようにしたお話
Advent Calendar2018 Elixir(Days15), fukuoka.ex Elixir/Phoenix(Days16) and Vim2(Days15)
Summary
家にあった古いアルバムをデジタル化した話
写真アルバム(左)が誰でもiPhone
で見れるようになった(右)
ゴールとかとか
Motivation
引っ越すよ
写真アルバムはスペースとるよ
誰もみてないよ
捨てるのもアレだよね
Goal
場所をとらないようにする
気軽に見れるようにする
やってみようと思ったこと
写真をデーター化して Apple's iCloud
の Shared albums
を利用して家族の誰でも気楽に写真を見れるようにする!
Tools
写真整理につかったスクリプトとかとか
Script lang | description |
---|---|
BashScript | 写真データーの枚数を数える |
BashScript | Exifデーターを連番にする |
Elixir | Exifデーターを連番にする |
Elixir, F# | ElixirとF#のちょっとした比較表 |
F# | 写真データーのファイル構成を変える |
Vim | Vim Manコマンドの設定 |
Vim | vim-refを使ってヘルプを調べる |
やったこと
01. 業者さんに写真データーのデジタル化を依頼
02. 納品データーのチェック
03. 重複データーを除く
04. 時系列に並び替えてグルーピングする
05. Apple Shared albums に写真をアップロードする
01 業者さんにデジタル化依頼
ここの作業、楽かと思ってたのですが意外とつらかったです・・・
01 アルバムをページごとにすべてデジカメで写真を撮る
02 アルバムから写真をべりべりはがす
03 アルバムごとの写真の枚数をエクセルに記入する
04 業者さんに発送
01-01 アルバムをページごとにすべてデジカメで写真を撮る
まず控えとして写真アルバムを記録します。写真の並びとか文字情報とかかなり重要なんで絶対に撮っておきます。(単調作業で途中で嫌になってきます)
01-02 アルバムから写真をべりべりはがす
依頼用にベリベリ剥がします。業者さんのコースによっては剥がさなくてもいいコースがあるのですが依頼料金が跳ね上がるので、お金のない callmekohei
は頑張ってベリベリ剥がしましたよ。 写真を傷つけないようにかなり神経を使うので休み休みやるのがおすすめ。心を無にしてマシーンになりませう!
01-03 アルバムごとの写真の枚数をエクセルに記入する
剥がした写真の枚数をエクセルとかに簡単にメモしておきます
01-04 業者さんに発送
依頼書類とか制約事項誓約書とかを記入して、箱詰めとかして業者さんに送ります
この状態にするのも一苦労やで・・・
02 納品データーのチェック
ここはコーヒー片手にささっとできちゃいます
01 納品データーのファイル構成を確認
02 枚数のチェック
03 以前に控えたアルバムの写真とつきあわせ
02-01 納品データーのファイル構成を確認
callmekohei
は DVD
での納品形態を選んだので、外付けのHDD
に一旦コピーします。(作業をしやすくするため)
こんな感じのファイル構成でした
納品データー/
├── DVD1
│ ├── _インデックス
│ └── バラ写真
│ ├── BA001
│ | ├── 色補正前データー
│ | | ├── BA001_0001.jpg
│ | | ├── BA001_0002.jpg
│ | | └── ...
│ | └── 色補正後データー
│ | ├── BA001_0001.jpg
│ | ├── BA001_0002.jpg
│ | └── ...
│ └── BA010
├── DVD2
│ ├── _インデックス
│ └── バラ写真
│ ├── BA011
│ ├── ...
│ └── BA029
├── DVD3
│ ├── _インデックス
│ └── フィルム
│ ├── SL001
│ | ├── 色補正前データー
│ | | ├── SL001_0001.JPG
│ | | ├── SL001_0002.JPG
│ | | └── ...
│ | └── 色補正後データー
│ | ├── SL001_0001.JPG
│ | ├── SL001_0002.JPG
│ | └── ...
│ └── SL050
└── DVD4
├── _インデックス
├── フィルム
│ ├── SL051
│ ├── ...
│ └── SL090
└── ポケットフィルム
├── PF001
| ├── 色補正前データー
| | ├── PF001_0001.JPG
| | ├── PF001_0002.JPG
| | └── ...
| └── 色補正後データー
| ├── PF001_0001.JPG
| ├── PF001_0002.JPG
| └── ...
├── ...
└── PF005
02-02 枚数のチェック
下記のコマンドでフォルダ毎に写真データーの枚数を出して、前にエクセルに記入した写真の枚数と照合します
#!/usr/bin/env bashfunction foo (){local folder=$1local path=${HOME}/Desktop/albums/${folder}for d in$(find $path-type d)do
local cnt=$(ls"$d" | grep-e'jpg'-e'JPG' | wc-l)if[!$cnt=="0"];then
echo$d" ---> "$cnt\
| grep-e'BA'-e'SL'-e'PF'\
| sed-e's|'${HOME}'/Desktop/albums||g'fi
done}
foo DVD1 | sort
foo DVD2 | sort
foo DVD3 | sort
foo DVD4 | sort
結果
/DVD1/バラ写真/BA001/色補正前のデータ ---> 53
/DVD1/バラ写真/BA001/色補正後のデータ ---> 53
/DVD1/バラ写真/BA002/色補正前のデータ ---> 86
...
02-03 以前に控えたアルバムの写真とつきあわせ
枚数はオーケーだったので、内容を目視でチェックします。ここはまぁだいたいで。
02-04 フォルダ構成を変更する
扱いやすいようにファルダ構成を変えます
色補正後データーに特に問題がなかったのでその分のデーターをまとめて下記のようにします
納品データー/
├── BA
| ├── BA001
| ├── BA001_0001.JPG
├── SL
| ├── SL001
| ├── SL001_0001.JPG
└── PF
├── PF001
├── PF001_0001.JPG
03 重複データーのチェック
ここが一番辛かったです・・・。コードを書いて解決できればよかったのですが僕にはそのスキルがなかったです
01 衝(main)となる写真種別を決める
02 重複写真をのぞく(アプリを使用する)
03 重複写真をのぞく(官能評価でおこなう)
03-01 衝(main)となる写真種別を決める
写真種別は今回3種類ありました
写真種別 | 意味 | callmekoheiの感想 |
---|---|---|
SL | フィルムからのデーター | 結構クリア |
PF | フィルムからのデーター | 結構クリア |
BA | 現像プリント写真からのデーター | 野暮ったい感じ |
SL,PF
にしかない写真もあれば、BA
にしかない写真もありますが、大部分はSL,PF
にもあってかつBA
にあるという状況でした。
何点か見比べてSL,PF
を衝としました。もしかしたらBA
のほうが綺麗な(味のある)写真があるかもですがそこはもう機械的にばっさりいきます
SLとBAのデーターの比較(左がSL, 右がBA)
03-02 重複写真をのぞく(アプリを使用する)
Similar Photos Cleanerというアプリを使ってみたのですが、小一時間やってみたのですが、callmekohei
的にはうまく使いこなせず、思うように重複写真をピックアップできなかったです。
かなり迷ったのですが、目視で行くことに決めました!
03-03 重複写真をのぞく(官能評価でおこなう)
目視で重複データーをチェックしました。
まず全ての写真のコンタクトシートを印刷します。コンタクトシートとは写真の一覧表です。左にSL,PF
のコンタクトシート、右にBA
のコンタクトシートを置いて、SL,PF
の写真一枚毎にBA
の写真全てに対して重複チェックします。重複写真が一枚の場合もあればそれ以上の場合もあるので最後までBA
の写真を確認します
実際の作業様子
トランプの神経衰弱っていうゲームあるじゃないですか?あれの辛いバージョンな感じでしたよ。。。
04 時系列に並び替える、フォルダわけ
重複データーを消し込んだら次は時系列に写真をソートします。具体的にはまずソートする前に簡単なメモを作っておきます例えばこんな感じ
あとはアルバムに記載されてた文字情報、アルバムの並び、自分の記憶、人の記憶、背景・風景、人の外見等でソートします(具体的にはPhots.app
のImage > Adjust Date and Time... > Adjusted
にて日時を調整してソートします)。それと割と新し目の写真には右下に日時が印字されてるのですが、間違ってることも多々あるので、おかしいなと思ったら盲目的に信じずに確認したほうがいいです
ここまでできたら、あとは写真をグループ分けするだけです!(僕の場合は引越しが多かったので居住地で分けました)
あとアルバムが結構いい加減で違う時間軸が混じってたりしたのですが、背景は意外と情報を与えてくれて整理するのに役立ちました。例えば下記の写真は、同じアルバムに入ってて並んでたのですが、実は違う住居地だったのが襖の模様でわかるという感じです
05 Apple Shared albums に写真をアップロードする
Apple Shared albums
に追加するのは簡単です。下記の手順で簡単に追加することができます
Shared albums に送りたい写真を選択
> 右クリック
> Shared
> Shared Albums
しかししかし、ここで問題が発生します
05-01 Shared albums に追加する際の問題
同一日時の写真はランダムに追加される
例えば下記3つのファイルはShared albums
に追加する場合、foo01 -> foo03 -> foo02
という並びになってほしいのですが、実際は foo01 -> foo03 -> foo02
もしくは foo03 -> foo01 -> foo02
となります。どちらになるかはその時次第という感じです
foo01.jpg 1983:01:01 12:11:42
foo02.jpg 1983:10:10 12:11:42
foo03.jpg 1983:01:01 12:11:42
追加順を確実にしたい場合は時刻を変更することでできます。たとえば上記のファイルの場合下記のようにすると確実に並び順を確定できます
foo01.jpg 1983:01:01 00:00:01
foo02.jpg 1983:10:10 00:00:03
foo03.jpg 1983:01:01 00:00:02
時刻を変更する場所は Phots.app
のImage > Adjust Date and Time... > Adjusted
にて変更可能です。ただ全ての写真データーに対してこの操作をするのは辛い感じがしたので、ネットで色々調べたところExifTool
というので変更できそうだということがわかりました!
05-02 ExifToolを使ってみる
グーグル検索してみるといろいろなホームページにexiftool
の使い方が載っているのでまずは試してみます
インストール
$ brew install exiftool
日付を変える
// 現状確認
$ exiftool -alldates foo.jpg
Date/Time Original : 1987:03:22 00:00:00
Create Date : 1987:03:22 16:14:50
Modify Date : 1987:03:22 16:14:50
// 日時を変更
$ exiftool -alldates="2999/01/01 00:00:01" foo.jpg
1 image files updated
// 変更されているか確認
$ exiftool -alldates foo.jpg
Date/Time Original : 2999:01:01 00:00:01
Create Date : 2999:01:01 00:00:01
Modify Date : 2999:01:01 00:00:01
foo.jpg
のexif
データーが変更されているのが確認できました
さて今回やりたいことはphoto.app
での表示順どおりにshared albums
にも表示したいということです。別の言い方をすると、photos.app
ではソートキーが第一キーが日時、第二キーがファイル名になっているのが観察されます。この並び順を時刻でするにはどうすればいいかは下記になりそうです
1. 1stソートキーを日時、2ndソートキーをファイル名にしてソートする
2. 時刻をリセット(`00:00:00`)にする
3. ソートした順に1秒ずつ足していく
やりたいことをするための手順はわかったのであとはExiftool
でどのようにするかを調べれば良さそうです。グーグル検索で調べてみました
しかしcallmekohei
のググる力がアレなためうまく見つけることができません
そういえばヘルプあるじゃんと・・・
$ exiftool --help
ヘルプは出てきたのですが、less
という文書閲覧プログラムをよく知らないためうまく読むことができません
05-03 vimでヘルプを読む
そういえばVim
でもヘルプを読むことができるのを思い出しましたよ
# Vimを立ち上げて$ vim
" Manコマンドで読みたいコマンド名を指定する: Man exiftool
色がついてる!
折りたたみも自由自在!
もちろん検索も簡単です!
どんな感じで調べるか?
さてvim
を使ってヘルプを読めるようになりましたが、どのように調べればいいのでしょうか?callmekohei
がわからないことは
1. 1stソートキーを日時、2ndソートキーをファイル名にしてソートする
2. 時刻をリセット(00:00:00)にする
3. ソートした順に1秒ずつ足していく
の方法です。ここでは1
についての調べ方です。callmekohei
はこんな感じで調べました
まずは、ページ上部をパッと見ます。ふむふむ。
exiftool は options, tag and file と3つの種類の引数をとるんだな
SYNOPSIS
Reading
exiftool [OPTIONS] [-TAG...] [--TAG...] FILE...
ソートだからsort
で調べてみよっと /\vsort
-sort Sort output alphabetically
-sort, --sort
Sort output by tag description, or by tag name if the -s option is
used. When sorting by description, the sort order will depend on
ほむほむ。tag
でソートされますよ、と
さらにn
をおすと下記の文言が
-fileOrder[-]TAG
Set file processing order according to the sorted value of the
specified TAG. For example, to process files in order of date:
exiftool -fileOrder DateTimeOriginal DIR
Additional -fileOrder options may be added for secondary sort
keys. Numbers are sorted numerically, and all other values are
sorted alphabetically. The sort order may be reversed by
prefixing the tag name with a "-"(eg. "-fileOrder -createdate").
Print conversion of the sorted values is disabled with the -n
option, or a "#" appended to the tag name. Other formatting
options (eg. -d) have no effect on the sorted values. Note that
the -fileOrder option has a large performance impact since it
involves an additional processing pass of each file.
callmekohei
は英語苦手なのですが、多分
TAGでソートするよ
追加で -fileOrder 書いたら入れ子のソート(2nd sort)になるかもね
と書いてるので、こんな感じで書けるのがわかります!
$ exiftool \-filename\-fileorder datetimeoriginal \-fileorder filename
vim
を使うとこのように自分の調べたいことに集中できるのでヘルプをちゃんと読むことができます!
05-04 BashScriptで連番振りスクリプト書いてみた
かなり四苦八苦しながらBashScript
で書いてみました!
function sortedFilepathList (){#{{{# (その1)ソートされたファイルパスのリストを作成# ExifToolのparamを配列に書くdeclare-aarrFileOrder=(-quiet-fast2-s3-filename-fileorder datetimeoriginal
-fileorder filename
)# Date/Time Originalの日時でソートされたファイルパスのリストを変数にいれるecho$(echo*jpg | xargs exiftool "${arrFileOrder[@]}")}#}}}function resetAllTime (){#{{{# (その2)時刻をリセットする# ExifToolのparamを配列に書くdeclare-aarrReset=(-quiet-fast2-s3-d'%Y:%m:%d 00:00:00'-overwrite_original_in_place"-DateTimeOriginal<DateTimeOriginal")# Date/Time Originalの時刻をゼロにリセットするecho*jpg | xargs exiftool "${arrReset[@]}"}#}}}function addOneSecond (){#{{{# (その3)時刻を1秒ずつ進めるlocal baseStr="-quiet -fast2 -s3 -overwrite_original_in_place -DateTimeOriginal+=0:0:"declare-alocal arrFPList=($fpList)local len=$(("${#arrFPList[@]}"-1))for idx in$(seq 0 $len);do
local fileName="${arrFPList[(($idx))]}"local orderedNumber=$idx
exiftool $fileName$baseStr$idxdone}#}}}function mainImpl (){#{{{# 写真のあるフォルダに移動local fld=$1cd$fld# (その1)ソートされたファイルパスのリストを作成local fpList=$( sortedFilepathList )# (その2)時刻をリセットする
resetAllTime
# (その3)時刻を1秒ずつ進める
addOneSecond
}#}}}function main (){#{{{# フォルダを指定するlocal fld=$HOME/Desktop/tmptmp
export-f sortedFilepathList
export-f resetAllTime
export-f addOneSecond
export-f mainImpl
find $fld-type d | xargs -I % bash -c"mainImpl %"}#}}}
main
結果
$ time bash foo.bash
real 9m2.675s
user 7m19.833s
sys 1m14.571s
これで無事 Apple Shared albums
に意図した順番で登録できました!
おしまい。。。
Others
01. Apple's iCloud Shared albums ってなに?
Appleのホームページによれば下記とのこと
共有アルバムを使えば、
自分で選んだ家族や友人とだけ写真やビデオを共有でき、
相手にも写真、ビデオ、コメントを投稿してもらえます。
---> 写真 App で共有アルバムを使う
---> マイフォトストリームと共有アルバムの制限
// (注)callmekohei のイメージです
アップルが写真データーの保存用に貸してくれるサーバーのこと
iCloudサーバーに保存した写真データーのみ shared albums 用のサーバーにコピーすることができる
こんな感じ( メモ書き )
02. F#でフォルダコピー
02-04 フォルダ構成を変更する
にて何度か元データーから上記のファイル構成を作成する必要があったのでF#
でコードを書いてみました
openSystem.IOopenSystem.Text.RegularExpressionsletSrcHDD_="/Users/callmekohei/Desktop/albums"letDstHDD_="/Users/callmekohei/tmp4"// コピーしたい写真データーのリストを作成するletsrcJPGs()=["DVD1";"DVD2";"DVD3";"DVD4"]|>List.map(funs->Directory.GetFiles(SrcHDD_+"/"+s,"*",SearchOption.AllDirectories)|>Array.filter(fun(s:string)->s.Contains("色補正後のデータ")))// コピー元のファイルパスとコピー先のファイルパスを組み(タプル)にしたリストを作成するletdstJPGs()=srcJPGs()|>List.map(funarr->arr|>Array.map(funsrcPath->letdestinateFilePath=Regex.Replace(srcPath,@"色補正後のデータ/","")|>funs->Regex.Replace(s,SrcHDD_+@"/DVD\d/バラ写真",DstHDD_+"/BA")|>funs->Regex.Replace(s,SrcHDD_+@"/DVD\d/フイルム",DstHDD_+"/SL")|>funs->Regex.Replace(s,SrcHDD_+@"/DVD\d/ポケットフイルム",DstHDD_+"/PF")|>funs->Regex.Replace(s,".JPG",".jpg")srcPath,destinateFilePath))// もしコピー先のフォルダがなければ作成するletcreateFolderIfnotExists()=dstJPGs()|>List.map(funarr->arr|>Array.map(funtpl->System.IO.Path.GetDirectoryName(tpl|>snd))|>Array.distinct)|>List.iter(funarr->arr|>Array.iter(funfolderPath->ifnot(Directory.Exists(folderPath))thenDirectory.CreateDirectory(folderPath)|>ignore))letmain()=createFolderIfnotExists()dstJPGs()|>Array.concat|>Array.map(fun(src,dst)->async{File.Copy(src,dst)})|>Async.Parallel|>Async.RunSynchronouslymain()
実行はこんな感じ
$ time fsharpi foo.fsx
real 0m39.002s
user 0m5.849s
sys 0m54.564s
03. vim の Man コマンドの設定
Vim
の場合
" see ---> :h man.vim" vimrcに書くlet runtime ftplugin/man.vim" foldingを使いたい場合は記述letg:ft_man_folding_enable=1
Neovim
の場合
" 特に設定は必要なし" see ---> :h nvim-features > Commands: > :Man" foldingを使いたい場合は vimrc に記述set foldmethod=indent
04. vim-ref でヘルプを調べる
:Man exiftool
とコマンドを調べましたが、例えばpython
のヘルプとかも同じような考え方で:pydoc print
とかでできないでしょうか?
vim-ref
というプラグインを使うとそういったことができます。
使い方はこんな感じ
exiftoolコマンドを調べる
# foo.bash
:Ref man exiftool
or
# exiftoolという単語の上で K を押す
exiftool
print関数を調べる
# foo.py:Refpydocprintor# printという単語の上で K を押すprint('foo')
install
vim-ref
をダウンロードする
$ git clone https://github.com/thinca/vim-ref
vim-ref
へのパスをセットする
" vimrcset runtimepath+=/path/to/vim-ref
setting
こんな感じ
" see also :h ref.vim , :h ref-man , :h ref-pydocletg:ref_man_cmd='man'letg:ref_pydoc_cmd='python3 -m pydoc'letg:ref_use_vimproc=v:true
注意ポイント
現象: 補完が効かない時がある
:Ref man exif "ここでタブ
"↓:Ref man exif " 補完が効かない
原因: コマンド名がcache
されていない
1. man のコマンド名のキャッシュをつくる
:Ref man less
2. あらたにコマンドをついかする( $ brew install exiftool )
$ brew install exiftool
3. キャッシュファイルに exiftoolのコマンド名がないので補完されない
:Ref man exif...
対策: 下記のコマンドを実行する
:Ref -nocache man exiftool
or
:Ref -updatecache man
:Ref man exiftool
05. F#とElixirのちょっとした比較コード
Elixir
のコードをパッとみた感じF#
のコードに似てるなと思いました。foo |> bar
のようにパイプがあるからです。というわけで多分そんなにF#
と違わないだろうと思ったので書いてみました! F#
と比較しながら書いたので、その時のちょっとしたメモを書いておきます。僕が直感で感じた通り似た感じでした!
basic
file extension
fsharp foo.fsx
elixir foo.exs
binding
fsharp let foo = 123
elixir foo = 123
function in pipe
fsharp
"foo" |> fun s ->
elixir
"foo" |> fn s -> ... end
or
"foo |> &( &1 )
// fsharp"hello"|>stdout.WriteLine[1..5]|>printfn"%A"// hello// [1; 2; 3; 4; 5]
# elixir"hello"|>IO.puts1..5|>IO.inspect# hello# 1..5
iter
["foo";"bar";"baz"]|>List.iterstdout.WriteLine#foo#bar#baz
# elixir["foo","bar","baz"]|>Enum.with_index()|>Enum.each(fn{e,_}->IO.putseend)# foo# bar# baz
tuple
// fsharp("foo","bar","baz")|>fun(_,x,_)->stdout.WriteLinex// bar
# elixir{"foo","bar","baz"}|>elem(1)|>IO.puts# bar
type cast( int -> strings )
// fsharp(1).ToString().GetType()|>stdout.WriteLine// System.String
# elixir ( typeof()がなさそう? )to_string(1)|>is_bitstring|>IO.puts# false
parallel
// fsharplethello1=async{stdout.WriteLine("hello")}letworld1=async{stdout.WriteLine("world")}[hello1;world1]|>Async.Parallel|>Async.RunSynchronously// hello world or world hello
# elixir["hello","world"]|>Task.async_stream(&(IO.puts&1))|>Enum.to_list()# hello world or world hello
module and function ( elixir has no class )
// fsharpmodulefoo=letbarbaz=stdout.WriteLine(baz)foo.bar"aaa"// aaa
# elixirdefmoduleFoododefbar(baz)doIO.puts(baz)endendFoo.bar"aaa"# aaa
06. Elixir で Exif データーを編集してみる
05-04 BashScriptで連番振りスクリプト書いてみた
で書いたコードをElixir
で書き直してみました!(もっといい方法があるかもしれません・・・・)
defmoduleFoododefsortedFileNameList(fp)doexifToolParam=["-quiet","-fast2","-s3","-filename","-fileorder datetimeoriginal","-fileorder filename"]bashCommand=["-c","cd "<>fp<>" ; echo *jpg | xargs exiftool "<>Enum.join(exifToolParam," ")]System.cmd("bash",bashCommand)|>elem(0)|>(fnx->String.split(x,"\n")end).()|>Enum.drop(-1)enddefresetAllTime(fp)doexifToolParam=["-quiet","-fast2","-s3","-d '%Y:%m:%d 00:00:00'","-overwrite_original_in_place","\"-alldates<alldates\""]bashCommand=["-c","cd "<>fp<>" ; echo *jpg | xargs exiftool "<>Enum.join(exifToolParam," ")]System.cmd("bash",bashCommand)|>elem(0)enddefaddOneSecond(fp)doexifToolParam=["cd "<>fp<>" ; exiftool","-quiet","-fast2","-s3","-overwrite_original_in_place -alldates+=0:0:"]exifToolParam2=Foo.sortedFileNameList(fp)|>Enum.with_index()|>Enum.map(fn{filename,idx}->Enum.join(exifToolParam," ")<>Kernel.inspect(idx)<>" "<>filenameend)exifToolParam2|>Enum.each(&(System.cmd("bash",["-c",&1])))end# 確認用defmyCheck(fp)doexifToolParam=["-quiet","-fast2","-s3","-filename","-datetimeoriginal","-fileorder datetimeoriginal","-fileorder filename"]bashCommand=["-c","cd "<>fp<>" ; echo *jpg | xargs exiftool "<>Enum.join(exifToolParam," ")]System.cmd("bash",bashCommand)|>elem(0)|>(fnx->String.split(x,"\n")end).()|>(fnlst->lst--[""]end).()enddefjpgFolderList(fp)doPath.wildcard(Path.expand(fp)<>"/**/*.jpg")|>Enum.map(&(Path.dirname(&1)))|>Enum.uniqenddefmainImpl(foo)do" sortedFileNameList "|>IO.putsFoo.sortedFileNameList(foo)" resetAllTime "|>IO.putsFoo.resetAllTime(foo)" addOneSecond "|>IO.putsFoo.addOneSecond(foo)" myCheck "|>IO.putsFoo.myCheck(foo)|>Enum.each(&(IO.puts(&1)))end# 写真データーのExifデーターを変更できるようにするために権限を変えるdefchmod644(fld)doSystem.cmd("bash",["-c","cd "<>fld<>" ; chmod 644 *jpg"])endenddefmoduleMaindo# 写真データーがあるフォルダを指定するbaseFolder="/Users/callmekohei/Desktop/tmptmp"# すべての写真データーのpermissionを644にするFoo.jpgFolderList(baseFolder)|>Task.async_stream(&(Foo.chmod644(&1)),[timeout::infinity,max_concurrency:1000])|>Enum.to_list()# メイン部分を実行Foo.jpgFolderList(baseFolder)|>Task.async_stream(&(Foo.mainImpl(&1)),[timeout::infinity,max_concurrency:1000])|>Enum.to_list()end
実行結果
$ time elixir foo.exs
real 5m48.747s
user 0m2.563s
sys 0m1.753s
ちなみにBashScript
の分はこんな感じ
$ time bash foo.bash
real 9m2.675s
user 7m19.833s
sys 1m14.571s
まえに書いたBashScript
より早くなってますね。パラレルが効いてるのでしょうか?
はまったところ
下記のようにTask.async_stream
を2重に使うと扱うデーター数が多くなるとタイムアウトでプログラムが止まってしまいます。今回の場合フォルダ数が5個以上の時にエラーが頻発しました
defaddOneSecond(fp)doexifToolParam2|>Task.async_stream(&(System.cmd("bash",["-c",&1])))|>Enum.to_list()endFoo.jpgFolderList(baseFolder)|>Task.async_stream(&(Foo.mainImpl(&1)),[timeout::infinity,max_concurrency:1000])|>Enum.to_list()
こんな感じのエラーがでます
(エラー回避)
内側の部分のアシンクを外します
defaddOneSecond(fp)doexifToolParam2|>Enum.each(&(System.cmd("bash",["-c",&1])))end
07. fukuoka ex について
Elixir
に興味を持ったのはfukuokaex
の@piacere_exさんがツイートでばんばんElixir
に関しての情報を流してくることがきっかけでした。fukuokaex
さんのもくもく会
というのに参加させていただいてElixir
への興味が強くなって今回コードを書くに至りました。福岡近辺のひとはもちろんそうでないひともリモートでもくもく会に参加できますので是非参加してみてください!Elixir
のこと好きになるかもです!そしてPhoenix
に関しても!
fukuoka ex のもくもく会はここを覗いてみてください!
---> fukuokaex もくもく会