From 4c22ab67585443b50c90e349a06b38128af0f32b Mon Sep 17 00:00:00 2001 From: Martin Folkerts Date: Wed, 3 Jan 2024 22:06:03 +0100 Subject: [PATCH] wip --- build_mosaic.sh | 6 +- .../Http/Controllers/DownloadController.php | 13 --- .../app/Jobs/ProjectDownloadTiffJob.php | 65 ++++++++++++++ .../app/Jobs/ProjectMosiacGeneratorJob.php | 20 +++-- .../app/Livewire/Download/DownloadForm.php | 61 ------------- .../app/Livewire/Download/DownloadGrid.php | 22 ----- .../app/Livewire/Projects/DownloadManager.php | 48 +++++++++- .../app/Livewire/Projects/MosaicManager.php | 11 ++- laravel_app/app/Models/Project.php | 49 +++++++++-- laravel_app/app/Models/ProjectDownload.php | 6 ++ laravel_app/app/Models/ProjectMosaic.php | 25 ++++++ .../app/Rules/AllMergedTiffsPresentRule.php | 19 ++-- .../app/Rules/DownloadDateRangeRule.php | 45 ++++++++++ ..._142339_create_project_downloads_table.php | 1 + ...024_01_03_190141_project_mosaics_table.php | 33 +++++++ .../database/seeders/DatabaseSeeder.php | 10 +++ laravel_app/package-lock.json | 6 ++ laravel_app/package.json | 1 + laravel_app/resources/css/app.css | 2 +- laravel_app/resources/js/app.js | 2 + .../download-create-modal.blade.php | 68 ++++++++++++++ .../resources/views/download/show.blade.php | 20 ----- .../livewire/download/download-form.blade.php | 47 ---------- .../livewire/download/download-grid.blade.php | 24 ----- .../projects/download-manager.blade.php | 70 ++++++++++++--- .../projects/mosaic-manager.blade.php | 14 +-- .../projects/report-manager.blade.php | 2 +- .../resources/views/navigation-menu.blade.php | 3 - laravel_app/routes/web.php | 1 - .../Rules/AllMergedTiffsPresentRuleTest.php | 23 +++-- .../Unit/Rules/DownloadDateRangeRuleTest.php | 83 ++++++++++++++++++ python_app/Chemba_download.ipynb | 10 ++- r_app/2_CI_data_prep.R | 13 ++- r_app/Rplots.pdf | Bin 161453 -> 161453 bytes runpython.sh | 26 +++--- 35 files changed, 582 insertions(+), 267 deletions(-) delete mode 100644 laravel_app/app/Http/Controllers/DownloadController.php create mode 100644 laravel_app/app/Jobs/ProjectDownloadTiffJob.php delete mode 100644 laravel_app/app/Livewire/Download/DownloadForm.php delete mode 100644 laravel_app/app/Livewire/Download/DownloadGrid.php create mode 100644 laravel_app/app/Models/ProjectMosaic.php create mode 100644 laravel_app/app/Rules/DownloadDateRangeRule.php create mode 100644 laravel_app/database/migrations/2024_01_03_190141_project_mosaics_table.php create mode 100644 laravel_app/resources/views/components/download-create-modal.blade.php delete mode 100644 laravel_app/resources/views/download/show.blade.php delete mode 100644 laravel_app/resources/views/livewire/download/download-form.blade.php delete mode 100644 laravel_app/resources/views/livewire/download/download-grid.blade.php create mode 100644 laravel_app/tests/Unit/Rules/DownloadDateRangeRuleTest.php diff --git a/build_mosaic.sh b/build_mosaic.sh index 4ec725d..efe24e8 100755 --- a/build_mosaic.sh +++ b/build_mosaic.sh @@ -19,12 +19,12 @@ while [ "$#" -gt 0 ]; do done # Controleer of de vereiste argumenten zijn ingesteld -if [ -z "$filename" ] || [ -z "$weeks_ago" ] || [ -z $report_date ]; then - echo "Missende argumenten. Gebruik: build_reports.sh --filename=hello.txt --weeks_ago=3 --report_date=2020-01-01" +if [ -z "$weeks_ago" ]; then + echo "Missende argumenten. Gebruik: build_mosiac.sh --weeks_ago=3" exit 1 fi echo "Weeks ago: $weeks_ago" cd /Users/mfolkerts/smartCane/r_app -Rscript 2_CI_data_prep.R $weeks_ago \ No newline at end of file +Rscript 2_CI_data_prep.R $weeks_ago diff --git a/laravel_app/app/Http/Controllers/DownloadController.php b/laravel_app/app/Http/Controllers/DownloadController.php deleted file mode 100644 index 774bc5e..0000000 --- a/laravel_app/app/Http/Controllers/DownloadController.php +++ /dev/null @@ -1,13 +0,0 @@ - $project]); - } - // -} diff --git a/laravel_app/app/Jobs/ProjectDownloadTiffJob.php b/laravel_app/app/Jobs/ProjectDownloadTiffJob.php new file mode 100644 index 0000000..9a7d9fb --- /dev/null +++ b/laravel_app/app/Jobs/ProjectDownloadTiffJob.php @@ -0,0 +1,65 @@ +date = $date; + $this->download = $download; + } + + /** + * Execute the job. + */ + public function handle(): void + { + $projectFolder = base_path('../'); + + $command = [ + sprintf('%srunpython.sh', $projectFolder), + sprintf('--date=%s', $this->date->format('Y-m-d')), + sprintf('--days=%d', $this->days), + ]; + + // Convert commands array to a single string + + $process = new Process($command); + $process->setTimeout(3600); // stel een geschikte timeout in + $process->start(); + + try { + $process->wait(function ($type, $buffer) use (&$myOutput){ + logger($buffer); + }); + } catch (ProcessFailedException $exception) { + logger('error', $exception->getMessage()); + } + + $this->download->update([ + 'status' => 'completed', + ]); + } +} diff --git a/laravel_app/app/Jobs/ProjectMosiacGeneratorJob.php b/laravel_app/app/Jobs/ProjectMosiacGeneratorJob.php index f13ce40..49474e8 100644 --- a/laravel_app/app/Jobs/ProjectMosiacGeneratorJob.php +++ b/laravel_app/app/Jobs/ProjectMosiacGeneratorJob.php @@ -3,6 +3,8 @@ namespace App\Jobs; use App\Models\Project; +use App\Models\ProjectDownload; +use App\Models\ProjectMosaic; use App\Models\ProjectReport; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; @@ -16,18 +18,16 @@ class ProjectMosiacGeneratorJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + public ProjectMosaic $mosaic; + + protected $timeout = 120; - public $year; - public $week; - public Project $project; /** * Create a new job instance. */ - public function __construct(Project $project, $year, $week) + public function __construct(ProjectMosaic $mosaic) { - $this->year = $year; - $this->week = $week; - // + $this->mosaic = $mosaic; } /** @@ -35,7 +35,7 @@ public function __construct(Project $project, $year, $week) */ public function handle(): void { - $weeksAgo = ProjectReport::weeksAgoForYearAndWeek($this->year, $this->week); + $weeksAgo = ProjectReport::weeksAgoForYearAndWeek($this->mosaic->year, $this->mosaic->week); $projectFolder = base_path('../'); @@ -63,7 +63,9 @@ public function handle(): void } catch (ProcessFailedException $exception) { echo $exception->getMessage(); - } + $this->mosaic->update([ + 'status' => 'complete', + ]); } } diff --git a/laravel_app/app/Livewire/Download/DownloadForm.php b/laravel_app/app/Livewire/Download/DownloadForm.php deleted file mode 100644 index e38ac62..0000000 --- a/laravel_app/app/Livewire/Download/DownloadForm.php +++ /dev/null @@ -1,61 +0,0 @@ -buttonText = __('Start'); - } - - public function start() - { - $this->buttonText = __('Downloading...'); - - // Commands to run - $projectFolder = base_path('../'); - - $command = [ - sprintf('%srunpython.sh', $projectFolder), - sprintf('--days=%d', $this->days), - ]; - - // Convert commands array to a single string - - $process = new Process($command); - $process->setTimeout(3600); // stel een geschikte timeout in - $process->start(); - - try { - $myOutput = []; - $process->wait(function ($type, $buffer) use (&$myOutput){ - $this->stream(to: 'output', content: $buffer); - $myOutput[] = $buffer; - }); - $this->output = collect($myOutput)->join('
'); - - } catch (ProcessFailedException $exception) { - - logger('error', $exception->getMessage()); - echo $exception->getMessage(); - } - $this->buttonText = __('Done'); - } - - - - - public function render() - { - return view('livewire.download.download-form'); - } -} diff --git a/laravel_app/app/Livewire/Download/DownloadGrid.php b/laravel_app/app/Livewire/Download/DownloadGrid.php deleted file mode 100644 index c625446..0000000 --- a/laravel_app/app/Livewire/Download/DownloadGrid.php +++ /dev/null @@ -1,22 +0,0 @@ -files = $project->getMosaicList(); -// dd($this->directories); - } - - public function render() - { - return view('livewire.download.download-grid')->with(['files' => $this->files]); - } -} diff --git a/laravel_app/app/Livewire/Projects/DownloadManager.php b/laravel_app/app/Livewire/Projects/DownloadManager.php index c47bb8f..bc067e6 100644 --- a/laravel_app/app/Livewire/Projects/DownloadManager.php +++ b/laravel_app/app/Livewire/Projects/DownloadManager.php @@ -3,15 +3,61 @@ namespace App\Livewire\Projects; use App\Models\Project; +use App\Rules\DownloadDateRangeRule; +use Carbon\Carbon; +use Carbon\CarbonPeriod; use Livewire\Component; +use Symfony\Component\Process\Process; class DownloadManager extends Component { public $project; - public function mount(Project $project) { + public $formData; + + + public $showDownloadModal = false; + + public function mount(Project $project) + { $this->path = $project->download_path; + $this->formData = [ + 'dateRange' => sprintf('%s to %s', + now()->subDays(6)->format('Y/m/d'), + now()->format('Y/m/d') + ) + ]; } + public function openDownloadModal() + { + $this->showDownloadModal = true; + } + + public function saveDownloads() + { + $this->validate([ + 'formData.dateRange' => [ + 'required', + new DownloadDateRangeRule(), + ] + ]); + + $dateRange = explode(' to ', $this->formData['dateRange']); + + $period = CarbonPeriod::create( + Carbon::parse($dateRange[0]), + Carbon::parse($dateRange[1]) + ); + + collect($period)->each(function ($date) { + $this->project->startDownload($date); + }); + + + $this->showDownloadModal = false; + } + + public function render() { return view('livewire.projects.download-manager', [ diff --git a/laravel_app/app/Livewire/Projects/MosaicManager.php b/laravel_app/app/Livewire/Projects/MosaicManager.php index e784de8..cda3692 100644 --- a/laravel_app/app/Livewire/Projects/MosaicManager.php +++ b/laravel_app/app/Livewire/Projects/MosaicManager.php @@ -33,7 +33,16 @@ public function saveMosiac(){ 'formData.week' => 'required', ]); - ProjectMosiacGeneratorJob::dispatch($this->project, $this->formData['year'], $this->formData['week']); + $mosaic = $this->project->mosaics()->updateOrCreate([ + 'name' => sprintf('Week %s, %s', $this->formData['week'], $this->formData['year']), + 'year' => $this->formData['year'], + 'week' => $this->formData['week'], + ],[ + 'status' => 'pending', + 'path' => $this->project->getMosaicPath(), + ]); + + ProjectMosiacGeneratorJob::dispatch($mosaic); $this->showCreateModal = false; } diff --git a/laravel_app/app/Models/Project.php b/laravel_app/app/Models/Project.php index 30478d2..e968ed6 100644 --- a/laravel_app/app/Models/Project.php +++ b/laravel_app/app/Models/Project.php @@ -2,9 +2,10 @@ namespace App\Models; +use App\Jobs\ProjectDownloadTiffJob; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -use Illuminate\Support\Carbon; +use Carbon\Carbon; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; @@ -69,7 +70,7 @@ private function upsertMailRecipients($formData) ); } - private function getMosaicPath() + public function getMosaicPath() { return sprintf('%s/%s', $this->download_path, 'weekly_mosaic'); } @@ -129,12 +130,18 @@ public function mailings() return $this->hasMany(ProjectMailing::class); } - public function downloads() + public function downloads(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(ProjectDownload::class); } - public function allMosaicsPresent(Carbon $endDate) + public function mosaics() : \Illuminate\Database\Eloquent\Relations\HasMany + { + return $this->hasMany(ProjectMosaic::class); + } + + + public function allMosaicsPresent(Carbon $endDate): bool { // end date is in the future if ($endDate->isFuture()) { @@ -220,6 +227,38 @@ public function allMergedTiffsPresent(Collection $haystack, Collection $needles) public function getMergedTiffList() { - return collect([]);; + return collect(Storage::files($this->download_path.'/merged_final_tif')) + ->filter(fn($file) => Str::endsWith($file, '.tif')) + ->sortByDesc(function ($file) { + $parts = explode('_', str_replace('.tif', '', $file)); + $date = $parts[1]; + return $date; + }) + ->values(); + } + + public function hasPendingDownload() : bool + { + return $this->downloads()->where('status', 'pending')->count() > 0; + } + + public function hasPendingMosaic() : bool + { + return $this->mosaics()->where('status', 'pending')->count() > 0; + } + + public function startDownload(Carbon $date) + { + $downloadRequest = $this->downloads()->updateOrCreate( + [ + 'project_id' => $this->id, // of een andere manier om project_id te bepalen + 'name' => sprintf('%s.tif', $date->format('Y-m-d')), + ], + [ + 'path' => sprintf('%s/%s/%s.tif', $this->download_path, 'merged_final_tif', $date->format('Y-m-d')), + 'status' => 'pending', + ] + ); + ProjectDownloadTiffJob::dispatch($downloadRequest, $date); } } diff --git a/laravel_app/app/Models/ProjectDownload.php b/laravel_app/app/Models/ProjectDownload.php index e7c39f4..acee947 100644 --- a/laravel_app/app/Models/ProjectDownload.php +++ b/laravel_app/app/Models/ProjectDownload.php @@ -8,4 +8,10 @@ class ProjectDownload extends Model { use HasFactory; + + protected $fillable = [ + 'name', + 'path', + 'status', + ]; } diff --git a/laravel_app/app/Models/ProjectMosaic.php b/laravel_app/app/Models/ProjectMosaic.php new file mode 100644 index 0000000..d2cc1b8 --- /dev/null +++ b/laravel_app/app/Models/ProjectMosaic.php @@ -0,0 +1,25 @@ +belongsTo(Project::class); + } + +} diff --git a/laravel_app/app/Rules/AllMergedTiffsPresentRule.php b/laravel_app/app/Rules/AllMergedTiffsPresentRule.php index c81c437..5ba0554 100644 --- a/laravel_app/app/Rules/AllMergedTiffsPresentRule.php +++ b/laravel_app/app/Rules/AllMergedTiffsPresentRule.php @@ -2,35 +2,30 @@ namespace App\Rules; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use App\Models\Project; use App\Models\ProjectReport; -class AllMergedTiffsPresentRule implements Rule +class AllMergedTiffsPresentRule implements ValidationRule { - protected $project; - protected $errorMessage = ''; + protected Project $project; public function __construct(Project $project) { $this->project = $project; } - public function passes($attribute, $value) + public function validate(string $attribute, mixed $value, Closure $fail): void { try { - return $this->project->allMergedTiffsPresent( + $this->project->allMergedTiffsPresent( $this->project->getMergedTiffList(), Project::getAllDatesOfWeeksInYear($value['year'], $value['week']) ); } catch (\Exception $e) { - $this->errorMessage = $e->getMessage(); - return false; + $fail($e->getMessage()); } } - public function message() - { - return $this->errorMessage; - } } diff --git a/laravel_app/app/Rules/DownloadDateRangeRule.php b/laravel_app/app/Rules/DownloadDateRangeRule.php new file mode 100644 index 0000000..0c3c554 --- /dev/null +++ b/laravel_app/app/Rules/DownloadDateRangeRule.php @@ -0,0 +1,45 @@ +validateDateString($value)) { + $fail('Date range must be in the format YYYY/MM/DD to YYYY/MM/DD.'); + return; + } + + if (!$this->startDate->isPast() || !$this->endDate->isPast()) { + $fail('Date range cannot be in the future.'); + return; + } + + if ($this->startDate->greaterThan($this->endDate)) { + $fail('Start date must be before end date.'); + } + } + + function validateDateString($dateString): bool + { + $regex = '/^(\d{4}\/\d{2}\/\d{2}) to (\d{4}\/\d{2}\/\d{2})$/'; + if (preg_match($regex, $dateString, $matches)) { + $this->startDate = Carbon::parse($matches[1]); + $this->endDate = Carbon::parse($matches[2]); + return true; + } + return false; + } + + +} diff --git a/laravel_app/database/migrations/2023_11_21_142339_create_project_downloads_table.php b/laravel_app/database/migrations/2023_11_21_142339_create_project_downloads_table.php index 0735dd9..315260f 100644 --- a/laravel_app/database/migrations/2023_11_21_142339_create_project_downloads_table.php +++ b/laravel_app/database/migrations/2023_11_21_142339_create_project_downloads_table.php @@ -16,6 +16,7 @@ public function up(): void $table->foreignId('project_id'); $table->string('name'); $table->string('path'); + $table->string('status')->default('pending'); $table->timestamps(); }); } diff --git a/laravel_app/database/migrations/2024_01_03_190141_project_mosaics_table.php b/laravel_app/database/migrations/2024_01_03_190141_project_mosaics_table.php new file mode 100644 index 0000000..8852bc6 --- /dev/null +++ b/laravel_app/database/migrations/2024_01_03_190141_project_mosaics_table.php @@ -0,0 +1,33 @@ +id(); + $table->foreignId('project_id'); + $table->string('week'); + $table->string('name'); + $table->string('year'); + $table->string('path'); + $table->string('status')->default('pending'); + $table->timestamps(); + }); // + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('project_mosaics'); + } +}; diff --git a/laravel_app/database/seeders/DatabaseSeeder.php b/laravel_app/database/seeders/DatabaseSeeder.php index edb27e0..96b88b0 100644 --- a/laravel_app/database/seeders/DatabaseSeeder.php +++ b/laravel_app/database/seeders/DatabaseSeeder.php @@ -61,6 +61,16 @@ private function createChembaProject() ], ]); + foreach($chembaProject->getMergedTiffList() as $mergedTiff) { + $chembaProject->downloads()->create([ + 'name' => basename($mergedTiff), + 'path' => $mergedTiff, + 'status' => 'completed', + 'created_at' => '2021-01-01 00:00:00', + 'updated_at' => '2021-01-01 00:00:00' + ]); + } + $chembaProject->emailRecipients()->createMany([ [ 'name' => 'Martin Folkerts', diff --git a/laravel_app/package-lock.json b/laravel_app/package-lock.json index b9a5dbb..e0902fb 100644 --- a/laravel_app/package-lock.json +++ b/laravel_app/package-lock.json @@ -12,6 +12,7 @@ "@ryangjchandler/alpine-clipboard": "^2.3.0", "@tailwindcss/aspect-ratio": "^0.4.2", "alpinejs": "^3.13.3", + "flatpickr": "^4.6.13", "tailwindcss": "^3.3.3" }, "devDependencies": { @@ -919,6 +920,11 @@ "node": ">=8" } }, + "node_modules/flatpickr": { + "version": "4.6.13", + "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz", + "integrity": "sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==" + }, "node_modules/focus-trap": { "version": "6.9.4", "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-6.9.4.tgz", diff --git a/laravel_app/package.json b/laravel_app/package.json index 4c11eae..127599c 100644 --- a/laravel_app/package.json +++ b/laravel_app/package.json @@ -23,6 +23,7 @@ "@ryangjchandler/alpine-clipboard": "^2.3.0", "@tailwindcss/aspect-ratio": "^0.4.2", "alpinejs": "^3.13.3", + "flatpickr": "^4.6.13", "tailwindcss": "^3.3.3" } } diff --git a/laravel_app/resources/css/app.css b/laravel_app/resources/css/app.css index 34ca985..9c1d151 100644 --- a/laravel_app/resources/css/app.css +++ b/laravel_app/resources/css/app.css @@ -1,9 +1,9 @@ +@import 'flatpickr/dist/flatpickr.css'; @import url('https://rsms.me/inter/inter.css'); @tailwind base; @tailwind components; @tailwind utilities; - [x-cloak] { display: none; } diff --git a/laravel_app/resources/js/app.js b/laravel_app/resources/js/app.js index 861ee70..a111dc0 100644 --- a/laravel_app/resources/js/app.js +++ b/laravel_app/resources/js/app.js @@ -1,2 +1,4 @@ import './bootstrap'; import('./alpine'); +import flatpckr from 'flatpickr'; +window.flatpckr = flatpckr; diff --git a/laravel_app/resources/views/components/download-create-modal.blade.php b/laravel_app/resources/views/components/download-create-modal.blade.php new file mode 100644 index 0000000..271b154 --- /dev/null +++ b/laravel_app/resources/views/components/download-create-modal.blade.php @@ -0,0 +1,68 @@ +@props([ + 'formData', + /** @var \App\Livewire\Projects\MosaicManager */ + 'manager' +]) + + + + + {{ __('Downloads') }} + + + + {{ __('Download for project') }} + + + + +
+
+
Date Range:
+ + +
+ + +
+
+ +
+
+ + + + {{ __('Saved.') }} + + + + {{ __('Cancel') }} + + + {{ __('Save') }} + + + +
+
diff --git a/laravel_app/resources/views/download/show.blade.php b/laravel_app/resources/views/download/show.blade.php deleted file mode 100644 index 04b8d4f..0000000 --- a/laravel_app/resources/views/download/show.blade.php +++ /dev/null @@ -1,20 +0,0 @@ - - -

