From f8005aa60d04e06420ccea7864deeced8f746e18 Mon Sep 17 00:00:00 2001 From: ro Date: Fri, 5 Apr 2024 12:29:38 -0600 Subject: [PATCH] turned on backups ported over the backup functionality from the old build to the new while making few tweaks instead of packaging up all files in the site to create massive zip files, now a list of files is created for the user and blog directories that the system will use to download and put them in the appropriate directories, resulting in a such slimmer backup file. archiving images my be added at a later date, but will be kept seperate from the current back up process --- .../Controllers/API/SettingsAPIController.php | 32 ++++++- app/Providers/FipamoServiceProvider.php | 7 ++ app/Services/MaintenanceService.php | 96 +++++++++++++++++++ app/Services/SettingsService.php | 2 +- app/Services/SortingService.php | 2 +- .../app/controllers/MaintenanceManager.js | 4 +- resources/views/back/settings.blade.php | 2 +- routes/api.php | 2 + 8 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 app/Services/MaintenanceService.php diff --git a/app/Http/Controllers/API/SettingsAPIController.php b/app/Http/Controllers/API/SettingsAPIController.php index d366b3b..24a73d7 100644 --- a/app/Http/Controllers/API/SettingsAPIController.php +++ b/app/Http/Controllers/API/SettingsAPIController.php @@ -6,16 +6,26 @@ use App\Http\Controllers\Controller; use Illuminate\Http\Request; use App\Services\SettingsService; use App\Services\RenderService; +use App\Services\MaintenanceService; +use App\Services\AuthService; class SettingsAPIController extends Controller { protected $settings; protected $render; + protected $mainteance; + protected $auth; - public function __construct(SettingsService $settingsService, RenderService $renderService) - { - $this->settings = $settingsService; - $this->render = $renderService; + public function __construct( + SettingsService $settingsService, + RenderService $renderService, + MaintenanceService $maintenanceService, + AuthService $authService + ) { + $this->settings = $settingsService; + $this->render = $renderService; + $this->maintenance = $maintenanceService; + $this->auth = $authService; } public function publish(Request $request) @@ -37,4 +47,18 @@ class SettingsAPIController extends Controller $result = $this->settings->navSync($body); return response()->json($result)->header('Content-Type', 'application/json'); } + + public function createBackup(Request $request) + { + return response()->json($this->maintenance->createBackup())->header('Content-Type', 'application/json'); + } + + public function downloadBackup(Request $request) + { + if ($this->auth::status()) { + $latest = $this->settings->getGlobal()['last_backup']; + $file = 'backup-' . $latest . '.zip'; + return response()->download('../content/backups/' . $file, $file, ['Content-Type: application/zip']); + } + } } diff --git a/app/Providers/FipamoServiceProvider.php b/app/Providers/FipamoServiceProvider.php index d157b2b..69d3d33 100644 --- a/app/Providers/FipamoServiceProvider.php +++ b/app/Providers/FipamoServiceProvider.php @@ -15,6 +15,7 @@ use App\Services\FileUploadService; use App\Services\RenderService; use App\Services\SortingService; use App\Services\AssetService; +use App\Services\MaintenanceService; class FipamoServiceProvider extends ServiceProvider { @@ -79,6 +80,12 @@ class FipamoServiceProvider extends ServiceProvider ) ); }); + + $this->app->bind(MaintenanceService::class, function ($app) { + return new MaintenanceService( + new SettingsService(new DocService(), new ContentService()) + ); + }); } /** diff --git a/app/Services/MaintenanceService.php b/app/Services/MaintenanceService.php new file mode 100644 index 0000000..0297579 --- /dev/null +++ b/app/Services/MaintenanceService.php @@ -0,0 +1,96 @@ +settings = $settingsService; + } + + public function createBackUp() + { + //make sure back directory is there + $stamp = Carbon::now()->format("YmdGis"); + if (!is_dir('../content/backups')) { + mkdir('../content/backups', 0755, true); + } + //creat backup zip + $zip = new \ZipArchive(); + + $zip->open( + '../content/backups/backup-' . $stamp . '.zip', + \ZipArchive::CREATE | \ZipArchive::OVERWRITE + ); + //gather data and path info for md pages + $pagePath = '../content/pages'; + $yearPaths = glob($pagePath . '/*', GLOB_ONLYDIR); + foreach ($yearPaths as $years) { + $year = explode('/', $years); + //grap the index and save it + if (trim($year[3]) == 'start') { + $options = [ + 'add_path' => 'content/pages/' . $year[3] . '/', + 'remove_all_path' => true, + ]; + $zip->addGlob($years . '/*.md', GLOB_BRACE, $options); + } + $monthsPath = glob($pagePath . '/' . $year[3] . '/*', GLOB_ONLYDIR); + foreach ($monthsPath as $months) { + $month = explode('/', $months); + //once info is collected, add md pages to zip + $options = [ + 'add_path' => 'content/pages/' . $year[3] . '/' . $month[4] . '/', + 'remove_all_path' => true, + ]; + $zip->addGlob($months . '/*.md', GLOB_BRACE, $options); + } + } + + //gather paths for blog images + $blogImages = []; + $dir = new \RecursiveDirectoryIterator('../public/assets/images/blog'); + $flat = new \RecursiveIteratorIterator($dir); + $files = new \RegexIterator($flat, '/\.png|jpg|gif$/i'); + foreach ($files as $file) { + $blogImages[] = ['path' => $file->getPath(), 'file' => $file->getFilename()]; + }; + + //gather paths for user images + $userImages = []; + $dir = new \RecursiveDirectoryIterator('../public/assets/images/user'); + $flat = new \RecursiveIteratorIterator($dir); + $files = new \RegexIterator($flat, '/\.png|jpg|gif$/i'); + foreach ($files as $file) { + $userImages[] = ['path' => $file->getPath(), 'file' => $file->getFilename()]; + }; + + //add directory for settings and save them + $zip->addEmptyDir('config'); + $zip->addEmptyDir('images'); + $zip->addFile(env('SETTINGS_PATH'), 'config/settings.json'); + $zip->addFile(env('FOLKS_PATH'), 'config/folks.json'); + $zip->addFile(env('TAGS_PATH'), 'config/tags.json'); + // create temp files for image lists + file_put_contents('../content/backups/blog_temp.json', json_encode($blogImages)); + file_put_contents('../content/backups/user_temp.json', json_encode($userImages)); + //add to zip + $zip->addFile('../content/backups/blog_temp.json', 'images/blog.json'); + $zip->addFile('../content/backups/user_temp.json', 'images/user.json'); + //save zip file + $zip->close(); + //clean up temp files + unlink('../content/backups/blog_temp.json'); + unlink('../content/backups/user_temp.json'); + + //update settings file with latest back up date + $this->settings->updateGlobalData('last_backup', $stamp); + + return ['message' => "Backup created. THIS IS A SAFE SPACE!"]; + } +} diff --git a/app/Services/SettingsService.php b/app/Services/SettingsService.php index ad9f13f..140be3b 100644 --- a/app/Services/SettingsService.php +++ b/app/Services/SettingsService.php @@ -70,7 +70,7 @@ class SettingsService public function updateGlobalData($key, $value) { $this->settings = $this->loadSettings(); - $this->settings['global'][$key] = $data; + $this->settings['global'][$key] = $value; $this->docs->writeSettings($this->settings); } diff --git a/app/Services/SortingService.php b/app/Services/SortingService.php index 1c102af..c2d35a7 100644 --- a/app/Services/SortingService.php +++ b/app/Services/SortingService.php @@ -274,7 +274,7 @@ class SortingService 'siteTitle' => $global['title'], 'baseUrl' => $global['base_url'], 'desc' => $global['descriptions'], - 'lastBackup' => $updated->format('Y M D d'), + 'lastBackup' => $updated->format('Y M D G i s'), 'currentTheme' => $global['theme'], 'themes' => $this->themes->getThemes(), 'apiStatus' => isset($global['externalAPI']) ? $global['externalAPI'] : 'false', diff --git a/public/assets/scripts/dash/app/controllers/MaintenanceManager.js b/public/assets/scripts/dash/app/controllers/MaintenanceManager.js index 5de2663..c8e648e 100644 --- a/public/assets/scripts/dash/app/controllers/MaintenanceManager.js +++ b/public/assets/scripts/dash/app/controllers/MaintenanceManager.js @@ -12,7 +12,7 @@ export const API_INIT = '/api/v1/init'; export const API_RESTORE = '/api/v1/restore'; export const API_GET_SECRET = '/api/v1/get-secret'; export const API_RESET_PASS = '/api/v1/reset-password'; -export const API_CREATE_BACKUP = '/api/v1/backup'; +export const API_CREATE_BACKUP = '/api/v1/backup/create'; export const API_DOWNLOAD_BACKUP = '/api/v1/backup/download'; export const API_RESTORE_BACKUP = '/api/v1/backup/restore'; export const API_UPLOAD_AVATAR = '/api/v1/settings/add-avatar'; @@ -133,7 +133,7 @@ class MaintenanceManager { url = API_CREATE_BACKUP; event = TASK_BACKUP_CREATE; - method = REQUEST_TYPE_POST; + method = REQUEST_TYPE_PUT; type = CONTENT_TYPE_JSON; data = { task: 'create_backup' }; this._request(url, null, event, method, type, data) diff --git a/resources/views/back/settings.blade.php b/resources/views/back/settings.blade.php index 5198c8d..ecaa985 100644 --- a/resources/views/back/settings.blade.php +++ b/resources/views/back/settings.blade.php @@ -30,7 +30,7 @@
@if($lastBackup != '') LAST BACK UP
- {{ $lastBackup }}
+ {{ $lastBackup }}
@else span No back ups. Frowny face. @endif diff --git a/routes/api.php b/routes/api.php index a7330fe..eb52653 100644 --- a/routes/api.php +++ b/routes/api.php @@ -28,3 +28,5 @@ Route::post("/v1/files", [FileUploadAPIController::class, 'upload']); Route::put("/v1/settings/publish", [SettingsAPIController::class, 'publish']); Route::put("/v1/settings/sync", [SettingsAPIController::class, 'sync']); Route::put("/v1/settings/nav-sync", [SettingsAPIController::class, 'navSync']); +Route::put("/v1/backup/create", [SettingsAPIController::class, 'createBackup']); +Route::get("/v1/backup/download", [SettingsAPIController::class, 'downloadBackup']);