123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- //
- // NCOperationQueue.swift
- // Nextcloud
- //
- // Created by Marino Faggiana on 03/06/2020.
- // Copyright © 2020 Marino Faggiana. All rights reserved.
- //
- // Author Marino Faggiana <marino.faggiana@nextcloud.com>
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- //
- import UIKit
- import Queuer
- import NCCommunication
- @objc class NCOperationQueue: NSObject {
- @objc public static let shared: NCOperationQueue = {
- let instance = NCOperationQueue()
- return instance
- }()
-
- private var downloadQueue = Queuer(name: "downloadQueue", maxConcurrentOperationCount: 5, qualityOfService: .default)
- private let deleteQueue = Queuer(name: "deleteQueue", maxConcurrentOperationCount: 1, qualityOfService: .default)
- private let copyMoveQueue = Queuer(name: "copyMoveQueue", maxConcurrentOperationCount: 1, qualityOfService: .default)
- private let synchronizationQueue = Queuer(name: "synchronizationQueue", maxConcurrentOperationCount: 1, qualityOfService: .default)
- private let downloadThumbnailQueue = Queuer(name: "downloadThumbnailQueue", maxConcurrentOperationCount: 10, qualityOfService: .default)
- private let downloadAvatarQueue = Queuer(name: "downloadAvatarQueue", maxConcurrentOperationCount: 10, qualityOfService: .default)
- private var timerReadFileForMediaQueue: Timer?
- @objc func cancelAllQueue() {
- downloadCancelAll()
- deleteCancelAll()
- copyMoveCancelAll()
- synchronizationCancelAll()
- downloadThumbnailCancelAll()
- downloadAvatarCancelAll()
- }
-
- // Download file
-
- func download(metadata: tableMetadata, selector: String) {
- for operation in downloadQueue.operations as! [NCOperationDownload] {
- if operation.metadata.ocId == metadata.ocId {
- return
- }
- }
- downloadQueue.addOperation(NCOperationDownload.init(metadata: metadata, selector: selector))
- }
- @objc func downloadCancelAll() {
- downloadQueue.cancelAll()
- }
- @objc func downloadCount() -> Int {
- return downloadQueue.operationCount
- }
- @objc func downloadExists(metadata: tableMetadata) -> Bool {
- for operation in downloadQueue.operations as! [NCOperationDownload] {
- if operation.metadata.ocId == metadata.ocId {
- return true
- }
- }
- return false
- }
-
- // Delete file
-
- @objc func delete(metadata: tableMetadata, onlyLocal: Bool) {
- for operation in deleteQueue.operations as! [NCOperationDelete] {
- if operation.metadata.ocId == metadata.ocId {
- return
- }
- }
- deleteQueue.addOperation(NCOperationDelete.init(metadata: metadata, onlyLocal: onlyLocal))
- }
- @objc func deleteCancelAll() {
- deleteQueue.cancelAll()
- }
- @objc func deleteCount() -> Int {
- return deleteQueue.operationCount
- }
-
- // Copy Move file
-
- @objc func copyMove(metadata: tableMetadata, serverUrl: String, overwrite: Bool, move: Bool) {
- for operation in copyMoveQueue.operations as! [NCOperationCopyMove] {
- if operation.metadata.ocId == metadata.ocId {
- return
- }
- }
- copyMoveQueue.addOperation(NCOperationCopyMove.init(metadata: metadata, serverUrlTo: serverUrl, overwrite: overwrite, move: move))
- }
- @objc func copyMoveCancelAll() {
- copyMoveQueue.cancelAll()
- }
- @objc func copyMoveCount() -> Int {
- return copyMoveQueue.operationCount
- }
-
- // Synchronization
-
- @objc func synchronizationMetadata(_ metadata: tableMetadata, selector: String) {
- for operation in synchronizationQueue.operations as! [NCOperationSynchronization] {
- if operation.metadata.ocId == metadata.ocId {
- return
- }
- }
- synchronizationQueue.addOperation(NCOperationSynchronization.init(metadata: metadata, selector: selector))
- }
- @objc func synchronizationCancelAll() {
- synchronizationQueue.cancelAll()
- }
-
- // Download Thumbnail
-
- @objc func downloadThumbnail(metadata: tableMetadata, placeholder: Bool, cell: UIView, view: UIView?) {
-
- let cell: NCCellProtocol = cell as! NCCellProtocol
-
- if placeholder {
- if metadata.iconName.count > 0 {
- cell.filePreviewImageView?.image = UIImage.init(named: metadata.iconName)
- } else {
- cell.filePreviewImageView?.image = NCBrandColor.cacheImages.file
- }
- }
-
- if metadata.hasPreview && metadata.status == NCGlobal.shared.metadataStatusNormal && (!CCUtility.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag)) {
- for operation in downloadThumbnailQueue.operations as! [NCOperationDownloadThumbnail] {
- if operation.metadata.ocId == metadata.ocId {
- return
- }
- }
- downloadThumbnailQueue.addOperation(NCOperationDownloadThumbnail.init(metadata: metadata, cell: cell, view: view))
- }
- }
-
- func cancelDownloadThumbnail(metadata: tableMetadata) {
- for operation in downloadThumbnailQueue.operations as! [NCOperationDownloadThumbnail] {
- if operation.metadata.ocId == metadata.ocId {
- operation.cancel()
- }
- }
- }
-
- @objc func downloadThumbnailCancelAll() {
- downloadThumbnailQueue.cancelAll()
- }
-
- // Download Avatar
-
- func downloadAvatar(user: String, fileName: String, placeholder: UIImage?, cell: UIView, view: UIView?) {
- let cell: NCCellProtocol = cell as! NCCellProtocol
- let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName
- #if !EXTENSION
- if let image = (UIApplication.shared.delegate as! AppDelegate).avatars[user] {
- cell.fileAvatarImageView?.image = image
- return
- }
- #endif
-
- cell.fileAvatarImageView?.image = placeholder
- if let image = UIImage(contentsOfFile: fileNameLocalPath) {
- cell.fileAvatarImageView?.image = NCUtility.shared.createAvatar(image: image, size: 30)
- }
-
- downloadAvatarQueue.addOperation(NCOperationDownloadAvatar.init(user: user, fileName: fileName, fileNameLocalPath: fileNameLocalPath, cell: cell, view: view))
- }
-
- func cancelDownloadAvatar(user: String) {
- for operation in downloadAvatarQueue.operations as! [NCOperationDownloadAvatar] {
- if operation.user == user {
- operation.cancel()
- }
- }
- }
-
- @objc func downloadAvatarCancelAll() {
- downloadAvatarQueue.cancelAll()
- }
- }
- //MARK: -
- class NCOperationDownload: ConcurrentOperation {
-
- var metadata: tableMetadata
- var selector: String
-
- init(metadata: tableMetadata, selector: String) {
- self.metadata = tableMetadata.init(value: metadata)
- self.selector = selector
- }
-
- override func start() {
- if isCancelled {
- self.finish()
- } else {
- NCNetworking.shared.download(metadata: metadata, selector: self.selector) { (_) in
- self.finish()
- }
- }
- }
- }
- //MARK: -
- class NCOperationDelete: ConcurrentOperation {
-
- var metadata: tableMetadata
- var onlyLocal: Bool
-
- init(metadata: tableMetadata, onlyLocal: Bool) {
- self.metadata = tableMetadata.init(value: metadata)
- self.onlyLocal = onlyLocal
- }
-
- override func start() {
- if isCancelled {
- self.finish()
- } else {
- NCNetworking.shared.deleteMetadata(metadata, onlyLocal: onlyLocal) { (errorCode, errorDescription) in
- if errorCode != 0 {
- NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
- }
- self.finish()
- }
- }
- }
- }
- //MARK: -
- class NCOperationCopyMove: ConcurrentOperation {
-
- var metadata: tableMetadata
- var serverUrlTo: String
- var overwrite: Bool
- var move: Bool
- init(metadata: tableMetadata, serverUrlTo: String, overwrite: Bool, move: Bool) {
- self.metadata = tableMetadata.init(value: metadata)
- self.serverUrlTo = serverUrlTo
- self.overwrite = overwrite
- self.move = move
- }
-
- override func start() {
- if isCancelled {
- self.finish()
- } else {
- if move {
- NCNetworking.shared.moveMetadata(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite) { (errorCode, errorDescription) in
- if errorCode != 0 {
- NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
- }
- self.finish()
- }
- } else {
- NCNetworking.shared.copyMetadata(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite) { (errorCode, errorDescription) in
- if errorCode != 0 {
- NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode)
- }
- self.finish()
- }
- }
- }
- }
- }
- //MARK: -
- class NCOperationSynchronization: ConcurrentOperation {
-
- var metadata: tableMetadata
- var selector: String
- var download: Bool
-
- init(metadata: tableMetadata, selector: String) {
- self.metadata = tableMetadata.init(value: metadata)
- self.selector = selector
- if selector == NCGlobal.shared.selectorDownloadFile || selector == NCGlobal.shared.selectorDownloadAllFile {
- self.download = true
- } else {
- self.download = false
- }
- }
-
- override func start() {
- if isCancelled {
- self.finish()
- } else {
- if metadata.directory {
-
- let serverUrl = metadata.serverUrl + "/" + metadata.fileName
- let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, serverUrl))
- NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in
- if (errorCode == 0) && (directory?.etag != files.first?.etag || self.selector == NCGlobal.shared.selectorDownloadAllFile) {
-
- NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in
-
- if errorCode == 0 {
-
- NCManageDatabase.shared.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: true, account: account) { (metadataFolder, metadatasFolder, metadatas) in
-
- let metadatasResult = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, NCGlobal.shared.metadataStatusNormal))
-
- if self.selector == NCGlobal.shared.selectorDownloadAllFile {
-
- NCManageDatabase.shared.updateMetadatas(metadatas, metadatasResult: metadatasResult)
- for metadata in metadatas {
- if metadata.directory {
- NCOperationQueue.shared.synchronizationMetadata(metadata, selector: self.selector)
- } else {
- if NCManageDatabase.shared.isDownloadMetadata(metadata, download: true) {
- NCOperationQueue.shared.download(metadata: metadata, selector: self.selector)
- }
- }
- }
-
- } else {
-
- let metadatasChanged = NCManageDatabase.shared.updateMetadatas(metadatas, metadatasResult: metadatasResult, addExistsInLocal: self.download, addCompareEtagLocal: true, addDirectorySynchronized: true)
- for metadata in metadatasChanged.metadatasUpdate {
- if metadata.directory {
- NCOperationQueue.shared.synchronizationMetadata(metadata, selector: self.selector)
- }
- }
-
- for metadata in metadatasChanged.metadatasLocalUpdate {
- NCOperationQueue.shared.download(metadata: metadata, selector: self.selector)
- }
- }
-
- // Update etag directory
- NCManageDatabase.shared.addDirectory(encrypted: metadataFolder.e2eEncrypted, favorite: metadataFolder.favorite, ocId: metadataFolder.ocId, fileId: metadataFolder.fileId, etag: metadataFolder.etag, permissions: metadataFolder.permissions, serverUrl: serverUrl, account: metadataFolder.account)
- }
-
- } else if errorCode == NCGlobal.shared.errorResourceNotFound && self.metadata.directory {
- NCManageDatabase.shared.deleteDirectoryAndSubDirectory(serverUrl: self.metadata.serverUrl, account: self.metadata.account)
- }
-
- self.finish()
- }
-
- } else {
-
- let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl))
- for metadata in metadatas {
- if metadata.directory {
- NCOperationQueue.shared.synchronizationMetadata(metadata, selector: self.selector)
- } else {
- if NCManageDatabase.shared.isDownloadMetadata(metadata, download: self.download) {
- NCOperationQueue.shared.download(metadata: metadata, selector: self.selector)
- }
- }
- }
-
- self.finish()
- }
- }
-
- } else {
- if NCManageDatabase.shared.isDownloadMetadata(metadata, download: self.download) {
- NCOperationQueue.shared.download(metadata: metadata, selector: self.selector)
- }
- self.finish()
- }
- }
- }
- }
- //MARK: -
- class NCOperationDownloadThumbnail: ConcurrentOperation {
-
- var metadata: tableMetadata
- var cell: NCCellProtocol!
- var view: UIView?
- var fileNamePath: String = ""
- var fileNamePreviewLocalPath: String = ""
- var fileNameIconLocalPath: String = ""
-
- init(metadata: tableMetadata, cell: NCCellProtocol, view: UIView?) {
- self.metadata = tableMetadata.init(value: metadata)
- self.cell = cell
- self.view = view
- self.fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, account: metadata.account)!
- self.fileNamePreviewLocalPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag)!
- self.fileNameIconLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)!
- }
-
- override func start() {
- if isCancelled {
- self.finish()
- } else {
- NCCommunication.shared.downloadPreview(fileNamePathOrFileId: fileNamePath, fileNamePreviewLocalPath: fileNamePreviewLocalPath , widthPreview: NCGlobal.shared.sizePreview, heightPreview: NCGlobal.shared.sizePreview, fileNameIconLocalPath: fileNameIconLocalPath, sizeIcon: NCGlobal.shared.sizeIcon) { (account, imagePreview, imageIcon, errorCode, errorDescription) in
-
- if errorCode == 0 && imageIcon != nil {
- if self.metadata.ocId == self.cell.fileObjectId {
- if let filePreviewImageView = self.cell?.filePreviewImageView {
- UIView.transition(with: filePreviewImageView,
- duration: 0.75,
- options: .transitionCrossDissolve,
- animations: { filePreviewImageView.image = imageIcon! },
- completion: nil)
- }
- } else {
- if self.view is UICollectionView {
- (self.view as? UICollectionView)?.reloadData()
- } else if self.view is UITableView{
- (self.view as? UITableView)?.reloadData()
- }
- }
- }
- self.finish()
- }
- }
- }
- }
- //MARK: -
- class NCOperationDownloadAvatar: ConcurrentOperation {
- var user: String
- var fileName: String
- var etag: String?
- var fileNameLocalPath: String
- var cell: NCCellProtocol!
- var view: UIView?
- init(user: String, fileName: String, fileNameLocalPath: String, cell: NCCellProtocol, view: UIView?) {
- self.user = user
- self.fileName = fileName
- self.fileNameLocalPath = fileNameLocalPath
- self.cell = cell
- self.view = view
- self.etag = NCManageDatabase.shared.getTableAvatar(fileName: fileName)?.etag
- }
-
- override func start() {
- if isCancelled {
- self.finish()
- } else {
- NCCommunication.shared.downloadAvatar(user: user, fileNameLocalPath: fileNameLocalPath, size: NCGlobal.shared.avatarSize, etag: self.etag) { (account, data, etag, errorCode, errorMessage) in
-
- if errorCode == 0, let data = data, let etag = etag, var image = UIImage.init(data: data) {
-
- image = NCUtility.shared.createAvatar(image: image, size: 30)
- NCManageDatabase.shared.addAvatar(fileName: self.fileName, etag: etag)
- #if !EXTENSION
- (UIApplication.shared.delegate as! AppDelegate).avatars[self.user] = image
- #endif
- if self.user == self.cell.fileUser {
- if let avatarImageView = self.cell?.fileAvatarImageView {
- UIView.transition(with: avatarImageView, duration: 0.75, options: .transitionCrossDissolve) {
- avatarImageView.image = image
- } completion: { _ in
- if self.view is UICollectionView {
- (self.view as? UICollectionView)?.reloadData()
- } else if self.view is UITableView{
- (self.view as? UITableView)?.reloadData()
- }
- }
- }
- } else {
- if self.view is UICollectionView {
- (self.view as? UICollectionView)?.reloadData()
- } else if self.view is UITableView{
- (self.view as? UITableView)?.reloadData()
- }
- }
- }
-
- self.finish()
- }
- }
- }
- }
|