Deploygateにアップロードする

#環境
Unity2018.3.0f2
2017.2.0p4

#概要
usb接続してAndroidビルドすると転送エラーになったりすることが頻繁に起こるので[Deploygate](https://deploygate.com/?locale=ja)にアップするようにしたエディタ拡張です。

#プログラム

2018.3.0f2対応。さらに名前とアイコンを固定にした

~~~c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.Networking;
using System.IO;
using System;
using UnityEditor.Build;
using UnityEditor.Callbacks;
using UnityEditor.Build.Reporting;

public class EditorDeploygateUploader : EditorWindow, IPostprocessBuildWithReport, IPreprocessBuildWithReport
{
	public class Param : ScriptableSingleton<Param>
	{
		public IEnumerator opFunc = null;   //保存されないのでここにある意味は特にない
		public int state = 0;
		public string path;
		public string productName = null;
		public Texture2D[] icons = null;
	}

	[ MenuItem( "Tools/Deploygate/Open" ) ]
	static void OnMenuOpen()
	{
		var window = EditorWindow.GetWindow<EditorDeploygateUploader>( "EditorDeploygateUploader" );
		window.ShowPopup();
	}

	private void OnEnable()
	{
	}

	private void OnDisable()
	{
	}

	private void OnGUI()
	{
		using( var verticalScope = new EditorGUILayout.VerticalScope( "Common" ) )
		{
			EditorGUILayout.LabelField( "AccountName" );
			var prevAccountName = EditorPrefs.GetString( "DeploygateAccountName", "" );
			var accountName = EditorGUILayout.TextField( prevAccountName );
			if( prevAccountName != accountName )
				EditorPrefs.SetString( "DeploygateAccountName", accountName );

			EditorGUILayout.LabelField( "ApiKey" );
			var prevKey = EditorPrefs.GetString( "DeploygateApiKey", "" );
			var key = EditorGUILayout.TextField( prevKey );
			if( prevKey != key )
				EditorPrefs.SetString( "DeploygateApiKey", key );
		}
	}


	[DidReloadScripts]
	private static void OnReloadScripts()
	{
		Debug.Log( "OnReloadScripts" );
		if( ScriptableSingleton<Param>.instance.state == 0 )
			return;
		EditorApplication.update += OnUpdate;
		ScriptableSingleton<Param>.instance.opFunc = OpUpload( ScriptableSingleton<Param>.instance.path );
	}

	private static void OnUpdate()
	{
		if( ScriptableSingleton<Param>.instance.opFunc == null )
			return;
		if( ScriptableSingleton<Param>.instance.opFunc.MoveNext() == false )
		{
			ScriptableSingleton<Param>.instance.state = 0;
			ScriptableSingleton<Param>.instance.opFunc = null;
			EditorApplication.update -= OnUpdate;
			Debug.Log( "End Update" );
		}
	}

	private static void Upload( string path )
	{
		ScriptableSingleton<Param>.instance.state = 1;
		ScriptableSingleton<Param>.instance.path = path;
		OnReloadScripts();
	}

	private static IEnumerator OpUpload( string path )
	{
		var accountName = EditorPrefs.GetString( "DeploygateAccountName", "" );
		var apikey = EditorPrefs.GetString( "DeploygateApiKey", "" );
		if(  string.IsNullOrEmpty( accountName ) == true || string.IsNullOrEmpty( apikey ) == true )
		{
			Debug.Log( "Deploygate NoSetting!" );
			yield break;
		}

		Debug.Log( "Begin Upload" );
		var bytes = File.ReadAllBytes( path );
		var form = new WWWForm();
		var fileName = "dummy.apk";//Path.GetFileName( path );
		form.AddBinaryData( "file", bytes, fileName, "application/octet-stream" );

		var url = string.Format( "https://deploygate.com/api/users/{0}/apps", accountName );

		var getData = new Dictionary<string, string>();
		getData[ "token" ] = apikey;
		getData[ "message" ] = "hogehoge" + DateTime.Now.ToString( "yyyyMMddHHmmss" );
		var strFormData = "?";
		foreach( var pair in getData )
		{
			strFormData += pair.Key + "=" +  pair.Value + "&";
		}
		var request = UnityWebRequest.Post( url + strFormData, form );
		request.SendWebRequest();
		while( request.isDone == false )
			yield return null;

		if( string.IsNullOrEmpty( request.error ) == false )
		{
			Debug.Log( request.error );
		}
		var responseJson = request.downloadHandler.text;
		Debug.Log( responseJson );

		request.Dispose();
		Debug.Log( "End Upload" );

		yield break;
	}
	int IOrderedCallback.callbackOrder { get { return 1000; } }
	void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report)
	{
		Debug.Log("IPreprocessBuildWithReport.OnPreprocessBuild for target " + report.summary.platform + " at path " + report.summary.outputPath);

		ScriptableSingleton<Param>.instance.productName = PlayerSettings.productName;
		ScriptableSingleton<Param>.instance.icons = PlayerSettings.GetIconsForTargetGroup( BuildTargetGroup.Unknown );
		PlayerSettings.productName = "dep_test";
		var icons = new Texture2D[ ScriptableSingleton<Param>.instance.icons.Length ];
		PlayerSettings.SetIconsForTargetGroup( BuildTargetGroup.Unknown, icons );
	}

	void IPostprocessBuildWithReport.OnPostprocessBuild( BuildReport report )
	{
		Debug.Log("IPostprocessBuildWithReport.OnPostprocessBuild for target " + report.summary.platform + " at path " + report.summary.outputPath);
		Upload( report.summary.outputPath );

		PlayerSettings.productName = ScriptableSingleton<Param>.instance.productName;
		PlayerSettings.SetIconsForTargetGroup(BuildTargetGroup.Unknown, ScriptableSingleton<Param>.instance.icons );
	}
}

