Python3: ファイルのアップロード

Python3 と jQuery でファイルをアップロードする方法です。
data_work というフォルダーにアップロードされます。

フォルダー構造

```text
$ tree
.
├── data_work -> /var/tmp/data_work/
├── index.html -> jquery_upload_python.html
├── jquery_upload.py
├── jquery_upload_python.html
├── jquery_upload_python.js
└── upload_file.py
```

```html:jquery_upload_python.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
<script src="/js/jquery-3.6.0.min.js"></script>
<script src="jquery_upload_python.js"></script>
<title>File Uplaod (jQuery & python3) (Apr/10/2021)</title>
</head>
<body>
<h2>File Uplaod (using jQuery & python3) (Apr/10/2021)</h2><p />
<div class="top">
</div>

<form action="javascript:;">
<input type="file" id="file" />
<input type="submit" id="upload" value="送信" />
</form>

<blockquote>
File is uploaded to data_work.<p />
</blockquote>
<hr />
<div class="contents">contents</div>
<hr />
<h2>message</h2>
<div id="message">message</div>
<hr />
<div id="result_aa">result_aa</div>
<hr />
<div id="outarea_aa">outarea_aa</div>
<div id="outarea_bb">outarea_bb</div>
<div id="outarea_cc">outarea_cc</div>
<div id="outarea_dd">outarea_dd</div>
<div id="outarea_ee">outarea_ee</div>
<div id="outarea_ff">outarea_ff</div>
<div id="outarea_gg">outarea_gg</div>
<div id="outarea_hh">outarea_hh</div>
<hr />
Apr/10/2021 AM 08:15<p />
</body>
</html>
```

```js:jquery_upload_python.js
// -----------------------------------------------------------------------
//	jquery_upload_python.js
//
//					Apr/10/2021
// -----------------------------------------------------------------------
jQuery(function ()
{
 
jQuery("#upload").bind ("click",function()
	{
	jQuery ("#outarea_bb").html ("*** clicked ***<br />");

	var fd = new FormData();

	if ( jQuery("#file").val() !== '' )
		{
		fd.append ("file",jQuery("#file").prop("files")[0]);
		}

	fd.append("username", "Groucho");
	fd.append("accountnum", 123456);
	fd.append("upload_dir", "./data_work");
 
// dataにFormDataを指定する場合 processData,contentTypeをfalseにしてjQueryがdataを処理しないようにする
	var postData = {
		type : "POST",
		dataType : "text",
		data : fd,
		processData : false,
		contentType : false
		};

	var url_action = "./jquery_upload.py";

	jQuery.ajax (url_action,postData).done(function (res)
		{
		jQuery ("#result_aa").html (res);
		jQuery ("#outarea_dd").html ("*** done ***<br />");

		var data_in = JSON.parse (res);

		var str_message = "<blockquote>";
		for (var it in data_in['message'])
			{
			str_message += data_in['message'][it] + '<br />';
			}

		str_message += "</blockquote>";

		jQuery ("#message").html (str_message);

		});
	});
});

// -----------------------------------------------------------------------
```

```py:jquery_upload.py
#! /usr/bin/python3
# -*- coding: utf-8 -*-
#
#	jquery_upload_python/jquery_upload.py
#
#					Apr/10/2021
#
# --------------------------------------------------------------------
import	os
import	sys
import	json
import	cgi
# --------------------------------------------------------------------
from upload_file import upload_file_proc
# --------------------------------------------------------------------
#
message = []
message.append ("*** start *** jquery_upload.py ***")
form = cgi.FieldStorage()
#
message.append (str (form["username"]))
message.append (str (form["accountnum"]))
message.append (str (form["upload_dir"]))
#
message.append (str (form["username"].value))
message.append (str (form["accountnum"].value))
message.append (str (form["upload_dir"].value))
upload_dir = form["upload_dir"].value
message.append ("upload_dir = " + upload_dir)
#
if "file" in form:
	item = form["file"]
	try:
		message_aa = upload_file_proc (upload_dir,item)
		message.extend (message_aa)
	except Exception as ee:
		message.append ("*** error *** upload_file_proc ***")
		message.append (str (ee))
else:
	message.append ("*** Select files ***")
#
message.append ("*** end ***")
rvalue = {}
rvalue["message"] = message
out_str = json.dumps (rvalue)
#
print ("Content-Type: application/json")
print ("")
#
print (out_str)
# --------------------------------------------------------------------
```

```py:upload_file.py
# -*- coding: utf-8 -*-
#
#	upload_file.py
#
#					Nov/20/2015
#
# --------------------------------------------------------------------
import	cgi
import	cgitb
import	os
import	sys
import	json
# --------------------------------------------------------------------
def single_upload_file_proc (upload_dir,item):
	message = []
#	message.append ("*** single_upload_file_proc *** start ***")
	file_in = item.filename
	message.append (file_in)
	path = os.path.join (upload_dir,os.path.basename (file_in))
	chunk = item.file.read ()
	if chunk:
		try:
			fout = open (path, 'wb')
			fout.write (chunk)
			fout.close()
			os.chmod (path, 0o666)
		except Exception as ee:
			message.append ("*** error *** single_upload_file_proc ***")
			message.append (str (ee))
#
#	message.append ("*** single_upload_file_proc *** end ***")
#
	return message
# --------------------------------------------------------------------
def multi_uploaded_file (upload_dir,fileitem):
	message = []
#
	for item in fileitem:
		message_s = single_upload_file_proc (upload_dir,item)
		message.extend (message_s)
#
	return message
#
# --------------------------------------------------------------------
def upload_file_proc (upload_dir,fileitem):
	message = []
#	message.append ("*** upload_file_proc *** start ***")
#
	if (isinstance (fileitem,list)):
		message.append ("*** save_uploaded_file ***")
		message_aa = multi_uploaded_file (upload_dir,fileitem)
		message.extend (message_aa)
	else:
		message_aa = single_upload_file_proc (upload_dir,fileitem)
		message.extend (message_aa)
#
#	message.append ("*** upload_file_proc *** end ***")
#
	return	message
# --------------------------------------------------------------------
```