Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Share Download Limit Features #107

Merged
merged 1 commit into from
Dec 20, 2024
Merged
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
33 changes: 33 additions & 0 deletions Sources/NextcloudKit/Models/NKDownloadLimit.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: Nextcloud GmbH
// SPDX-FileCopyrightText: 2024 Iva Horn
// SPDX-License-Identifier: GPL-3.0-or-later

import Foundation

///
/// Data model for a download limit as returned in the WebDAV response for file properties.
///
/// Each relates to a share of a file and is optionally provided by the [Files Download Limit](https://github.com/nextcloud/files_downloadlimit) app for Nextcloud server.
///
public class NKDownloadLimit: NSObject {
///
/// The number of downloads which already happened.
///
public let count: Int

///
/// Total number of allowed downloas.
///
public let limit: Int

///
/// The token identifying the related share.
///
public let token: String

init(count: Int, limit: Int, token: String) {
self.count = count
self.limit = limit
self.token = token
}
}
6 changes: 6 additions & 0 deletions Sources/NextcloudKit/Models/NKFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
public var date = Date()
public var directory: Bool = false
public var downloadURL = ""

///
/// Download limits for shares of this file.
///
public var downloadLimits = [NKDownloadLimit]()

Check warning on line 24 in Sources/NextcloudKit/Models/NKFile.swift

View workflow job for this annotation

GitHub Actions / Lint

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
i2h3 marked this conversation as resolved.
Show resolved Hide resolved
public var e2eEncrypted: Bool = false
public var etag = ""
public var favorite: Bool = false
Expand Down
9 changes: 9 additions & 0 deletions Sources/NextcloudKit/Models/NKProperties.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,18 @@
// SPDX-FileCopyrightText: 2023 Claudio Cambra
// SPDX-License-Identifier: GPL-3.0-or-later

///
/// Definition of properties used for decoding in ``NKDataFileXML``.
///
public enum NKProperties: String, CaseIterable {
/// DAV
case displayname = "<d:displayname />"

///
/// Download limits for shares of a file as optionally provided by the [Files Download Limit](https://github.com/nextcloud/files_downloadlimit) app for Nextcloud server.
///
case downloadLimit = "<nc:share-download-limits />"

case getlastmodified = "<d:getlastmodified />"
case getetag = "<d:getetag />"
case getcontenttype = "<d:getcontenttype />"
Expand Down
18 changes: 17 additions & 1 deletion Sources/NextcloudKit/NKDataFileXML.swift
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@
return xml["ocs", "data", "apppassword"].text
}

func convertDataFile(xmlData: Data, nkSession: NKSession, showHiddenFiles: Bool, includeHiddenFiles: [String]) -> [NKFile] {

Check warning on line 300 in Sources/NextcloudKit/NKDataFileXML.swift

View workflow job for this annotation

GitHub Actions / Lint

Function Body Length Violation: Function body should span 200 lines or less excluding comments and whitespace: currently spans 245 lines (function_body_length)
var files: [NKFile] = []
let rootFiles = "/" + nkSession.dav + "/files/"
guard let baseUrl = self.nkCommonInstance.getHostName(urlString: nkSession.urlBase) else {
Expand Down Expand Up @@ -560,7 +560,23 @@
}

file.placePhotos = propstat["d:prop", "nc:metadata-photos-place"].text


for downloadLimit in propstat["d:prop", "nc:share-download-limits", "nc:share-download-limit"] {
guard let token = downloadLimit["nc:token"].text else {
continue
}

guard let limit = downloadLimit["nc:limit"].int else {
continue
}

guard let count = downloadLimit["nc:count"].int else {
continue
}

file.downloadLimits.append(NKDownloadLimit(count: count, limit: limit, token: token))
}

let results = self.nkCommonInstance.getInternalType(fileName: file.fileName, mimeType: file.contentType, directory: file.directory, account: nkSession.account)

file.contentType = results.mimeType
Expand Down
90 changes: 90 additions & 0 deletions Sources/NextcloudKit/NextcloudKit+ShareDownloadLimit.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// SPDX-FileCopyrightText: Nextcloud GmbH
// SPDX-FileCopyrightText: 2024 Iva Horn
// SPDX-License-Identifier: GPL-3.0-or-later

import Alamofire
import Foundation

public extension NextcloudKit {
private func makeEndpoint(with token: String) -> String {
"ocs/v2.php/apps/files_downloadlimit/api/v1/\(token)/limit"
}

func removeShareDownloadLimit(account: String, token: String, completion: @escaping (_ error: NKError) -> Void) {
let endpoint = makeEndpoint(with: token)
let options = NKRequestOptions()

guard let nkSession = nkCommonInstance.getSession(account: account),
let url = nkCommonInstance.createStandardUrl(serverUrl: nkSession.urlBase, endpoint: endpoint, options: options),
let headers = nkCommonInstance.getStandardHeaders(account: account, options: options) else {
return options.queue.async {
completion(.urlError)
}
}

nkSession
.sessionData
.request(url, method: .delete, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil)
.validate(statusCode: 200..<300)
.response(queue: self.nkCommonInstance.backgroundQueue) { response in
if self.nkCommonInstance.levelLog > 0 {
debugPrint(response)
}

switch response.result {
case .failure(let error):
let error = NKError(error: error, afResponse: response, responseData: response.data)

options.queue.async {
completion(error)
}
case .success:
options.queue.async {
completion(.success)
}
}
}
}

func setShareDownloadLimit(account: String, token: String, limit: Int, completion: @escaping (_ error: NKError) -> Void) {
let endpoint = makeEndpoint(with: token)
let options = NKRequestOptions()
options.contentType = "application/json"

guard let nkSession = nkCommonInstance.getSession(account: account),
let url = nkCommonInstance.createStandardUrl(serverUrl: nkSession.urlBase, endpoint: endpoint, options: options),
let headers = nkCommonInstance.getStandardHeaders(account: account, options: options),
var urlRequest = try? URLRequest(url: url, method: .put, headers: headers) else {
return options.queue.async {
completion(.urlError)
}
}

urlRequest.httpBody = try? JSONEncoder().encode([
"limit": limit
])

nkSession
.sessionData
.request(urlRequest)
.validate(statusCode: 200..<300)
.response(queue: self.nkCommonInstance.backgroundQueue) { response in
if self.nkCommonInstance.levelLog > 0 {
debugPrint(response)
}

switch response.result {
case .failure(let error):
let error = NKError(error: error, afResponse: response, responseData: response.data)

options.queue.async {
completion(error)
}
case .success:
options.queue.async {
completion(.success)
}
}
}
}
}
Loading