Changeset View
Changeset View
Standalone View
Standalone View
src/kio_gdrive.cpp
Show All 21 Lines | |||||
22 | #include "gdrivedebug.h" | 22 | #include "gdrivedebug.h" | ||
23 | #include "gdrivehelper.h" | 23 | #include "gdrivehelper.h" | ||
24 | #include "gdriveurl.h" | 24 | #include "gdriveurl.h" | ||
25 | #include "gdriveversion.h" | 25 | #include "gdriveversion.h" | ||
26 | 26 | | |||
27 | #include <QApplication> | 27 | #include <QApplication> | ||
28 | #include <QUrlQuery> | 28 | #include <QUrlQuery> | ||
29 | #include <QTemporaryFile> | 29 | #include <QTemporaryFile> | ||
30 | #include <QUuid> | ||||
30 | 31 | | |||
31 | #include <KGAPI/Account> | 32 | #include <KGAPI/Account> | ||
32 | #include <KGAPI/AuthJob> | 33 | #include <KGAPI/AuthJob> | ||
33 | #include <KGAPI/Drive/About> | 34 | #include <KGAPI/Drive/About> | ||
34 | #include <KGAPI/Drive/AboutFetchJob> | 35 | #include <KGAPI/Drive/AboutFetchJob> | ||
35 | #include <KGAPI/Drive/ChildReference> | 36 | #include <KGAPI/Drive/ChildReference> | ||
36 | #include <KGAPI/Drive/ChildReferenceFetchJob> | 37 | #include <KGAPI/Drive/ChildReferenceFetchJob> | ||
37 | #include <KGAPI/Drive/ChildReferenceCreateJob> | 38 | #include <KGAPI/Drive/ChildReferenceCreateJob> | ||
38 | #include <KGAPI/Drive/File> | 39 | #include <KGAPI/Drive/File> | ||
39 | #include <KGAPI/Drive/FileCopyJob> | 40 | #include <KGAPI/Drive/FileCopyJob> | ||
40 | #include <KGAPI/Drive/FileCreateJob> | 41 | #include <KGAPI/Drive/FileCreateJob> | ||
41 | #include <KGAPI/Drive/FileModifyJob> | 42 | #include <KGAPI/Drive/FileModifyJob> | ||
42 | #include <KGAPI/Drive/FileTrashJob> | 43 | #include <KGAPI/Drive/FileTrashJob> | ||
43 | #include <KGAPI/Drive/FileFetchJob> | 44 | #include <KGAPI/Drive/FileFetchJob> | ||
44 | #include <KGAPI/Drive/FileFetchContentJob> | 45 | #include <KGAPI/Drive/FileFetchContentJob> | ||
45 | #include <KGAPI/Drive/FileSearchQuery> | 46 | #include <KGAPI/Drive/FileSearchQuery> | ||
46 | #include <KGAPI/Drive/ParentReference> | 47 | #include <KGAPI/Drive/ParentReference> | ||
47 | #include <KGAPI/Drive/Permission> | 48 | #include <KGAPI/Drive/Permission> | ||
49 | #include <KGAPI/Drive/Drives> | ||||
50 | #include <KGAPI/Drive/DrivesCreateJob> | ||||
51 | #include <KGAPI/Drive/DrivesFetchJob> | ||||
52 | #include <KGAPI/Drive/DrivesModifyJob> | ||||
53 | #include <KGAPI/Drive/DrivesDeleteJob> | ||||
elvisangelaccio: Please keep the list of includes sorted. | |||||
48 | #include <KIO/AccessManager> | 54 | #include <KIO/AccessManager> | ||
49 | #include <KIO/Job> | 55 | #include <KIO/Job> | ||
50 | #include <KLocalizedString> | 56 | #include <KLocalizedString> | ||
51 | 57 | | |||
52 | #include <QNetworkRequest> | 58 | #include <QNetworkRequest> | ||
53 | #include <QNetworkReply> | 59 | #include <QNetworkReply> | ||
54 | #include <QMimeDatabase> | 60 | #include <QMimeDatabase> | ||
55 | 61 | | |||
▲ Show 20 Lines • Show All 205 Lines • ▼ Show 20 Line(s) | 262 | { | |||
261 | entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); | 267 | entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); | ||
262 | entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0); | 268 | entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0); | ||
263 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); | 269 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); | ||
264 | entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, QStringLiteral("folder-gdrive")); | 270 | entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, QStringLiteral("folder-gdrive")); | ||
265 | 271 | | |||
266 | return entry; | 272 | return entry; | ||
267 | } | 273 | } | ||
268 | 274 | | |||
275 | KIO::UDSEntry KIOGDrive::sharedDriveToUDSEntry(const DrivesPtr sharedDrive) | ||||
elvisangelaccio: Missing pass-by-reference | |||||
276 | { | ||||
277 | KIO::UDSEntry entry; | ||||
278 | | ||||
279 | qlonglong udsAccess = S_IRUSR | S_IXUSR | S_IRGRP; | ||||
280 | if (sharedDrive->capabilities()->canRenameDrive() || sharedDrive->capabilities()->canDeleteDrive()) { | ||||
281 | udsAccess |= S_IWUSR; | ||||
282 | } | ||||
283 | | ||||
284 | entry.fastInsert(KIO::UDSEntry::UDS_NAME, sharedDrive->id()); | ||||
285 | entry.fastInsert(KIO::UDSEntry::UDS_DISPLAY_NAME, sharedDrive->name()); | ||||
286 | entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); | ||||
287 | entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0); | ||||
288 | entry.fastInsert(KIO::UDSEntry::UDS_CREATION_TIME, sharedDrive->createdDate().toSecsSinceEpoch()); | ||||
289 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, udsAccess); | ||||
290 | entry.fastInsert(KIO::UDSEntry::UDS_HIDDEN, sharedDrive->hidden()); | ||||
291 | entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, QStringLiteral("folder-gdrive")); | ||||
292 | | ||||
293 | return entry; | ||||
294 | } | ||||
295 | | ||||
269 | void KIOGDrive::createAccount() | 296 | void KIOGDrive::createAccount() | ||
270 | { | 297 | { | ||
271 | const KGAPI2::AccountPtr account = m_accountManager->createAccount(); | 298 | const KGAPI2::AccountPtr account = m_accountManager->createAccount(); | ||
272 | if (!account->accountName().isEmpty()) { | 299 | if (!account->accountName().isEmpty()) { | ||
273 | // Redirect to the account we just created. | 300 | // Redirect to the account we just created. | ||
274 | redirection(QUrl(QStringLiteral("gdrive:/%1").arg(account->accountName()))); | 301 | redirection(QUrl(QStringLiteral("gdrive:/%1").arg(account->accountName()))); | ||
275 | finished(); | 302 | finished(); | ||
276 | return; | 303 | return; | ||
Show All 35 Lines | 317 | { | |||
312 | entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0); | 339 | entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0); | ||
313 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); | 340 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); | ||
314 | listEntry(entry); | 341 | listEntry(entry); | ||
315 | 342 | | |||
316 | finished(); | 343 | finished(); | ||
317 | return; | 344 | return; | ||
318 | } | 345 | } | ||
319 | 346 | | |||
347 | void KIOGDrive::listSharedDrivesRoot(const QUrl &url) | ||||
348 | { | ||||
349 | const auto gdriveUrl = GDriveUrl(url); | ||||
350 | const QString accountId = gdriveUrl.account(); | ||||
351 | DrivesFetchJob sharedDrivesFetchJob(getAccount(accountId)); | ||||
352 | sharedDrivesFetchJob.setFields({ | ||||
353 | Drives::Fields::Kind, | ||||
354 | Drives::Fields::Id, | ||||
355 | Drives::Fields::Name, | ||||
356 | Drives::Fields::Hidden, | ||||
357 | Drives::Fields::CreatedDate, | ||||
358 | Drives::Fields::Capabilities | ||||
359 | }); | ||||
360 | | ||||
361 | if (runJob(sharedDrivesFetchJob, url, accountId)) { | ||||
362 | ObjectsList objects = sharedDrivesFetchJob.items(); | ||||
elvisangelaccio: `const` | |||||
363 | for (const ObjectPtr &object : objects) { | ||||
elvisangelaccio: Q_FOREACH is deprecated, please avoid it in new code. | |||||
364 | const DrivesPtr sharedDrive = object.dynamicCast<Drives>(); | ||||
365 | const KIO::UDSEntry entry = sharedDriveToUDSEntry(sharedDrive); | ||||
366 | listEntry(entry); | ||||
367 | } | ||||
368 | | ||||
369 | auto entry = fetchSharedDrivesRootEntry(accountId, FetchEntryFlags::CurrentDir); | ||||
370 | listEntry(entry); | ||||
371 | | ||||
372 | finished(); | ||||
373 | } | ||||
374 | } | ||||
375 | | ||||
376 | bool KIOGDrive::createSharedDrive(const QUrl &url) | ||||
elvisangelaccio: Nitpick: opening brace goes to the next line | |||||
377 | { | ||||
378 | const auto gdriveUrl = GDriveUrl(url); | ||||
379 | const QString accountId = gdriveUrl.account(); | ||||
380 | | ||||
381 | DrivesPtr sharedDrive = DrivesPtr::create(); | ||||
382 | sharedDrive->setName(gdriveUrl.filename()); | ||||
383 | | ||||
elvisangelaccio: `const` | |||||
384 | const QString requestId = QUuid::createUuid().toString(); | ||||
385 | DrivesCreateJob createJob(requestId, sharedDrive, getAccount(accountId)); | ||||
386 | return runJob(createJob, url, accountId); | ||||
387 | } | ||||
388 | | ||||
Missing pass-by-reference Nitpick: opening brace goes to the next line elvisangelaccio: Missing pass-by-reference
Nitpick: opening brace goes to the next line | |||||
389 | bool KIOGDrive::deleteSharedDrive(const QUrl &url) | ||||
390 | { | ||||
391 | const auto gdriveUrl = GDriveUrl(url); | ||||
392 | const QString accountId = gdriveUrl.account(); | ||||
393 | DrivesDeleteJob sharedDriveDeleteJob(gdriveUrl.filename(), getAccount(accountId)); | ||||
394 | return runJob(sharedDriveDeleteJob, url, accountId); | ||||
395 | } | ||||
Missing pass-by-reference Nitpick: opening brace goes to the next line elvisangelaccio: Missing pass-by-reference
Nitpick: opening brace goes to the next line | |||||
396 | | ||||
397 | void KIOGDrive::statSharedDrive(const QUrl &url) | ||||
398 | { | ||||
399 | const auto gdriveUrl = GDriveUrl(url); | ||||
400 | const QString accountId = gdriveUrl.account(); | ||||
401 | DrivesFetchJob sharedDriveFetchJob(gdriveUrl.filename(), getAccount(accountId)); | ||||
402 | sharedDriveFetchJob.setFields({ | ||||
403 | Drives::Fields::Kind, | ||||
404 | Drives::Fields::Id, | ||||
405 | Drives::Fields::Name, | ||||
406 | Drives::Fields::Hidden, | ||||
407 | Drives::Fields::CreatedDate, | ||||
408 | Drives::Fields::Capabilities | ||||
elvisangelaccio: Redundant comment, info is already in the apidox of `runJob`. | |||||
409 | }); | ||||
410 | if (!runJob(sharedDriveFetchJob, url, accountId)) { | ||||
411 | return; | ||||
412 | } | ||||
elvisangelaccio: Prefer `at(0)` | |||||
413 | | ||||
414 | ObjectPtr object = sharedDriveFetchJob.items().at(0); | ||||
415 | const DrivesPtr sharedDrive = object.dynamicCast<Drives>(); | ||||
416 | const auto entry = sharedDriveToUDSEntry(sharedDrive); | ||||
417 | statEntry(entry); | ||||
418 | finished(); | ||||
419 | } | ||||
420 | | ||||
421 | KIO::UDSEntry KIOGDrive::fetchSharedDrivesRootEntry(const QString &accountId, FetchEntryFlags flags) | ||||
422 | { | ||||
423 | // Not every user is allowed to create shared Drives, | ||||
424 | // check with About resource. | ||||
425 | bool canCreateDrives = false; | ||||
426 | AboutFetchJob aboutFetch(getAccount(accountId)); | ||||
427 | aboutFetch.setFields({ | ||||
428 | About::Fields::Kind, | ||||
429 | About::Fields::CanCreateDrives | ||||
430 | }); | ||||
431 | QEventLoop eventLoop; | ||||
432 | QObject::connect(&aboutFetch, &KGAPI2::Job::finished, | ||||
433 | &eventLoop, &QEventLoop::quit); | ||||
elvisangelaccio: Can't we use `runJob()` here? | |||||
The desired behavior is silently failing if the user isn't allowed to create shared drives and being that runJob() will always call error(), it isn't used. barchiesi: The desired behavior is silently failing if the user isn't allowed to create shared drives and… | |||||
434 | eventLoop.exec(); | ||||
435 | if (aboutFetch.error() == KGAPI2::OK || aboutFetch.error() == KGAPI2::NoError) { | ||||
436 | const AboutPtr about = aboutFetch.aboutData(); | ||||
437 | if (about) { | ||||
438 | canCreateDrives = about->canCreateDrives(); | ||||
439 | } | ||||
440 | } | ||||
441 | qCDebug(GDRIVE) << "Account" << accountId << (canCreateDrives ? "can" : "can't") << "create Drives"; | ||||
442 | | ||||
443 | KIO::UDSEntry entry; | ||||
444 | | ||||
445 | if (flags == FetchEntryFlags::CurrentDir) { | ||||
446 | entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral(".")); | ||||
447 | } | ||||
448 | else { | ||||
elvisangelaccio: Nitpick: else after closing brace on previous line | |||||
449 | entry.fastInsert(KIO::UDSEntry::UDS_NAME, GDriveUrl::SharedDrivesDir); | ||||
450 | entry.fastInsert(KIO::UDSEntry::UDS_DISPLAY_NAME, GDriveUrl::SharedDrivesDir); | ||||
451 | } | ||||
452 | entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); | ||||
453 | entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0); | ||||
454 | entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, QStringLiteral("folder-gdrive")); | ||||
elvisangelaccio: This comment should be just before the `if()` | |||||
455 | | ||||
456 | qlonglong udsAccess = S_IRUSR | S_IXUSR; | ||||
457 | // If user is allowed to create shared Drives, add write bit on directory | ||||
458 | if (canCreateDrives) { | ||||
459 | udsAccess |= S_IWUSR; | ||||
460 | } | ||||
461 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, udsAccess); | ||||
462 | | ||||
463 | return entry; | ||||
464 | } | ||||
465 | | ||||
320 | class RecursionDepthCounter | 466 | class RecursionDepthCounter | ||
321 | { | 467 | { | ||
322 | public: | 468 | public: | ||
323 | RecursionDepthCounter() | 469 | RecursionDepthCounter() | ||
324 | { | 470 | { | ||
325 | ++sDepth; | 471 | ++sDepth; | ||
326 | } | 472 | } | ||
327 | ~RecursionDepthCounter() | 473 | ~RecursionDepthCounter() | ||
Show All 36 Lines | 494 | { | |||
364 | const auto gdriveUrl = GDriveUrl(url); | 510 | const auto gdriveUrl = GDriveUrl(url); | ||
365 | Q_ASSERT(!gdriveUrl.isRoot()); | 511 | Q_ASSERT(!gdriveUrl.isRoot()); | ||
366 | 512 | | |||
367 | if (gdriveUrl.isAccountRoot() || gdriveUrl.isTrashDir()) { | 513 | if (gdriveUrl.isAccountRoot() || gdriveUrl.isTrashDir()) { | ||
368 | qCDebug(GDRIVE) << "Resolved" << path << "to \"root\""; | 514 | qCDebug(GDRIVE) << "Resolved" << path << "to \"root\""; | ||
369 | return rootFolderId(gdriveUrl.account()); | 515 | return rootFolderId(gdriveUrl.account()); | ||
370 | } | 516 | } | ||
371 | 517 | | |||
518 | if (gdriveUrl.isSharedDrive()) { | ||||
519 | qCDebug(GDRIVE) << "Resolved" << path << "to Shared Drive" << gdriveUrl.filename(); | ||||
520 | return gdriveUrl.filename(); | ||||
521 | } | ||||
522 | | ||||
elvisangelaccio: Nitpick: `else` not needed after `return` | |||||
523 | if (gdriveUrl.isSharedDrivesRoot()) { | ||||
524 | qCDebug(GDRIVE) << "Resolved" << path << "to Shared Drives root"; | ||||
525 | return QString(); | ||||
526 | } | ||||
527 | | ||||
372 | // Try to recursively resolve ID of parent path - either from cache, or by | 528 | // Try to recursively resolve ID of parent path - either from cache, or by | ||
373 | // querying Google | 529 | // querying Google | ||
374 | const QString parentId = resolveFileIdFromPath(gdriveUrl.parentPath(), KIOGDrive::PathIsFolder); | 530 | const QString parentId = resolveFileIdFromPath(gdriveUrl.parentPath(), KIOGDrive::PathIsFolder); | ||
375 | if (parentId.isEmpty()) { | 531 | if (parentId.isEmpty()) { | ||
376 | // We failed to resolve parent -> error | 532 | // We failed to resolve parent -> error | ||
377 | return QString(); | 533 | return QString(); | ||
378 | } | 534 | } | ||
379 | 535 | | |||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Line(s) | 599 | if (accountId == QLatin1String("new-account")) { | |||
445 | return; | 601 | return; | ||
446 | } | 602 | } | ||
447 | 603 | | |||
448 | QString folderId; | 604 | QString folderId; | ||
449 | if (gdriveUrl.isRoot()) { | 605 | if (gdriveUrl.isRoot()) { | ||
450 | listAccounts(); | 606 | listAccounts(); | ||
451 | return; | 607 | return; | ||
452 | } else if (gdriveUrl.isAccountRoot()) { | 608 | } else if (gdriveUrl.isAccountRoot()) { | ||
609 | auto entry = fetchSharedDrivesRootEntry(accountId); | ||||
610 | listEntry(entry); | ||||
453 | folderId = rootFolderId(accountId); | 611 | folderId = rootFolderId(accountId); | ||
612 | } else if (gdriveUrl.isSharedDrivesRoot()) { | ||||
613 | listSharedDrivesRoot(url); | ||||
614 | return; | ||||
454 | } else { | 615 | } else { | ||
455 | folderId = m_cache.idForPath(url.path()); | 616 | folderId = m_cache.idForPath(url.path()); | ||
456 | if (folderId.isEmpty()) { | 617 | if (folderId.isEmpty()) { | ||
457 | folderId = resolveFileIdFromPath(url.adjusted(QUrl::StripTrailingSlash).path(), | 618 | folderId = resolveFileIdFromPath(url.adjusted(QUrl::StripTrailingSlash).path(), | ||
458 | KIOGDrive::PathIsFolder); | 619 | KIOGDrive::PathIsFolder); | ||
459 | } | 620 | } | ||
460 | if (folderId.isEmpty()) { | 621 | if (folderId.isEmpty()) { | ||
461 | error(KIO::ERR_DOES_NOT_EXIST, url.path()); | 622 | error(KIO::ERR_DOES_NOT_EXIST, url.path()); | ||
Show All 32 Lines | |||||
494 | entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); | 655 | entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); | ||
495 | entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0); | 656 | entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0); | ||
496 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH); | 657 | entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH); | ||
497 | listEntry(entry); | 658 | listEntry(entry); | ||
498 | 659 | | |||
499 | finished(); | 660 | finished(); | ||
500 | } | 661 | } | ||
501 | 662 | | |||
502 | | ||||
503 | void KIOGDrive::mkdir(const QUrl &url, int permissions) | 663 | void KIOGDrive::mkdir(const QUrl &url, int permissions) | ||
504 | { | 664 | { | ||
505 | // NOTE: We deliberately ignore the permissions field here, because GDrive | 665 | // NOTE: We deliberately ignore the permissions field here, because GDrive | ||
506 | // does not recognize any privileges that could be mapped to standard UNIX | 666 | // does not recognize any privileges that could be mapped to standard UNIX | ||
507 | // file permissions. | 667 | // file permissions. | ||
508 | Q_UNUSED(permissions); | 668 | Q_UNUSED(permissions); | ||
509 | 669 | | |||
510 | qCDebug(GDRIVE) << "Creating directory" << url; | 670 | qCDebug(GDRIVE) << "Creating directory" << url; | ||
511 | 671 | | |||
512 | const auto gdriveUrl = GDriveUrl(url); | 672 | const auto gdriveUrl = GDriveUrl(url); | ||
513 | const QString accountId = gdriveUrl.account(); | 673 | const QString accountId = gdriveUrl.account(); | ||
514 | // At least account and new folder name | 674 | // At least account and new folder name | ||
515 | if (gdriveUrl.isRoot() || gdriveUrl.isAccountRoot()) { | 675 | if (gdriveUrl.isRoot() || gdriveUrl.isAccountRoot()) { | ||
516 | error(KIO::ERR_DOES_NOT_EXIST, url.path()); | 676 | error(KIO::ERR_DOES_NOT_EXIST, url.path()); | ||
517 | return; | 677 | return; | ||
518 | } | 678 | } | ||
679 | | ||||
680 | if (gdriveUrl.isSharedDrive()) { | ||||
681 | qCDebug(GDRIVE) << "Directory is shared drive, creating that instead" << url; | ||||
682 | if (createSharedDrive(url)) { | ||||
683 | // runJob will have shown an error otherwise | ||||
elvisangelaccio: Typo: runJob | |||||
684 | finished(); | ||||
685 | } | ||||
686 | return; | ||||
687 | } | ||||
688 | | ||||
519 | QString parentId; | 689 | QString parentId; | ||
520 | if (gdriveUrl.isTopLevel()) { | 690 | if (gdriveUrl.isTopLevel()) { | ||
521 | parentId = rootFolderId(accountId); | 691 | parentId = rootFolderId(accountId); | ||
522 | } else { | 692 | } else { | ||
523 | parentId = resolveFileIdFromPath(gdriveUrl.parentPath(), KIOGDrive::PathIsFolder); | 693 | parentId = resolveFileIdFromPath(gdriveUrl.parentPath(), KIOGDrive::PathIsFolder); | ||
524 | } | 694 | } | ||
525 | 695 | | |||
526 | if (parentId.isEmpty()) { | 696 | if (parentId.isEmpty()) { | ||
Show All 26 Lines | 720 | if (gdriveUrl.isRoot()) { | |||
553 | return; | 723 | return; | ||
554 | } | 724 | } | ||
555 | if (gdriveUrl.isAccountRoot()) { | 725 | if (gdriveUrl.isAccountRoot()) { | ||
556 | const KIO::UDSEntry entry = accountToUDSEntry(accountId); | 726 | const KIO::UDSEntry entry = accountToUDSEntry(accountId); | ||
557 | statEntry(entry); | 727 | statEntry(entry); | ||
558 | finished(); | 728 | finished(); | ||
559 | return; | 729 | return; | ||
560 | } | 730 | } | ||
731 | if (gdriveUrl.isSharedDrivesRoot()) { | ||||
732 | qCDebug(GDRIVE) << "stat()ing Shared Drives root"; | ||||
733 | const auto entry = fetchSharedDrivesRootEntry(accountId); | ||||
734 | statEntry(entry); | ||||
735 | finished(); | ||||
736 | return; | ||||
737 | } | ||||
738 | if (gdriveUrl.isSharedDrive()) { | ||||
739 | qCDebug(GDRIVE) << "stat()ing Shared Drive" << url; | ||||
740 | statSharedDrive(url); | ||||
741 | return; | ||||
742 | } | ||||
561 | 743 | | |||
562 | const QUrlQuery urlQuery(url); | 744 | const QUrlQuery urlQuery(url); | ||
563 | const QString fileId | 745 | const QString fileId | ||
564 | = urlQuery.hasQueryItem(QStringLiteral("id")) | 746 | = urlQuery.hasQueryItem(QStringLiteral("id")) | ||
565 | ? urlQuery.queryItemValue(QStringLiteral("id")) | 747 | ? urlQuery.queryItemValue(QStringLiteral("id")) | ||
566 | : resolveFileIdFromPath(url.adjusted(QUrl::StripTrailingSlash).path(), | 748 | : resolveFileIdFromPath(url.adjusted(QUrl::StripTrailingSlash).path(), | ||
567 | KIOGDrive::None); | 749 | KIOGDrive::None); | ||
568 | if (fileId.isEmpty()) { | 750 | if (fileId.isEmpty()) { | ||
569 | error(KIO::ERR_DOES_NOT_EXIST, url.path()); | 751 | error(KIO::ERR_DOES_NOT_EXIST, url.path()); | ||
570 | return; | 752 | return; | ||
571 | } | 753 | } | ||
572 | 754 | | |||
573 | FileFetchJob fileFetchJob(fileId, getAccount(accountId)); | 755 | FileFetchJob fileFetchJob(fileId, getAccount(accountId)); | ||
574 | if (!runJob(fileFetchJob, url, accountId)) { | 756 | if (!runJob(fileFetchJob, url, accountId)) { | ||
757 | qCDebug(GDRIVE) << "Failed stat()ing file" << fileFetchJob.errorString(); | ||||
575 | return; | 758 | return; | ||
576 | } | 759 | } | ||
577 | 760 | | |||
578 | const ObjectsList objects = fileFetchJob.items(); | 761 | const ObjectsList objects = fileFetchJob.items(); | ||
579 | if (objects.count() != 1) { | 762 | if (objects.count() != 1) { | ||
580 | error(KIO::ERR_DOES_NOT_EXIST, url.path()); | 763 | error(KIO::ERR_DOES_NOT_EXIST, url.path()); | ||
581 | return; | 764 | return; | ||
582 | } | 765 | } | ||
▲ Show 20 Lines • Show All 235 Lines • ▼ Show 20 Line(s) | 1000 | { | |||
818 | // NOTE: We deliberately ignore the permissions field here, because GDrive | 1001 | // NOTE: We deliberately ignore the permissions field here, because GDrive | ||
819 | // does not recognize any privileges that could be mapped to standard UNIX | 1002 | // does not recognize any privileges that could be mapped to standard UNIX | ||
820 | // file permissions. | 1003 | // file permissions. | ||
821 | Q_UNUSED(permissions) | 1004 | Q_UNUSED(permissions) | ||
822 | Q_UNUSED(flags) | 1005 | Q_UNUSED(flags) | ||
823 | 1006 | | |||
824 | qCDebug(GDRIVE) << Q_FUNC_INFO << url; | 1007 | qCDebug(GDRIVE) << Q_FUNC_INFO << url; | ||
825 | 1008 | | |||
1009 | const auto gdriveUrl = GDriveUrl(url); | ||||
1010 | | ||||
1011 | if (gdriveUrl.isSharedDrive()) { | ||||
1012 | qCDebug(GDRIVE) << "Can't create files in Shared Drives root" << url; | ||||
1013 | error(KIO::ERR_CANNOT_WRITE, url.path()); | ||||
1014 | return; | ||||
1015 | } | ||||
1016 | | ||||
826 | if (QUrlQuery(url).hasQueryItem(QStringLiteral("id"))) { | 1017 | if (QUrlQuery(url).hasQueryItem(QStringLiteral("id"))) { | ||
827 | if (!putUpdate(url)) { | 1018 | if (!putUpdate(url)) { | ||
828 | return; | 1019 | return; | ||
829 | } | 1020 | } | ||
830 | } else { | 1021 | } else { | ||
831 | if (!putCreate(url)) { | 1022 | if (!putCreate(url)) { | ||
832 | return; | 1023 | return; | ||
833 | } | 1024 | } | ||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Line(s) | 1121 | { | |||
935 | 1126 | | |||
936 | // FIXME: Because of the above, we are not really deleting the file, but only | 1127 | // FIXME: Because of the above, we are not really deleting the file, but only | ||
937 | // moving it to trash - so if users really really really wants to delete the | 1128 | // moving it to trash - so if users really really really wants to delete the | ||
938 | // file, they have to go to GDrive web interface and delete it there. I think | 1129 | // file, they have to go to GDrive web interface and delete it there. I think | ||
939 | // that we should do the DELETE operation here, because for trash people have | 1130 | // that we should do the DELETE operation here, because for trash people have | ||
940 | // their local trashes. This however requires fixing the first FIXME first, | 1131 | // their local trashes. This however requires fixing the first FIXME first, | ||
941 | // otherwise we are risking severe data loss. | 1132 | // otherwise we are risking severe data loss. | ||
942 | 1133 | | |||
1134 | const auto gdriveUrl = GDriveUrl(url); | ||||
1135 | | ||||
1136 | // Trying to delete the Team Drive root is pointless | ||||
1137 | if (gdriveUrl.isSharedDrivesRoot()) { | ||||
1138 | qCDebug(GDRIVE) << "Tried deleting Shared Drives root."; | ||||
1139 | error(KIO::ERR_SLAVE_DEFINED, i18n("Can't delete Shared Drives root.")); | ||||
1140 | return; | ||||
1141 | } | ||||
1142 | | ||||
943 | qCDebug(GDRIVE) << "Deleting URL" << url << "- is it a file?" << isfile; | 1143 | qCDebug(GDRIVE) << "Deleting URL" << url << "- is it a file?" << isfile; | ||
944 | 1144 | | |||
945 | const QUrlQuery urlQuery(url); | 1145 | const QUrlQuery urlQuery(url); | ||
946 | const QString fileId | 1146 | const QString fileId | ||
947 | = isfile && urlQuery.hasQueryItem(QStringLiteral("id")) | 1147 | = isfile && urlQuery.hasQueryItem(QStringLiteral("id")) | ||
948 | ? urlQuery.queryItemValue(QStringLiteral("id")) | 1148 | ? urlQuery.queryItemValue(QStringLiteral("id")) | ||
949 | : resolveFileIdFromPath(url.adjusted(QUrl::StripTrailingSlash).path(), | 1149 | : resolveFileIdFromPath(url.adjusted(QUrl::StripTrailingSlash).path(), | ||
950 | isfile ? KIOGDrive::PathIsFile : KIOGDrive::PathIsFolder); | 1150 | isfile ? KIOGDrive::PathIsFile : KIOGDrive::PathIsFolder); | ||
951 | if (fileId.isEmpty()) { | 1151 | if (fileId.isEmpty()) { | ||
952 | error(KIO::ERR_DOES_NOT_EXIST, url.path()); | 1152 | error(KIO::ERR_DOES_NOT_EXIST, url.path()); | ||
953 | return; | 1153 | return; | ||
954 | } | 1154 | } | ||
955 | const auto gdriveUrl = GDriveUrl(url); | | |||
956 | const QString accountId = gdriveUrl.account(); | 1155 | const QString accountId = gdriveUrl.account(); | ||
957 | 1156 | | |||
958 | // If user tries to delete the account folder, remove the account from the keychain | 1157 | // If user tries to delete the account folder, remove the account from the keychain | ||
959 | if (gdriveUrl.isAccountRoot()) { | 1158 | if (gdriveUrl.isAccountRoot()) { | ||
960 | const KGAPI2::AccountPtr account = getAccount(accountId); | 1159 | const KGAPI2::AccountPtr account = getAccount(accountId); | ||
961 | if (account->accountName().isEmpty()) { | 1160 | if (account->accountName().isEmpty()) { | ||
962 | error(KIO::ERR_DOES_NOT_EXIST, accountId); | 1161 | error(KIO::ERR_DOES_NOT_EXIST, accountId); | ||
963 | return; | 1162 | return; | ||
964 | } | 1163 | } | ||
965 | m_accountManager->removeAccount(accountId); | 1164 | m_accountManager->removeAccount(accountId); | ||
966 | finished(); | 1165 | finished(); | ||
967 | return; | 1166 | return; | ||
968 | } | 1167 | } | ||
969 | 1168 | | |||
1169 | if (gdriveUrl.isSharedDrive()) { | ||||
1170 | qCDebug(GDRIVE) << "Deleting Shared Drive" << url; | ||||
1171 | if (deleteSharedDrive(url)) { | ||||
1172 | // error( will have been called in case of error | ||||
elvisangelaccio: "error() will have been called in case of error" | |||||
1173 | finished(); | ||||
1174 | } | ||||
1175 | return; | ||||
1176 | } | ||||
1177 | | ||||
970 | // GDrive allows us to delete entire directory even when it's not empty, | 1178 | // GDrive allows us to delete entire directory even when it's not empty, | ||
971 | // so we need to emulate the normal behavior ourselves by checking number of | 1179 | // so we need to emulate the normal behavior ourselves by checking number of | ||
972 | // child references | 1180 | // child references | ||
973 | if (!isfile) { | 1181 | if (!isfile) { | ||
974 | ChildReferenceFetchJob referencesFetch(fileId, getAccount(accountId)); | 1182 | ChildReferenceFetchJob referencesFetch(fileId, getAccount(accountId)); | ||
975 | if (!runJob(referencesFetch, url, accountId)) { | 1183 | if (!runJob(referencesFetch, url, accountId)) { | ||
976 | return; | 1184 | return; | ||
977 | } | 1185 | } | ||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Line(s) | 1228 | = urlQuery.hasQueryItem(QStringLiteral("id")) | |||
1021 | ? urlQuery.queryItemValue(QStringLiteral("id")) | 1229 | ? urlQuery.queryItemValue(QStringLiteral("id")) | ||
1022 | : resolveFileIdFromPath(src.adjusted(QUrl::StripTrailingSlash).path(), | 1230 | : resolveFileIdFromPath(src.adjusted(QUrl::StripTrailingSlash).path(), | ||
1023 | KIOGDrive::PathIsFile); | 1231 | KIOGDrive::PathIsFile); | ||
1024 | if (sourceFileId.isEmpty()) { | 1232 | if (sourceFileId.isEmpty()) { | ||
1025 | error(KIO::ERR_DOES_NOT_EXIST, src.path()); | 1233 | error(KIO::ERR_DOES_NOT_EXIST, src.path()); | ||
1026 | return; | 1234 | return; | ||
1027 | } | 1235 | } | ||
1028 | 1236 | | |||
1237 | if (srcGDriveUrl.isSharedDrive()) { | ||||
1238 | qCDebug(GDRIVE) << "Renaming Shared Drive" << srcGDriveUrl.filename() << "to" << destGDriveUrl.filename(); | ||||
1239 | DrivesPtr drives = DrivesPtr::create(); | ||||
1240 | drives->setId(sourceFileId); | ||||
1241 | drives->setName(destGDriveUrl.filename()); | ||||
1242 | | ||||
1243 | DrivesModifyJob modifyJob(drives, getAccount(sourceAccountId)); | ||||
1244 | if (!runJob(modifyJob, src, sourceAccountId)) { | ||||
1245 | return; | ||||
elvisangelaccio: `runJob` already called `error()` here, no? | |||||
1246 | } | ||||
1247 | | ||||
1248 | finished(); | ||||
1249 | return; | ||||
1250 | } | ||||
1251 | | ||||
1029 | // We need to fetch ALL, so that we can do update later | 1252 | // We need to fetch ALL, so that we can do update later | ||
1030 | FileFetchJob sourceFileFetchJob(sourceFileId, getAccount(sourceAccountId)); | 1253 | FileFetchJob sourceFileFetchJob(sourceFileId, getAccount(sourceAccountId)); | ||
1031 | if (!runJob(sourceFileFetchJob, src, sourceAccountId)) { | 1254 | if (!runJob(sourceFileFetchJob, src, sourceAccountId)) { | ||
1032 | return; | 1255 | return; | ||
1033 | } | 1256 | } | ||
1034 | 1257 | | |||
1035 | const ObjectsList objects = sourceFileFetchJob.items(); | 1258 | const ObjectsList objects = sourceFileFetchJob.items(); | ||
1036 | if (objects.count() != 1) { | 1259 | if (objects.count() != 1) { | ||
▲ Show 20 Lines • Show All 86 Lines • Show Last 20 Lines |
Please keep the list of includes sorted.