port to 4.1 upload by url

This commit is contained in:
aina-esokia
2019-03-18 16:16:14 +04:00
parent 6ca847558a
commit 8ab2888850
4 changed files with 116 additions and 27 deletions

View File

@@ -88,9 +88,10 @@ use Alchemy\Phrasea\Status\StatusStructure;
use Alchemy\Phrasea\TaskManager\LiveInformation; use Alchemy\Phrasea\TaskManager\LiveInformation;
use Alchemy\Phrasea\Utilities\NullableDateTime; use Alchemy\Phrasea\Utilities\NullableDateTime;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use JMS\TranslationBundle\Annotation\Ignore; use Guzzle\Http\Client as Guzzle;
use League\Fractal\Resource\Item; use League\Fractal\Resource\Item;
use media_subdef; use media_subdef;
use Neutron\TemporaryFilesystem\TemporaryFilesystemInterface;
use Symfony\Component\Form\Form; use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@@ -905,19 +906,6 @@ class V1Controller extends Controller
public function addRecordAction(Request $request) public function addRecordAction(Request $request)
{ {
if (count($request->files->get('file')) == 0) {
return $this->getBadRequestAction($request, 'Missing file parameter');
}
$file = $request->files->get('file');
if (!$file instanceof UploadedFile) {
return $this->getBadRequestAction($request, 'You can upload one file at time');
}
if (!$file->isValid()) {
return $this->getBadRequestAction($request, 'Data corrupted, please try again');
}
if (!$request->get('base_id')) { if (!$request->get('base_id')) {
return $this->getBadRequestAction($request, 'Missing base_id parameter'); return $this->getBadRequestAction($request, 'Missing base_id parameter');
} }
@@ -930,16 +918,54 @@ class V1Controller extends Controller
))->createResponse(); ))->createResponse();
} }
// Add file extension if (count($request->files->get('file')) == 0) {
$uploadedFilename = $file->getRealPath(); if(count($request->get('url')) == 0) {
return $this->getBadRequestAction($request, 'Missing file parameter');
}
else {
// upload via url
$url = $request->get('url');
$pi = pathinfo($url); // filename, extension
$renamedFilename = $file->getRealPath() . '.' . pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION); /** @var TemporaryFilesystemInterface $tmpFs */
$tmpFs = $this->app['temporary-filesystem'];
$tempfile = $tmpFs->createTemporaryFile('download_', null, $pi['extension']);
$this->getFilesystem()->rename($uploadedFilename, $renamedFilename); try {
$guzzle = new Guzzle($url);
$res = $guzzle->get("", [], ['save_to' => $tempfile])->send();
}
catch (\Exception $e) {
return $this->getBadRequestAction($request, sprintf('Error "%s" downloading "%s"', $e->getMessage(), $url));
}
$media = $this->app->getMediaFromUri($renamedFilename); if($res->getStatusCode() !== 200) {
return $this->getBadRequestAction($request, sprintf('Error %s downloading "%s"', $res->getStatusCode(), $url));
}
$Package = new File($this->app, $media, $collection, $file->getClientOriginalName()); $originalName = $pi['filename'] . '.' . $pi['extension'];
$newPathname = $tempfile;
}
}
else {
// upload via file
$file = $request->files->get('file');
if (!$file instanceof UploadedFile) {
return $this->getBadRequestAction($request, 'You can upload one file at time');
}
if (!$file->isValid()) {
return $this->getBadRequestAction($request, 'Data corrupted, please try again');
}
$originalName = $file->getClientOriginalName();
$newPathname = $file->getPathname() . '.' . $file->getClientOriginalExtension();
if (false === rename($file->getPathname(), $newPathname)) {
return Result::createError($request, 403, 'Error while renaming file')->createResponse();
}
}
$media = $this->app->getMediaFromUri($newPathname);
$Package = new File($this->app, $media, $collection, $originalName);
if ($request->get('status')) { if ($request->get('status')) {
$Package->addAttribute(new Status($this->app, $request->get('status'))); $Package->addAttribute(new Status($this->app, $request->get('status')));

View File

@@ -26,6 +26,7 @@ use Alchemy\Phrasea\Model\Entities\LazaretFile;
use Alchemy\Phrasea\Model\Entities\LazaretSession; use Alchemy\Phrasea\Model\Entities\LazaretSession;
use DataURI\Exception\Exception as DataUriException; use DataURI\Exception\Exception as DataUriException;
use DataURI\Parser; use DataURI\Parser;
use Guzzle\Http\Client as Guzzle;
use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
@@ -76,6 +77,30 @@ class UploadController extends Controller
]); ]);
} }
public function getHead(Request $request)
{
$response = [
'content-type' => null,
'content-length' => null,
'basename' => null
];
try {
$url = $request->get('url');
$basename = pathinfo($url, PATHINFO_BASENAME);
$guzzle = new Guzzle($url);
$res = $guzzle->head("")->send();
$response['content-type'] = $res->getContentType();
$response['content-length'] = $res->getContentLength();
$response['basename'] = $basename;
}
catch (\Exception $e) {
// no-op : head will return no info but will not crash
}
return $this->app->json($response);
}
/** /**
* Upload processus * Upload processus
* *
@@ -98,7 +123,7 @@ class UploadController extends Controller
'message' => '', 'message' => '',
'element' => '', 'element' => '',
'reasons' => [], 'reasons' => [],
'id' => '', 'id' => '',
]; ];
if (null === $request->files->get('files')) { if (null === $request->files->get('files')) {
@@ -119,18 +144,44 @@ class UploadController extends Controller
throw new AccessDeniedHttpException('User is not allowed to add record on this collection'); throw new AccessDeniedHttpException('User is not allowed to add record on this collection');
} }
/** @var UploadedFile $file */
$file = current($request->files->get('files')); $file = current($request->files->get('files'));
if (!$file->isValid()) { if (!$file->isValid()) {
throw new BadRequestHttpException('Uploaded file is invalid'); throw new BadRequestHttpException('Uploaded file is invalid');
} }
try { if ($file->getClientOriginalName() === "blob" && $file->getClientMimeType() === "application/json") {
// a "upload by url" was done, we receive a tiny json that contains url.
$json = json_decode(file_get_contents($file->getRealPath()), true);
$url = $json['url'];
$pi = pathinfo($url); // filename, extension
$tempfile = $this->getTemporaryFilesystem()->createTemporaryFile('download_', null, $pi['extension']);
try {
$guzzle = new Guzzle($url);
$res = $guzzle->get("", [], ['save_to' => $tempfile])->send();
}
catch (\Exception $e) {
throw new BadRequestHttpException(sprintf('Error "%s" downloading "%s"', $e->getMessage(), $url));
}
if($res->getStatusCode() !== 200) {
throw new BadRequestHttpException(sprintf('Error %s downloading "%s"', $res->getStatusCode(), $url));
}
$uploadedFilename = $renamedFilename = $tempfile;
$originalName = $pi['filename'] . '.' . $pi['extension'];
} else {
// Add file extension, so mediavorus can guess file type for octet-stream file // Add file extension, so mediavorus can guess file type for octet-stream file
$uploadedFilename = $file->getRealPath(); $uploadedFilename = $file->getRealPath();
$renamedFilename = null; $renamedFilename = null;
if(!empty($this->app['conf']->get(['main', 'storage', 'tmp_files']))){ if(!empty($this->app['conf']->get(['main', 'storage', 'tmp_files']))) {
$tmpStorage = \p4string::addEndSlash($this->app['conf']->get(['main', 'storage', 'tmp_files'])).'upload/'; $tmpStorage = \p4string::addEndSlash($this->app['conf']->get(['main', 'storage', 'tmp_files'])).'upload/';
if(!is_dir($tmpStorage)){ if(!is_dir($tmpStorage)){
@@ -139,12 +190,16 @@ class UploadController extends Controller
$renamedFilename = $tmpStorage. pathinfo($file->getRealPath(), PATHINFO_FILENAME) .'.' . pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION); $renamedFilename = $tmpStorage. pathinfo($file->getRealPath(), PATHINFO_FILENAME) .'.' . pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION);
}else{ } else {
$renamedFilename = $file->getRealPath() . '.' . pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION); $renamedFilename = $file->getRealPath() . '.' . pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION);
} }
$this->getFilesystem()->rename($uploadedFilename, $renamedFilename); $this->getFilesystem()->rename($uploadedFilename, $renamedFilename);
$originalName = $file->getClientOriginalName();
}
try {
$media = $this->app->getMediaFromUri($renamedFilename); $media = $this->app->getMediaFromUri($renamedFilename);
$collection = \collection::getByBaseId($this->app, $base_id); $collection = \collection::getByBaseId($this->app, $base_id);
@@ -153,7 +208,7 @@ class UploadController extends Controller
$this->getEntityManager()->persist($lazaretSession); $this->getEntityManager()->persist($lazaretSession);
$packageFile = new File($this->app, $media, $collection, $file->getClientOriginalName()); $packageFile = new File($this->app, $media, $collection, $originalName);
$postStatus = $request->request->get('status'); $postStatus = $request->request->get('status');
@@ -184,7 +239,9 @@ class UploadController extends Controller
$code = $this->getBorderManager()->process( $lazaretSession, $packageFile, $callback, $forceBehavior); $code = $this->getBorderManager()->process( $lazaretSession, $packageFile, $callback, $forceBehavior);
$this->getFilesystem()->rename($renamedFilename, $uploadedFilename); if($renamedFilename !== $uploadedFilename) {
$this->getFilesystem()->rename($renamedFilename, $uploadedFilename);
}
if (!!$forceBehavior) { if (!!$forceBehavior) {
$reasons = []; $reasons = [];

View File

@@ -66,6 +66,9 @@ class Upload implements ControllerProviderInterface, ServiceProviderInterface
$controllers->get('/html5-version/', 'controller.prod.upload:getHtml5UploadForm') $controllers->get('/html5-version/', 'controller.prod.upload:getHtml5UploadForm')
->bind('upload_html5_form'); ->bind('upload_html5_form');
$controllers->get('/head/', 'controller.prod.upload:getHead')
->bind('upload_head');
$controllers->post('/', 'controller.prod.upload:upload') $controllers->post('/', 'controller.prod.upload:upload')
->bind('upload'); ->bind('upload');

View File

@@ -31,7 +31,10 @@
<span>{{ 'Select files...' | trans }}</span> <span>{{ 'Select files...' | trans }}</span>
<input type="file" name="files[]" multiple> <input type="file" name="files[]" multiple>
</span> </span>
<br /> <br />
<p class="or_upload">{{ "Or" | trans }}</p>
<div class="url_upload"><input type="url" value="" id="add-url"><button class="add-url add_url_upload">{{ 'Add this url' | trans }}</button></div>
<br/>
<span class="comment"> <span class="comment">
({% trans with {'%maxFileSizeReadable%' : maxFileSizeReadable} %}maximum : %maxFileSizeReadable%{% endtrans %}) ({% trans with {'%maxFileSizeReadable%' : maxFileSizeReadable} %}maximum : %maxFileSizeReadable%{% endtrans %})
</span> </span>