Schedule Import: Moved file, initial cleanup, updated schedules
This commit is contained in:
parent
aef53a306b
commit
790a04dc14
|
@ -187,11 +187,11 @@ $route->addGroup(
|
|||
$route->addGroup(
|
||||
'/schedule',
|
||||
function (RouteCollector $route): void {
|
||||
$route->get('', 'Admin\\Schedule\\ImportSchedule@index');
|
||||
$route->get('/edit[/{schedule_id:\d+}]', 'Admin\\Schedule\\ImportSchedule@edit');
|
||||
$route->post('/edit[/{schedule_id:\d+}]', 'Admin\\Schedule\\ImportSchedule@save');
|
||||
$route->get('/load/{schedule_id:\d+}', 'Admin\\Schedule\\ImportSchedule@loadSchedule');
|
||||
$route->post('/import/{schedule_id:\d+}', 'Admin\\Schedule\\ImportSchedule@importSchedule');
|
||||
$route->get('', 'Admin\\ScheduleController@index');
|
||||
$route->get('/edit[/{schedule_id:\d+}]', 'Admin\\ScheduleController@edit');
|
||||
$route->post('/edit[/{schedule_id:\d+}]', 'Admin\\ScheduleController@save');
|
||||
$route->get('/load/{schedule_id:\d+}', 'Admin\\ScheduleController@loadSchedule');
|
||||
$route->post('/import/{schedule_id:\d+}', 'Admin\\ScheduleController@importSchedule');
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -59,8 +59,6 @@ $includeFiles = [
|
|||
__DIR__ . '/../includes/pages/admin_user.php',
|
||||
__DIR__ . '/../includes/pages/user_myshifts.php',
|
||||
__DIR__ . '/../includes/pages/user_shifts.php',
|
||||
|
||||
__DIR__ . '/../includes/pages/schedule/ImportSchedule.php',
|
||||
];
|
||||
|
||||
foreach ($includeFiles as $file) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Admin\Schedule;
|
||||
namespace Engelsystem\Controllers\Admin;
|
||||
|
||||
use Engelsystem\Controllers\NotificationType;
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
|
@ -17,7 +17,7 @@ use Engelsystem\Helpers\Uuid;
|
|||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Models\Location;
|
||||
use Engelsystem\Models\Shifts\Schedule as ScheduleUrl;
|
||||
use Engelsystem\Models\Shifts\Schedule as ScheduleModel;
|
||||
use Engelsystem\Models\Shifts\ScheduleShift;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
|
@ -25,56 +25,28 @@ use Engelsystem\Models\User\User;
|
|||
use ErrorException;
|
||||
use GuzzleHttp\Client as GuzzleClient;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Illuminate\Database\Connection as DatabaseConnection;
|
||||
use Illuminate\Database\Eloquent\Builder as QueryBuilder;
|
||||
use Illuminate\Database\Eloquent\Collection as DatabaseCollection;
|
||||
use Illuminate\Support\Collection;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
|
||||
class ImportSchedule extends BaseController
|
||||
class ScheduleController extends BaseController
|
||||
{
|
||||
use HasUserNotifications;
|
||||
|
||||
/** @var DatabaseConnection */
|
||||
protected $db;
|
||||
|
||||
/** @var LoggerInterface */
|
||||
protected $log;
|
||||
|
||||
protected array $permissions = [
|
||||
'schedule.import',
|
||||
];
|
||||
|
||||
/** @var XmlParser */
|
||||
protected $parser;
|
||||
|
||||
/** @var Response */
|
||||
protected $response;
|
||||
|
||||
/** @var SessionInterface */
|
||||
protected $session;
|
||||
|
||||
/** @var string */
|
||||
protected $url = '/admin/schedule';
|
||||
|
||||
/** @var GuzzleClient */
|
||||
protected $guzzle;
|
||||
protected string $url = '/admin/schedule';
|
||||
|
||||
public function __construct(
|
||||
Response $response,
|
||||
SessionInterface $session,
|
||||
GuzzleClient $guzzle,
|
||||
XmlParser $parser,
|
||||
DatabaseConnection $db,
|
||||
LoggerInterface $log
|
||||
protected Response $response,
|
||||
protected GuzzleClient $guzzle,
|
||||
protected XmlParser $parser,
|
||||
protected DatabaseConnection $db,
|
||||
protected LoggerInterface $log
|
||||
) {
|
||||
$this->guzzle = $guzzle;
|
||||
$this->parser = $parser;
|
||||
$this->response = $response;
|
||||
$this->session = $session;
|
||||
$this->db = $db;
|
||||
$this->log = $log;
|
||||
}
|
||||
|
||||
public function index(): Response
|
||||
|
@ -83,7 +55,7 @@ class ImportSchedule extends BaseController
|
|||
'admin/schedule/index.twig',
|
||||
[
|
||||
'is_index' => true,
|
||||
'schedules' => ScheduleUrl::all(),
|
||||
'schedules' => ScheduleModel::all(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -91,7 +63,7 @@ class ImportSchedule extends BaseController
|
|||
public function edit(Request $request): Response
|
||||
{
|
||||
$scheduleId = $request->getAttribute('schedule_id'); // optional
|
||||
$schedule = ScheduleUrl::find($scheduleId);
|
||||
$schedule = ScheduleModel::find($scheduleId);
|
||||
|
||||
return $this->response->withView(
|
||||
'admin/schedule/edit.twig',
|
||||
|
@ -103,12 +75,15 @@ class ImportSchedule extends BaseController
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ErrorException
|
||||
*/
|
||||
public function save(Request $request): Response
|
||||
{
|
||||
$scheduleId = $request->getAttribute('schedule_id'); // optional
|
||||
|
||||
/** @var ScheduleUrl $schedule */
|
||||
$schedule = ScheduleUrl::findOrNew($scheduleId);
|
||||
/** @var ScheduleModel $schedule */
|
||||
$schedule = ScheduleModel::findOrNew($scheduleId);
|
||||
|
||||
if ($request->request->has('delete')) {
|
||||
return $this->delete($schedule);
|
||||
|
@ -173,7 +148,7 @@ class ImportSchedule extends BaseController
|
|||
return redirect('/admin/schedule/load/' . $schedule->id);
|
||||
}
|
||||
|
||||
protected function delete(ScheduleUrl $schedule): Response
|
||||
protected function delete(ScheduleModel $schedule): Response
|
||||
{
|
||||
foreach ($schedule->scheduleShifts as $scheduleShift) {
|
||||
// Only guid is needed here
|
||||
|
@ -196,6 +171,7 @@ class ImportSchedule extends BaseController
|
|||
}
|
||||
$schedule->delete();
|
||||
|
||||
$this->log->info('Schedule {name} deleted', ['name' => $schedule->name]);
|
||||
$this->addNotification('schedule.delete.success');
|
||||
return redirect('/admin/schedule');
|
||||
}
|
||||
|
@ -209,7 +185,7 @@ class ImportSchedule extends BaseController
|
|||
* @var Event[] $deleteEvents
|
||||
* @var Room[] $newRooms
|
||||
* @var int $shiftType
|
||||
* @var ScheduleUrl $scheduleUrl
|
||||
* @var ScheduleModel $scheduleModel
|
||||
* @var Schedule $schedule
|
||||
* @var int $minutesBefore
|
||||
* @var int $minutesAfter
|
||||
|
@ -220,7 +196,7 @@ class ImportSchedule extends BaseController
|
|||
$deleteEvents,
|
||||
$newRooms,
|
||||
,
|
||||
$scheduleUrl,
|
||||
$scheduleModel,
|
||||
$schedule
|
||||
) = $this->getScheduleData($request);
|
||||
} catch (ErrorException $e) {
|
||||
|
@ -231,7 +207,7 @@ class ImportSchedule extends BaseController
|
|||
return $this->response->withView(
|
||||
'admin/schedule/load.twig',
|
||||
[
|
||||
'schedule_id' => $scheduleUrl->id,
|
||||
'schedule_id' => $scheduleModel->id,
|
||||
'schedule' => $schedule,
|
||||
'locations' => [
|
||||
'add' => $newRooms,
|
||||
|
@ -254,7 +230,7 @@ class ImportSchedule extends BaseController
|
|||
* @var Event[] $deleteEvents
|
||||
* @var Room[] $newRooms
|
||||
* @var int $shiftType
|
||||
* @var ScheduleUrl $scheduleUrl
|
||||
* @var ScheduleModel $schedule
|
||||
*/
|
||||
list(
|
||||
$newEvents,
|
||||
|
@ -262,14 +238,14 @@ class ImportSchedule extends BaseController
|
|||
$deleteEvents,
|
||||
$newRooms,
|
||||
$shiftType,
|
||||
$scheduleUrl
|
||||
$schedule
|
||||
) = $this->getScheduleData($request);
|
||||
} catch (ErrorException $e) {
|
||||
$this->addNotification($e->getMessage(), NotificationType::ERROR);
|
||||
return back();
|
||||
}
|
||||
|
||||
$this->log('Started schedule "{name}" import', ['name' => $scheduleUrl->name]);
|
||||
$this->log->info('Started schedule "{name}" import', ['name' => $schedule->name]);
|
||||
|
||||
foreach ($newRooms as $room) {
|
||||
$this->createLocation($room);
|
||||
|
@ -283,7 +259,7 @@ class ImportSchedule extends BaseController
|
|||
$locations
|
||||
->where('name', $event->getRoom()->getName())
|
||||
->first(),
|
||||
$scheduleUrl
|
||||
$schedule
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -294,16 +270,16 @@ class ImportSchedule extends BaseController
|
|||
$locations
|
||||
->where('name', $event->getRoom()->getName())
|
||||
->first(),
|
||||
$scheduleUrl
|
||||
$schedule
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($deleteEvents as $event) {
|
||||
$this->deleteEvent($event, $scheduleUrl);
|
||||
$this->deleteEvent($event, $schedule);
|
||||
}
|
||||
|
||||
$scheduleUrl->touch();
|
||||
$this->log('Ended schedule "{name}" import', ['name' => $scheduleUrl->name]);
|
||||
$schedule->touch();
|
||||
$this->log->info('Ended schedule "{name}" import', ['name' => $schedule->name]);
|
||||
|
||||
$this->addNotification('schedule.import.success');
|
||||
return redirect($this->url, 303);
|
||||
|
@ -315,7 +291,7 @@ class ImportSchedule extends BaseController
|
|||
$location->name = $room->getName();
|
||||
$location->save();
|
||||
|
||||
$this->log('Created schedule location "{location}"', ['location' => $room->getName()]);
|
||||
$this->log->info('Created schedule location "{location}"', ['location' => $room->getName()]);
|
||||
}
|
||||
|
||||
protected function fireDeleteShiftEntryEvents(Event $event, ScheduleUrl $schedule): void
|
||||
|
@ -349,7 +325,7 @@ class ImportSchedule extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
protected function createEvent(Event $event, int $shiftTypeId, Location $location, ScheduleUrl $scheduleUrl): void
|
||||
protected function createEvent(Event $event, int $shiftTypeId, Location $location, ScheduleModel $scheduleUrl): void
|
||||
{
|
||||
$user = auth()->user();
|
||||
$eventTimeZone = Carbon::now()->timezone;
|
||||
|
@ -370,7 +346,7 @@ class ImportSchedule extends BaseController
|
|||
$scheduleShift->shift()->associate($shift);
|
||||
$scheduleShift->save();
|
||||
|
||||
$this->log(
|
||||
$this->log->info(
|
||||
'Created schedule shift "{shift}" in "{location}" ({from} {to}, {guid})',
|
||||
[
|
||||
'shift' => $shift->title,
|
||||
|
@ -402,7 +378,7 @@ class ImportSchedule extends BaseController
|
|||
|
||||
$this->fireUpdateShiftUpdateEvent($oldShift, $shift);
|
||||
|
||||
$this->log(
|
||||
$this->log->info(
|
||||
'Updated schedule shift "{shift}" in "{location}" ({from} {to}, {guid})',
|
||||
[
|
||||
'shift' => $shift->title,
|
||||
|
@ -424,7 +400,7 @@ class ImportSchedule extends BaseController
|
|||
|
||||
$this->fireDeleteShiftEntryEvents($event, $schedule);
|
||||
|
||||
$this->log(
|
||||
$this->log->info(
|
||||
'Deleted schedule shift "{shift}" in {location} ({from} {to}, {guid})',
|
||||
[
|
||||
'shift' => $shift->title,
|
||||
|
@ -445,20 +421,19 @@ class ImportSchedule extends BaseController
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return Event[]|Room[]|Location[]
|
||||
* @throws ErrorException
|
||||
*/
|
||||
protected function getScheduleData(Request $request)
|
||||
protected function getScheduleData(Request $request): array
|
||||
{
|
||||
$scheduleId = (int) $request->getAttribute('schedule_id');
|
||||
|
||||
/** @var ScheduleUrl $scheduleUrl */
|
||||
$scheduleUrl = ScheduleUrl::findOrFail($scheduleId);
|
||||
/** @var ScheduleModel $scheduleUrl */
|
||||
$scheduleUrl = ScheduleModel::findOrFail($scheduleId);
|
||||
|
||||
try {
|
||||
$scheduleResponse = $this->guzzle->get($scheduleUrl->url);
|
||||
} catch (ConnectException $e) {
|
||||
} catch (ConnectException | GuzzleException) {
|
||||
throw new ErrorException('schedule.import.request-error');
|
||||
}
|
||||
|
||||
|
@ -503,16 +478,11 @@ class ImportSchedule extends BaseController
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Schedule $schedule
|
||||
* @param ScheduleUrl $scheduleUrl
|
||||
* @param int $shiftType
|
||||
* @param int $minutesBefore
|
||||
* @param int $minutesAfter
|
||||
* @return Event[]
|
||||
*/
|
||||
protected function shiftsDiff(
|
||||
Schedule $schedule,
|
||||
ScheduleUrl $scheduleUrl,
|
||||
ScheduleModel $scheduleUrl,
|
||||
int $shiftType,
|
||||
int $minutesBefore,
|
||||
int $minutesAfter
|
||||
|
@ -554,6 +524,7 @@ class ImportSchedule extends BaseController
|
|||
$guid = $scheduleShift->guid;
|
||||
$shift = $scheduleShift->shift;
|
||||
$event = $scheduleEvents[$guid];
|
||||
/** @var Location $location */
|
||||
$location = $locations->where('name', $event->getRoom()->getName())->first();
|
||||
|
||||
if (
|
||||
|
@ -607,17 +578,17 @@ class ImportSchedule extends BaseController
|
|||
/**
|
||||
* @return Location[]|Collection
|
||||
*/
|
||||
protected function getAllLocations(): Collection
|
||||
protected function getAllLocations(): Collection | array
|
||||
{
|
||||
return Location::all();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ScheduleUrl $scheduleUrl
|
||||
* @param string[] $events
|
||||
* @return QueryBuilder[]|DatabaseCollection|Collection|ScheduleShift[]
|
||||
*
|
||||
* @return Collection|ScheduleShift[]
|
||||
*/
|
||||
protected function getScheduleShiftsByGuid(ScheduleUrl $scheduleUrl, array $events)
|
||||
protected function getScheduleShiftsByGuid(ScheduleModel $scheduleUrl, array $events): Collection | array
|
||||
{
|
||||
return ScheduleShift::with('shift.location')
|
||||
->whereIn('guid', $events)
|
||||
|
@ -626,24 +597,14 @@ class ImportSchedule extends BaseController
|
|||
}
|
||||
|
||||
/**
|
||||
* @param ScheduleUrl $scheduleUrl
|
||||
* @param string[] $events
|
||||
* @return QueryBuilder[]|DatabaseCollection|Collection|ScheduleShift[]
|
||||
* @return Collection|ScheduleShift[]
|
||||
*/
|
||||
protected function getScheduleShiftsWhereNotGuid(ScheduleUrl $scheduleUrl, array $events)
|
||||
protected function getScheduleShiftsWhereNotGuid(ScheduleModel $scheduleUrl, array $events): Collection | array
|
||||
{
|
||||
return ScheduleShift::with('shift.location')
|
||||
->whereNotIn('guid', $events)
|
||||
->where('schedule_id', $scheduleUrl->id)
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array $context
|
||||
*/
|
||||
protected function log(string $message, array $context = []): void
|
||||
{
|
||||
$this->log->info($message, $context);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<schedule
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/voc/voctosched/master/schema/basic.xsd"
|
||||
xsi:noNamespaceSchemaLocation="https://c3voc.de/schedule/schema.xsd"
|
||||
>
|
||||
<version>dolor</version>
|
||||
<conference>
|
||||
<title>Basic Test Event</title>
|
||||
<acronym>Test2</acronym>
|
||||
<acronym>test-2</acronym>
|
||||
<start>2042-01-03</start>
|
||||
<end>2042-01-03</end>
|
||||
<days>1</days>
|
||||
|
@ -21,7 +21,7 @@
|
|||
<start>14:15</start>
|
||||
<duration>00:45</duration>
|
||||
<room>Some Room</room>
|
||||
<slug>lorem/ipsum</slug>
|
||||
<slug>lorem-42-ipsum</slug>
|
||||
<recording>
|
||||
<license>WTFPL</license>
|
||||
<optout>true</optout>
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<schedule
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/voc/voctosched/master/schema/extended.xsd"
|
||||
xsi:noNamespaceSchemaLocation="https://c3voc.de/schedule/schema.xsd"
|
||||
>
|
||||
<generator name="Engelsystem" version="1.2.3"/>
|
||||
<version>Some version string</version>
|
||||
<conference>
|
||||
<title>Test Event</title>
|
||||
<acronym>Test3</acronym>
|
||||
<start>2042-01-01</start>
|
||||
<end>2042-01-01</end>
|
||||
<acronym>test-3</acronym>
|
||||
<start>2042-01-01T01:00:00+02:00</start>
|
||||
<end>2042-01-01T22:59:00+02:00</end>
|
||||
<days>1</days>
|
||||
<timeslot_duration>00:15</timeslot_duration>
|
||||
<base_url>https://foo.bar/baz/schedule/</base_url>
|
||||
<time_zone_name>Europe/Berlin</time_zone_name>
|
||||
</conference>
|
||||
<day index='1' date='2042-01-01' start='2042-01-01T01:00:00+02:00' end='2042-01-01T22:59:00+02:00'>
|
||||
<room name='Rooming'>
|
||||
<room name='Rooming' guid="bf5f1132-82bd-4da2-bbe0-1abbf8daf4ab">
|
||||
<event guid='e427cfa9-9ba1-4b14-a99f-bce83ffe5a1c' id='1337'>
|
||||
<date>2042-01-01T12:30:00+02:00</date>
|
||||
<title>Foo Bar Test</title>
|
||||
|
@ -22,10 +24,12 @@
|
|||
<start>12:30</start>
|
||||
<duration>00:30</duration>
|
||||
<room>Rooming</room>
|
||||
<slug>foo-bar-test</slug>
|
||||
<slug>some-3-test</slug>
|
||||
<recording>
|
||||
<license>WTFPL</license>
|
||||
<optout>false</optout>
|
||||
<url>https://recorder.test/some-3-test/recorded</url>
|
||||
<link>https://recorder.test/some-3-test</link>
|
||||
</recording>
|
||||
<video_download_url>https://foo.bar/baz/schedule/ipsum/recording.mp4</video_download_url>
|
||||
<track>Testing</track>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<version>0.0.1</version>
|
||||
<conference>
|
||||
<title>Some Test Event</title>
|
||||
<acronym>Test1</acronym>
|
||||
<acronym>test-1</acronym>
|
||||
</conference>
|
||||
<day index='1' date='2042-01-02' start='2042-01-02T00:00:00+00:00' end='2042-01-02T22:59:00+00:00'>
|
||||
<room name='Random Room'>
|
||||
|
@ -13,7 +13,7 @@
|
|||
<start>13:30</start>
|
||||
<duration>00:30</duration>
|
||||
<room>Rooming</room>
|
||||
<slug>minimum-setup-test</slug>
|
||||
<slug>minimum-1-setup</slug>
|
||||
<track>Testing</track>
|
||||
<type>Talk</type>
|
||||
<abstract>A minimal description</abstract>
|
||||
|
|
Loading…
Reference in New Issue