Taking photos using the Pi camera is easy. But how to allow remote access of the photo is a headache. I do not want to Port Forwarding in my router (especially on SSH ports) because I think my Pi is not yet appropriately hardened. I decide to upload the photos to the cloud.
Google has well-documented API for the Google Drive access. In particular, I love Petter Rasmussen's gdrive, which is a CLI (command-line-interface) client for many Operating Systems because it is a static binary which does not need external libraries.
I have tried the Windows 64 bit build and the Raspberry Pi build and it works. For the Windows build, I even try it behind the proxy server of my company and it works after I set up the http_proxy environment variable.
The github page of the gdrive already provides extensive documentation (with examples) and it is easy to adopt. The following are my major usage:
(1) Initial setup
gdrive about
gdrive will print out a URL. Using browser to launch the URL and enter the account password, Google will print out a verification code. I will enter the verification code to the CLI.
There is documentation on Service Account, which is said to make server-to-Google access with password-less access. But I find that even using the verification code approach, I find gdrive can refresh the token file automatically. In other words, I only need to input the verification code once. Therefore I finally do not bother to set up a Service Account.
(2) List File details
gdrive list --query "name = 'file_name_or_folder_name' "
C:\PortableApps\gdrive>gdrive-windows-x64.exe list --query "name = 'PI_PHOTO_00.jpg' "
Id Name Type Size Created
xxxxxxxxxxxxxxxxxxxxxxxxxxxx PI_PHOTO_00.jpg bin 4.8 MB 2017-07-26 10:00:16
C:\PortableApps\gdrive>gdrive-windows-x64.exe list --query "name = 'pi-photos' "
Id Name Type Size Created
xxxxxxxxxxxxxxxxxxxxxxxxxxxx pi-photos dir 2017-07-21 19:50:23
(3) List Files inside a folder
gdrive list --query " 'Parent_Folder_Id' in parents"
C:\PortableApps\gdrive>gdrive-windows-x64.exe list --query " '0Bzo1pJKfp9QEdVZFdVV2RTV2RVE' in parents "
Id Name Type Size Created
xxxxxxxxxxxxxxxxxxxxxxxxxxxx PI_PHOTO_35.jpg bin 4.8 MB 2017-07-26 10:35:12
xxxxxxxxxxxxxxxxxxxxxxxxxxxx PI_PHOTO_30.jpg bin 4.7 MB 2017-07-26 10:30:12
(4) Upload File to specified folder
gdrive --parent Parent_Folder_Id Upload_Filename
(5) Delete File
gdrive delete File_Id
I then start to code my bash script (which will be run by cron periodically) to take photo and then upload the photo. I use the minute digits to name my photo filename and originally thought that this nomenclature can automatically recycle my photo copies without an explicit housekeeping job. But I am wrong. I find Google Drive allow multiple copies of the same filename (even not using the versioning feature) and these multiple copies will be assigned with different File-Id.
Worst still I find gdrive has no direct command to delete a file (or files) by filename. I need to first list the File_id by the inputted filename and then delete them (if more than one) one-by-one. The logic is:
gdrive list --no-header --query "name = 'Filename' " | awk '{print $1}' | xargs -n 1 gdrive delete
The xargs command is to ensure the gdrive is executed one-by-one
The following is my script:
#!/bin/bash
# use 00-59 minutes for filename recycling
DATE_MM=$(date +"%M")
cd /home/pi/photos
raspistill -n -o PI_PHOTO_${DATE_MM}.jpg
# delete duplicated copies at Google drive
/home/pi/gdrive-linux-rpi list --no-header --query "name = 'PI_PHOTO_${DATE_MM}.jpg'" | awk '{print $1}' | xargs -n 1 /home/pi/gdrive-linux-rpi delete
# upload to pi_photos folder at Google Drive
/home/pi/gdrive-linux-rpi upload --parent xxxxxxxxxxxxxxxxxxxxxxxxxxxx --delete PI_PHOTO_${DATE_MM}.jpg