From 49e302e1bcf7b906056d87dc8fe3e2692fd87916 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 30 May 2018 18:36:21 +0200 Subject: [PATCH] Reinstate ability to download config. --- .../Controllers/Import/IndexController.php | 34 +++++++++++++++++++ .../Import/JobStatusController.php | 28 ++++++++++----- public/js/ff/import/status_v2.js | 5 +-- resources/lang/en_US/import.php | 2 ++ resources/views/import/status.twig | 9 +++-- routes/web.php | 3 ++ 6 files changed, 68 insertions(+), 13 deletions(-) diff --git a/app/Http/Controllers/Import/IndexController.php b/app/Http/Controllers/Import/IndexController.php index 8d471992a5..c416cb8c98 100644 --- a/app/Http/Controllers/Import/IndexController.php +++ b/app/Http/Controllers/Import/IndexController.php @@ -25,8 +25,10 @@ namespace FireflyIII\Http\Controllers\Import; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Import\Prerequisites\PrerequisitesInterface; +use FireflyIII\Models\ImportJob; use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use FireflyIII\Repositories\User\UserRepositoryInterface; +use Illuminate\Http\Response as LaravelResponse; use Log; use View; @@ -138,11 +140,43 @@ class IndexController extends Controller // @codeCoverageIgnoreEnd } Log::debug('Job has configuration. Redirect to job-config.'); + // Otherwise just redirect to job configuration. return redirect(route('import.job.configuration.index', [$importJob->key])); } + /** + * Generate a JSON file of the job's configuration and send it to the user. + * + * @param ImportJob $job + * + * @return LaravelResponse + */ + public function download(ImportJob $job): LaravelResponse + { + Log::debug('Now in download()', ['job' => $job->key]); + $config = $job->configuration; + // This is CSV import specific: + $config['delimiter'] = "\t" === $config['delimiter'] ? 'tab' : $config['delimiter']; + + // this prevents private information from escaping + $config['column-mapping-config'] = []; + $result = json_encode($config, JSON_PRETTY_PRINT); + $name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\')); + /** @var LaravelResponse $response */ + $response = response($result, 200); + $response->header('Content-disposition', 'attachment; filename=' . $name) + ->header('Content-Type', 'application/json') + ->header('Content-Description', 'File Transfer') + ->header('Connection', 'Keep-Alive') + ->header('Expires', '0') + ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') + ->header('Pragma', 'public') + ->header('Content-Length', \strlen($result)); + + return $response; + } /** * General import index. diff --git a/app/Http/Controllers/Import/JobStatusController.php b/app/Http/Controllers/Import/JobStatusController.php index 3e7e7258ff..0fbe1884c9 100644 --- a/app/Http/Controllers/Import/JobStatusController.php +++ b/app/Http/Controllers/Import/JobStatusController.php @@ -80,13 +80,23 @@ class JobStatusController extends Controller { $count = \count($importJob->transactions); $json = [ - 'status' => $importJob->status, - 'errors' => $importJob->errors, - 'count' => $count, - 'tag_id' => $importJob->tag_id, - 'tag_name' => null === $importJob->tag_id ? null : $importJob->tag->tag, - 'report_txt' => trans('import.unknown_import_result'), + 'status' => $importJob->status, + 'errors' => $importJob->errors, + 'count' => $count, + 'tag_id' => $importJob->tag_id, + 'tag_name' => null === $importJob->tag_id ? null : $importJob->tag->tag, + 'report_txt' => trans('import.unknown_import_result'), + 'download_config' => false, + 'download_config_text' => '', ]; + + if ($importJob->provider === 'file') { + $json['download_config'] = true; + $json['download_config_text'] + = trans('import.should_download_config', ['route' => route('import.job.download', [$importJob->key])]) . ' ' + . trans('import.share_config_file'); + } + // if count is zero: if (null !== $importJob->tag_id) { $count = $importJob->tag->transactionJournals->count(); @@ -114,13 +124,15 @@ class JobStatusController extends Controller public function start(ImportJob $importJob): JsonResponse { // catch impossible status: - $allowed = ['ready_to_run', 'need_job_config','error']; // todo remove error + $allowed = ['ready_to_run', 'need_job_config', 'error']; // todo remove error if (null !== $importJob && !\in_array($importJob->status, $allowed, true)) { Log::error('Job is not ready.'); $this->repository->setStatus($importJob, 'error'); - return response()->json(['status' => 'NOK', 'message' => sprintf('JobStatusController::start expects status "ready_to_run" instead of "%s".', $importJob->status)]); + return response()->json( + ['status' => 'NOK', 'message' => sprintf('JobStatusController::start expects status "ready_to_run" instead of "%s".', $importJob->status)] + ); } $importProvider = $importJob->provider; $key = sprintf('import.routine.%s', $importProvider); diff --git a/public/js/ff/import/status_v2.js b/public/js/ff/import/status_v2.js index b5d230eee4..d5cafb34a7 100644 --- a/public/js/ff/import/status_v2.js +++ b/public/js/ff/import/status_v2.js @@ -113,8 +113,9 @@ function showJobResults(data) { console.error(element); $('#import-status-errors').append($('
  • ').text(element)); }); - - + } + if(data.download_config) { + $('#import-status-download').append($('').html(data.download_config_text)); } // show success box. diff --git a/resources/lang/en_US/import.php b/resources/lang/en_US/import.php index 5cedcebb1f..feb4f58645 100644 --- a/resources/lang/en_US/import.php +++ b/resources/lang/en_US/import.php @@ -131,6 +131,8 @@ return [ 'job_config_bunq_accounts_title' => 'bunq accounts', 'job_config_bunq_accounts_text' => 'These are the accounts associated with your bunq account. Please select the accounts from which you want to import, and in which account the transactions must be imported.', 'bunq_no_mapping' => 'It seems you have not selected any accounts.', + 'should_download_config' => 'You should download the configuration file for this job. This will make future imports way easier.', + 'share_config_file' => 'If you have imported data from a public bank, you should share your configuration file so it will be easy for other users to import their data. Sharing your configuration file will not expose your financial details.', // keys from "extra" array: 'spectre_extra_key_iban' => 'IBAN', diff --git a/resources/views/import/status.twig b/resources/views/import/status.twig index 4cc0744180..900c3a9de1 100644 --- a/resources/views/import/status.twig +++ b/resources/views/import/status.twig @@ -139,6 +139,9 @@

    {{ trans('import.status_finished_text') }} +

    +

    +

      @@ -176,9 +179,9 @@ var jobStorageStartUri = '{{ route('import.job.store', [importJob.key]) }}'; // import is running: - var langImportRunning = '{{ trans('import.status_job_running') }}'; - var langImportStoring = '{{ trans('import.status_job_storing') }}'; - var langImportRules = '{{ trans('import.status_job_rules') }}'; + var langImportRunning = '{{ trans('import.status_job_running')|escape('js') }}'; + var langImportStoring = '{{ trans('import.status_job_storing')|escape('js') }}'; + var langImportRules = '{{ trans('import.status_job_rules')|escape('js') }}'; // some useful translations. {#var langImportTimeOutError = '(time out thing)';#} diff --git a/routes/web.php b/routes/web.php index b42c46a96c..7c98292c2a 100755 --- a/routes/web.php +++ b/routes/web.php @@ -464,6 +464,9 @@ Route::group( Route::any('job/start/{importJob}', ['uses' => 'Import\JobStatusController@start', 'as' => 'job.start']); Route::any('job/store/{importJob}', ['uses' => 'Import\JobStatusController@store', 'as' => 'job.store']); + // download config: + Route::get('download/{importJob}', ['uses' => 'Import\IndexController@download', 'as' => 'job.download']); + // import method prerequisites: # #