- {{ __('Download') }} -

-
- -
-
-
- -
- - -
- @livewire('download.download-form') -
-
-
-
diff --git a/laravel_app/resources/views/livewire/download/download-form.blade.php b/laravel_app/resources/views/livewire/download/download-form.blade.php deleted file mode 100644 index 404db60..0000000 --- a/laravel_app/resources/views/livewire/download/download-form.blade.php +++ /dev/null @@ -1,47 +0,0 @@ - - - {{ __('Satellite data') }} - - - - {{ __('Add additional satellite data to your account.') }} - - - -

- {{ __('Download satellite data') }} - -

-
-

- {{ __('Vul een aantal dagen in en druk op start om de betreffende sateliet data te downloaden') }} - -

-
-
-

- {{ __('') }} -

-
- @if ($this->output) -
{{ $output }} -
- @endif -
- - {{ $buttonText }} - -
-
-
- - - - - diff --git a/laravel_app/resources/views/livewire/download/download-grid.blade.php b/laravel_app/resources/views/livewire/download/download-grid.blade.php deleted file mode 100644 index 18e4056..0000000 --- a/laravel_app/resources/views/livewire/download/download-grid.blade.php +++ /dev/null @@ -1,24 +0,0 @@ -
- - - {{ __('Available Satellite data') }} - - - - {{ __('The grid has a date for every date the data has already been downloaded.') }} - - - - -
- @foreach ($files as $file) -
-
- {{ $file }} -
-
- @endforeach -
-
-
-
diff --git a/laravel_app/resources/views/livewire/projects/download-manager.blade.php b/laravel_app/resources/views/livewire/projects/download-manager.blade.php index dae8557..20e534f 100644 --- a/laravel_app/resources/views/livewire/projects/download-manager.blade.php +++ b/laravel_app/resources/views/livewire/projects/download-manager.blade.php @@ -1,16 +1,60 @@ - - Download details - Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsa, reprehenderit. - -
-
- +
hasPendingDownload()) + wire:poll.1s="" + @endif + > +
+
+
+

