Prechádzať zdrojové kódy

EditController: Add deletion to AudioCollectionModel

Closes #689
Edgar Fouillet 5 rokov pred
rodič
commit
cbd19382b4

+ 23 - 2
SharedSources/MediaLibraryModel/AudioCollectionModel.swift

@@ -13,8 +13,29 @@ import Foundation
 protocol AudioCollectionModel: MLBaseModel { }
 
 extension AudioCollectionModel {
-
     func delete(_ items: [VLCMLObject]) {
-        preconditionFailure("AudioCollectionModel: Audio collections can not be deleted, they disappear when their last title got deleted")
+        do {
+            for case let item as MediaCollectionModel in items {
+                if let tracks = item.files() {
+                    for track in tracks {
+                        if let mainFile = track.mainFile() {
+                            try FileManager.default.removeItem(atPath: mainFile.mrl.path)
+                        }
+                    }
+                    let folderPaths = Set(tracks.map {
+                        $0.mainFile()?.mrl.deletingLastPathComponent()
+                    })
+                    for path in folderPaths {
+                        if let path = path {
+                            try FileManager.default.deleteMediaFolder(name: item.title(), at: path)
+                        }
+                    }
+                }
+            }
+            medialibrary.reload()
+        }
+        catch let error as NSError {
+            assertionFailure("AudioCollectionModel: Delete failed: \(error.localizedDescription)")
+        }
     }
 }

+ 1 - 2
Sources/EditToolbar.swift

@@ -80,11 +80,10 @@ class EditToolbar: UIView {
     }
 
     private func setupStackView() {
-        let stackView = UIStackView(arrangedSubviews: [addToPlaylistButton])
+        let stackView = UIStackView(arrangedSubviews: [addToPlaylistButton, deleteButton])
         let file = category.anyfiles.first
 
         if !(file is VLCMLArtist) && !(file is VLCMLGenre) && !(file is VLCMLAlbum) {
-            stackView.addArrangedSubview(deleteButton)
             stackView.addArrangedSubview(renameButton)
         }
 

+ 83 - 0
Sources/FileManager+DeleteMediaFolder.swift

@@ -0,0 +1,83 @@
+/*****************************************************************************
+* FileManager+DeleteMediaFolder.swift
+* VLC for iOS
+*****************************************************************************
+* Copyright (c) 2019 VideoLAN. All rights reserved.
+*
+* Authors: Edgar Fouillet <vlc # edgar.fouillet.eu>
+*
+* Refer to the COPYING file of the official project for license.
+*****************************************************************************/
+
+import Foundation
+
+extension FileManager {
+    func deleteMediaFolder(name: String, at path: URL) throws {
+        let documentPath = FileManager.default.urls(for: .documentDirectory,
+                                                    in: .userDomainMask).first?.resolvingSymlinksInPath()
+        if path.resolvingSymlinksInPath() != documentPath {
+            if let dirContent = try? FileManager.default.contentsOfDirectory(at: path,
+                                                                             includingPropertiesForKeys: []) {
+                if dirContent.isEmpty || canDeleteFolder(content: dirContent, name: name) {
+                    do {
+                        let parentPath = path.deletingLastPathComponent()
+                        try FileManager.default.removeItem(at: path)
+                        if canDeleteParent(at: path, name: name) {
+                            try FileManager.default.removeItem(at: parentPath)
+                        }
+                    }
+                    catch let error as NSError {
+                        throw error
+                    }
+                }
+            }
+        }
+    }
+}
+
+// MARK: - Private helpers
+
+private extension FileManager {
+    func canDeleteFolder(content: [URL], name: String) -> Bool {
+        var coverNames: Set = [
+            "album",
+            "albumart",
+            "albumartsmall",
+            "back",
+            "cover",
+            ".folder",
+            "folder",
+            "front",
+            "thumb"
+        ]
+        let coverExtensions: Set = [
+            "jpg",
+            "jpeg",
+            "png",
+            "gif",
+            "bmp"
+        ]
+        if !name.isEmpty {
+            coverNames.insert(name.lowercased())
+        }
+        for file in content {
+            if !coverNames.contains(file.deletingPathExtension().lastPathComponent.lowercased())
+                || !coverExtensions.contains(file.pathExtension.lowercased()) {
+                    return false
+            }
+        }
+        return true
+    }
+
+    func canDeleteParent(at path: URL, name: String) -> Bool {
+        let parentPath = path.deletingLastPathComponent()
+        if parentPath.lastPathComponent == name {
+            if let parentDirContent = try? FileManager.default.contentsOfDirectory(at: parentPath, includingPropertiesForKeys: []) {
+                if parentDirContent.isEmpty {
+                    return true
+                }
+            }
+        }
+        return false
+    }
+}

+ 4 - 0
VLC.xcodeproj/project.pbxproj

@@ -87,6 +87,7 @@
 		6B4E33D11BF2A39400A35255 /* playerControl.css in Resources */ = {isa = PBXBuildFile; fileRef = 6B4E33CF1BF2A39400A35255 /* playerControl.css */; };
 		6B4E33D21BF2A39400A35255 /* playerControl.js in Resources */ = {isa = PBXBuildFile; fileRef = 6B4E33D01BF2A39400A35255 /* playerControl.js */; };
 		6D8E642A234CBF2200EBC8FC /* AudioCollectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D8E6429234CBF2200EBC8FC /* AudioCollectionModel.swift */; };
