FlashAirのLuaでGoogle Driveに写真を自動アップロードする (2)

前回,FlashAirのLuaスクリプト実行機能を用いてGoogle Driveに写真をアップロードすることを試みました. このときはただ単にあらかじめ指定されたファイルをアップロードするに留まりましたが,今回はより実践的なコードを目指して,

  • 最新のAPIの利用
  • 最新ファイルのアップロード
  • 元ファイル名を保持してアップロード
  • より安全に実行する

の4点について改良を行っています.

Google Drive API v3

前回のコードでは,参考にしていたチュートリアルに従ってGoogle Drive APIのバージョン2を用いていました. しかし,最新のものはバージョン3であるため,まずはこれを使えるようにします.

とはいえたいした違いがあるわけではないので,ここではサンプルコードを載せるだけにとどめておきます.

最新ファイルパスの取得

LUA で FlashAir の特定フォルダ以下の最新ファイルを探す : まだプログラマーですが何か?にて紹介されているコードを拝借します.

このコードでは,DCIM以下のファイルを更新日時をもとに走査しています.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
local function findNewestFile()
  last_fname = ""
  last_fpath = ""
  max_mod = 0
  fpath = "/DCIM"
  for dirname in lfs.dir(fpath) do
    dirpath = fpath .. "/" .. dirname
    mod_dir = lfs.attributes( dirpath, "mode" )
    if mod_dir == "directory" then
      for filename in lfs.dir(dirpath) do
        filepath = dirpath .. "/" .. filename
        mod = lfs.attributes( filepath, "modification" )
        if mod > max_mod then
        max_mod = mod
          last_fname = filename
          last_fpath = filepath
        end
      end
    else
      mod = lfs.attributes( dirpath, "modification" )
      if mod > max_mod then
        max_mod = mod
        last_fname = dirname
        last_fpath = dirpath
      end
    end
  end
  return last_fpath
end

元ファイル名の保持

findNewestFile()関数より得た最新ファイルのパスから,ファイル名のみを取り出します.

1
local fileName = string.sub(filePath,(string.len(filePath) - string.find(string.reverse(filePath),"/") + 2))

これをリクエストボディの”name”フィールドに入れておけば元ファイル名を保持しつつアップロードが可能になります.

サンプル

これらの変更を行ったコードを以下に示します.

実行のために

  • client_id
  • client_secret
  • refresh_token

を設定してください.(前回記事参考)

安全に実行するために

このままのコードでは,たまにアップロードにミスったりするとフリーズしてしまうので,以下の記事を参考にデバッグ用のコードを用います.

電子工作記録: FlashAir上でLuaスクリプトのエラーを表示する

1
2
3
4
5
6
7
8
9
10
11
12
13
f = loadfile("upload_to_gdrive.lua")
local flag, ret = pcall(f)
if not flag then
   print("HTTP/1.1 500 Internal Server Error\n\n")
   print("<pre>")
   print("!!! Lua error detected.!!!\n")
   print("------------\n")
   print(ret)
   print("\n------------\n")
   print("</pre>")
else
   print("<!-- OK -->")
end

ほぼそのまま,1行目のロードされるスクリプトを書き換えただけです.

ブラウザから実行する際にはこちらのデバッグ用のスクリプトにアクセスするようにします.

まとめ

以上のステップを踏むことで,だいぶ実用的になったと思われます.

今後はこれを書き込み時自動実行用スクリプトとして利用したいと思いますが, これをそのまま用いるといくつか問題が発生する可能性があるので,もう少し調整が必要そうです.