Downloads

+

+ @if ($project->hasPendingDownload()) + Pending downloads for this project: {{ $project->downloads()->where('status', 'pending')->count() }} + @endif +

- - -
- @livewire('download.download-form') +
+ + {{ __('Create Download') }} +
- - +
+
+
+ + + + + + + + + + @foreach($project->downloads()->orderBy('name', 'desc')->get() as $download) + + + + + + @endforeach + +
+ Name + + Status + + Edit +
{{ $download->name }} + {{ $download->path }} + + +
+
+
+
+
+ +
diff --git a/laravel_app/resources/views/livewire/projects/mosaic-manager.blade.php b/laravel_app/resources/views/livewire/projects/mosaic-manager.blade.php index 6c14faa..292ec99 100644 --- a/laravel_app/resources/views/livewire/projects/mosaic-manager.blade.php +++ b/laravel_app/resources/views/livewire/projects/mosaic-manager.blade.php @@ -1,8 +1,12 @@ -
+
hasPendingMosaic()) + wire:poll.1s="" + @endif +>
-

Reports

+

Mosaics

@@ -31,14 +35,14 @@ class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg - @foreach($project->getMosaicList() as $mosaic) + @foreach($project->mosaics()->orderBy('year','desc')->orderBy('week', 'desc')->get() as $mosaic) {{ $project->name }} - {{ $mosaic }} + {{ $mosaic->name }}-{{ $mosaic->week}} - + @endforeach diff --git a/laravel_app/resources/views/livewire/projects/report-manager.blade.php b/laravel_app/resources/views/livewire/projects/report-manager.blade.php index 6cc00fb..97dae9b 100644 --- a/laravel_app/resources/views/livewire/projects/report-manager.blade.php +++ b/laravel_app/resources/views/livewire/projects/report-manager.blade.php @@ -37,7 +37,7 @@ class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg - @foreach($project->reports()->orderBy('created_at', 'desc')->get() as $report) + @foreach($project->reports()->orderBy('year', 'desc')->orderBy('week', 'desc')->get() as $report) @endforeach diff --git a/laravel_app/resources/views/navigation-menu.blade.php b/laravel_app/resources/views/navigation-menu.blade.php index c1b41cc..f862f60 100644 --- a/laravel_app/resources/views/navigation-menu.blade.php +++ b/laravel_app/resources/views/navigation-menu.blade.php @@ -15,9 +15,6 @@ {{ __('Dashboard') }} - - {{ __('Download') }} - {{ __('Report') }} diff --git a/laravel_app/routes/web.php b/laravel_app/routes/web.php index 2ad39e2..fcfd010 100644 --- a/laravel_app/routes/web.php +++ b/laravel_app/routes/web.php @@ -29,7 +29,6 @@ Route::get('/dashboard', function () { return view('dashboard'); })->name('dashboard'); - Route::get('/download', [\App\Http\Controllers\DownloadController::class, 'show'])->name('download'); Route::get('/report', [\App\Http\Controllers\ReportController::class, 'index'])->name('report'); Route::get('/projects/{project}', [\App\Http\Controllers\ProjectController::class, 'show'])->name('project.show'); Route::get('/projects/{projectReport}/download', [\App\Http\Controllers\ProjectReportController::class, 'download'])->name('project.report.download'); diff --git a/laravel_app/tests/Unit/Rules/AllMergedTiffsPresentRuleTest.php b/laravel_app/tests/Unit/Rules/AllMergedTiffsPresentRuleTest.php index d2bdf0a..15b125e 100644 --- a/laravel_app/tests/Unit/Rules/AllMergedTiffsPresentRuleTest.php +++ b/laravel_app/tests/Unit/Rules/AllMergedTiffsPresentRuleTest.php @@ -7,6 +7,7 @@ use App\Rules\AllMergedTiffsPresentRule; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Validator; use Mockery; use Tests\TestCase; @@ -48,10 +49,12 @@ public function validatesCorrectValue() $rule = new AllMergedTiffsPresentRule($projectMock); - $this->assertTrue($rule->passes( - 'attribute', - ['year' => '2021', 'week' => '1'] - )); + $val = Validator::make( + ['attribute' => ['year' => '2021', 'week' => '1']], + ['attribute' => $rule] + ); + + $this->assertTrue($val->passes()); } public function testInvalidatesIncorrectValue() @@ -81,13 +84,15 @@ public function testInvalidatesIncorrectValue() $rule = new AllMergedTiffsPresentRule($projectMock); - $this->assertFalse($rule->passes( - 'attribute', - ['year' => '2021', 'week' => '1'] - )); + $val = Validator::make( + ['attribute' => ['year' => '2021', 'week' => '1']], + ['attribute' => $rule] + ); + + $this->assertFalse($val->passes()); $this->assertEquals( 'Missing merged tiffs: 2021-01-04', - $rule->message() + $val->errors()->first() ); } diff --git a/laravel_app/tests/Unit/Rules/DownloadDateRangeRuleTest.php b/laravel_app/tests/Unit/Rules/DownloadDateRangeRuleTest.php new file mode 100644 index 0000000..66e8f9b --- /dev/null +++ b/laravel_app/tests/Unit/Rules/DownloadDateRangeRuleTest.php @@ -0,0 +1,83 @@ + '2023/12/26 to 2024/01/02'], + ['dateRange' => new DownloadDateRangeRule()] + ); + $this->assertTrue($val->passes()); + + $this->assertEmpty( + $val->errors() + ); + } + + public function testInvalidatesIncorrectValue() + { + Carbon::setTestNow(Carbon::create(2021, 1, 1)); + + $val = Validator::make( + ['dateRange' => '2023/12/26 to 2024/01/02'], + ['dateRange' => new DownloadDateRangeRule()] + ); + $this->assertFalse($val->passes()); + + $this->assertEquals( + 'Date range cannot be in the future.', + $val->errors()->first() + ); + } + + public function testInvalidFormat() + { + $val = Validator::make( + ['dateRange' => '2023/12/26 tot 2024/01/02'], + ['dateRange' => new DownloadDateRangeRule()] + ); + $this->assertFalse($val->passes()); + + $this->assertEquals( + 'Date range must be in the format YYYY/MM/DD to YYYY/MM/DD.', + $val->errors()->first() + ); + } + + public function testEndDateBeforeStartDate() + { + $val = Validator::make( + ['dateRange' => '2024/01/02 to 2023/12/26'], + ['dateRange' => new DownloadDateRangeRule()] + ); + $this->assertFalse($val->passes()); + + $this->assertEquals( + 'Start date must be before end date.', + $val->errors()->first() + ); + } +} diff --git a/python_app/Chemba_download.ipynb b/python_app/Chemba_download.ipynb index 4490d36..3900ec2 100644 --- a/python_app/Chemba_download.ipynb +++ b/python_app/Chemba_download.ipynb @@ -333,8 +333,16 @@ "\n", "days_needed = int(os.environ.get(\"DAYS\", 28))\n", " # Adjust the number of days needed\n", + " \n", + "date_str = os.environ.get(\"DATE\")\n", + "if date_str:\n", + " # Parse de datumstring naar een datetime.date object\n", + " end = datetime.datetime.strptime(date_str, \"%Y-%m-%d\").date()\n", + "else:\n", + " # Gebruik de huidige datum als fallback\n", + " end = datetime.date.today() \n", + "\n", "\n", - "end = datetime.date.today()\n", "#end = datetime.datetime(2023, 11, 10)\n", "#start = datetime.datetime(2023, 10, 19)\n", "start = end - datetime.timedelta(days=days_needed - 1)\n", diff --git a/r_app/2_CI_data_prep.R b/r_app/2_CI_data_prep.R index 2a3c6be..b9259c0 100644 --- a/r_app/2_CI_data_prep.R +++ b/r_app/2_CI_data_prep.R @@ -37,7 +37,7 @@ extracted_CI_dir <- here(data_dir, "extracted_ci") daily_CI_vals_dir <- here(extracted_CI_dir, "daily_vals") cumulative_CI_vals_dir <- here(extracted_CI_dir, "cumulative_vals") -weekly_CI_mosaic <- here(data_dir, "weekly_mosaic") +weekly_CI_mosaic <- here(laravel_storage_dir, "chemba/weekly_mosaic") daily_vrt <- here(data_dir, "vrt") harvest_dir <- here(data_dir, "HarvestData") @@ -53,16 +53,18 @@ dir.create(merged_final) # Creating weekly mosaic dates <- date_list(weeks_ago) -head(dates) -print(planet_tif_folder) #load pivot geojson pivot_sf_q <- st_read(here( "pivot_20210625.geojson")) %>% dplyr::select(pivot, pivot_quadrant) %>% vect() +raster_files <- list.files(planet_tif_folder,full.names = T, pattern = ".tif") +head(raster_files) + filtered_files <- map(dates$days_filter, ~ raster_files[grepl(pattern = .x, x = raster_files)]) %>% compact() %>% flatten_chr() + #rasters_masked <- map(filtered_files, mask_raster, fields = pivot_sf_q) %>% set_names(filtered_files) @@ -79,7 +81,9 @@ message("starting ", file) CI <- rast(file) # names(CI) <- c("green","nir") message("raster loaded") -print(CI) + + + CI <- CI[[2]]/CI[[1]]-1 # CI <- CI$nir/CI$green-1 message("CI calculated") @@ -228,6 +232,7 @@ plot(x$CI, main = paste("CI map", dates$week)) # writeRaster(x, here(weekly_CI_mosaic ,paste0("week_", dates$week, "_", dates$year, ".tif")), overwrite=TRUE) writeRaster(x, here(weekly_CI_mosaic ,paste0("week_", dates$week, "_", dates$year, ".tif")), overwrite=TRUE) message("raster written/ made") +message( here(weekly_CI_mosaic ,paste0("week_", dates$week, "_", dates$year, ".tif"))) # Extracting CI diff --git a/r_app/Rplots.pdf b/r_app/Rplots.pdf index b804666089b7d77737b69a2d6c32da295a68eae9..e65a449852e88f2e8dd40db7bb2da67294b728fa 100644 GIT binary patch delta 57 zcmZ4cmUHb}&Iu-JCI*HE#zsa4Mn*=OT>8HGDK3d6sR|k{RzM+yTw_#g6yw$?rr8HGDK3d6sR|k{Rz?O!2)V|n)+olUQB1*Q E0PuSdIsgCw diff --git a/runpython.sh b/runpython.sh index 2654b48..0a0a832 100755 --- a/runpython.sh +++ b/runpython.sh @@ -1,24 +1,27 @@ #!/bin/bash - +date=$(date +%Y-%m-%d) # Standaardwaarde voor days -days=7 +days=1 # Loop door alle argumenten -for arg in "$@" -do - case $arg in +while [ "$#" -gt 0 ]; do + case "$1" in --days=*) - days="${arg#*=}" - shift # Verwijder --days=5 van $@ - ;; + days="${1#*=}" + ;; + --date=*) + date="${1#*=}" + ;; *) - # Andere argumenten die je wilt verwerken - shift - ;; + echo "Onbekende optie: $1" + exit 1 + ;; esac + shift done # Gebruik de variabele in je script +echo "Datum: $date" echo "Aantal dagen: $days" # Activeer de virtuele omgeving @@ -26,6 +29,7 @@ script_dir="$(dirname "$0")" source "$script_dir/python_app/myenv/bin/activate" export DAYS=$days +export DATE=$date # Hier kan je verdere stappen toevoegen, zoals het uitvoeren van je Python-script of Jupyter Notebook jupyter nbconvert --execute --to script --stdout "$script_dir/python_app/Chemba_download.ipynb"