+		6D220D0D234B8E3700BD694F /* FileManager+DeleteMediaFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D220D0C234B8E3700BD694F /* FileManager+DeleteMediaFolder.swift */; };
 		7AC8629D1765DC560011611A /* style.css in Resources */ = {isa = PBXBuildFile; fileRef = 7AC8629B1765DC560011611A /* style.css */; };
 		7AC862A61765E9510011611A /* jquery-1.10.1.min.js in Resources */ = {isa = PBXBuildFile; fileRef = 7AC8629E1765E90C0011611A /* jquery-1.10.1.min.js */; };
 		7AC862A71765E9510011611A /* jquery.fileupload.js in Resources */ = {isa = PBXBuildFile; fileRef = 7AC8629F1765E90C0011611A /* jquery.fileupload.js */; };
@@ -567,6 +568,7 @@
 		6B4E33CF1BF2A39400A35255 /* playerControl.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = playerControl.css; path = Resources/web/playerControl.css; sourceTree = SOURCE_ROOT; };
 		6B4E33D01BF2A39400A35255 /* playerControl.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = playerControl.js; path = Resources/web/playerControl.js; sourceTree = SOURCE_ROOT; };
 		6D8E6429234CBF2200EBC8FC /* AudioCollectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioCollectionModel.swift; sourceTree = "<group>"; };
+		6D220D0C234B8E3700BD694F /* FileManager+DeleteMediaFolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "FileManager+DeleteMediaFolder.swift"; path = "Sources/FileManager+DeleteMediaFolder.swift"; sourceTree = "<group>"; };
 		703A80CCC005093CCDFBECBF /* Pods-VLC-iOS-Screenshots.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS-Screenshots.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-iOS-Screenshots/Pods-VLC-iOS-Screenshots.distribution.xcconfig"; sourceTree = "<group>"; };
 		7AC8629B1765DC560011611A /* style.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = style.css; sourceTree = "<group>"; };
 		7AC8629E1765E90C0011611A /* jquery-1.10.1.min.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "jquery-1.10.1.min.js"; sourceTree = "<group>"; };
@@ -2018,6 +2020,7 @@
 		A7C3025A175A538700AD4388 /* Extensions */ = {
 			isa = PBXGroup;
 			children = (
+				6D220D0C234B8E3700BD694F /* FileManager+DeleteMediaFolder.swift */,
 				418B144F20179CB9000447AA /* LayoutAnchorContainer.swift */,
 				7D3784C4183A9972009EE944 /* NSString+SupportedMedia.h */,
 				7D3784C5183A9972009EE944 /* NSString+SupportedMedia.m */,
@@ -3116,6 +3119,7 @@
 				417D7F601F7BA26200DDF36A /* VLCRemoteControlService.m in Sources */,
 				DD510B701B14E564003BA71C /* VLCPlayerDisplayController.m in Sources */,
 				DD3EFF431BDEBCE500B68579 /* VLCSharedLibraryParser.m in Sources */,
+				6D220D0D234B8E3700BD694F /* FileManager+DeleteMediaFolder.swift in Sources */,
 				9B088308183D7BEC004B5C2A /* VLCCloudStorageTableViewController.m in Sources */,
 				7D30F3EC183AB34200FFC021 /* VLCGoogleDriveTableViewController.m in Sources */,
 			);