Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Nextcloud Android Library
*
* SPDX-FileCopyrightText: 2025 TSI-mc <surinder.kumar@t-systems.com>
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-FileCopyrightText: 2023 Álvaro Brey <alvaro.brey@nextcloud.com>
Expand Down Expand Up @@ -679,6 +680,11 @@ class WebdavEntry constructor(
const val SHAREES_SHARE_TYPE = "type"
const val PROPERTY_QUOTA_USED_BYTES = "quota-used-bytes"
const val PROPERTY_QUOTA_AVAILABLE_BYTES = "quota-available-bytes"
const val PROPERTY_LAST_PHOTO = "last-photo"
const val PROPERTY_NB_ITEMS = "nbItems"
const val PROPERTY_LOCATION = "location"
const val PROPERTY_DATE_RANGE = "dateRange"
const val PROPERTY_COLLABORATORS = "collaborators"
private const val IS_ENCRYPTED = "1"
private const val CODE_PROP_NOT_FOUND = 404
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* Nextcloud Android Library
*
* SPDX-FileCopyrightText: 2025 TSI-mc <surinder.kumar@t-systems.com>
* SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2023 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro.brey@nextcloud.com>
Expand Down Expand Up @@ -221,6 +222,20 @@ public static DavPropertyNameSet getChunksPropSet() {
return propSet;
}

public static DavPropertyNameSet getAlbumPropSet() {
DavPropertyNameSet propertySet = new DavPropertyNameSet();
Namespace ncNamespace = Namespace.getNamespace("nc",WebdavEntry.NAMESPACE_NC);

propertySet.add(DavPropertyName.create(WebdavEntry.PROPERTY_LAST_PHOTO,ncNamespace));
propertySet.add(DavPropertyName.create(WebdavEntry.PROPERTY_NB_ITEMS, ncNamespace));
propertySet.add(DavPropertyName.create(WebdavEntry.PROPERTY_LOCATION, ncNamespace));
propertySet.add(DavPropertyName.create(WebdavEntry.PROPERTY_DATE_RANGE, ncNamespace));
propertySet.add(DavPropertyName.create(WebdavEntry.PROPERTY_COLLABORATORS, ncNamespace));

return propertySet;
}


/**
*
* @param rawEtag
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
/*
* Nextcloud Android Library
*
* SPDX-FileCopyrightText: 2025 TSI-mc <surinder.kumar@t-systems.com>
* SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2017 Mario Danic <mario@lovelyhq.com>
* SPDX-License-Identifier: MIT
*/
package com.owncloud.android.lib.common.utils;

import android.net.Uri;

import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.WebdavEntry;
import com.owncloud.android.lib.resources.files.model.RemoteFile;
Expand All @@ -15,6 +18,8 @@
import org.apache.jackrabbit.webdav.MultiStatusResponse;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* WebDav helper.
Expand Down Expand Up @@ -59,4 +64,33 @@ public ArrayList<RemoteFile> readData(MultiStatus remoteData,

return mFolderAndFiles;
}

/**
* Read the data retrieved from the server about the contents of the target folder
*
* @param remoteData Full response got from the server with the data of the target
* folder and its direct children.
* @param client Client instance to the remote server where the data were
* retrieved.
* @return
*/
public List<RemoteFile> readAlbumData(MultiStatus remoteData, OwnCloudClient client) {
String baseUrl = client.getBaseUri() + "/remote.php/dav/photos/" + client.getUserId();
String encodedPath = Uri.parse(baseUrl).getEncodedPath();
if (encodedPath == null) {
return Collections.emptyList();
}

final var responses = remoteData.getResponses();
List<RemoteFile> files = new ArrayList<>(Math.max(0, responses.length - 1));

// reading from 1 as 0th item will be just the root album path
for (int i = 1; i < responses.length; i++) {
WebdavEntry entry = new WebdavEntry(responses[i], encodedPath);
RemoteFile remoteFile = new RemoteFile(entry);
files.add(remoteFile);
}

return files;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* Nextcloud Android Library
*
* SPDX-FileCopyrightText: 2025 TSI-mc <surinder.kumar@t-systems.com>
* SPDX-License-Identifier: MIT
*/
package com.owncloud.android.lib.resources.albums

import android.util.Log
import com.nextcloud.common.SessionTimeOut
import com.nextcloud.common.defaultSessionTimeOut
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import org.apache.commons.httpclient.HttpStatus
import org.apache.jackrabbit.webdav.DavException
import org.apache.jackrabbit.webdav.Status
import org.apache.jackrabbit.webdav.client.methods.CopyMethod
import java.io.IOException

/**
* Remote operation moving a remote file or folder in the ownCloud server to a different folder
* in the same account.
*
*
* Allows renaming the moving file/folder at the same time.
*/
class CopyFileToAlbumRemoteOperation @JvmOverloads constructor(
private val mSrcRemotePath: String,
private val mTargetRemotePath: String,
private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut
) :
RemoteOperation<Any>() {
/**
* Performs the operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
@Deprecated("Deprecated in Java")
@Suppress("TooGenericExceptionCaught")
override fun run(client: OwnCloudClient): RemoteOperationResult<Any> {
/** check parameters */

var result: RemoteOperationResult<Any>
if (mTargetRemotePath == mSrcRemotePath) {
// nothing to do!
result = RemoteOperationResult(ResultCode.OK)
} else if (mTargetRemotePath.startsWith(mSrcRemotePath)) {
result = RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT)
} else {
/** perform remote operation */
var copyMethod: CopyMethod? = null
try {
copyMethod = CopyMethod(
client.getFilesDavUri(this.mSrcRemotePath),
"${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${
WebdavUtils.encodePath(
mTargetRemotePath
)
}",
false
)
val status = client.executeMethod(
copyMethod,
sessionTimeOut.readTimeOut,
sessionTimeOut.connectionTimeOut
)

/** process response */
result = when (status) {
HttpStatus.SC_MULTI_STATUS -> processPartialError(copyMethod)
HttpStatus.SC_PRECONDITION_FAILED -> {
client.exhaustResponse(copyMethod.responseBodyAsStream)
RemoteOperationResult<Any>(ResultCode.INVALID_OVERWRITE)
}

else -> {
client.exhaustResponse(copyMethod.responseBodyAsStream)
RemoteOperationResult<Any>(isSuccess(status), copyMethod)
}
}

Log.i(
TAG,
"Copy $mSrcRemotePath to $mTargetRemotePath : ${result.logMessage}"
)
} catch (e: Exception) {
result = RemoteOperationResult<Any>(e)
Log.e(
TAG,
"Copy $mSrcRemotePath to $mTargetRemotePath : ${result.logMessage}", e
)
} finally {
copyMethod?.releaseConnection()
}
}

return result
}

