Skip to content

Commit 8c404f7

Browse files
authored
Merge pull request #4 from codestudiohq/2.0
Merging in upstream master
2 parents 96f13ab + a437c9e commit 8c404f7

File tree

6 files changed

+158
-12
lines changed

6 files changed

+158
-12
lines changed

resources/views/tasks/index.blade.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,21 @@
7171
@stop
7272
@section('main-panel-footer')
7373
<a class="uk-button uk-button-primary uk-button-small" href="{{route('totem.task.create')}}">New Task</a>
74+
<a class="uk-button uk-button-primary uk-button-small uk-float-right" href="{{route('totem.task.export')}}">Export</a>
7475
{{$tasks->links('totem::partials.pagination')}}
76+
@stop
77+
@section('main-panel-after')
78+
<div class="uk-card uk-card-default">
79+
<div class="uk-card-footer">
80+
@if($errors->any())
81+
<div class="uk-text-danger">
82+
{{$errors->first()}}
83+
</div>
84+
@endif
85+
{!! Form::open(['route' => 'totem.task.import', 'enctype' => 'multipart/form-data']) !!}
86+
{!! Form::file('tasks') !!}
87+
{!! Form::submit('Upload', ['class' => 'uk-button uk-button-primary uk-button-small uk-float-right']) !!}
88+
{!! Form::close() !!}
89+
</div>
90+
</div>
7591
@stop

routes/web.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
Route::get('create', 'TasksController@create')->name('totem.task.create');
1616
Route::post('create', 'TasksController@store');
1717

18+
Route::get('export', 'TasksController@export')->name('totem.task.export');
19+
20+
Route::get('import', 'TasksController@import')->name('totem.task.import');
21+
1822
Route::get('{task}', 'TasksController@view')->name('totem.task.view');
1923

2024
Route::get('{task}/edit', 'TasksController@edit')->name('totem.task.edit');

src/Http/Controllers/TasksController.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Studio\Totem\Task;
66
use Studio\Totem\Totem;
7+
use Studio\Totem\Frequency;
78
use Studio\Totem\Contracts\TaskInterface;
89
use Studio\Totem\Http\Requests\TaskRequest;
910

@@ -127,4 +128,72 @@ public function destroy($task)
127128
->route('totem.tasks.all')
128129
->with('success', trans('totem::messages.success.delete'));
129130
}
131+
132+
/**
133+
* JSON representation of tasks and their frequencies.
134+
*
135+
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
136+
*/
137+
public function export()
138+
{
139+
return response($this->tasks->findAll()->toJson(), 200, [
140+
'Content-Type' => 'application/json',
141+
'Content-Disposition' => 'attachment; filename="totem_tasks.json"',
142+
]);
143+
}
144+
145+
/**
146+
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
147+
*/
148+
public function import()
149+
{
150+
$errors = [];
151+
$records_imported = 0;
152+
if (request()->hasFile('tasks')) {
153+
$file = request()->file('tasks');
154+
if (ends_with($file->getClientOriginalName(), '.json')) {
155+
try {
156+
$data = json_decode(file_get_contents($file->getPathname()));
157+
foreach ($data as $record) {
158+
$task = Task::updateOrCreate([
159+
'id' => $record->id,
160+
], [
161+
'description' => $record->description,
162+
'command' => $record->command,
163+
'parameters' => $record->parameters,
164+
'expression' => $record->expression,
165+
'timezone' => $record->timezone,
166+
'is_active' => $record->is_active,
167+
'dont_overlap' => $record->dont_overlap,
168+
'run_in_maintenance' => $record->run_in_maintenance,
169+
'notification_email_address' => $record->notification_email_address,
170+
'notification_phone_number' => $record->notification_phone_number,
171+
'notification_slack_webhook' => $record->notification_slack_webhook,
172+
]);
173+
174+
if (! empty($record->frequencies)) {
175+
foreach ($record->frequencies as $freq) {
176+
Frequency::updateOrCreate([
177+
'id' => $freq->id,
178+
], [
179+
'task_id' => $task->id,
180+
'label' => $freq->label,
181+
'interval' => $freq->interval,
182+
]);
183+
}
184+
}
185+
$records_imported++;
186+
}
187+
} catch (\Exception $ex) {
188+
$errors[] = 'An error occurred while importing data.';
189+
}
190+
}
191+
}
192+
193+
if ($records_imported == 0) {
194+
$errors[] = 'Invalid data or no record selected.';
195+
}
196+
197+
return redirect(route('totem.tasks.all'))->withErrors($errors);
198+
}
130199
}

src/Providers/TotemServiceProvider.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Studio\Totem\Providers;
44

55
use Cron\CronExpression;
6+
use Illuminate\Support\Facades\Log;
67
use Illuminate\Support\Facades\Schema;
78
use Illuminate\Support\ServiceProvider;
89
use Illuminate\Support\Facades\Validator;
@@ -49,8 +50,13 @@ public function register()
4950
$this->app->register(TotemRouteServiceProvider::class);
5051
$this->app->register(TotemEventServiceProvider::class);
5152

