mirror of https://github.com/nextcloud/calendar
enh(appointments): add moar debug logging and overwrite app id
Signed-off-by: Anna Larch <anna@nextcloud.com>
This commit is contained in:
parent
1c6eb45b7a
commit
9d54b96c24
|
@ -31,6 +31,7 @@ use DateTimeImmutable;
|
|||
use DateTimeZone;
|
||||
use OCA\Calendar\Db\AppointmentConfig;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use function ceil;
|
||||
use function max;
|
||||
use function min;
|
||||
|
@ -39,7 +40,7 @@ class AvailabilityGenerator {
|
|||
/** @var ITimeFactory */
|
||||
private $timeFactory;
|
||||
|
||||
public function __construct(ITimeFactory $timeFactory) {
|
||||
public function __construct(ITimeFactory $timeFactory, private LoggerInterface $logger) {
|
||||
$this->timeFactory = $timeFactory;
|
||||
}
|
||||
|
||||
|
@ -79,11 +80,17 @@ class AvailabilityGenerator {
|
|||
|
||||
// If we reach this state then there are no available dates anymore
|
||||
if ($latestEnd <= $earliestStart) {
|
||||
$this->logger->debug('Appointment config ' . $config->getToken() . ' has {latestEnd} as latest end but {earliestStart} as earliest start. No slots available.', [
|
||||
'latestEnd' => $latestEnd,
|
||||
'earliestStart' => $earliestStart,
|
||||
'app' => 'calendar-appointments'
|
||||
]);
|
||||
return [];
|
||||
}
|
||||
|
||||
if (empty($config->getAvailability())) {
|
||||
// No availability -> full time range is available
|
||||
$this->logger->debug('Full time range available', ['app' => 'calendar-appointments']);
|
||||
return [
|
||||
new Interval($earliestStart, $latestEnd),
|
||||
];
|
||||
|
@ -95,6 +102,7 @@ class AvailabilityGenerator {
|
|||
$slots = $availabilityRule['slots'];
|
||||
|
||||
$applicableSlots = $this->filterDates($start, $slots, $timeZone);
|
||||
$this->logger->debug('Found ' . count($applicableSlots) . ' applicable slot(s) after date filtering', ['app' => 'calendar-appointments']);
|
||||
|
||||
$intervals = [];
|
||||
foreach ($applicableSlots as $slot) {
|
||||
|
|
|
@ -142,13 +142,13 @@ class BookingService {
|
|||
$this->mailService->sendBookingInformationEmail($booking, $config, $calendar);
|
||||
$this->mailService->sendOrganizerBookingInformationEmail($booking, $config, $calendar);
|
||||
} catch (ServiceException $e) {
|
||||
$this->logger->info('Could not send booking emails after confirmation from user ' . $booking->getEmail(), ['exception' => $e]);
|
||||
$this->logger->info('Could not send booking emails after confirmation from user ' . $booking->getEmail(), ['exception' => $e, 'app' => 'calendar-appointments']);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->mailService->sendOrganizerBookingInformationNotification($booking, $config);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
$this->logger->warning('Could not send booking information notification after confirmation by user ' . $booking->getEmail(), ['exception' => $e]);
|
||||
$this->logger->warning('Could not send booking information notification after confirmation by user ' . $booking->getEmail(), ['exception' => $e, 'app' => 'calendar-appointments']);
|
||||
}
|
||||
|
||||
return $booking;
|
||||
|
@ -203,10 +203,13 @@ class BookingService {
|
|||
if ($config->getFutureLimit() !== null) {
|
||||
/** @var int $maxEndTime */
|
||||
$maxEndTime = time() + $config->getFutureLimit();
|
||||
$this->logger->debug('Maximum end time: ' . $maxEndTime, ['app' => 'calendar-appointments']);
|
||||
if ($startTime > $maxEndTime) {
|
||||
$this->logger->debug('Start time is higher than maximum end time. Start time: ' . $startTime, ['app' => 'calendar-appointments']);
|
||||
return [];
|
||||
}
|
||||
if ($endTime > $maxEndTime) {
|
||||
$this->logger->debug('End time is higher than maximum end time. Setting end time to maximum end time. End time: ' . $endTime, ['app' => 'calendar-appointments']);
|
||||
$endTime = $maxEndTime;
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +227,8 @@ class BookingService {
|
|||
'availabilityIntervals' => count($availabilityIntervals),
|
||||
'allPossibleSlots' => count($allPossibleSlots),
|
||||
'filteredByDailyLimit' => count($filteredByDailyLimit),
|
||||
'available' => count($available)
|
||||
'available' => count($available),
|
||||
'app' => 'calendar-appointments',
|
||||
]);
|
||||
|
||||
return $available;
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace OCA\Calendar\Service\Appointments;
|
|||
use OCA\Calendar\Db\AppointmentConfig;
|
||||
use OCP\Calendar\ICalendarQuery;
|
||||
use OCP\Calendar\IManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use function array_filter;
|
||||
use function array_values;
|
||||
use function count;
|
||||
|
@ -36,7 +37,7 @@ class DailyLimitFilter {
|
|||
/** @var IManager */
|
||||
private $calendarManger;
|
||||
|
||||
public function __construct(IManager $calendarManger) {
|
||||
public function __construct(IManager $calendarManger, private LoggerInterface $logger) {
|
||||
$this->calendarManger = $calendarManger;
|
||||
}
|
||||
|
||||
|
@ -47,6 +48,10 @@ class DailyLimitFilter {
|
|||
* @return Interval[]
|
||||
*/
|
||||
public function filter(AppointmentConfig $config, array $slots): array {
|
||||
$this->logger->debug('Slots before daily limit filtering:' . count($slots), ['app' => 'calendar-appointments']);
|
||||
if(empty($slots)) {
|
||||
return [];
|
||||
}
|
||||
// 0. If there is no limit then we don't have to filter anything
|
||||
if ($config->getDailyMax() === null) {
|
||||
return $slots;
|
||||
|
@ -90,10 +95,13 @@ class DailyLimitFilter {
|
|||
}
|
||||
|
||||
// 3. Filter out the slots that are on an unavailable day
|
||||
return array_values(array_filter($slots, function (Interval $slot) use ($available): bool {
|
||||
$available = array_values(array_filter($slots, function (Interval $slot) use ($available): bool {
|
||||
$startOfDay = $slot->getStartAsObject()->setTime(0, 0, 0, 0);
|
||||
$ts = $startOfDay->getTimestamp();
|
||||
return $available[$ts];
|
||||
}));
|
||||
|
||||
$this->logger->debug('Slots after daily limit filtering:' . count($available), ['app' => 'calendar-appointments']);
|
||||
return $available;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,10 @@ class EventConflictFilter {
|
|||
* @return Interval[]
|
||||
*/
|
||||
public function filter(AppointmentConfig $config, array $slots): array {
|
||||
$this->logger->debug('Slots before event conflict filtering:' . count($slots), ['app' => 'calendar-appointments']);
|
||||
if(empty($slots)) {
|
||||
return [];
|
||||
}
|
||||
$query = $this->calendarManager->newQuery($config->getPrincipalUri());
|
||||
foreach ($config->getCalendarFreebusyUrisAsArray() as $uri) {
|
||||
$query->addSearchCalendar($uri);
|
||||
|
@ -63,7 +67,7 @@ class EventConflictFilter {
|
|||
$query->addType('VEVENT');
|
||||
$preparationDuration = DateInterval::createFromDateString($config->getPreparationDuration() . ' seconds');
|
||||
$followUpDuration = DateInterval::createFromDateString($config->getFollowupDuration() . ' seconds');
|
||||
return array_filter($slots, function (Interval $slot) use ($followUpDuration, $preparationDuration, $query, $config): bool {
|
||||
$available = array_filter($slots, function (Interval $slot) use ($followUpDuration, $preparationDuration, $query, $config): bool {
|
||||
$query->setTimerangeStart($slot->getStartAsObject()->sub($preparationDuration));
|
||||
$query->setTimerangeEnd($slot->getEndAsObject()->add($followUpDuration));
|
||||
|
||||
|
@ -81,7 +85,7 @@ class EventConflictFilter {
|
|||
|
||||
$this->logger->debug('Appointment config ' . $config->getToken() . ' is looking within {start} and {followup} in calendar {calendarUri}. Conflicting UIDs are {uids}', [
|
||||
'start' => $slot->getStartAsObject()->sub($preparationDuration)->format(DateTimeInterface::ATOM),
|
||||
'end' => $slot->getEndAsObject()->add($followUpDuration)->format(DateTimeInterface::ATOM),
|
||||
'followup' => $slot->getEndAsObject()->add($followUpDuration)->format(DateTimeInterface::ATOM),
|
||||
'calendarUri' => $config->getTargetCalendarUri(),
|
||||
'uids' => implode(' : ', $uids)
|
||||
]);
|
||||
|
@ -89,5 +93,8 @@ class EventConflictFilter {
|
|||
// If there is at least one event at this time then the slot is taken
|
||||
return empty($objects);
|
||||
});
|
||||
|
||||
$this->logger->debug('Slots after event conflict filtering:' . count($available), ['app' => 'calendar-appointments']);
|
||||
return $available;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,14 +146,14 @@ class MailService {
|
|||
try {
|
||||
$failed = $this->mailer->send($message);
|
||||
if (count($failed) > 0) {
|
||||
$this->logger->warning('Mail delivery failed for some recipients.');
|
||||
$this->logger->warning('Mail delivery failed for some recipients.', ['app' => 'calendar-appointments']);
|
||||
foreach ($failed as $fail) {
|
||||
$this->logger->debug('Failed to deliver email to ' . $fail);
|
||||
$this->logger->debug('Failed to deliver email to ' . $fail, ['app' => 'calendar-appointments']);
|
||||
}
|
||||
throw new ServiceException('Could not send mail for recipient(s) ' . implode(', ', $failed));
|
||||
}
|
||||
} catch (Exception $ex) {
|
||||
$this->logger->error($ex->getMessage(), ['exception' => $ex]);
|
||||
$this->logger->error($ex->getMessage(), ['exception' => $ex, 'app' => 'calendar-appointments']);
|
||||
throw new ServiceException('Could not send mail: ' . $ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
}
|
||||
|
@ -215,14 +215,14 @@ class MailService {
|
|||
try {
|
||||
$failed = $this->mailer->send($message);
|
||||
if (count($failed) > 0) {
|
||||
$this->logger->warning('Mail delivery failed for some recipients.');
|
||||
$this->logger->warning('Mail delivery failed for some recipients.', ['app' => 'calendar-appointments']);
|
||||
foreach ($failed as $fail) {
|
||||
$this->logger->debug('Failed to deliver email to ' . $fail);
|
||||
$this->logger->debug('Failed to deliver email to ' . $fail, ['app' => 'calendar-appointments']);
|
||||
}
|
||||
throw new ServiceException('Could not send mail for recipient(s) ' . implode(', ', $failed));
|
||||
}
|
||||
} catch (Exception $ex) {
|
||||
$this->logger->error($ex->getMessage(), ['exception' => $ex]);
|
||||
$this->logger->error($ex->getMessage(), ['exception' => $ex, 'app' => 'calendar-appointments']);
|
||||
throw new ServiceException('Could not send mail: ' . $ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
}
|
||||
|
@ -320,14 +320,14 @@ class MailService {
|
|||
try {
|
||||
$failed = $this->mailer->send($message);
|
||||
if (count($failed) > 0) {
|
||||
$this->logger->warning('Mail delivery failed for some recipients.');
|
||||
$this->logger->warning('Mail delivery failed for some recipients.', ['app' => 'calendar-appointments']);
|
||||
foreach ($failed as $fail) {
|
||||
$this->logger->debug('Failed to deliver email to ' . $fail);
|
||||
$this->logger->debug('Failed to deliver email to ' . $fail, ['app' => 'calendar-appointments']);
|
||||
}
|
||||
throw new ServiceException('Could not send mail for recipient(s) ' . implode(', ', $failed));
|
||||
}
|
||||
} catch (Exception $ex) {
|
||||
$this->logger->error('Could not send appointment organizer email: ' . $ex->getMessage(), ['exception' => $ex]);
|
||||
$this->logger->error('Could not send appointment organizer email: ' . $ex->getMessage(), ['exception' => $ex, 'app' => 'calendar-appointments']);
|
||||
throw new ServiceException('Could not send mail: ' . $ex->getMessage(), $ex->getCode(), $ex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,17 +26,28 @@ declare(strict_types=1);
|
|||
namespace OCA\Calendar\Service\Appointments;
|
||||
|
||||
use OCA\Calendar\Db\AppointmentConfig;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class SlotExtrapolator {
|
||||
|
||||
public function __construct(private LoggerInterface $logger) {
|
||||
|
||||
}
|
||||
/**
|
||||
* @param AppointmentConfig $config
|
||||
* @param Interval[] $availabilityIntervals
|
||||
* @param int $to
|
||||
*
|
||||
* @return Interval[]
|
||||
*/
|
||||
public function extrapolate(AppointmentConfig $config,
|
||||
array $availabilityIntervals): array {
|
||||
$this->logger->debug('Intervals before extrapolating:' . count($availabilityIntervals), ['app' => 'calendar-appointments']);
|
||||
if(empty($availabilityIntervals)) {
|
||||
return [];
|
||||
}
|
||||
foreach ($availabilityIntervals as $availabilityInterval) {
|
||||
$this->logger->debug('Interval start: ' . $availabilityInterval->getStart() . ', interval end: ' . $availabilityInterval->getEnd(), ['app' => 'calendar-appointments']);
|
||||
}
|
||||
$increment = $config->getIncrement();
|
||||
$length = $config->getLength();
|
||||
$slots = [];
|
||||
|
@ -50,6 +61,7 @@ class SlotExtrapolator {
|
|||
}
|
||||
}
|
||||
|
||||
$this->logger->debug('Slots after extrapolating:' . count($slots), ['app' => 'calendar-appointments']);
|
||||
return $slots;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,14 +34,12 @@ use OCA\Calendar\Service\Appointments\Interval;
|
|||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Calendar\ICalendarQuery;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class AvailabilityGeneratorTest extends TestCase {
|
||||
/** @var ITimeFactory|MockObject */
|
||||
private $timeFactory;
|
||||
|
||||
/** @var AvailabilityGenerator */
|
||||
private $generator;
|
||||
|
||||
private ITimeFactory|MockObject $timeFactory;
|
||||
private MockObject|LoggerInterface $logger;
|
||||
private AvailabilityGenerator $generator;
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
|
@ -50,9 +48,10 @@ class AvailabilityGeneratorTest extends TestCase {
|
|||
}
|
||||
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->generator = new AvailabilityGenerator(
|
||||
$this->timeFactory,
|
||||
$this->logger,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,16 +32,15 @@ use OCA\Calendar\Service\Appointments\Interval;
|
|||
use OCP\Calendar\ICalendarQuery;
|
||||
use OCP\Calendar\IManager;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* @requires OCP\Calendar\ICalendarQuery::newQuery
|
||||
*/
|
||||
class DailyLimitFilterTest extends TestCase {
|
||||
/** @var IManager|MockObject */
|
||||
private $manager;
|
||||
|
||||
/** @var DailyLimitFilter */
|
||||
private $filter;
|
||||
private IManager|MockObject $manager;
|
||||
private MockObject|LoggerInterface $logger;
|
||||
private DailyLimitFilter $filter;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
@ -51,9 +50,11 @@ class DailyLimitFilterTest extends TestCase {
|
|||
}
|
||||
|
||||
$this->manager = $this->createMock(IManager::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
|
||||
$this->filter = new DailyLimitFilter(
|
||||
$this->manager,
|
||||
$this->logger,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,13 @@ use OCA\Calendar\Db\AppointmentConfig;
|
|||
use OCA\Calendar\Service\Appointments\Interval;
|
||||
use OCA\Calendar\Service\Appointments\SlotExtrapolator;
|
||||
use OCP\Calendar\ICalendarQuery;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LoggerInterface\PHPUnit\Framework\MockObject\MockObject;
|
||||
|
||||
class SlotExtrapolatorTest extends TestCase {
|
||||
/** @var SlotExtrapolator */
|
||||
private $extrapolator;
|
||||
private MockObject|LoggerInterface $logger;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
@ -42,7 +45,8 @@ class SlotExtrapolatorTest extends TestCase {
|
|||
self::markTestIncomplete();
|
||||
}
|
||||
|
||||
$this->extrapolator = new SlotExtrapolator();
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->extrapolator = new SlotExtrapolator($this->logger);
|
||||
}
|
||||
|
||||
public function testNoAvailability(): void {
|
||||
|
|
Loading…
Reference in New Issue