Androidで写真を撮影したらWindowsのクリップボードにURLをコピーするプログラムについて紹介します。
Android開発はしたことがない、なぜなら開発環境の構築で挫折しているから。どうもyuisです。僕みたいなandroid嫌いなわけではないけどなんか無理って人には、IFTTTがおすすめなんです。僕はIFTTTは日本ではほとんど名前聞かないくらいのころから存じておりましたが、あれはプログラミングができない人が使うものだ、俺らには関係ない。とずっと思っておりました、が…実はIFTTTは結構プログラマブルなんですよね。というのは、他のIFTTT記事や今回の記事を読んでいただければわかります。
今回はandroidで動画や…動画はできなかった、画像、写真を撮影したら、いろいろ内部で処理して、最終的にWindows 10のクリップボードに公開URLをコピーする、ということをします。
全体の流れ
ひとつひとつやってることは難しいことではないのですが、使う技術は相変わらず多いので、場合によっては時間がかかるかもしれませんが、これができると他のandroidのデータのやりとりにも応用できるのでぜひがんばってみてください。
- androidで写真を撮ったらIFTTTにアップロードされてURLが発行され、それがサーバーに送られる
- ubuntuのsinatraサーバーでそれを受け取ってパースしてファイルにテキストを保存
- テキストファイルからWSLからURLを取得する。そのURLを使い続けるのはインセキュアなので、wgetしてローカルに入れてから、いろいろ処理してリモートのサーバーにアップロードしてそのURLをクリップボードにコピー
事前準備
- ポートフォワーディングができるWifiルーターにしましょう。
ポート転送をすることで、ローカルで動かしているサーバーをグローバルIPの公開URLからリクエストするため、そういうルーターでない方は買いましょう。幸運にも、どのルーターを買えばいいのかは明白です。
光回線工事後、4台のルーターを実際に買って検証した結果導き出された最高のwifiルーターとは
- WSL
WSL(Windows Subsystem for Linux)を初期から使っている僕がLinuxやプログラミングの初心者向けにWSLのメリットを解説してみる
WSL bash on ubuntu on windows インストール手順
- Ruby環境を作りましょう
Rubyでsinatraを動かします。3分でできるのでささっと環境を作りましょう。
sudo apt update ; sudo apt install build-essential patch zlib1g-dev liblzma-dev ruby{,-dev} -y ; sudo gem install bundler
mkdir -p /mnt/c/pg/ruby_dev && cd $_
sudo bundle init
vim Gemfile
sudo bundle install
vim Gemfile
# add
gem "pry"
gem "sinatra"
手順
- wifiルーターでポートフォワーディングの設定をします
- IFTTTでアプレットを作ります
this … android photo
that … webhooks
title(例) … If Any new photo, then post request to server
URL(例) … http://220.247.111.111:8005/android-photo
method … post
type … json
body … { "TemporaryPublicPhotoURL": "{{TemporaryPublicPhotoURL}}", "TakenDate": "{{TakenDate}}" }
- Windowsのフォルダをマウントしてファイルを同期できるようにしておきます
sudo mount -t cifs //192.168.0.167/_sync_ ~/share -o user=ifgm2,pass=hoge,dir_mode=0777,file_mode=0777
Ubuntu 18.04でWindows 10の共有フォルダをマウントする方法
windows 10のシェア(共有)フォルダをubuntu16.04でマウント(同期)する
シェアディレクトリのandroid-photo-url.txt
にデータをストアしておき、それをWSLで定期的に読み取って処理する、ということをあとで実装します。
- sinatraを動かします
require "sinatra"
require "open3"
require 'json'
require 'pry'
Encoding.default_external = 'UTF-8'
post "/android-photo" do
binding.pry
# puts "ok"
puts @body = request.body.read
json = JSON.parse( @body )
puts text = json["TemporaryPublicPhotoURL"]
stdout, stderr, statusCode = Open3.capture3( %( bash -ic "printf '#{ text }' > /home/yuis/share/android-photo-url.txt || echo '' " ) )
puts stdout, stderr, statusCode
end
sudo bundle exec ruby dev.rb -o 0.0.0.0
- WSL側で使用する関数を定義してください
今回はexpecto
とsharefile
を使っています。
expectはexpectを使いやすくしたもので、sharefileはリモートサーバーにローカルファイルを公開URLとして公開したのちクリップボードにコピーするユーティリティです。
上記2つの関数のコードは以下それぞれの記事にて参照してください。
パスワード省略できないサーバーにexpect経由で自動SSHする
Bash リモートサーバーにファイルをコピーして共有のためのURLを取得する
はじめてのBash。関数やエイリアスを読み込むまで [初心者向け]
上記2つ以外の関数など
tmpdird ()
{
: tmpdir default;
dirname=$(plaindate) && cd "${TMPDIR}" && mkdir $dirname && cd $dirname
}
plaindate ()
{
date '+%Y%m%d%H%M%S'
}
random ()
{
ARG1=${1:-32};
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $ARG1 | head -n 1
}
- WSL側で定期的にコマンドテキストの入ったファイルを監視するスクリプトを実行します
conemuなどで以下のスクリプトを実行して放置。
while true; do
echo -ne "$(isodate)\tNothing updated.\033[0K\r"
[[ -s "$SHAREDDIR/android-photo-url.txt" ]] && {
tmpdird
wget "$( cat "$SHAREDDIR/android-photo-url.txt" )"
# sed -Ee 's/.*\.(\w+)\?.*/\1/g' # extract extension, in need
filename="android_photo_$(random).jpg"
mv "$( command ls -1 | head -1 )" "${filename}"
pwd > ~/pwd.txt
eval "$(echo "expecto 'bash -ic \"cd \\"$(cat ~/pwd.txt)\\" ; sharefile ${filename}\"' $XSERV_PASSWORD")"
printf "Copied remote photo url to clipboard." ;
> "$SHAREDDIR/android-photo-url.txt"
}
sleep 2s
done
今回はbashのコードのほうが複雑になりました。sharefile
をパスワード入力無しでやろうとした結果です。
説明が必要そうですので、軽く説明します。
tmpdird
ファイルが一つしかない状態が望ましいので、テンポラリーディレクトリを作ってそこへ移動します。
wget "$( cat "$SHAREDDIR/android-photo-url.txt" )"
IFTTTのURLをローカルに保存します
filename="android_photo_$(random).jpg"
ファイル名を作成
mv "$( command ls -1 | head -1 )" "${filename}"
IFTTTから保存したファイルの名前を変更
pwd > ~/pwd.txt
bash -ic
してしまうと、サブプロセスなのでカレントディレクトリが変わってしまいます。なので、まずカレントディレクトリの情報を↑でファイルに保存し、次のステップでそれをbash -ic
のなかでコマンドしてcd
します。
eval "$(echo "expecto 'bash -ic \"cd \\"$(cat ~/pwd.txt)\\" ; sharefile ${filename}\"' $XSERV_PASSWORD")"
expecto
の第一引数は展開なしの生のコマンドである必要があります。なので単純に、全てechoで展開してからevalしてやります。少し複雑。
> "$SHAREDDIR/android-photo-url.txt"
ファイルを空にしてます。
- 実際に動くかテストします
なんか問題があればコメントしてください。