~~~

2017.2.0p4

~~~c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.Networking;
using System.IO;
using System;
using UnityEditor.Build;
using UnityEditor.Callbacks;

public class EditorDeploygateUploader : EditorWindow, IPostprocessBuild
{
	public class Param : ScriptableSingleton<Param>
	{
		public IEnumerator opFunc = null;   //保存されないのでここにある意味は特にない
		public int state = 0;
		public string path;
	}

	[ MenuItem( "Tools/Deploygate/Open" ) ]
	static void OnMenuOpen()
	{
		var window = EditorWindow.GetWindow<EditorDeploygateUploader>( "EditorDeploygateUploader" );
		window.ShowPopup();
	}

	private void OnEnable()
	{
	}

	private void OnDisable()
	{
	}

	private void OnGUI()
	{
		using( var verticalScope = new EditorGUILayout.VerticalScope( "Common" ) )
		{
			EditorGUILayout.LabelField( "AccountName" );
			var prevAccountName = EditorPrefs.GetString( "DeploygateAccountName", "" );
			var accountName = EditorGUILayout.TextField( prevAccountName );
			if( prevAccountName != accountName )
				EditorPrefs.SetString( "DeploygateAccountName", accountName );

			EditorGUILayout.LabelField( "ApiKey" );
			var prevKey = EditorPrefs.GetString( "DeploygateApiKey", "" );
			var key = EditorGUILayout.TextField( prevKey );
			if( prevKey != key )
				EditorPrefs.SetString( "DeploygateApiKey", key );
		}
	}


	[DidReloadScripts]
	private static void OnReloadScripts()
	{
		Debug.Log( "OnReloadScripts" );
		if( ScriptableSingleton<Param>.instance.state == 0 )
			return;
		EditorApplication.update += OnUpdate;
		ScriptableSingleton<Param>.instance.opFunc = OpUpload( ScriptableSingleton<Param>.instance.path );
	}

	private static void OnUpdate()
	{
		if( ScriptableSingleton<Param>.instance.opFunc == null )
			return;
		if( ScriptableSingleton<Param>.instance.opFunc.MoveNext() == false )
		{
			ScriptableSingleton<Param>.instance.state = 0;
			ScriptableSingleton<Param>.instance.opFunc = null;
			EditorApplication.update -= OnUpdate;
			Debug.Log( "End Update" );
		}
	}

	private static void Upload( string path )
	{
		ScriptableSingleton<Param>.instance.state = 1;
		ScriptableSingleton<Param>.instance.path = path;
	}

	private static IEnumerator OpUpload( string path )
	{
		var accountName = EditorPrefs.GetString( "DeploygateAccountName", "" );
		var apikey = EditorPrefs.GetString( "DeploygateApiKey", "" );
		if(  string.IsNullOrEmpty( accountName ) == true || string.IsNullOrEmpty( apikey ) == true )
		{
			Debug.Log( "Deploygate NoSetting!" );
			yield break;
		}

		Debug.Log( "Begin Upload" );
		var bytes = File.ReadAllBytes( path );
		var form = new WWWForm();
		var fileName = Path.GetFileName( path );
		form.AddBinaryData( "file", bytes, fileName, "application/octet-stream" );

		var url = string.Format( "https://deploygate.com/api/users/{0}/apps", accountName );

		var getData = new Dictionary<string, string>();
		getData[ "token" ] = apikey;
		getData[ "message" ] = "hogehoge" + DateTime.Now.ToString( "yyyyMMddHHmmss" );
		var strFormData = "?";
		foreach( var pair in getData )
		{
			strFormData += pair.Key + "=" +  pair.Value + "&";
		}
		var request = UnityWebRequest.Post( url + strFormData, form );
		request.SendWebRequest();
		while( request.isDone == false )
			yield return null;

		if( string.IsNullOrEmpty( request.error ) == false )
		{
			Debug.Log( request.error );
		}
		var responseJson = request.downloadHandler.text;
		Debug.Log( responseJson );

		request.Dispose();
		Debug.Log( "End Upload" );

		yield break;
	}

	int IOrderedCallback.callbackOrder { get { return 1000; } }
	void IPostprocessBuild.OnPostprocessBuild( BuildTarget target, string path )
	{
		Debug.Log( "OnPostprocessBuild:" + target + "path:" + path );
		Upload( path );
	}
}
~~~