#!/usr/bin/python
# -*- coding:utf-8 -*-

#-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
# REVISION
#   V1.00    2017.02.17  : original
#   V1.01    2017.02.17  : エラー検出時のリトライ処理

import	urllib
import	urllib2
import	json
import	datetime
import	codecs
import	time
import	os
import	shutil
import	sys

#-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
# -- const valiable --

#####
# Debug mode...
#   0: no output
#   1: output stdout
#   2: output file( ./log.txt )
#   3: (1) and (2)
DEBUG_MODE = 2

URL_INFO = "http://192.168.1.1/osc/info"
URL_EXECUTE = "http://192.168.1.1/osc/commands/execute"
URL_STATE = "http://192.168.1.1/osc/state"

INSTALL_DIR = "/var/www/html"

# V1.01 --->
#####
# 画像撮影失敗時の再試行回数
NUM_OF_RETRY = 3
# V1.01 <---

#-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
# functions

#####
# Debug Output
def	dprint( str, kind ):
	
	if kind == 1 or kind == "i" :
		strKind = "[INFO ]"
	elif kind == 2 or kind == "w" :
		strKind = "[WARN ]"
	elif kind == 3 or kind == "e" :
		strKind = "[ERROR]"
	else :
		strKind = "[DEBUG]"
	
	if DEBUG_MODE > 0 :
		
		nowTime = datetime.datetime.now()
		strTime = nowTime.strftime("%Y.%m.%d %H:%M:%S.") + "%04d:" % ( nowTime.microsecond // 1000 )
		output = strKind + strTime + " " + str
		
		if ( DEBUG_MODE & 0b0001 ) > 0 :
			print output
		
		if ( DEBUG_MODE & 0b0010 ) > 0 :
			fp = codecs.open( INSTALL_DIR + "/log.txt", "a", "utf-8" )
			fp.write( output + "\n" )
			fp.close()
		
	return 0

#####
# http post
def	httppost( url, json_params ):
	
	try :
		if json_params is None :
			res = urllib2.urlopen( url, timeout=10 ).read()
		else :
			res = urllib2.urlopen( url, json_params, timeout=10 ).read()
		response = json.loads( res )
	except urllib2.URLError, e:
		dprint( "URLError, " + e, "e" )
		response = None
	return response

#####
# image data download and save
def	getImageData( url, json_params, fname ):
	
	fp = open( fname, "wb" )
	
	try:
		res = urllib2.urlopen( url, json_params, timeout=10 ).read()
		fp.write( res )
		fp.close()
	except urllib2.URLError, e:
		dprint( "URLError, " + e, "e" )
		response = None
	return 0
	
# V1.01 --->
#####
# main
def	main_loop():
# V1.01 <---
	# V1.01 indent ---->
	#-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
	# main
	
	try:
		# THETA Sの情報を取得
		response = httppost( URL_INFO, None )
		if not (response is None) :
			serialNo = response["serialNumber"]
			firmwareVer = response["firmwareVersion"]
			dprint( "Boot process...( theta.py )", "i" )
			dprint( " SerialNo:" + serialNo, "i" )
			dprint( " FirmwVer:" + firmwareVer, "i" )
		else :
			dprint( "Did not get a response...", "e" )
			#sys.exit()     # V1.01 del
			return 1        # V1.01
		
		# 保存件数の取得
		data = json.dumps({"name":"camera.listImages","parameters":{"entryCount":0,"includeThumb":False}})
		response = httppost( URL_EXECUTE, data )
		if not (response is None) :
			totalEntries = response["results"]["totalEntries"]
			dprint( "totalEntries: " + str(totalEntries), "i" )
		
		# 画像一覧を取得
		imagesUri = []
		data = json.dumps({"name":"camera.listImages","parameters":{"entryCount":totalEntries,"includeThumb":False}})
		response = httppost( URL_EXECUTE, data )
		if not (response is None) :
			for i in range( 0, totalEntries ):
				imagesUri.append( response["results"]["entries"][i]["uri"] )
		
		# 取得した画像一覧をもとに削除を行う
		for i in range( 0, totalEntries ):
			data = json.dumps({"name":"camera.delete","parameters":{"fileUri":imagesUri[i]}})
			response = httppost( URL_EXECUTE, data )
			if not (response is None) :
				dprint( "Delete picture sucess. ListNo(" + str(i + 1) + ")", "i" )
			else :
				dprint( "Response is none...", "e" )
				#sys.exit()     # V1.01 del
				return 1        # V1.01
		
		# SessionIDを取得
		data = json.dumps({"name":"camera.startSession", "parameters":{}})
		response = httppost( URL_EXECUTE, data )
		if not (response is None) :
			state = response["state"]
			if state == "done" :
				sessionId = response["results"]["sessionId"]
				dprint( "Start session. " + sessionId, "i" )
			else :
				dprint( sts, "e" )
				#sys.exit()     # V1.01 del
				return 1        # V1.01
		else :
			dprint( "Response is none...", "e" )
			#sys.exit()     # V1.01 del
			return 1        # V1.01
		
		# state checkを行い、撮影前のfingePrintIdを取得
		curFingerPrintID = ""
		data = json.dumps({})
		response = httppost( URL_STATE, data )
		if not (response is None) :
			curFingerPrintID = response["fingerprint"]
			dprint( "Current State...", "i" )
			dprint( " FingerPrintID:" + curFingerPrintID, "i" )
		else :
			dprint( "Response is none...", "e" )
			#sys.exit()     # V1.01 del
			return 1
		
		# takePictureを行い、撮影する
		data = json.dumps({"name":"camera.takePicture","parameters":{"sessionId":sessionId}})
		response = httppost( URL_EXECUTE, data )
		if not (response is None) :
			state = response["state"]
			dprint( "Take picture state. " + state, "i" )
		else :
			dprint( "Response is none...", "e" )
			#sys.exit()     # V1.01 del
			return 1
		
		## 撮影時刻の保持
		nowTime = datetime.datetime.now()
		saveFileName = INSTALL_DIR +  "/picture/" + nowTime.strftime("%Y%m%d%H%M%S") + ".jpg"
		
		# state checkをloopし、fingerPrintIdが変化する（保存完了）を待つ
		fileUri = ""
		loop = 1
		loopCnt = 0
		while loop > 0:
			newFingerPrintID = ""
			data = json.dumps({})
			response = httppost( URL_STATE, data )
			if not (response is None) :
				newFingerPrintID = response["fingerprint"]
				dprint( "Newest State...", "i" )
				dprint( " FingerPrintID:" + newFingerPrintID, "i" )
				if newFingerPrintID != curFingerPrintID:
					dprint( "Change fingerPrintID loop is end.", "i" )
					fileUri = response["state"]["_latestFileUri"]
					loop = 0
				else:
					loopCnt += 1
					if (loopCnt > 100) :
						dprint( "Not Change fingerPrintID.", "e" )
						loop = 0
			else :
				dprint( "Response is none...", "e" )
				#sys.exit()     # V1.01 del
				return 1        # V1.01
		
		# fingerPrintIdが変化したstate checkのレスポンスから保存したファイルのuriを得る
		dprint( "PictureFile Uri is " + fileUri, "i" )
		
		# 保存したファイルのuriを使用してダウンロードを行う
		data = json.dumps({"name":"camera.getImage","parameters":{"fileUri":fileUri}})
		response = getImageData( URL_EXECUTE, data, INSTALL_DIR + "/img.jpg" )
		if not (response is None) :
			dprint( "File download is sucess.", "i" )
		else :
			dprint( "File download is failed.", "e" )
			#sys.exit()     # V1.01 del
			return 1        # V1.01
		
		# ダウンロード完了後、撮影したファイルの消去を行う
		data = json.dumps({"name":"camera.delete","parameters":{"fileUri":fileUri}})
		response = httppost( URL_EXECUTE, data )
		if not (response is None) :
			dprint( "Delete picture sucess.", "i" )
		else :
			dprint( "Response is none...", "e" )
			#sys.exit()     # V1.01 del
			return 1        # V1.01
		
		# Sessionを閉じる
		data = json.dumps({"name":"camera.closeSession", "parameters":{"sessionId":sessionId}})
		response = httppost( URL_EXECUTE, data )
		if not (response is None) :
			state = response["state"]
			if state == "done" :
				dprint( "...Finish", "i" )
			else :
				dprint( state, "w" )
		else :
			dprint( "Response is none...", "e" )
			#sys.exit()     # V1.01 del
			return 1        # V1.01
		
		# downloadした画像ファイルのrenameを行う
		os.chmod( INSTALL_DIR + "/img.jpg", 0777 )
		fileSize = os.path.getsize( INSTALL_DIR +  "/img.jpg" )
		if ( fileSize > 100000 ) :
			shutil.copy( INSTALL_DIR + "/img.jpg", INSTALL_DIR + "/picture/current.jpg" )
			os.rename( INSTALL_DIR + "/img.jpg", saveFileName )
			dprint( "File copy success. file name is " + saveFileName, "i" )
			import subprocess
			subprocess.call ("curl -T /var/www/html/picture/current.jpg http://penta-02.ptgw.net/theta/picture/",shell=True)

		else :
			dprint( "File copy failed. file size is " + str( fileSize ), "e" )
		
		return 0
		
	except Exception as e:
		dprint( "Error...", "e" )
		dprint( " Type:" + str( type(e) ), "e" )
		dprint( " args:" + str( e.args ), "e" )
		dprint( " msg :" + e.message, "e" )
		dprint( " info:" + str(e), "e" )
		return 1
	
	# （可能であれば）指定サーバにアップロードを行う
	return 0

# V1.01 --->
#-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
# main
for retry in range( 0, 3 ):
	sts = main_loop()
	if sts == 0 :
		# Normal end
		break
	if retry < 2 :
		# Retry process
		dprint( "Retry... (" + str( retry + 1 ) + ")", "i" )
	else :
		# Error exit
		dprint( "Exit ... (" + str( retry + 1 ) + ")", "i" )
# V1.01 <---
