From 9ff51d99b28a24baf10eed1e7b9f187e12f87218 Mon Sep 17 00:00:00 2001
From: Manuel Plazas Palacio <manuelplazaspalacio@gmail.com>
Date: Tue, 3 Oct 2023 14:59:08 +0200
Subject: [PATCH] Getting the file path and opening it

---
 .../webdav/properties/OCMetaPathForUser.kt    | 24 +++++++++++++
 .../files/GetFileMetaInfoRemoteOperation.kt   | 35 ++++++++++++++++---
 2 files changed, 54 insertions(+), 5 deletions(-)
 create mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/properties/OCMetaPathForUser.kt

diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/properties/OCMetaPathForUser.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/properties/OCMetaPathForUser.kt
new file mode 100644
index 00000000..44893108
--- /dev/null
+++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/properties/OCMetaPathForUser.kt
@@ -0,0 +1,24 @@
+package com.owncloud.android.lib.common.http.methods.webdav.properties
+
+import at.bitfire.dav4jvm.Property
+import at.bitfire.dav4jvm.PropertyFactory
+import at.bitfire.dav4jvm.XmlUtils
+import org.xmlpull.v1.XmlPullParser
+
+data class OCMetaPathForUser(val path: String) : Property {
+    class Factory : PropertyFactory {
+        override fun getName() = NAME
+
+        override fun create(parser: XmlPullParser): OCMetaPathForUser? {
+            XmlUtils.readText(parser)?.let {
+                return OCMetaPathForUser(it)
+            }
+            return null
+        }
+    }
+
+    companion object {
+        @JvmField
+        val NAME = Property.Name(XmlUtils.NS_OWNCLOUD, "meta-path-for-user")
+    }
+}
diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetFileMetaInfoRemoteOperation.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetFileMetaInfoRemoteOperation.kt
index 7b5e31ed..c1a64881 100644
--- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetFileMetaInfoRemoteOperation.kt
+++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/files/GetFileMetaInfoRemoteOperation.kt
@@ -1,24 +1,39 @@
 package com.owncloud.android.lib.resources.files
 
+import at.bitfire.dav4jvm.PropStat
+import at.bitfire.dav4jvm.Property
+import at.bitfire.dav4jvm.PropertyRegistry
+import at.bitfire.dav4jvm.Response
 import com.owncloud.android.lib.common.OwnCloudClient
 import com.owncloud.android.lib.common.http.HttpConstants
-import com.owncloud.android.lib.common.http.methods.webdav.DavUtils
-import com.owncloud.android.lib.common.http.methods.webdav.DavUtils.allPropSet
+import com.owncloud.android.lib.common.http.methods.webdav.DavConstants
 import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod
+import com.owncloud.android.lib.common.http.methods.webdav.properties.OCMetaPathForUser
 import com.owncloud.android.lib.common.operations.RemoteOperation
 import com.owncloud.android.lib.common.operations.RemoteOperationResult
 import timber.log.Timber
 import java.net.URL
+import java.util.concurrent.TimeUnit
 
 class GetFileMetaInfoRemoteOperation(val fileId: String) : RemoteOperation<String>() {
-    private val stringUrl = "${client.baseUri}$META_PATH$fileId"
 
     override fun run(client: OwnCloudClient): RemoteOperationResult<String> {
+        PropertyRegistry.register(OCMetaPathForUser.Factory())
+
+        val stringUrl = "${client.baseUri}$META_PATH$fileId"
         return try {
-            val propFindMethod = PropfindMethod(URL(stringUrl), 0, allPropSet)
+
+            val propFindMethod =
+                PropfindMethod(URL(stringUrl), DavConstants.DEPTH_0, arrayOf(OCMetaPathForUser.NAME)).apply {
+                    setReadTimeout(40_000L, TimeUnit.SECONDS)
+                    setConnectionTimeout(5_000L, TimeUnit.SECONDS)
+                }
 
             val status = client.executeHttpMethod(propFindMethod)
-            if (isSuccess(status)) RemoteOperationResult<String>(RemoteOperationResult.ResultCode.OK)
+            if (isSuccess(status)) RemoteOperationResult<String>(RemoteOperationResult.ResultCode.OK).apply {
+                data = propFindMethod.root?.properties?.find { property -> property is OCMetaPathForUser }
+                    ?.let { property -> (property as OCMetaPathForUser).path } ?: ""
+            }
             else RemoteOperationResult<String>(propFindMethod)
         } catch (e: Exception) {
             Timber.e(e, "Could not get actuall (or redirected) base URL from base url (/).")
@@ -28,7 +43,17 @@ class GetFileMetaInfoRemoteOperation(val fileId: String) : RemoteOperation<Strin
 
     private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS
 
+    private fun getPropertiesEvenIfPostProcessing(response: Response): List<Property> {
+        return if (response.isSuccess())
+            response.propstat.filter { propStat -> propStat.isSuccessOrPostProcessing() }.map { it.properties }.flatten()
+        else
+            emptyList()
+    }
+
+    private fun PropStat.isSuccessOrPostProcessing() = (status.code / 100 == 2 || status.code == HttpConstants.HTTP_TOO_EARLY)
+
     companion object {
         private const val META_PATH = "/remote.php/dav/meta/"
+        private const val TIMEOUT = 10_000L
     }
 }
\ No newline at end of file