From 5a036df4e56dd0a4dadcc9b158758a9cb8c16953 Mon Sep 17 00:00:00 2001 From: Nithya Vasudevan Date: Thu, 1 Aug 2024 19:56:11 +0200 Subject: [PATCH] Fix download from URL for Google Drive and Dropbox For URLs to download books in Google Drive and Dropbox, the URL provided by the user needs to be fixed up before a download can be attempted. Tested book download from Google Drive and Dropbox URLs for individual files and zip files. Fixes: #1077 Signed-off-by: Nithya Vasudevan --- .../ItemList Screen/ItemListViewModel.swift | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/BookPlayer/Library/ItemList Screen/ItemListViewModel.swift b/BookPlayer/Library/ItemList Screen/ItemListViewModel.swift index c83e1746..7cd373fc 100644 --- a/BookPlayer/Library/ItemList Screen/ItemListViewModel.swift +++ b/BookPlayer/Library/ItemList Screen/ItemListViewModel.swift @@ -925,7 +925,7 @@ class ItemListViewModel: ViewModelProtocol { BPActionItem( title: "download_title".localized, inputHandler: { [weak self] url in - if let bookUrl = URL(string: url) { + if let bookUrl = self?.getDownloadURL(for: url) { self?.handleDownload(bookUrl) } else { self?.sendEvent(.showAlert( @@ -1311,6 +1311,43 @@ extension ItemListViewModel { ) )) } + + func getDownloadURL(for givenString : String) -> URL? { + let givenUrl = URL(string: givenString) + + if let givenUrl, let hostname = givenUrl.host { + if hostname == "drive.google.com" { + return getGoogleDriveURL(for: givenUrl) + } else if hostname == "www.dropbox.com" { + return getDropboxURL(for: givenUrl) + } + } + return nil + } + + func getGoogleDriveURL(for url: URL) -> URL? + { + let pathComponents = url.pathComponents + if let index = pathComponents.firstIndex(of: "d"), index + 1 < pathComponents.count { + return URL(string: "https://drive.google.com/uc?export=download&id=" + pathComponents[index + 1]) + } + return nil; + } + + func getDropboxURL (for url : URL) -> URL? + { + guard var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) else { + return nil + } + var queryItems = urlComponents.queryItems ?? [] + if let index = queryItems.firstIndex(where: {$0.name == "dl"}) { + queryItems[index].value = "1" + } else { + queryItems.append(URLQueryItem(name: "dl", value: "1")) + } + urlComponents.queryItems = queryItems + return urlComponents.url + } } extension ItemListViewModel: AlertPresenter {