* @brief Deletes a file or empty directory under the 'AI/' write root. */
| 647 | * @brief Deletes a file or empty directory under the 'AI/' write root. |
| 648 | */ |
| 649 | QJsonObject AI::FileSandbox::remove(const QJsonObject& args) const |
| 650 | { |
| 651 | const auto resolved = resolveWrite(args.value(QStringLiteral("path")).toString()); |
| 652 | if (!resolved.ok) |
| 653 | return failure(resolved.error, resolved.hint); |
| 654 | |
| 655 | if (resolved.path == writeRoot()) |
| 656 | return failure(QStringLiteral("refused"), |
| 657 | QStringLiteral("Refusing to delete the AI/ root itself.")); |
| 658 | |
| 659 | const QFileInfo info(resolved.path); |
| 660 | if (!info.exists()) |
| 661 | return failure(QStringLiteral("not_found")); |
| 662 | |
| 663 | bool removed = false; |
| 664 | if (info.isDir()) { |
| 665 | QDir dir(resolved.path); |
| 666 | if (!dir.isEmpty()) |
| 667 | return failure(QStringLiteral("dir_not_empty"), |
| 668 | QStringLiteral("Delete the directory's files first; recursive delete is " |
| 669 | "not supported.")); |
| 670 | |
| 671 | removed = QDir().rmdir(resolved.path); |
| 672 | } else { |
| 673 | removed = QFile::remove(resolved.path); |
| 674 | } |
| 675 | |
| 676 | if (!removed) |
| 677 | return failure(QStringLiteral("delete_failed")); |
| 678 | |
| 679 | QJsonObject out; |
| 680 | out[QStringLiteral("ok")] = true; |
| 681 | out[QStringLiteral("path")] = displayPath(resolved.path, workspaceRoot()); |
| 682 | out[QStringLiteral("deleted")] = true; |
| 683 | return out; |
| 684 | } |