File indexing completed on 2024-02-18 04:58:20

0001 /***************************************************************************
0002  *   Copyright (C) 2010 Matthias Fuchs <mat69@gmx.net>                     *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU General Public License     *
0015  *   along with this program; if not, write to the                         *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
0018  ***************************************************************************/
0019 
0020 #ifndef KGET_URL_CHECKER_H
0021 #define KGET_URL_CHECKER_H
0022 
0023 #include "kget_export.h"
0024 
0025 #include <QHash>
0026 #include <QList>
0027 #include <QUrl>
0028 
0029 class Transfer;
0030 class TransferHandler;
0031 
0032 /**
0033  * This class provides static methods to check if urls are valid, and if not
0034  * provides enums to see what is not valid and provides translated error messages
0035  */
0036 class KGET_EXPORT UrlChecker
0037 {
0038 public:
0039     enum UrlType { Source, Destination, Folder };
0040 
0041     /**
0042      * Before using UrlChecker you have to specify a type
0043      * You can either do that in the constructor and later
0044      * via setType
0045      *
0046      * @see setType
0047      */
0048     explicit UrlChecker(UrlType type);
0049     ~UrlChecker();
0050 
0051     /**
0052      * Removes duplicates of a list of urls
0053      */
0054     static void removeDuplicates(QList<QUrl> &urls);
0055 
0056     // NOTE only first found error is reported, i.e. NotWriteable before ExistingFile if both are the case
0057     enum UrlError {
0058         // General
0059         NoError = 0,
0060         Empty,
0061         Invalid,
0062 
0063         // Source only
0064         NoProtocol,
0065         NoHost,
0066 
0067         // Destination and Folder only
0068         NotWriteable
0069     };
0070 
0071     enum UrlWarning {
0072         NoWarning = 0,
0073         // Source and Destination only
0074         ExistingFinishedTransfer,
0075         ExistingTransfer,
0076 
0077         // Destination only
0078         ExistingFile
0079     };
0080 
0081     /**
0082      * Folder:
0083      * Checks if the destination url points to is a folder that is writeable and existent.
0084      *
0085      * Destination:
0086      * Checks if url points to a file (can be non-existent) and if the
0087      * directory this file is (would) be in is existent and writeable
0088      *
0089      * @param url the URL
0090      * @param type all types supported here
0091      * @param showNotification true shows a notification if an error is found
0092      * @note checkExisting is not done within this method
0093      * @note you can use the convenience methods checkSource, checkDestination, checkFolder
0094      * directly
0095      * @see checkExisting
0096      */
0097     static UrlError checkUrl(const QUrl &url, const UrlType type, bool showNotification = false);
0098 
0099     /**
0100      * Convenience method of checkUrl
0101      * @param source the URL
0102      * @param showNotification true shows a notification if an error is found
0103      */
0104     static UrlError checkSource(const QUrl &source, bool showNotification = false);
0105 
0106     /**
0107      * Convenience method of checkUrl
0108      * @param destination the URL
0109      * @param showNotification true shows a notification if an error is found
0110      */
0111     static UrlError checkDestination(const QUrl &destination, bool showNotification = false);
0112 
0113     /**
0114      * Convenience method of checkUrl
0115      * @param folder the folder
0116      * @param showNotification true shows a notification if an error is found
0117      */
0118     static UrlError checkFolder(const QUrl &folder, bool showNotification = false);
0119 
0120     /**
0121      * Checks if source is local and exists already
0122      * @note If both @p dest and @p source are the same and local, then @c false will be returned
0123      * since it is assumed, that local files are either not handled by any
0124      * transfer plugin or are e.g. metalink or torrent files otherwise and thus
0125      * can have the same @p source / @p dest.
0126      * Also keep in mind that false will be returned if @p dest is being removed
0127      * at the moment. Avoid to ask a user twice in worst case.
0128      */
0129     static bool wouldOverwrite(const QUrl &source, const QUrl &dest);
0130 
0131     /**
0132      * Checks if there is an existing transfer for url with type
0133      * @param url the URL
0134      * @param type Source checks if there is a transfer with the same source
0135      * destination checks if there is a transfer with the same destination
0136      * @param warning the warning type
0137      * @return if an existing transfer is found it will be returned,
0138      * otherwise @c nullptr will be returned
0139      * @note checkUrl check is not done and UrlType Folder is not supported
0140      * Keep in mind, that the same transfers could be found via Source and Destination!
0141      * @see checkUrl
0142      */
0143     static TransferHandler *existingTransfer(const QUrl &url, const UrlType type, UrlWarning *warning = nullptr);
0144 
0145     /**
0146      * @note UrlType folder is not supported, the result then is undefined!
0147      */
0148     static QList<QUrl> hasExistingTransferMessages(const QList<QUrl> &urls, const UrlType type);
0149 
0150     /**
0151      * Get a describing message for UrlError
0152      * @param url is only needed here to include it in some error messages,
0153      * if url is empty, then it won't be used.
0154      * @param type the URL type
0155      * @param error the error type
0156      * @note this method does no checks, it only creates messages based on the error code
0157      * @see checkUrl
0158      */
0159     static QString message(const QUrl &url, const UrlType type, const UrlError error);
0160 
0161     /**
0162      * Get a describing message for UrlWarning
0163      * @param url is only needed here to include it in some error messages,
0164      * if @p url is empty, then it won't be used.
0165      * @param type the URL type
0166      * @param warning the warning type
0167      * @note this method does no checks, it only creates messages based on the warning code
0168      * @see existingTransfer fileExists
0169      */
0170     static QString message(const QUrl &url, const UrlType type, const UrlWarning warning);
0171 
0172     /**
0173      * Convenience method for multiple urls (urls can be empty)
0174      * @see message
0175      */
0176     static QString message(const QList<QUrl> &urls, const UrlType type, const UrlError error);
0177 
0178     /**
0179      * Convenience method for multiple urls (urls can be empty)
0180      * @see message
0181      */
0182     static QString message(const QList<QUrl> &urls, const UrlType type, const UrlWarning warning);
0183 
0184     /**
0185      * Takes an url to a source and an url to either the destination or a folder
0186      *  and returns a destination url.
0187      *
0188      * @param destOrFolder An existing folder then a file name derived from source
0189      * will be appended to it and returned
0190      * otherwise no modification will be done and destOrFolder will be returned
0191      * @param source the source
0192      * @param fileName the filename
0193      * @note no checkUrl check happens!
0194      * @see checkUrl
0195      */
0196     static QUrl destUrl(const QUrl &destOrFolder, const QUrl &source, const QString &fileName = QString());
0197 
0198     /// Non static methods following
0199 
0200     UrlType type() const;
0201 
0202     /**
0203      * Sets the type for the following operations to type
0204      * @note calls clear
0205      * @see clear
0206      */
0207     void setType(UrlType type);
0208 
0209     /**
0210      * Clears all data, like correctUrls, errorUrls, responses from checkExistingFile ...
0211      */
0212     void clear();
0213 
0214     /**
0215      * Checks url of type()
0216      * @return UrlError, None if no error has been found
0217      * @note checkExisting is not done within this method
0218      * @note both this method and checkUrls() will store all correct
0219      * urls in correctUrls() and the others in errorUrls() and
0220      * splitErrorUrls()
0221      */
0222     UrlError addUrl(const QUrl &url);
0223 
0224     /**
0225      * Does checkUrl for a list of urls.
0226      * @return true if all urls are valid, false, if at least one url is invalid
0227      * @note checkExisting is not done within this method
0228      * @note both this method and checkUrl() will store all correct
0229      * urls in correctUrls() and the others in errorUrls() and
0230      * splitErrorUrls()
0231      * @see addUrl
0232      */
0233     bool addUrls(const QList<QUrl> &urls);
0234 
0235     /**
0236      * Displays error messages for the collected urls if any are needed
0237      */
0238     void displayErrorMessages();
0239 
0240     /**
0241      * Returns the correct urls collected with the last call to urlCollectErrors
0242      * @see urlCollectErrors
0243      */
0244     QList<QUrl> correctUrls() const;
0245 
0246     /**
0247      * Checks all correctUrls() if there are existing Transfers
0248      * for the specified UrlType and asks the user how to proceed.
0249      *
0250      * After this urls where the user decided that they should not be downloaded
0251      * won't be in correctUrls anymore.
0252      * @note UrlType folder is not supported, the result then is undefined!
0253      * @return urls to download, after user interaction
0254      * @see correctUrls errorUrls splitErrorUrls
0255      */
0256     void existingTransfers();
0257 
0258     /**
0259      * Checks if the file at destination exists already, source needs to be defined
0260      * to have a nice dialog and to make sure that both source and destination aren't
0261      * the same
0262      * @note This method does _not_ affect other methods like correctUrls or existingTransfers
0263      * etc., though responses like overwrite all files are stored in case you call this method
0264      * again you can clear that with clear.
0265      * @return returns the destination to download the file to, if empty then the file
0266      * should not be downloaded
0267      * @see clear
0268      */
0269     QUrl checkExistingFile(const QUrl &source, const QUrl &destination);
0270 
0271     /**
0272      * Returns all wrong urls
0273      * @note the order of the urls is not guaranteed to be the same as it initially was
0274      * @see urlCollectErrors splitErrorUrls existingTransfers
0275      */
0276     QList<QUrl> errorUrls() const;
0277 
0278     /**
0279      * Returns all wrong urls collected with the last call to urlCollectErrors
0280      * or existingTransfers categorized by their errors
0281      * @note urls without an error (UrlError == None) are not included
0282      * @see urlCollectErrors correctUrls errorUrls existingTransfers
0283      */
0284     QHash<UrlError, QList<QUrl>> splitErrorUrls() const;
0285 
0286 private:
0287     static TransferHandler *existingSource(const QUrl &url, UrlWarning &warning);
0288     static TransferHandler *existingDestination(const QUrl &url, UrlWarning &warning);
0289     static int hasExistingDialog(const QUrl &url, const UrlChecker::UrlType type, const UrlWarning warning); // TODO description --> returncode etc.!
0290     static void removeTransfers(const QList<TransferHandler *> &toRemove);
0291 
0292 private:
0293     UrlType m_type;
0294     QList<QUrl> m_correctUrls;
0295     QHash<UrlError, QList<QUrl>> m_splitErrorUrls;
0296 
0297     QHash<UrlWarning, QPair<QUrl, Transfer *>> m_existingTransfers;
0298     QList<QUrl> m_nonExistingUrls;
0299 
0300     // Existing files stuff
0301     bool m_cancel;
0302     bool m_overwriteAll;
0303     bool m_autoRenameAll;
0304     bool m_skipAll;
0305 };
0306 
0307 #endif