From: Vincent Vanwaelscappel Date: Wed, 15 Feb 2023 18:36:06 +0000 (+0100) Subject: wip #5718 @1 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=0c92788bc8280f958bdeddf7ec8998d2c15dd22a;p=fluidbook-toolbox.git wip #5718 @1 --- diff --git a/app/Http/Controllers/Admin/Operations/Files/DownloadOperation.php b/app/Http/Controllers/Admin/Operations/Files/DownloadOperation.php new file mode 100644 index 000000000..8c6098015 --- /dev/null +++ b/app/Http/Controllers/Admin/Operations/Files/DownloadOperation.php @@ -0,0 +1,127 @@ +withoutMiddleware([CheckIfAdmin::class]); + Route::match(['get'], $segment . '/{hash}/{file}', $controller . '@download')->withoutMiddleware([CheckIfAdmin::class]); + + } + + protected function setupDownloadDefaults() + { + $this->crud->addButtonFromView('line', 'install', 'files.install', 'end'); + $this->crud->addButtonFromView('line', 'download', 'files.download', 'end'); + } + + protected function download($hash, $name) + { + $file = File::where('hash', $hash)->where('name', $name)->first(); + if ($file === null) { + abort(404); + } + return XSendFileController::sendfile($file->path); + } + + /** + * @throws IOException + */ + protected function manifestIpa($hash) + { + $file = File::where('hash', $hash)->first(); + if ($file === null) { + abort(404); + } + + $xml = Cache::rememberForever('ipamanifest_' . $hash, function () use ($file) { + $ipa = $file->path; + + $zip = new ZipArchive(); + $zip->open($ipa); + for ($i = 0; $i < $zip->numFiles; $i++) { + $filename = $zip->getNameIndex($i); + if (preg_match('|Payload/(.+).app/Info.plist|', $filename, $matches)) { + $idx = $i; + break; + } + } + if (!$idx) { + return; + } + + $tmp = Files::tempnam(); + file_put_contents($tmp, $zip->getFromIndex($idx)); + + $plist = new CFPropertyList($tmp); + + $infos = $plist->toArray(); + $bundle = $infos['CFBundleIdentifier']; + $appName = $infos['CFBundleDisplayName']; + $version = $infos['CFBundleVersion']; + + return ' + + + + items + + + assets + + + kind + software-package + url + ' . $file->getURL() . ' + + + kind + display-image + url + https://toolbox.fluidbook.com/images/ios/57.png + + + kind + full-size-image + url + https://toolbox.fluidbook.com/images/ios/57.png + + + metadata + + bundle-identifier + ' . $bundle . ' + bundle-version + ' . $version . ' + kind + software + title + ' . $appName . ' + + + + +'; + }); + + + return response($xml, 200, ['Content-type' => 'application/xml']); + + + } + +} + diff --git a/app/Models/File.php b/app/Models/File.php index 6e8b8934a..1df51800f 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -2,7 +2,9 @@ namespace App\Models; +use App\Http\Controllers\Admin\Operations\Files\DownloadOperation; use App\Models\Base\ToolboxModel; +use Cubist\Backpack\CubistBackpackServiceProvider; use Cubist\Backpack\Magic\Fields\Date; use Cubist\Backpack\Magic\Fields\Hidden; use Cubist\Backpack\Magic\Fields\Integer; @@ -24,24 +26,33 @@ class File extends ToolboxModel protected static $_permissionBase = 'files'; + protected $_enableEdition = false; + protected $_enableClone = false; + + protected $primaryKey = 'hash'; + public $incrementing = false; + protected $keyType = 'string'; + + + protected $_operations = [DownloadOperation::class]; + public function setFields() { parent::setFields(); + //$this->addField('hash', Text::class, __('Hash'), ['column' => false, 'database_index' => true]); $this->addField('name', Text::class, __('Nom du fichier'), ['column' => true]); $this->addField('path', Hidden::class, __('Chemin')); $this->addField('ext', Text::class, __('Type'), ['column' => true]); $this->addField('updated_at', Date::class, __('Date'), ['column' => true]); - $this->addField('size', Integer::class, __('Taille'), ['column' => true]); + $this->addField('size', Integer::class, __('Taille'), ['column' => true, 'column_type' => 'filesize', 'column_view_namespace' => CubistBackpackServiceProvider::NAMESPACE . '::columns']); $this->addField('from', \App\Fields\User::class, __('Envoyé par'), ['column' => true]); $this->addField('to', \App\Fields\User::class, __('Destiné à'), ['column' => true]); - $this->addField('hash', Hidden::class, __('Hash')); $this->addField('mtime', Hidden::class, ''); - $this->addOwnerField(['column' => false]); } - protected function getData() + protected function _getData() { /** @var User $user */ $users = User::withoutGlobalScopes()->get(); @@ -49,10 +60,7 @@ class File extends ToolboxModel foreach ($users as $user) { $this->_listFilesOfUser($user->id, $files); } - usort($files, function ($a, $b) { - return $a['mtime'] - $b['mtime']; - }); - return array_values($files); + return $files; } protected function _listFilesOfUser($id, &$files) @@ -61,11 +69,11 @@ class File extends ToolboxModel return $this->___listFilesOfUser($id); }); - foreach ($uFiles as $path => $uFile) { - if (isset($files[$path])) { + foreach ($uFiles as $hash => $uFile) { + if (isset($files[$hash])) { continue; } - $files[$path] = $uFile; + $files[$hash] = $uFile; } } @@ -101,8 +109,9 @@ class File extends ToolboxModel $date = new \DateTime(); $date->setTimestamp($mtime); + $hash = Files::hashFileAttributes($pathname); - $res[$pathname] = [ + $res[$hash] = [ 'path' => $pathname, 'name' => $file->getFilename(), 'ext' => mb_strtolower($file->getExtension()), @@ -113,13 +122,18 @@ class File extends ToolboxModel 'to' => $to, 'owner' => $id, 'mtime' => $mtime, - 'hash' => Files::hashFileAttributes($pathname), + 'hash' => $hash, ]; } return $res; } + public function showPrimaryColumn() + { + return false; + } + public static function addOwnerClause(Builder $builder) { @@ -134,4 +148,9 @@ class File extends ToolboxModel } $builder->whereIn(static::$_ownerAttribute, backpack_user()->getManagedUsers()); } + + public function getURL() + { + return config('url', 'https://toolbox.fluidbook.com') . '/file/' . $this->hash . '/' . $this->name; + } } diff --git a/composer.json b/composer.json index 1b1f00797..7b3c9bf6e 100644 --- a/composer.json +++ b/composer.json @@ -46,12 +46,12 @@ "mxl/laravel-job": "^1.3", "nyholm/psr7": "^1.5", "php-ffmpeg/php-ffmpeg": "^0.18.0", + "rodneyrehm/plist": "^2.0", "rustici-software/scormcloud-api-v2-client-php": "^2.0", "symfony/http-client": "^v6.0" }, "require-dev": { "facade/ignition": "^2.17", - "fzaninotto/faker": "^1.9", "mockery/mockery": "^1.5", "nunomaduro/collision": "^4.3", "phpunit/phpunit": "^8.5", @@ -62,7 +62,10 @@ "config": { "optimize-autoloader": true, "preferred-install": "dist", - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "php-http/discovery": true + } }, "extra": { "laravel": { diff --git a/composer.lock b/composer.lock index 49ba241da..237ff04de 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3841d2420cde41846464f40adf52e325", + "content-hash": "9e1d830868759266a700df2a00576cf8", "packages": [ { "name": "ahmadshah/lucy", @@ -1660,13 +1660,13 @@ "source": { "type": "git", "url": "git://git.cubedesigners.com/cubist_cms-back.git", - "reference": "3cbabfd839e1ee1449dfe53050e2f5537d0dd7fd" + "reference": "541015ec6f5b6838d5ac59fbfef12aac086311e7" }, "dist": { "type": "tar", - "url": "https://composer.cubedesigners.com/dist/cubist/cms-back/cubist-cms-back-dev-master-37b21b.tar", - "reference": "3cbabfd839e1ee1449dfe53050e2f5537d0dd7fd", - "shasum": "a5d02527b1621e284024d141f3d71634cd90d7fb" + "url": "https://composer.cubedesigners.com/dist/cubist/cms-back/cubist-cms-back-dev-master-0f74fc.tar", + "reference": "541015ec6f5b6838d5ac59fbfef12aac086311e7", + "shasum": "3adce0eeb2370518325f7ca2ab03f99d6d724267" }, "require": { "backpack/backupmanager": "^3.0", @@ -1747,7 +1747,7 @@ } ], "description": "Cubist Backpack extension", - "time": "2023-02-15T09:41:45+00:00" + "time": "2023-02-15T15:17:43+00:00" }, { "name": "cubist/cms-front", @@ -8381,6 +8381,75 @@ ], "time": "2022-02-11T10:27:51+00:00" }, + { + "name": "rodneyrehm/plist", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/TECLIB/CFPropertyList.git", + "reference": "eb1f97cc44427359be9f09e617d68eef57707617" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TECLIB/CFPropertyList/zipball/eb1f97cc44427359be9f09e617d68eef57707617", + "reference": "eb1f97cc44427359be9f09e617d68eef57707617", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0", + "squizlabs/php_codesniffer": "^3.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "CFPropertyList\\": "src/CFPropertyList/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Kruse", + "email": "cjk@wwwtech.de", + "role": "developer" + }, + { + "name": "Rodney Rehm", + "email": "mail+github@rodneyrehm.de", + "role": "developer" + }, + { + "name": "Thierry Bugier", + "email": "tbugier@teclib.com", + "role": "developer" + } + ], + "description": "Library for reading and writing Apple's CFPropertyList (plist) files in XML as well as binary format.", + "homepage": "https://github.com/TECLIB/CFPropertyList", + "keywords": [ + "CFPropertyList", + "Core Foundation", + "apple", + "binary", + "plist", + "xml" + ], + "support": { + "docs": "http://teclib.github.io/CFPropertyList/howtos/", + "email": "contact@teclib.com", + "issues": "https://github.com/TECLIB/CFPropertyList/issues", + "rss": "https://teclib.github.io/CFPropertyList/feed.xml", + "source": "https://github.com/TECLIB/CFPropertyList" + }, + "time": "2021-12-01T18:24:28+00:00" + }, { "name": "rustici-software/scormcloud-api-v2-client-php", "version": "2.1.0", @@ -13173,61 +13242,6 @@ ], "time": "2022-11-02T16:23:29+00:00" }, - { - "name": "fzaninotto/faker", - "version": "v1.9.2", - "source": { - "type": "git", - "url": "https://github.com/fzaninotto/Faker.git", - "reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/848d8125239d7dbf8ab25cb7f054f1a630e68c2e", - "reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "ext-intl": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7", - "squizlabs/php_codesniffer": "^2.9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "autoload": { - "psr-4": { - "Faker\\": "src/Faker/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "François Zaninotto" - } - ], - "description": "Faker is a PHP library that generates fake data for you.", - "keywords": [ - "data", - "faker", - "fixtures" - ], - "support": { - "issues": "https://github.com/fzaninotto/Faker/issues", - "source": "https://github.com/fzaninotto/Faker/tree/v1.9.2" - }, - "abandoned": true, - "time": "2020-12-11T09:56:16+00:00" - }, { "name": "hamcrest/hamcrest-php", "version": "v2.0.1", diff --git a/public/images/ios/512.png b/public/images/ios/512.png new file mode 100644 index 000000000..197673eec Binary files /dev/null and b/public/images/ios/512.png differ diff --git a/public/images/ios/57.png b/public/images/ios/57.png new file mode 100644 index 000000000..77cbba409 Binary files /dev/null and b/public/images/ios/57.png differ diff --git a/resources/views/vendor/backpack/crud/buttons/files/download.blade.php b/resources/views/vendor/backpack/crud/buttons/files/download.blade.php new file mode 100644 index 000000000..9ae23d7af --- /dev/null +++ b/resources/views/vendor/backpack/crud/buttons/files/download.blade.php @@ -0,0 +1,2 @@ + {{__('Télécharger')}} diff --git a/resources/views/vendor/backpack/crud/buttons/files/install.blade.php b/resources/views/vendor/backpack/crud/buttons/files/install.blade.php new file mode 100644 index 000000000..3533677a5 --- /dev/null +++ b/resources/views/vendor/backpack/crud/buttons/files/install.blade.php @@ -0,0 +1,8 @@ +@if($entry->ext==='apk') + {{__('Installer')}} +@elseif($entry->ext==='ipa') + {{__('Installer')}} +@endif