This repository has been archived on 2024-09-05. You can view files and clone it, but cannot push or open issues or pull requests.
shimmie2/ext/bulk_import_export/main.php

175 lines
6 KiB
PHP
Raw Normal View History

2021-12-14 18:32:47 +00:00
<?php
declare(strict_types=1);
2020-06-02 23:05:09 +00:00
namespace Shimmie2;
2020-06-02 23:05:09 +00:00
class BulkImportExport extends DataHandlerExtension
{
2021-12-14 18:32:47 +00:00
public const EXPORT_ACTION_NAME = "bulk_export";
public const EXPORT_INFO_FILE_NAME = "export.json";
protected array $SUPPORTED_MIME = [MimeType::ZIP];
2020-06-02 23:05:09 +00:00
public function onDataUpload(DataUploadEvent $event): void
2020-06-02 23:05:09 +00:00
{
global $user, $database;
2020-06-02 23:05:09 +00:00
2020-06-14 16:05:55 +00:00
if ($this->supported_mime($event->mime) &&
2020-06-02 23:05:09 +00:00
$user->can(Permissions::BULK_IMPORT)) {
2023-01-11 11:15:26 +00:00
$zip = new \ZipArchive();
2020-06-02 23:05:09 +00:00
if ($zip->open($event->tmpname) === true) {
$json_data = $this->get_export_data($zip);
2020-07-07 16:07:23 +00:00
if (empty($json_data)) {
return;
2020-06-02 23:05:09 +00:00
}
2020-06-02 23:05:09 +00:00
$total = 0;
2020-06-04 14:48:43 +00:00
$skipped = 0;
$failed = 0;
2020-06-02 23:05:09 +00:00
while (!empty($json_data)) {
$item = array_pop($json_data);
try {
$image = Image::by_hash($item->hash);
2023-11-11 21:49:12 +00:00
if ($image != null) {
$skipped++;
2020-10-26 15:22:30 +00:00
log_info(BulkImportExportInfo::KEY, "Post $item->hash already present, skipping");
continue;
}
2020-06-02 23:05:09 +00:00
2024-01-20 20:48:47 +00:00
$tmpfile = shm_tempnam("bulk_import");
$stream = $zip->getStream($item->hash);
2024-01-15 13:08:59 +00:00
if ($stream === false) {
2024-02-11 15:47:40 +00:00
throw new UserError("Could not import " . $item->hash . ": File not in zip");
}
2020-06-02 23:05:09 +00:00
file_put_contents($tmpfile, $stream);
2024-01-09 21:59:24 +00:00
$database->with_savepoint(function () use ($item, $tmpfile, $event) {
$images = send_event(new DataUploadEvent($tmpfile, basename($item->filename), 0, [
2024-01-09 21:59:24 +00:00
'tags' => $item->new_tags,
]))->images;
2020-06-02 23:05:09 +00:00
2024-01-09 21:59:24 +00:00
if (count($images) == 0) {
2024-02-11 15:47:40 +00:00
throw new UserError("Unable to import file $item->hash");
}
2024-01-09 21:59:24 +00:00
foreach ($images as $image) {
$event->images[] = $image;
if ($item->source != null) {
$image->set_source($item->source);
}
send_event(new BulkImportEvent($image, $item));
}
});
2020-06-02 23:05:09 +00:00
$total++;
2023-01-11 11:15:26 +00:00
} catch (\Exception $ex) {
$failed++;
log_error(BulkImportExportInfo::KEY, "Could not import " . $item->hash . ": " . $ex->getMessage(), "Could not import " . $item->hash . ": " . $ex->getMessage());
2020-06-02 23:05:09 +00:00
} finally {
if (!empty($tmpfile) && is_file($tmpfile)) {
2020-06-02 23:05:09 +00:00
unlink($tmpfile);
}
}
}
log_info(
BulkImportExportInfo::KEY,
"Imported $total items, skipped $skipped, $failed failed",
"Imported $total items, skipped $skipped, $failed failed"
);
2020-06-02 23:05:09 +00:00
} else {
2024-02-11 15:47:40 +00:00
throw new UserError("Could not open zip archive");
2020-06-02 23:05:09 +00:00
}
}
}
public function onBulkActionBlockBuilding(BulkActionBlockBuildingEvent $event): void
2020-06-02 23:05:09 +00:00
{
2020-10-29 01:28:46 +00:00
global $user;
2020-06-02 23:05:09 +00:00
if ($user->can(Permissions::BULK_EXPORT)) {
$event->add_action(self::EXPORT_ACTION_NAME, "Export");
}
}
public function onBulkAction(BulkActionEvent $event): void
2020-06-02 23:05:09 +00:00
{
global $user, $page;
if ($user->can(Permissions::BULK_EXPORT) &&
($event->action == self::EXPORT_ACTION_NAME)) {
$download_filename = $user->name . '-' . date('YmdHis') . '.zip';
2024-01-20 20:48:47 +00:00
$zip_filename = shm_tempnam("bulk_export");
2023-01-11 11:15:26 +00:00
$zip = new \ZipArchive();
2020-06-02 23:05:09 +00:00
$json_data = [];
2023-01-11 11:15:26 +00:00
if ($zip->open($zip_filename, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE) === true) {
2020-06-02 23:05:09 +00:00
foreach ($event->items as $image) {
$img_loc = warehouse_path(Image::IMAGE_DIR, $image->hash, false);
2023-02-04 20:50:26 +00:00
$export_event = send_event(new BulkExportEvent($image));
2020-06-02 23:05:09 +00:00
$data = $export_event->fields;
$data["hash"] = $image->hash;
$data["tags"] = $image->get_tag_array();
$data["filename"] = $image->filename;
$data["source"] = $image->source;
2023-01-11 11:15:26 +00:00
$json_data[] = $data;
2020-06-02 23:05:09 +00:00
$zip->addFile($img_loc, $image->hash);
}
$json_data = \Safe\json_encode($json_data, JSON_PRETTY_PRINT);
2020-06-02 23:05:09 +00:00
$zip->addFromString(self::EXPORT_INFO_FILE_NAME, $json_data);
$zip->close();
$page->set_mode(PageMode::FILE);
$page->set_file($zip_filename, true);
$page->set_filename($download_filename);
$event->redirect = false;
2020-06-02 23:05:09 +00:00
}
}
}
2024-01-09 21:59:24 +00:00
2020-06-02 23:05:09 +00:00
// we don't actually do anything, just accept one upload and spawn several
protected function media_check_properties(MediaCheckPropertiesEvent $event): void
{
}
protected function check_contents(string $tmpname): bool
{
return false;
}
protected function create_thumb(Image $image): bool
2020-06-02 23:05:09 +00:00
{
return false;
}
/**
* @return array<mixed>
*/
2023-01-11 11:15:26 +00:00
private function get_export_data(\ZipArchive $zip): ?array
{
$info = $zip->getStream(self::EXPORT_INFO_FILE_NAME);
if ($info !== false) {
try {
$json_string = \Safe\stream_get_contents($info);
$json_data = json_decode($json_string);
2023-01-11 11:59:56 +00:00
return $json_data;
} finally {
fclose($info);
}
} else {
return null;
}
}
2020-06-02 23:05:09 +00:00
}