/**
* Analyzes a multistatus response from the OC server to generate an appropriate result.
*
*
* In WebDAV, a COPY request on collections (folders) can be PARTIALLY successful: some
* children are copied, some other aren't.
*
*
* According to the WebDAV specification, a multistatus response SHOULD NOT include partial
* successes (201, 204) nor for descendants of already failed children (424) in the response
* entity. But SHOULD NOT != MUST NOT, so take carefully.
*
* @param copyMethod Copy operation just finished with a multistatus response
* @return A result for the [CopyFileToAlbumRemoteOperation] caller
* @throws java.io.IOException If the response body could not be parsed
* @throws org.apache.jackrabbit.webdav.DavException If the status code is other than MultiStatus or if obtaining
* the response XML document fails
*/
@Throws(IOException::class, DavException::class)
private fun processPartialError(copyMethod: CopyMethod): RemoteOperationResult<Any> {
// Adding a list of failed descendants to the result could be interesting; or maybe not.
// For the moment, let's take the easy way.
/** check that some error really occurred */

val responses = copyMethod.responseBodyAsMultiStatus.responses
var status: Array<Status>?
var failFound = false
var i = 0
while (i < responses.size && !failFound) {
status = responses[i].status
failFound = (!status.isNullOrEmpty() && status[0].statusCode > FAILED_STATUS_CODE
)
i++
}
val result: RemoteOperationResult<Any> = if (failFound) {
RemoteOperationResult<Any>(ResultCode.PARTIAL_COPY_DONE)
} else {
RemoteOperationResult<Any>(true, copyMethod)
}

return result
}

private fun isSuccess(status: Int): Boolean {
return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT
}

companion object {
private val TAG: String = CopyFileToAlbumRemoteOperation::class.java.simpleName
private const val FAILED_STATUS_CODE = 299
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Nextcloud Android Library
*
* SPDX-FileCopyrightText: 2025 TSI-mc <surinder.kumar@t-systems.com>
* SPDX-License-Identifier: MIT
*/
package com.owncloud.android.lib.resources.albums

import com.nextcloud.common.SessionTimeOut
import com.nextcloud.common.defaultSessionTimeOut
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.utils.Log_OC
import org.apache.commons.httpclient.HttpStatus
import org.apache.jackrabbit.webdav.client.methods.MkColMethod

class CreateNewAlbumRemoteOperation
@JvmOverloads
constructor(
val newAlbumName: String,
private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut
) : RemoteOperation<Void>() {
/**
* Performs the operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
@Deprecated("Deprecated in Java")
@Suppress("TooGenericExceptionCaught")
override fun run(client: OwnCloudClient): RemoteOperationResult<Void> {
var mkCol: MkColMethod? = null
var result: RemoteOperationResult<Void>
try {
mkCol =
MkColMethod(
"${client.baseUri}/remote.php/dav/photos/${client.userId}/albums${
WebdavUtils.encodePath(
newAlbumName
)
}"
)
client.executeMethod(
mkCol,
sessionTimeOut.readTimeOut,
sessionTimeOut.connectionTimeOut
)
if (HttpStatus.SC_METHOD_NOT_ALLOWED == mkCol.statusCode) {
result =
RemoteOperationResult(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS)
} else {
result = RemoteOperationResult(mkCol.succeeded(), mkCol)
result.resultData = null
}

Log_OC.d(TAG, "Create album $newAlbumName : ${result.logMessage}")
client.exhaustResponse(mkCol.responseBodyAsStream)
} catch (e: Exception) {
result = RemoteOperationResult(e)
Log_OC.e(TAG, "Create album $newAlbumName : ${result.logMessage}", e)
} finally {
mkCol?.releaseConnection()
}

return result
}

companion object {
private val TAG: String = CreateNewAlbumRemoteOperation::class.java.simpleName
}
}
Loading
Loading