見出し画像

PythonでAndroidアプリ作成してみる #5 サーバーと通信方式

こんにちは、Rcatです。
前回無事にスマホ内のファイルを検索できたところで、そろそろ本題に入っていきたいと思います。やっとです。
今回はネットワークを通じたバックアップの方法と具体的な処理内容の検討になります。

本シリーズはこちら


バックアップ方法の検討

構想

さて、バックアップの方法についてですが、httpを使おうと考えています。
もっと簡単に言えば、ウェブページのフォームでよくあるファイルを選択してアップロードするやつです。
あれを使ってファイル名や作成日時、更新日時、そしてファイル本体をまとめて送付することで、クライアント側の処理としてはただのアップロードですが、サーバー側で取得した情報に応じてデータを管理することで、バックアップという動作を実現するといったところでしょうか。
効率はあまり良くなさそうですが。

超適当ですが、図にするとこんな感じです。
特徴としては、せっかくhttpを使うので、その辺の機能を活かしたいところです。
例えばよくあるログイン画面ですね。一番最初の接続でログイン情報をクッキーとして発行してもらい。以降はその情報を使って認証を行います。
こうすることで、自分以外の人ともバックアップサーバーを共用できます。
共用するとなると暗号化とか考えないといけないですが、とりあえずそれは後にします。

具体的にはどうする?

まずクライアント側ですが、requestsを使おうと思います。こちら側はそこまで難しくないですね。
globで検索してrequestsで送りつけるだけです。

サーバー側はいつも通りFlaskを使います。
いつもと違うのは、ファイルをアップロードされた時の保存先をPOSTで送信される他の情報に順次で変更するといったところでしょうか?
仮に暗号化するのであれば、こちらで受け取った瞬間にユーザーパスワードのハッシュで暗号化するといったところでしょうか?

通信プログラムの作成

さて、ここからは通信部分のプログラムを書いていきます。
クライアントとサーバーを、同時に考えないと進めていけないので、同時に解説になっていきます。

サーバー #1 とりあえずテスト用

さて、進めていくには両方のプログラムが必要なので、まず仮サーバーを作っていきます。
具体的にはユーザー認証なしでPOSTで送ったファイルを任意のディレクトリに格納できる機能まで搭載です。

サーバーのプログラムは下記動画の説明欄に載っているテンプレートを使います。テンプレート部分の記述に関しては特に解説しません。気になった方は"FlaskWEBサーバーテンプレート"をご確認ください。

とりあえずサーバーの受信部はこんな感じにしました
POSTで受け取ったデータを保存するだけ。
ただしパラメータとしてフォルダが渡されるのでツリー階層としてアップロードされる仕組み。
Flaskの前提などはすっ飛ばしています。詳しくは動画の方をご確認ください。

@app.route("/backup_uploadvgi",methods=['POST'])
def BackupUploadcgi():
	UPDir = "./DATA"
	DATANAME = "Upload"
	fname = request.form.get("fname","")
	fdir = request.form.get("fdir","/") 

	upload_files = request.files.getlist(DATANAME)
	for file in upload_files:
		fileName = file.filename
		if fileName == "": continue
		fullpath = os.path.join(UPDir,fdir)
		os.makedirs(fullpath, exist_ok=True)
		file.save(os.path.join(fullpath, fileName))
	
	return "OK"

クライアント #1 とりあえず送信

次にクライアントはこんな感じ。
globで検索したファイルをpostでアップロードするだけ。
ただしパラメータとしてフォルダ情報も同時に送る

	def BackUpButton_Click(self):
		"バックアップボタン押下時のイベント"
		if self.ids.Profiles.text in Config.Config["profiles"]:
			p = Config.Config["profiles"][self.ids.Profiles.text]
			l = [f for f in glob.glob(os.path.join(p["dirs"][0],"**/*.*"),recursive=True) if os.path.isfile(f)]
		
			for i in l:
				files = {'Upload': open(i, 'rb')}
				data = {'fdir': os.path.relpath(os.path.dirname(i),os.path.dirname(p["dirs"][0]))}
				response = requests.post('http://192.168.0.199:27510/backup_uploadvgi', files=files, data=data)

実験稼働

ではさっそく稼働します
まずはテストなので適当なフォルダを選択して設定を作ります。

プロファイルを選択したらバックアップ開始

サーバー側はこんな感じで表示されています。
予定通りファイル本体とフォルダパスが受信できています。

こちらがサーバー側の保存フォルダ。きちんとフォルダ構成を維持してアップロードできていますね!
この調子で作りこんでいきます

悲報

スマホは動かなかった…
バックアップボタンを押した瞬間に落ちます。
調べたところ、kivyとrequestsの相性がとても悪いようで、kivy用のリクエストライブラリがあるみたいです。ただファイルのアップロードがサポートされていないみたいなのでどうしたものか…。

まとめ

今回は通信方式の検討と動作確認を行いました。
おおむね思い通りでしたが、スマホで全く動かないのでダメですね…。
作りこんでからスマホで動かないということにならなくてまだよかったです。
というわけで次回はスマホでのアップロードはどうするか考えていきます。
最悪ダメなら中止かも…。
ではまたお会いしましょう。

情報が役に立ったと思えば、僅かでも投げ銭していただけるとありがたいです。