mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-17 20:32:41 +01:00
Allow Calendar imports to be configured with hourly or daily auto-updates
Summary: Ref T10747. For URI-based (and, in the future, Google-based) imports, we can automatically refresh them periodically. (In the general case there's no way to get a push notification for an ICS file, so we just have to do this every-so-often.) Test Plan: - Set an ICS file to update hourly. - Used `bin/trigger fire --id ...` to fire it artificially. - Saw Calendar update. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10747 Differential Revision: https://secure.phabricator.com/D16752
This commit is contained in:
parent
a69ac888b3
commit
2d7f574b9d
13 changed files with 344 additions and 9 deletions
|
@ -0,0 +1,8 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_calendar.calendar_import
|
||||||
|
ADD triggerPHID VARBINARY(64);
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_calendar.calendar_import
|
||||||
|
ADD triggerFrequency VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT};
|
||||||
|
|
||||||
|
UPDATE {$NAMESPACE}_calendar.calendar_import
|
||||||
|
SET triggerFrequency = 'once' WHERE triggerFrequency = '';
|
|
@ -2121,6 +2121,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorCalendarImportEpochLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportEpochLogType.php',
|
'PhabricatorCalendarImportEpochLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportEpochLogType.php',
|
||||||
'PhabricatorCalendarImportFetchLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportFetchLogType.php',
|
'PhabricatorCalendarImportFetchLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportFetchLogType.php',
|
||||||
'PhabricatorCalendarImportFrequencyLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportFrequencyLogType.php',
|
'PhabricatorCalendarImportFrequencyLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportFrequencyLogType.php',
|
||||||
|
'PhabricatorCalendarImportFrequencyTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportFrequencyTransaction.php',
|
||||||
'PhabricatorCalendarImportICSFileTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportICSFileTransaction.php',
|
'PhabricatorCalendarImportICSFileTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportICSFileTransaction.php',
|
||||||
'PhabricatorCalendarImportICSLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportICSLogType.php',
|
'PhabricatorCalendarImportICSLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportICSLogType.php',
|
||||||
'PhabricatorCalendarImportICSURITransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportICSURITransaction.php',
|
'PhabricatorCalendarImportICSURITransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportICSURITransaction.php',
|
||||||
|
@ -2139,10 +2140,12 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorCalendarImportQuery' => 'applications/calendar/query/PhabricatorCalendarImportQuery.php',
|
'PhabricatorCalendarImportQuery' => 'applications/calendar/query/PhabricatorCalendarImportQuery.php',
|
||||||
'PhabricatorCalendarImportReloadController' => 'applications/calendar/controller/PhabricatorCalendarImportReloadController.php',
|
'PhabricatorCalendarImportReloadController' => 'applications/calendar/controller/PhabricatorCalendarImportReloadController.php',
|
||||||
'PhabricatorCalendarImportReloadTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportReloadTransaction.php',
|
'PhabricatorCalendarImportReloadTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportReloadTransaction.php',
|
||||||
|
'PhabricatorCalendarImportReloadWorker' => 'applications/calendar/worker/PhabricatorCalendarImportReloadWorker.php',
|
||||||
'PhabricatorCalendarImportSearchEngine' => 'applications/calendar/query/PhabricatorCalendarImportSearchEngine.php',
|
'PhabricatorCalendarImportSearchEngine' => 'applications/calendar/query/PhabricatorCalendarImportSearchEngine.php',
|
||||||
'PhabricatorCalendarImportTransaction' => 'applications/calendar/storage/PhabricatorCalendarImportTransaction.php',
|
'PhabricatorCalendarImportTransaction' => 'applications/calendar/storage/PhabricatorCalendarImportTransaction.php',
|
||||||
'PhabricatorCalendarImportTransactionQuery' => 'applications/calendar/query/PhabricatorCalendarImportTransactionQuery.php',
|
'PhabricatorCalendarImportTransactionQuery' => 'applications/calendar/query/PhabricatorCalendarImportTransactionQuery.php',
|
||||||
'PhabricatorCalendarImportTransactionType' => 'applications/calendar/xaction/PhabricatorCalendarImportTransactionType.php',
|
'PhabricatorCalendarImportTransactionType' => 'applications/calendar/xaction/PhabricatorCalendarImportTransactionType.php',
|
||||||
|
'PhabricatorCalendarImportTriggerLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportTriggerLogType.php',
|
||||||
'PhabricatorCalendarImportUpdateLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportUpdateLogType.php',
|
'PhabricatorCalendarImportUpdateLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportUpdateLogType.php',
|
||||||
'PhabricatorCalendarImportViewController' => 'applications/calendar/controller/PhabricatorCalendarImportViewController.php',
|
'PhabricatorCalendarImportViewController' => 'applications/calendar/controller/PhabricatorCalendarImportViewController.php',
|
||||||
'PhabricatorCalendarRemarkupRule' => 'applications/calendar/remarkup/PhabricatorCalendarRemarkupRule.php',
|
'PhabricatorCalendarRemarkupRule' => 'applications/calendar/remarkup/PhabricatorCalendarRemarkupRule.php',
|
||||||
|
@ -6964,6 +6967,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorCalendarImportEpochLogType' => 'PhabricatorCalendarImportLogType',
|
'PhabricatorCalendarImportEpochLogType' => 'PhabricatorCalendarImportLogType',
|
||||||
'PhabricatorCalendarImportFetchLogType' => 'PhabricatorCalendarImportLogType',
|
'PhabricatorCalendarImportFetchLogType' => 'PhabricatorCalendarImportLogType',
|
||||||
'PhabricatorCalendarImportFrequencyLogType' => 'PhabricatorCalendarImportLogType',
|
'PhabricatorCalendarImportFrequencyLogType' => 'PhabricatorCalendarImportLogType',
|
||||||
|
'PhabricatorCalendarImportFrequencyTransaction' => 'PhabricatorCalendarImportTransactionType',
|
||||||
'PhabricatorCalendarImportICSFileTransaction' => 'PhabricatorCalendarImportTransactionType',
|
'PhabricatorCalendarImportICSFileTransaction' => 'PhabricatorCalendarImportTransactionType',
|
||||||
'PhabricatorCalendarImportICSLogType' => 'PhabricatorCalendarImportLogType',
|
'PhabricatorCalendarImportICSLogType' => 'PhabricatorCalendarImportLogType',
|
||||||
'PhabricatorCalendarImportICSURITransaction' => 'PhabricatorCalendarImportTransactionType',
|
'PhabricatorCalendarImportICSURITransaction' => 'PhabricatorCalendarImportTransactionType',
|
||||||
|
@ -6986,10 +6990,12 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorCalendarImportQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorCalendarImportQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorCalendarImportReloadController' => 'PhabricatorCalendarController',
|
'PhabricatorCalendarImportReloadController' => 'PhabricatorCalendarController',
|
||||||
'PhabricatorCalendarImportReloadTransaction' => 'PhabricatorCalendarImportTransactionType',
|
'PhabricatorCalendarImportReloadTransaction' => 'PhabricatorCalendarImportTransactionType',
|
||||||
|
'PhabricatorCalendarImportReloadWorker' => 'PhabricatorWorker',
|
||||||
'PhabricatorCalendarImportSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
'PhabricatorCalendarImportSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'PhabricatorCalendarImportTransaction' => 'PhabricatorModularTransaction',
|
'PhabricatorCalendarImportTransaction' => 'PhabricatorModularTransaction',
|
||||||
'PhabricatorCalendarImportTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
'PhabricatorCalendarImportTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
'PhabricatorCalendarImportTransactionType' => 'PhabricatorModularTransactionType',
|
'PhabricatorCalendarImportTransactionType' => 'PhabricatorModularTransactionType',
|
||||||
|
'PhabricatorCalendarImportTriggerLogType' => 'PhabricatorCalendarImportLogType',
|
||||||
'PhabricatorCalendarImportUpdateLogType' => 'PhabricatorCalendarImportLogType',
|
'PhabricatorCalendarImportUpdateLogType' => 'PhabricatorCalendarImportLogType',
|
||||||
'PhabricatorCalendarImportViewController' => 'PhabricatorCalendarController',
|
'PhabricatorCalendarImportViewController' => 'PhabricatorCalendarController',
|
||||||
'PhabricatorCalendarRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
'PhabricatorCalendarRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||||
|
|
|
@ -33,7 +33,7 @@ final class PhabricatorCalendarImportDropController
|
||||||
->addCancelButton($cancel_uri, pht('Done'));
|
->addCancelButton($cancel_uri, pht('Done'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$engine = new PhabricatorCalendarICSImportEngine();
|
$engine = new PhabricatorCalendarICSFileImportEngine();
|
||||||
$imports = array();
|
$imports = array();
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
$import = PhabricatorCalendarImport::initializeNewCalendarImport(
|
$import = PhabricatorCalendarImport::initializeNewCalendarImport(
|
||||||
|
|
|
@ -167,6 +167,50 @@ final class PhabricatorCalendarImportViewController
|
||||||
pht('Source Type'),
|
pht('Source Type'),
|
||||||
$engine->getImportEngineTypeName());
|
$engine->getImportEngineTypeName());
|
||||||
|
|
||||||
|
if ($import->getIsDisabled()) {
|
||||||
|
$auto_updates = phutil_tag('em', array(), pht('Import Disabled'));
|
||||||
|
$has_trigger = false;
|
||||||
|
} else {
|
||||||
|
$frequency = $import->getTriggerFrequency();
|
||||||
|
$frequency_map = PhabricatorCalendarImport::getTriggerFrequencyMap();
|
||||||
|
$frequency_names = ipull($frequency_map, 'name');
|
||||||
|
$auto_updates = idx($frequency_names, $frequency, $frequency);
|
||||||
|
|
||||||
|
if ($frequency == PhabricatorCalendarImport::FREQUENCY_ONCE) {
|
||||||
|
$has_trigger = false;
|
||||||
|
$auto_updates = phutil_tag('em', array(), $auto_updates);
|
||||||
|
} else {
|
||||||
|
$has_trigger = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$properties->addProperty(
|
||||||
|
pht('Automatic Updates'),
|
||||||
|
$auto_updates);
|
||||||
|
|
||||||
|
if ($has_trigger) {
|
||||||
|
$trigger = id(new PhabricatorWorkerTriggerQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($import->getTriggerPHID()))
|
||||||
|
->needEvents(true)
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if (!$trigger) {
|
||||||
|
$next_trigger = phutil_tag('em', array(), pht('Invalid Trigger'));
|
||||||
|
} else {
|
||||||
|
$now = PhabricatorTime::getNow();
|
||||||
|
$next_epoch = $trigger->getNextEventPrediction();
|
||||||
|
$next_trigger = pht(
|
||||||
|
'%s (%s)',
|
||||||
|
phabricator_datetime($next_epoch, $viewer),
|
||||||
|
phutil_format_relative_time($next_epoch - $now));
|
||||||
|
}
|
||||||
|
|
||||||
|
$properties->addProperty(
|
||||||
|
pht('Next Update'),
|
||||||
|
$next_trigger);
|
||||||
|
}
|
||||||
|
|
||||||
$engine->appendImportProperties(
|
$engine->appendImportProperties(
|
||||||
$viewer,
|
$viewer,
|
||||||
$import,
|
$import,
|
||||||
|
|
|
@ -80,6 +80,9 @@ final class PhabricatorCalendarImportEditEngine
|
||||||
protected function buildCustomEditFields($object) {
|
protected function buildCustomEditFields($object) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$engine = $object->getEngine();
|
||||||
|
$can_trigger = $engine->supportsTriggers($object);
|
||||||
|
|
||||||
$fields = array(
|
$fields = array(
|
||||||
id(new PhabricatorTextEditField())
|
id(new PhabricatorTextEditField())
|
||||||
->setKey('name')
|
->setKey('name')
|
||||||
|
@ -89,6 +92,7 @@ final class PhabricatorCalendarImportEditEngine
|
||||||
PhabricatorCalendarImportNameTransaction::TRANSACTIONTYPE)
|
PhabricatorCalendarImportNameTransaction::TRANSACTIONTYPE)
|
||||||
->setConduitDescription(pht('Rename the import.'))
|
->setConduitDescription(pht('Rename the import.'))
|
||||||
->setConduitTypeDescription(pht('New import name.'))
|
->setConduitTypeDescription(pht('New import name.'))
|
||||||
|
->setPlaceholder($object->getDisplayName())
|
||||||
->setValue($object->getName()),
|
->setValue($object->getName()),
|
||||||
id(new PhabricatorBoolEditField())
|
id(new PhabricatorBoolEditField())
|
||||||
->setKey('disabled')
|
->setKey('disabled')
|
||||||
|
@ -123,6 +127,22 @@ final class PhabricatorCalendarImportEditEngine
|
||||||
->setValue(false),
|
->setValue(false),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($can_trigger) {
|
||||||
|
$frequency_map = PhabricatorCalendarImport::getTriggerFrequencyMap();
|
||||||
|
$frequency_options = ipull($frequency_map, 'name');
|
||||||
|
|
||||||
|
$fields[] = id(new PhabricatorSelectEditField())
|
||||||
|
->setKey('frequency')
|
||||||
|
->setLabel(pht('Update Automatically'))
|
||||||
|
->setDescription(pht('Configure an automatic update frequncy.'))
|
||||||
|
->setTransactionType(
|
||||||
|
PhabricatorCalendarImportFrequencyTransaction::TRANSACTIONTYPE)
|
||||||
|
->setConduitDescription(pht('Set the automatic update frequency.'))
|
||||||
|
->setConduitTypeDescription(pht('Update frequency constant.'))
|
||||||
|
->setValue($object->getTriggerFrequency())
|
||||||
|
->setOptions($frequency_options);
|
||||||
|
}
|
||||||
|
|
||||||
$import_engine = $object->getEngine();
|
$import_engine = $object->getEngine();
|
||||||
foreach ($import_engine->newEditEngineFields($this, $object) as $field) {
|
foreach ($import_engine->newEditEngineFields($this, $object) as $field) {
|
||||||
$fields[] = $field;
|
$fields[] = $field;
|
||||||
|
|
|
@ -27,26 +27,112 @@ final class PhabricatorCalendarImportEditor
|
||||||
protected function applyFinalEffects(
|
protected function applyFinalEffects(
|
||||||
PhabricatorLiskDAO $object,
|
PhabricatorLiskDAO $object,
|
||||||
array $xactions) {
|
array $xactions) {
|
||||||
|
$actor = $this->getActor();
|
||||||
$type_reload = PhabricatorCalendarImportReloadTransaction::TRANSACTIONTYPE;
|
|
||||||
|
|
||||||
// We import events when you create a source, or if you later reload it
|
// We import events when you create a source, or if you later reload it
|
||||||
// explicitly.
|
// explicitly.
|
||||||
$should_reload = $this->getIsNewObject();
|
$should_reload = $this->getIsNewObject();
|
||||||
|
|
||||||
|
// We adjust the import trigger if you change the import frequency or
|
||||||
|
// disable the import.
|
||||||
|
$should_trigger = false;
|
||||||
|
|
||||||
foreach ($xactions as $xaction) {
|
foreach ($xactions as $xaction) {
|
||||||
if ($xaction->getTransactionType() == $type_reload) {
|
$xaction_type = $xaction->getTransactionType();
|
||||||
|
switch ($xaction_type) {
|
||||||
|
case PhabricatorCalendarImportReloadTransaction::TRANSACTIONTYPE:
|
||||||
$should_reload = true;
|
$should_reload = true;
|
||||||
break;
|
break;
|
||||||
|
case PhabricatorCalendarImportFrequencyTransaction::TRANSACTIONTYPE:
|
||||||
|
$should_trigger = true;
|
||||||
|
break;
|
||||||
|
case PhabricatorCalendarImportDisableTransaction::TRANSACTIONTYPE:
|
||||||
|
$should_trigger = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($should_reload) {
|
if ($should_reload) {
|
||||||
$actor = $this->getActor();
|
|
||||||
|
|
||||||
$import_engine = $object->getEngine();
|
$import_engine = $object->getEngine();
|
||||||
$import_engine->importEventsFromSource($actor, $object);
|
$import_engine->importEventsFromSource($actor, $object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($should_trigger) {
|
||||||
|
$trigger_phid = $object->getTriggerPHID();
|
||||||
|
if ($trigger_phid) {
|
||||||
|
$trigger = id(new PhabricatorWorkerTriggerQuery())
|
||||||
|
->setViewer($actor)
|
||||||
|
->withPHIDs(array($trigger_phid))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if ($trigger) {
|
||||||
|
$engine = new PhabricatorDestructionEngine();
|
||||||
|
$engine->destroyObject($trigger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$frequency = $object->getTriggerFrequency();
|
||||||
|
$now = PhabricatorTime::getNow();
|
||||||
|
switch ($frequency) {
|
||||||
|
case PhabricatorCalendarImport::FREQUENCY_ONCE:
|
||||||
|
$clock = null;
|
||||||
|
break;
|
||||||
|
case PhabricatorCalendarImport::FREQUENCY_HOURLY:
|
||||||
|
$clock = new PhabricatorMetronomicTriggerClock(
|
||||||
|
array(
|
||||||
|
'period' => phutil_units('1 hour in seconds'),
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case PhabricatorCalendarImport::FREQUENCY_DAILY:
|
||||||
|
$clock = new PhabricatorDailyRoutineTriggerClock(
|
||||||
|
array(
|
||||||
|
'start' => $now,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Unknown import trigger frequency "%s".',
|
||||||
|
$frequency));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the object has been disabled, don't write a new trigger.
|
||||||
|
if ($object->getIsDisabled()) {
|
||||||
|
$clock = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($clock) {
|
||||||
|
$trigger_action = new PhabricatorScheduleTaskTriggerAction(
|
||||||
|
array(
|
||||||
|
'class' => 'PhabricatorCalendarImportReloadWorker',
|
||||||
|
'data' => array(
|
||||||
|
'importPHID' => $object->getPHID(),
|
||||||
|
),
|
||||||
|
'options' => array(
|
||||||
|
'objectPHID' => $object->getPHID(),
|
||||||
|
'priority' => PhabricatorWorker::PRIORITY_BULK,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$trigger_phid = PhabricatorPHID::generateNewPHID(
|
||||||
|
PhabricatorWorkerTriggerPHIDType::TYPECONST);
|
||||||
|
|
||||||
|
$object
|
||||||
|
->setTriggerPHID($trigger_phid)
|
||||||
|
->save();
|
||||||
|
|
||||||
|
$trigger = id(new PhabricatorWorkerTrigger())
|
||||||
|
->setClock($clock)
|
||||||
|
->setAction($trigger_action)
|
||||||
|
->setPHID($trigger_phid)
|
||||||
|
->save();
|
||||||
|
} else {
|
||||||
|
$object
|
||||||
|
->setTriggerPHID(null)
|
||||||
|
->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $xactions;
|
return $xactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@ final class PhabricatorCalendarICSFileImportEngine
|
||||||
return pht('Import an event in ".ics" (iCalendar) format.');
|
return pht('Import an event in ".ics" (iCalendar) format.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function supportsTriggers(PhabricatorCalendarImport $import) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function appendImportProperties(
|
public function appendImportProperties(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorCalendarImport $import,
|
PhabricatorCalendarImport $import,
|
||||||
|
|
|
@ -17,6 +17,10 @@ final class PhabricatorCalendarICSURIImportEngine
|
||||||
return pht('Import or subscribe to a calendar in .ics format by URI.');
|
return pht('Import or subscribe to a calendar in .ics format by URI.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function supportsTriggers(PhabricatorCalendarImport $import) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public function appendImportProperties(
|
public function appendImportProperties(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorCalendarImport $import,
|
PhabricatorCalendarImport $import,
|
||||||
|
|
|
@ -39,6 +39,9 @@ abstract class PhabricatorCalendarImportEngine
|
||||||
throw new PhutilMethodNotImplementedException();
|
throw new PhutilMethodNotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract public function supportsTriggers(
|
||||||
|
PhabricatorCalendarImport $import);
|
||||||
|
|
||||||
final public static function getAllImportEngines() {
|
final public static function getAllImportEngines() {
|
||||||
return id(new PhutilClassMapQuery())
|
return id(new PhutilClassMapQuery())
|
||||||
->setAncestorClass(__CLASS__)
|
->setAncestorClass(__CLASS__)
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorCalendarImportTriggerLogType
|
||||||
|
extends PhabricatorCalendarImportLogType {
|
||||||
|
|
||||||
|
const LOGTYPE = 'trigger';
|
||||||
|
|
||||||
|
public function getDisplayType(
|
||||||
|
PhabricatorUser $viewer,
|
||||||
|
PhabricatorCalendarImportLog $log) {
|
||||||
|
return pht('Import Triggered');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDisplayDescription(
|
||||||
|
PhabricatorUser $viewer,
|
||||||
|
PhabricatorCalendarImportLog $log) {
|
||||||
|
return pht('Triggered a periodic update.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDisplayIcon(
|
||||||
|
PhabricatorUser $viewer,
|
||||||
|
PhabricatorCalendarImportLog $log) {
|
||||||
|
return 'fa-clock-o';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDisplayColor(
|
||||||
|
PhabricatorUser $viewer,
|
||||||
|
PhabricatorCalendarImportLog $log) {
|
||||||
|
return 'blue';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,6 +14,12 @@ final class PhabricatorCalendarImport
|
||||||
protected $engineType;
|
protected $engineType;
|
||||||
protected $parameters = array();
|
protected $parameters = array();
|
||||||
protected $isDisabled = 0;
|
protected $isDisabled = 0;
|
||||||
|
protected $triggerPHID;
|
||||||
|
protected $triggerFrequency;
|
||||||
|
|
||||||
|
const FREQUENCY_ONCE = 'once';
|
||||||
|
const FREQUENCY_HOURLY = 'hourly';
|
||||||
|
const FREQUENCY_DAILY = 'daily';
|
||||||
|
|
||||||
private $engine = self::ATTACHABLE;
|
private $engine = self::ATTACHABLE;
|
||||||
|
|
||||||
|
@ -27,7 +33,8 @@ final class PhabricatorCalendarImport
|
||||||
->setEditPolicy($actor->getPHID())
|
->setEditPolicy($actor->getPHID())
|
||||||
->setIsDisabled(0)
|
->setIsDisabled(0)
|
||||||
->setEngineType($engine->getImportEngineType())
|
->setEngineType($engine->getImportEngineType())
|
||||||
->attachEngine($engine);
|
->attachEngine($engine)
|
||||||
|
->setTriggerFrequency(self::FREQUENCY_ONCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getConfiguration() {
|
protected function getConfiguration() {
|
||||||
|
@ -40,6 +47,8 @@ final class PhabricatorCalendarImport
|
||||||
'name' => 'text',
|
'name' => 'text',
|
||||||
'engineType' => 'text64',
|
'engineType' => 'text64',
|
||||||
'isDisabled' => 'bool',
|
'isDisabled' => 'bool',
|
||||||
|
'triggerPHID' => 'phid?',
|
||||||
|
'triggerFrequency' => 'text64',
|
||||||
),
|
),
|
||||||
self::CONFIG_KEY_SCHEMA => array(
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
'key_author' => array(
|
'key_author' => array(
|
||||||
|
@ -85,6 +94,21 @@ final class PhabricatorCalendarImport
|
||||||
return $this->getEngine()->getDisplayName($this);
|
return $this->getEngine()->getDisplayName($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getTriggerFrequencyMap() {
|
||||||
|
return array(
|
||||||
|
self::FREQUENCY_ONCE => array(
|
||||||
|
'name' => pht('No Automatic Updates'),
|
||||||
|
),
|
||||||
|
self::FREQUENCY_HOURLY => array(
|
||||||
|
'name' => pht('Update Hourly'),
|
||||||
|
),
|
||||||
|
self::FREQUENCY_DAILY => array(
|
||||||
|
'name' => pht('Update Daily'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,6 +179,17 @@ final class PhabricatorCalendarImport
|
||||||
|
|
||||||
$this->openTransaction();
|
$this->openTransaction();
|
||||||
|
|
||||||
|
$trigger_phid = $this->getTriggerPHID();
|
||||||
|
if ($trigger_phid) {
|
||||||
|
$trigger = id(new PhabricatorWorkerTriggerQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($trigger_phid))
|
||||||
|
->executeOne();
|
||||||
|
if ($trigger) {
|
||||||
|
$engine->destroyObject($trigger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$events = id(new PhabricatorCalendarEventQuery())
|
$events = id(new PhabricatorCalendarEventQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withImportSourcePHIDs(array($this->getPHID()))
|
->withImportSourcePHIDs(array($this->getPHID()))
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorCalendarImportReloadWorker extends PhabricatorWorker {
|
||||||
|
|
||||||
|
protected function doWork() {
|
||||||
|
$import = $this->loadImport();
|
||||||
|
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||||
|
|
||||||
|
if ($import->getIsDisabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$author = id(new PhabricatorPeopleQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($import->getAuthorPHID()))
|
||||||
|
->needUserSettings(true)
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
$import_engine = $import->getEngine();
|
||||||
|
|
||||||
|
$import->newLogMessage(
|
||||||
|
PhabricatorCalendarImportTriggerLogType::LOGTYPE,
|
||||||
|
array());
|
||||||
|
|
||||||
|
$import_engine->importEventsFromSource($author, $import);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loadImport() {
|
||||||
|
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||||
|
|
||||||
|
$data = $this->getTaskData();
|
||||||
|
$import_phid = idx($data, 'importPHID');
|
||||||
|
|
||||||
|
$import = id(new PhabricatorCalendarImportQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($import_phid))
|
||||||
|
->executeOne();
|
||||||
|
if (!$import) {
|
||||||
|
throw new PhabricatorWorkerPermanentFailureException(
|
||||||
|
pht(
|
||||||
|
'Failed to load import with PHID "%s".',
|
||||||
|
$import_phid));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $import;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorCalendarImportFrequencyTransaction
|
||||||
|
extends PhabricatorCalendarImportTransactionType {
|
||||||
|
|
||||||
|
const TRANSACTIONTYPE = 'calendar.import.frequency';
|
||||||
|
|
||||||
|
public function generateOldValue($object) {
|
||||||
|
return $object->getTriggerFrequency();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyInternalEffects($object, $value) {
|
||||||
|
$object->setTriggerFrequency($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle() {
|
||||||
|
return pht(
|
||||||
|
'%s changed the automatic update frequency for this import.',
|
||||||
|
$this->renderAuthor());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateTransactions($object, array $xactions) {
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
$frequency_map = PhabricatorCalendarImport::getTriggerFrequencyMap();
|
||||||
|
$valid = array_keys($frequency_map);
|
||||||
|
$valid = array_fuse($valid);
|
||||||
|
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$value = $xaction->getNewValue();
|
||||||
|
|
||||||
|
if (!isset($valid[$value])) {
|
||||||
|
$errors[] = $this->newInvalidError(
|
||||||
|
pht(
|
||||||
|
'Import frequency "%s" is not valid. Valid frequences are: %s.',
|
||||||
|
$value,
|
||||||
|
implode(', ', $valid)),
|
||||||
|
$xaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue