File indexing completed on 2024-05-19 05:00:39

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Daniel Vrátil <dvratil@redhat.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  *
0006  */
0007 
0008 #include "gdrivehelper.h"
0009 
0010 #include <KGAPI/Drive/File>
0011 #include <KIO/Job>
0012 #include <KLocalizedString>
0013 
0014 using namespace KGAPI2::Drive;
0015 
0016 #define VND_GOOGLE_APPS_DOCUMENT QStringLiteral("application/vnd.google-apps.document")
0017 #define VND_GOOGLE_APPS_DRAWING QStringLiteral("application/vnd.google-apps.drawing")
0018 #define VND_GOOGLE_APPS_FILE QStringLiteral("application/vnd.google-apps.file")
0019 #define VND_GOOGLE_APPS_FORM QStringLiteral("application/vnd.google-apps.form")
0020 #define VND_GOOGLE_APPS_PRESENTATION QStringLiteral("application/vnd.google-apps.presentation")
0021 #define VND_GOOGLE_APPS_SPREADSHEET QStringLiteral("application/vnd.google-apps.spreadsheet")
0022 #define VND_GOOGLE_APPS_FOLDER QStringLiteral("application/vnd.google-apps.folder")
0023 
0024 #define VND_OASIS_OPENDOCUMENT_TEXT QStringLiteral("application/vnd.oasis.opendocument.text")
0025 #define VND_OASIS_OPENDOCUMENT_PRESENTATION QStringLiteral("application/vnd.oasis.opendocument.presentation")
0026 // Google's Drive API v2 mistakenly documents an x-vnd style MIME type
0027 // for .ods files, so we #define both the correct but undocumented,
0028 // as well as the incorrect but publicly documented MIME type.
0029 #define VND_OASIS_OPENDOCUMENT_SPREADSHEET QStringLiteral("application/vnd.oasis.opendocument.spreadsheet")
0030 #define X_VND_OASIS_OPENDOCUMENT_SPREADSHEET QStringLiteral("application/x-vnd.oasis.opendocument.spreadsheet")
0031 
0032 #define VND_OPENXMLFORMATS_OFFICEDOCUMENT_WORDPROCESSINGML_DOCUMENT QStringLiteral("application/vnd.openxmlformats-officedocument.wordprocessingml.document")
0033 #define VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_PRESENTATION                                                                                          \
0034     QStringLiteral("application/vnd.openxmlformats-officedocument.presentationml.presentation")
0035 #define VND_OPENXMLFORMATS_OFFICEDOCUMENT_SPREADSHEETML_SHEET QStringLiteral("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
0036 
0037 #define IMAGE_PNG QStringLiteral("image/png")
0038 #define IMAGE_JPEG QStringLiteral("image/jpeg")
0039 #define APPLICATION_PDF QStringLiteral("application/pdf")
0040 
0041 namespace GDriveHelper
0042 {
0043 
0044 static const QMap<QString /* mimetype */, QString /* .ext */> ExtensionsMap{
0045     {VND_OASIS_OPENDOCUMENT_TEXT, QStringLiteral(".odt")},
0046     {VND_OASIS_OPENDOCUMENT_SPREADSHEET, QStringLiteral(".ods")},
0047     {VND_OASIS_OPENDOCUMENT_PRESENTATION, QStringLiteral(".odp")},
0048     {VND_OPENXMLFORMATS_OFFICEDOCUMENT_WORDPROCESSINGML_DOCUMENT, QStringLiteral(".docx")},
0049     {VND_OPENXMLFORMATS_OFFICEDOCUMENT_SPREADSHEETML_SHEET, QStringLiteral(".xlsx")},
0050     {VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_PRESENTATION, QStringLiteral(".pptx")},
0051     {IMAGE_PNG, QStringLiteral(".png")},
0052     {IMAGE_JPEG, QStringLiteral(".jpg")},
0053     {APPLICATION_PDF, QStringLiteral(".pdf")}};
0054 
0055 static const QMap<QString /* mimetype */, QStringList /* target mimetypes */> ConversionMap{
0056     {VND_GOOGLE_APPS_DOCUMENT, {VND_OASIS_OPENDOCUMENT_TEXT, VND_OPENXMLFORMATS_OFFICEDOCUMENT_WORDPROCESSINGML_DOCUMENT, APPLICATION_PDF}},
0057     {VND_GOOGLE_APPS_DRAWING, {IMAGE_PNG, IMAGE_JPEG, APPLICATION_PDF}},
0058     {VND_GOOGLE_APPS_PRESENTATION, {VND_OASIS_OPENDOCUMENT_PRESENTATION, VND_OPENXMLFORMATS_OFFICEDOCUMENT_PRESENTATIONML_PRESENTATION, APPLICATION_PDF}},
0059     {VND_GOOGLE_APPS_SPREADSHEET, {VND_OASIS_OPENDOCUMENT_SPREADSHEET, VND_OPENXMLFORMATS_OFFICEDOCUMENT_SPREADSHEETML_SHEET, APPLICATION_PDF}}};
0060 
0061 }
0062 
0063 QString GDriveHelper::folderMimeType()
0064 {
0065     return VND_GOOGLE_APPS_FOLDER;
0066 }
0067 
0068 bool GDriveHelper::isGDocsDocument(const KGAPI2::Drive::FilePtr &file)
0069 {
0070     return GDriveHelper::ConversionMap.contains(file->mimeType());
0071 }
0072 
0073 QUrl GDriveHelper::convertFromGDocs(KGAPI2::Drive::FilePtr &file)
0074 {
0075     const QString originalMimeType = file->mimeType();
0076     auto convIt = GDriveHelper::ConversionMap.constFind(originalMimeType);
0077     if (convIt == GDriveHelper::ConversionMap.cend()) {
0078         return file->downloadUrl();
0079     }
0080 
0081     const auto exportLinks = file->exportLinks();
0082     const QStringList targetMimeTypeList{convIt.value()};
0083     for (const QString &targetMimeType : targetMimeTypeList) {
0084         const auto linkIt = exportLinks.constFind(targetMimeType);
0085         if (linkIt != exportLinks.cend()) {
0086             // Extra check to safeguard against a mistake in Google's Drive API v2
0087             // documentation which lists an invalid MIME type for .ods files.
0088             if (targetMimeType == X_VND_OASIS_OPENDOCUMENT_SPREADSHEET) {
0089                 file->setMimeType(VND_OASIS_OPENDOCUMENT_SPREADSHEET);
0090             } else {
0091                 file->setMimeType(targetMimeType);
0092             }
0093             file->setTitle(file->title() + GDriveHelper::ExtensionsMap[targetMimeType]);
0094             return *linkIt;
0095         }
0096     }
0097 
0098     // If we got here that means that the file cannot be converted to any meaningful
0099     // type, so we do nothing
0100     return file->downloadUrl();
0101 }
0102 
0103 QUrl GDriveHelper::downloadUrl(const KGAPI2::Drive::FilePtr &file)
0104 {
0105     if (file->downloadUrl().isValid()) {
0106         return file->downloadUrl();
0107     }
0108 
0109     return file->exportLinks().value(file->mimeType());
0110 }
0111 
0112 // Currently unused, see https://phabricator.kde.org/T3443
0113 /*
0114 KIO::UDSEntry GDriveHelper::trash()
0115 {
0116     KIO::UDSEntry trashEntry;
0117     trashEntry.insert(KIO::UDSEntry::UDS_NAME, GDriveUrl::TrashDir);
0118     trashEntry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, i18n("Trash"));
0119     trashEntry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
0120     trashEntry.insert(KIO::UDSEntry::UDS_ICON_NAME, QStringLiteral("user-trash"));
0121     return trashEntry;
0122 }
0123 */
0124 
0125 QString GDriveHelper::elideToken(const QString &token)
0126 {
0127     if (token.isEmpty()) {
0128         return {};
0129     }
0130     return token.mid(0, 30).append(QStringLiteral("..."));
0131 }