52-
if (Schema::hasTable('tasks')) {
53-
$this->app->register(ConsoleServiceProvider::class);
53+
try {
54+
if (Schema::hasTable('tasks')) {
55+
$this->app->register(ConsoleServiceProvider::class);
56+
}
57+
} catch (\PDOException $ex) {
58+
// This will trigger if DB cannot be connected to
59+
Log::error($ex->getMessage());
5460
}
5561

5662
$this->mergeConfigFrom(

src/Task.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ public function compileParameters($console = false)
7171
$regex = '/(?=\S)[^\'"\s]*(?:\'[^\']*\'[^\'"\s]*|"[^"]*"[^\'"\s]*)*/';
7272
preg_match_all($regex, $this->parameters, $matches, PREG_SET_ORDER, 0);
7373

74-
$parameters = collect($matches)->mapWithKeys(function ($parameter) use ($console) {
74+
$argument_index = 0;
75+
$parameters = collect($matches)->mapWithKeys(function ($parameter) use ($console, &$argument_index) {
7576
$param = explode('=', $parameter[0]);
7677

77-
return count($param) > 1 ?
78-
($console ? ((starts_with($param[0], '--') ? [$param[0] => $param[1]] : [$param[1]])) : [$param[0] => $param[1]])
79-
: (starts_with($param[0], '--') && ! $console ? [$param[0] => true] : $param);
78+
return count($param) > 1 ? [$param[0] => $param[1]]
79+
: (starts_with($param[0], '--') && ! $console ? [$param[0] => true] : [$argument_index++ => $param[0]]);
8080
})->toArray();
8181

8282
return $parameters;

tests/Feature/CompileParametersTest.php

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,15 @@
77

88
class CompileParametersTest extends TestCase
99
{
10-
/** @test */
11-
public function no_paramters()
10+
public function test_no_paramters()
1211
{
1312
$task = factory(Task::class)->create();
1413
$parameters = $task->compileParameters();
1514

1615
$this->assertEmpty($parameters);
1716
}
1817

19-
/** @test */
20-
public function multiple_paramters()
18+
public function test_multiple_paramters()
2119
{
2220
$task = factory(Task::class)->create();
2321
$task->parameters = '--parameter-1=value --parameter-2=value --parameter-3=value';
@@ -29,7 +27,7 @@ public function multiple_paramters()
2927
$this->assertEquals('value', $parameters['--parameter-3']);
3028
}
3129

32-
public function flag_and_paramter()
30+
public function test_flag_and_paramter()
3331
{
3432
$task = factory(Task::class)->create();
3533
$task->parameters = '--parameter-1=value --dry-run';
@@ -41,7 +39,7 @@ public function flag_and_paramter()
4139
$this->assertEquals('value', $parameters['--parameter-1']);
4240
}
4341

44-
public function multiple_flags()
42+
public function test_multiple_flags()
4543
{
4644
$task = factory(Task::class)->create();
4745
$task->parameters = '--dry-run --debug --log-output';
@@ -55,4 +53,57 @@ public function multiple_flags()
5553
$this->assertTrue($parameters['--debug']);
5654
$this->assertTrue($parameters['--log-output']);
5755
}
56+
57+
public function test_multiple_arguments()
58+
{
59+
$task = factory(Task::class)->create();
60+
$task->parameters = 'arg1 arg2 arg3';
61+
$parameters = $task->compileParameters();
62+
63+
$this->assertCount(3, $parameters);
64+
$this->assertSame('arg1', $parameters[0]);
65+
$this->assertSame('arg2', $parameters[1]);
66+
$this->assertSame('arg3', $parameters[2]);
67+
}
68+
69+
public function test_multiple_named_arguments()
70+
{
71+
$task = factory(Task::class)->create();
72+
$task->parameters = 'arg1=name arg2=airport arg3=100';
73+
$parameters = $task->compileParameters();
74+
75+
$this->assertCount(3, $parameters);
76+
$this->assertSame('name', $parameters['arg1']);
77+
$this->assertSame('airport', $parameters['arg2']);
78+
$this->assertSame('100', $parameters['arg3']);
79+
}
80+
81+
public function test_multiple_mixed_arguments()
82+
{
83+
$task = factory(Task::class)->create();
84+
$task->parameters = 'arg1 arg2=test arg3=15 arg4';
85+
$parameters = $task->compileParameters();
86+
87+
$this->assertCount(4, $parameters);
88+
$this->assertSame('arg1', $parameters[0]);
89+
$this->assertSame('test', $parameters['arg2']);
90+
$this->assertSame('15', $parameters['arg3']);
91+
$this->assertSame('arg4', $parameters[1]);
92+
}
93+
94+
public function test_all_mixed_arguments()
95+
{
96+
$task = factory(Task::class)->create();
97+
$task->parameters = 'arg1 arg2=test arg3=15 arg4 --flag --flag2 --option=yes --someplace=warm';
98+
$parameters = $task->compileParameters();
99+
100+
$this->assertCount(8, $parameters);
101+
$this->assertSame('arg1', $parameters[0]);
102+
$this->assertSame('test', $parameters['arg2']);
103+
$this->assertSame('15', $parameters['arg3']);
104+
$this->assertSame('arg4', $parameters[1]);
105+
$this->assertSame('warm', $parameters['--someplace']);
106+
$this->assertTrue($parameters['--flag']);
107+
$this->assertArrayHasKey('--flag', $parameters);
108+
}
58109
}

0 commit comments

Comments
 (0)