using System.Collections; using UnityEngine; using TMPro; using Google.Apis.Auth.OAuth2; using Google.Apis.Drive.v3; using Google.Apis.Services; public class UploadToGoogleDrive : MonoBehaviour { public float PrintBrightnessMultiplier = 1.2f; public class UploadRequest { public string uploadDest; public string id; public string summary; public string filename; public bool discard; public bool default_image; } public RenderTexture renderTexture_postcard; public RenderTexture renderTexture_share; public string OutputFolder = "output"; public string FirebaseUrl = "https://firestore.googleapis.com/v1/projects/uc-24070-thegreattipsy/databases/(default)/documents/"; public TextMeshProUGUI TextNumber; public TextMeshProUGUI TextSummary; public GameObject BackgroundText; public GameObject BackgroundDefault; public GameObject ImageDiscard; public GameObject ImageGenerate; public GameObject ImageDiscardPostcard; public GameObject ImageGeneratePostcard; // Start is called before the first frame update public string GoogleDriveFolderId = "1m6qxzRrWfj3UcVxJNgACabS4aM8arbHq"; UploadRequest latest_input; // DriveService service; void Start() { setupService(); } // Update is called once per frame void Update() { } public void Save(string input_text) { var parmas = input_text.Split('#'); if (parmas.Length < 2) { Debug.LogError("Input text must contain at least two parts separated by '#'."); return; } string uploadDest = parmas[0].Trim(); string id = parmas[1].Trim(); var id_paths = id.Split('/'); if (id_paths.Length > 0) { id = id_paths[id_paths.Length - 1]; } string summary = parmas[2].Trim(); string filename = parmas.Length > 3 ? parmas[3].Trim() : System.DateTime.Now.ToString("yyyyMMdd_hhmmss"); bool discard = parmas.Length > 4 && (parmas[4].Trim().ToLower() == "discard"); bool default_image = parmas.Length > 5 && (parmas[5].Trim().ToLower() == "default"); if (ImageDiscard != null) ImageDiscard.SetActive(discard); if (ImageDiscardPostcard != null) ImageDiscardPostcard.SetActive(discard); Debug.Log("discard: " + discard + " default" + default_image + " summary:" + summary); if (summary.Length > 0) { BackgroundDefault.SetActive(false); BackgroundText.SetActive(true); } else { BackgroundDefault.SetActive(true); BackgroundText.SetActive(false); } if (default_image) { ImageGenerate.SetActive(false); ImageGeneratePostcard.SetActive(false); } else { ImageGenerate.SetActive(true); ImageGeneratePostcard.SetActive(true); } TextNumber.SetText(id); TextSummary.SetText(summary); TextNumber.ForceMeshUpdate(); TextSummary.ForceMeshUpdate(); latest_input = new UploadRequest() { uploadDest = uploadDest, id = id, summary = summary, filename = filename, discard = discard, default_image = default_image }; StartCoroutine(ExportAfterFrame(latest_input)); } private IEnumerator ExportAfterFrame(UploadRequest uploadRequest) { // Wait for the end of the current frame, after all Update and LateUpdate calls have finished. yield return new WaitForEndOfFrame(); // Now, call the Export function. Export(uploadRequest); } public void Export(UploadRequest uploadRequest = null) { if (uploadRequest == null) { Debug.LogError("UploadRequest is null."); return; } string uploadDest = uploadRequest.uploadDest; string id = uploadRequest.id; string summary = uploadRequest.summary; string filename = uploadRequest.filename; bool discard = uploadRequest.discard; bool default_image = uploadRequest.default_image; Debug.Log("Saving image to: " + uploadDest + " filename=" + filename + " id=" + id); if (string.IsNullOrEmpty(uploadDest)) { return; } if (string.IsNullOrEmpty(filename)) { Debug.LogError("Filename cannot be null or empty."); return; } Debug.Log("Saving image to: " + uploadDest + " filename=" + filename + " id=" + id); string timestamp = System.DateTime.Now.ToString("yyyyMMdd"); if (!System.IO.Directory.Exists(OutputFolder + "/" + uploadDest)) { System.IO.Directory.CreateDirectory(OutputFolder + "/" + uploadDest); } SaveRenderTextureToPNG(renderTexture_postcard, System.IO.Path.Combine(OutputFolder + "/" + uploadDest, filename + "_print.png")); Debug.Log("Image saved to " + filename); SaveRenderTextureToPNG(renderTexture_share, System.IO.Path.Combine(OutputFolder + "/" + uploadDest, filename + ".png")); Debug.Log("Image saved to " + filename); // Optionally, you can also log the full path string print_fullPath = System.IO.Path.Combine(OutputFolder + "/" + uploadDest + "/", filename + "_print.png"); Debug.Log("print_path: " + print_fullPath); upload(print_fullPath, id, "print", !default_image && !discard); string share_fullPath = System.IO.Path.Combine(OutputFolder + "/" + uploadDest + "/", filename + ".png"); Debug.Log("share_path: " + share_fullPath); upload(share_fullPath, id, "share"); } void SaveRenderTextureToPNG(RenderTexture rt, string filePath) { Debug.Log("Saving RenderTexture to PNG at " + filePath); RenderTexture currentRT = RenderTexture.active; RenderTexture.active = rt; Texture2D tex = new Texture2D(rt.width, rt.height, TextureFormat.RGBA32, false); tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); // Apply gamma correction (sRGB conversion) to each pixel for (int y = 0; y < tex.height; y++) { for (int x = 0; x < tex.width; x++) { Color linearColor = tex.GetPixel(x, y); Color sRGBColor = new Color( Mathf.LinearToGammaSpace(linearColor.r), Mathf.LinearToGammaSpace(linearColor.g), Mathf.LinearToGammaSpace(linearColor.b), linearColor.a ); sRGBColor.r *= PrintBrightnessMultiplier;                 sRGBColor.g *= PrintBrightnessMultiplier; sRGBColor.b *= PrintBrightnessMultiplier; tex.SetPixel(x, y, sRGBColor); } } tex.Apply(); byte[] bytes = tex.EncodeToPNG(); System.IO.File.WriteAllBytes(filePath, bytes); Debug.Log("Saved RenderTexture to PNG at " + filePath + " with size: " + bytes.Length + " bytes"); RenderTexture.active = currentRT; Destroy(tex); } void setupService() { // Debug.Log("Setting up Google Drive service..."); // // Initialize Google Drive API service // service = new DriveService(new BaseClientService.Initializer() // { // HttpClientInitializer = GoogleCredential.FromFile("../Material/tech-277909-8bd38efb7464.json").CreateScoped(DriveService.Scope.DriveFile), // ApplicationName = "24070-Upload", // }); GoogleDriveUtils.setupService(); } void upload(string _uploadFile, string _fileId, string type, bool needToPrint = true) { if (GoogleDriveUtils.service == null) { Debug.Log("service is null, setting up service again."); setupService(); } string path = _fileId; int lastSlash = path.LastIndexOf('/'); if (lastSlash >= 0) { path = path[..lastSlash]; } Debug.Log("Uploading file to Google Drive: " + _uploadFile + " folder=" + path); string folderId = GoogleDriveUtils.getFolder(GoogleDriveUtils.service, path, GoogleDriveFolderId); StartCoroutine(GoogleDriveUtils.UploadCoroutine(GoogleDriveUtils.service, _uploadFile, folderId, _fileId, type, (response) => { if (response != null) { var url = response; Debug.Log("Upload successful:" + url); if (type == "print") { if (needToPrint) writeToFirebase("prints", System.DateTime.Now.ToString("yyyyMMdd_hhmmss"), url, type); } else { writeToFirebase("records", "user/" + _fileId + "/file/" + type, url, type); } } else { Debug.LogError("Upload failed: " + response); } } )); } public void writeToFirebase(string collection, string id, string url, string type) { Debug.Log("Writing to Firebase: " + collection + "/" + id); StartCoroutine(WriteToFirebaseCoroutine(id, url)); IEnumerator WriteToFirebaseCoroutine(string id, string url) { // string[] tags=filename.Split('/'); // string id=tags[tags.Length - 1].Split('.')[0]; Debug.Log("Extracted ID: " + id); string firebaseUrl = FirebaseUrl + collection + "/" + id; string jsonData = "{ \"fields\": { " + "\"" + type + "_url\": { \"stringValue\": \"" + url + "\" }, " + "\"timestamp\": { \"timestampValue\": \"" + System.DateTime.UtcNow.ToString("o") + "\" } " + "} }"; using (var www = new UnityEngine.Networking.UnityWebRequest(firebaseUrl, "PATCH")) { byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonData); www.uploadHandler = new UnityEngine.Networking.UploadHandlerRaw(bodyRaw); www.downloadHandler = new UnityEngine.Networking.DownloadHandlerBuffer(); www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); #if UNITY_2020_1_OR_NEWER if (www.result != UnityEngine.Networking.UnityWebRequest.Result.Success) #else if (www.isNetworkError || www.isHttpError) #endif { Debug.LogError("Error writing to Firebase: " + www.error); Debug.LogError("Response: " + www.downloadHandler.text); } else { Debug.Log("Successfully wrote to Firebase: " + www.downloadHandler.text); } } } } }