Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14006619
D15440.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
27 KB
Referenced Files
None
Subscribers
None
D15440.id.diff
View Options
diff --git a/resources/sql/autopatches/20160308.nuance.06.label.sql b/resources/sql/autopatches/20160308.nuance.06.label.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160308.nuance.06.label.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_nuance.nuance_item
+ DROP sourceLabel;
diff --git a/resources/sql/autopatches/20160308.nuance.07.itemtype.sql b/resources/sql/autopatches/20160308.nuance.07.itemtype.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160308.nuance.07.itemtype.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_nuance.nuance_item
+ ADD itemType VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20160308.nuance.08.itemkey.sql b/resources/sql/autopatches/20160308.nuance.08.itemkey.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160308.nuance.08.itemkey.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_nuance.nuance_item
+ ADD itemKey VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20160308.nuance.09.itemcontainer.sql b/resources/sql/autopatches/20160308.nuance.09.itemcontainer.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160308.nuance.09.itemcontainer.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_nuance.nuance_item
+ ADD itemContainerKey VARCHAR(64) COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20160308.nuance.10.itemkeyu.sql b/resources/sql/autopatches/20160308.nuance.10.itemkeyu.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160308.nuance.10.itemkeyu.sql
@@ -0,0 +1,2 @@
+UPDATE {$NAMESPACE}_nuance.nuance_item
+ SET itemKey = id WHERE itemKey = '';
diff --git a/resources/sql/autopatches/20160308.nuance.11.requestor.sql b/resources/sql/autopatches/20160308.nuance.11.requestor.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160308.nuance.11.requestor.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_nuance.nuance_item
+ CHANGE requestorPHID requestorPHID VARBINARY(64);
diff --git a/resources/sql/autopatches/20160308.nuance.12.queue.sql b/resources/sql/autopatches/20160308.nuance.12.queue.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160308.nuance.12.queue.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_nuance.nuance_item
+ CHANGE queuePHID queuePHID VARBINARY(64);
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1419,7 +1419,6 @@
'NuanceConduitAPIMethod' => 'applications/nuance/conduit/NuanceConduitAPIMethod.php',
'NuanceConsoleController' => 'applications/nuance/controller/NuanceConsoleController.php',
'NuanceController' => 'applications/nuance/controller/NuanceController.php',
- 'NuanceCreateItemConduitAPIMethod' => 'applications/nuance/conduit/NuanceCreateItemConduitAPIMethod.php',
'NuanceDAO' => 'applications/nuance/storage/NuanceDAO.php',
'NuanceGitHubRepositoryImportCursor' => 'applications/nuance/cursor/NuanceGitHubRepositoryImportCursor.php',
'NuanceGitHubRepositorySourceDefinition' => 'applications/nuance/source/NuanceGitHubRepositorySourceDefinition.php',
@@ -1428,10 +1427,13 @@
'NuanceImportCursorDataQuery' => 'applications/nuance/query/NuanceImportCursorDataQuery.php',
'NuanceImportCursorPHIDType' => 'applications/nuance/phid/NuanceImportCursorPHIDType.php',
'NuanceItem' => 'applications/nuance/storage/NuanceItem.php',
+ 'NuanceItemController' => 'applications/nuance/controller/NuanceItemController.php',
'NuanceItemEditController' => 'applications/nuance/controller/NuanceItemEditController.php',
'NuanceItemEditor' => 'applications/nuance/editor/NuanceItemEditor.php',
+ 'NuanceItemListController' => 'applications/nuance/controller/NuanceItemListController.php',
'NuanceItemPHIDType' => 'applications/nuance/phid/NuanceItemPHIDType.php',
'NuanceItemQuery' => 'applications/nuance/query/NuanceItemQuery.php',
+ 'NuanceItemSearchEngine' => 'applications/nuance/query/NuanceItemSearchEngine.php',
'NuanceItemTransaction' => 'applications/nuance/storage/NuanceItemTransaction.php',
'NuanceItemTransactionComment' => 'applications/nuance/storage/NuanceItemTransactionComment.php',
'NuanceItemTransactionQuery' => 'applications/nuance/query/NuanceItemTransactionQuery.php',
@@ -5668,12 +5670,14 @@
'NuanceConduitAPIMethod' => 'ConduitAPIMethod',
'NuanceConsoleController' => 'NuanceController',
'NuanceController' => 'PhabricatorController',
- 'NuanceCreateItemConduitAPIMethod' => 'NuanceConduitAPIMethod',
'NuanceDAO' => 'PhabricatorLiskDAO',
'NuanceGitHubRepositoryImportCursor' => 'NuanceImportCursor',
'NuanceGitHubRepositorySourceDefinition' => 'NuanceSourceDefinition',
'NuanceImportCursor' => 'Phobject',
- 'NuanceImportCursorData' => 'NuanceDAO',
+ 'NuanceImportCursorData' => array(
+ 'NuanceDAO',
+ 'PhabricatorPolicyInterface',
+ ),
'NuanceImportCursorDataQuery' => 'NuanceQuery',
'NuanceImportCursorPHIDType' => 'PhabricatorPHIDType',
'NuanceItem' => array(
@@ -5681,10 +5685,13 @@
'PhabricatorPolicyInterface',
'PhabricatorApplicationTransactionInterface',
),
+ 'NuanceItemController' => 'NuanceController',
'NuanceItemEditController' => 'NuanceController',
'NuanceItemEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'NuanceItemListController' => 'NuanceItemController',
'NuanceItemPHIDType' => 'PhabricatorPHIDType',
'NuanceItemQuery' => 'NuanceQuery',
+ 'NuanceItemSearchEngine' => 'PhabricatorApplicationSearchEngine',
'NuanceItemTransaction' => 'NuanceTransaction',
'NuanceItemTransactionComment' => 'PhabricatorApplicationTransactionComment',
'NuanceItemTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
diff --git a/src/applications/nuance/application/PhabricatorNuanceApplication.php b/src/applications/nuance/application/PhabricatorNuanceApplication.php
--- a/src/applications/nuance/application/PhabricatorNuanceApplication.php
+++ b/src/applications/nuance/application/PhabricatorNuanceApplication.php
@@ -40,6 +40,7 @@
'/nuance/' => array(
'' => 'NuanceConsoleController',
'item/' => array(
+ $this->getQueryRoutePattern() => 'NuanceItemListController',
'view/(?P<id>[1-9]\d*)/' => 'NuanceItemViewController',
'edit/(?P<id>[1-9]\d*)/' => 'NuanceItemEditController',
'new/' => 'NuanceItemEditController',
diff --git a/src/applications/nuance/conduit/NuanceCreateItemConduitAPIMethod.php b/src/applications/nuance/conduit/NuanceCreateItemConduitAPIMethod.php
deleted file mode 100644
--- a/src/applications/nuance/conduit/NuanceCreateItemConduitAPIMethod.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-
-final class NuanceCreateItemConduitAPIMethod extends NuanceConduitAPIMethod {
-
- public function getAPIMethodName() {
- return 'nuance.createitem';
- }
-
- public function getMethodDescription() {
- return pht('Create a new item.');
- }
-
- protected function defineParamTypes() {
- return array(
- 'requestorPHID' => 'required string',
- 'sourcePHID' => 'required string',
- 'ownerPHID' => 'optional string',
- );
- }
-
- protected function defineReturnType() {
- return 'nonempty dict';
- }
-
- protected function defineErrorTypes() {
- return array(
- 'ERR-NO-REQUESTOR-PHID' => pht('Items must have a requestor.'),
- 'ERR-NO-SOURCE-PHID' => pht('Items must have a source.'),
- );
- }
-
- protected function execute(ConduitAPIRequest $request) {
- $source_phid = $request->getValue('sourcePHID');
- $owner_phid = $request->getValue('ownerPHID');
- $requestor_phid = $request->getValue('requestorPHID');
-
- $user = $request->getUser();
-
- $item = NuanceItem::initializeNewItem();
- $xactions = array();
-
- if ($source_phid) {
- $xactions[] = id(new NuanceItemTransaction())
- ->setTransactionType(NuanceItemTransaction::TYPE_SOURCE)
- ->setNewValue($source_phid);
- } else {
- throw new ConduitException('ERR-NO-SOURCE-PHID');
- }
-
- if ($owner_phid) {
- $xactions[] = id(new NuanceItemTransaction())
- ->setTransactionType(NuanceItemTransaction::TYPE_OWNER)
- ->setNewValue($owner_phid);
- }
-
- if ($requestor_phid) {
- $xactions[] = id(new NuanceItemTransaction())
- ->setTransactionType(NuanceItemTransaction::TYPE_REQUESTOR)
- ->setNewValue($requestor_phid);
- } else {
- throw new ConduitException('ERR-NO-REQUESTOR-PHID');
- }
-
- $source = PhabricatorContentSource::newFromConduitRequest($request);
- $editor = id(new NuanceItemEditor())
- ->setActor($user)
- ->setContentSource($source)
- ->applyTransactions($item, $xactions);
-
- return $item->toDictionary();
- }
-
-}
diff --git a/src/applications/nuance/controller/NuanceConsoleController.php b/src/applications/nuance/controller/NuanceConsoleController.php
--- a/src/applications/nuance/controller/NuanceConsoleController.php
+++ b/src/applications/nuance/controller/NuanceConsoleController.php
@@ -26,6 +26,13 @@
->setIcon('fa-filter')
->addAttribute(pht('Manage Nuance sources.')));
+ $menu->addItem(
+ id(new PHUIObjectItemView())
+ ->setHeader(pht('Items'))
+ ->setHref($this->getApplicationURI('item/'))
+ ->setIcon('fa-clone')
+ ->addAttribute(pht('Manage Nuance items.')));
+
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Console'));
diff --git a/src/applications/nuance/controller/NuanceItemController.php b/src/applications/nuance/controller/NuanceItemController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/nuance/controller/NuanceItemController.php
@@ -0,0 +1,11 @@
+<?php
+
+abstract class NuanceItemController
+ extends NuanceController {
+
+ public function buildApplicationMenu() {
+ return $this->newApplicationMenu()
+ ->setSearchEngine(new NuanceItemSearchEngine());
+ }
+
+}
diff --git a/src/applications/nuance/controller/NuanceItemEditController.php b/src/applications/nuance/controller/NuanceItemEditController.php
--- a/src/applications/nuance/controller/NuanceItemEditController.php
+++ b/src/applications/nuance/controller/NuanceItemEditController.php
@@ -74,7 +74,7 @@
$viewer->renderHandle($item->getQueuePHID()));
$source = $item->getSource();
- $definition = $source->requireDefinition();
+ $definition = $source->getDefinition();
$definition->renderItemEditProperties(
$viewer,
diff --git a/src/applications/nuance/controller/NuanceItemListController.php b/src/applications/nuance/controller/NuanceItemListController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/nuance/controller/NuanceItemListController.php
@@ -0,0 +1,12 @@
+<?php
+
+final class NuanceItemListController
+ extends NuanceItemController {
+
+ public function handleRequest(AphrontRequest $request) {
+ return id(new NuanceItemSearchEngine())
+ ->setController($this)
+ ->buildResponse();
+ }
+
+}
diff --git a/src/applications/nuance/cursor/NuanceGitHubRepositoryImportCursor.php b/src/applications/nuance/cursor/NuanceGitHubRepositoryImportCursor.php
--- a/src/applications/nuance/cursor/NuanceGitHubRepositoryImportCursor.php
+++ b/src/applications/nuance/cursor/NuanceGitHubRepositoryImportCursor.php
@@ -37,44 +37,146 @@
}
protected function pullDataFromSource() {
+ $viewer = $this->getViewer();
+ $now = PhabricatorTime::getNow();
+
$source = $this->getSource();
$user = $source->getSourceProperty('github.user');
$repository = $source->getSourceProperty('github.repository');
$api_token = $source->getSourceProperty('github.token');
- $uri = "/repos/{$user}/{$repository}/events";
- $data = array();
+ // This API only supports fetching 10 pages of 30 events each, for a total
+ // of 300 events.
+ $etag = null;
+ $new_items = array();
+ $hit_known_items = false;
+ for ($page = 1; $page <= 10; $page++) {
+ $uri = "/repos/{$user}/{$repository}/events";
+ $data = array(
+ 'page' => $page,
+ );
+
+ $future = id(new PhutilGitHubFuture())
+ ->setAccessToken($api_token)
+ ->setRawGitHubQuery($uri, $data);
+
+ if ($page == 1) {
+ $cursor_etag = $this->getCursorProperty('github.poll.etag');
+ if ($cursor_etag) {
+ $future->addHeader('If-None-Match', $cursor_etag);
+ }
+ }
+
+ $this->logInfo(
+ pht(
+ 'Polling GitHub Repository API endpoint "%s".',
+ $uri));
+ $response = $future->resolve();
+
+ // Do this first: if we hit the rate limit, we get a response but the
+ // body isn't valid.
+ $this->updateRateLimits($response);
+
+ if ($response->getStatus()->getStatusCode() == 304) {
+ $this->logInfo(
+ pht(
+ 'Received a 304 Not Modified from GitHub, no new events.'));
+ }
+
+ // This means we hit a rate limit or a "Not Modified" because of the
+ // "ETag" header. In either case, we should bail out.
+ if ($response->getStatus()->isError()) {
+ $this->updatePolling($response, $now, false);
+ $this->getCursorData()->save();
+ return false;
+ }
+
+ if ($page == 1) {
+ $etag = $response->getHeaderValue('ETag');
+ }
+
+ $records = $response->getBody();
+ foreach ($records as $record) {
+ $item = $this->newNuanceItemFromGitHubEvent($record);
+ $item_key = $item->getItemKey();
- $future = id(new PhutilGitHubFuture())
- ->setAccessToken($api_token)
- ->setRawGitHubQuery($uri, $data);
+ $this->logInfo(
+ pht(
+ 'Fetched event "%s".',
+ $item_key));
- $etag = $this->getCursorProperty('github.poll.etag');
- if ($etag) {
- $future->addHeader('If-None-Match', $etag);
+ $new_items[$item->getItemKey()] = $item;
+ }
+
+ if ($new_items) {
+ $existing = id(new NuanceItemQuery())
+ ->setViewer($viewer)
+ ->withSourcePHIDs(array($source->getPHID()))
+ ->withItemKeys(array_keys($new_items))
+ ->execute();
+ $existing = mpull($existing, null, 'getItemKey');
+ foreach ($new_items as $key => $new_item) {
+ if (isset($existing[$key])) {
+ unset($new_items[$key]);
+ $hit_known_items = true;
+
+ $this->logInfo(
+ pht(
+ 'Event "%s" is previously known.',
+ $key));
+ }
+ }
+ }
+
+ if ($hit_known_items) {
+ break;
+ }
+
+ if (count($records) < 30) {
+ break;
+ }
}
- $this->logInfo(
- pht(
- 'Polling GitHub Repository API endpoint "%s".',
- $uri));
- $response = $future->resolve();
-
- // Do this first: if we hit the rate limit, we get a response but the
- // body isn't valid.
- $this->updateRateLimits($response);
-
- // This means we hit a rate limit or a "Not Modified" because of the "ETag"
- // header. In either case, we should bail out.
- if ($response->getStatus()->isError()) {
- // TODO: Save cursor data!
- return false;
+ // TODO: When we go through the whole queue without hitting anything we
+ // have seen before, we should record some sort of global event so we
+ // can tell the user when the bridging started or was interrupted?
+ if (!$hit_known_items) {
+ $already_polled = $this->getCursorProperty('github.polled');
+ if ($already_polled) {
+ // TODO: This is bad: we missed some items, maybe because too much
+ // stuff happened too fast or the daemons were broken for a long
+ // time.
+ } else {
+ // TODO: This is OK, we're doing the initial import.
+ }
+ }
+
+ if ($etag !== null) {
+ $this->updateETag($etag);
}
- $this->updateETag($response);
+ $this->updatePolling($response, $now, true);
- var_dump($response->getBody());
+ $source->openTransaction();
+ foreach ($new_items as $new_item) {
+ $new_item->save();
+ }
+ $this->getCursorData()->save();
+ $source->saveTransaction();
+
+ foreach ($new_items as $new_item) {
+ PhabricatorWorker::scheduleTask(
+ 'NuanceImportWorker',
+ array(
+ 'itemPHID' => $new_item->getPHID(),
+ ),
+ array(
+ 'objectPHID' => $new_item->getPHID(),
+ ));
+ }
+
+ return false;
}
private function updateRateLimits(PhutilGitHubResponse $response) {
@@ -100,8 +202,7 @@
new PhutilNumber($limit_reset - $now)));
}
- private function updateETag(PhutilGitHubResponse $response) {
- $etag = $response->getHeaderValue('ETag');
+ private function updateETag($etag) {
$this->setCursorProperty('github.poll.etag', $etag);
@@ -111,4 +212,54 @@
$etag));
}
+ private function updatePolling(
+ PhutilGitHubResponse $response,
+ $start,
+ $success) {
+
+ if ($success) {
+ $this->setCursorProperty('github.polled', true);
+ }
+
+ $poll_interval = (int)$response->getHeaderValue('X-Poll-Interval');
+ $poll_ttl = $start + $poll_interval;
+ $this->setCursorProperty('github.poll.ttl', $poll_ttl);
+
+ $now = PhabricatorTime::getNow();
+
+ $this->logInfo(
+ pht(
+ 'Set API poll TTL to +%s second(s) (%s second(s) from now).',
+ new PhutilNumber($poll_interval),
+ new PhutilNumber($poll_ttl - $now)));
+ }
+
+ private function newNuanceItemFromGitHubEvent(array $record) {
+ $source = $this->getSource();
+
+ $id = $record['id'];
+ $item_key = "github.event.{$id}";
+
+ $container_key = null;
+
+ $issue_id = idxv(
+ $record,
+ array(
+ 'payload',
+ 'issue',
+ 'id',
+ ));
+ if ($issue_id) {
+ $container_key = "github.issue.{$issue_id}";
+ }
+
+ return NuanceItem::initializeNewItem()
+ ->setStatus(NuanceItem::STATUS_IMPORTING)
+ ->setSourcePHID($source->getPHID())
+ ->setItemType('github.event')
+ ->setItemKey($item_key)
+ ->setItemContainerKey($container_key)
+ ->setItemProperty('api.raw', $record);
+ }
+
}
diff --git a/src/applications/nuance/cursor/NuanceImportCursor.php b/src/applications/nuance/cursor/NuanceImportCursor.php
--- a/src/applications/nuance/cursor/NuanceImportCursor.php
+++ b/src/applications/nuance/cursor/NuanceImportCursor.php
@@ -5,6 +5,7 @@
private $cursorData;
private $cursorKey;
private $source;
+ private $viewer;
abstract protected function shouldPullDataFromSource();
abstract protected function pullDataFromSource();
@@ -40,6 +41,15 @@
return $this->cursorKey;
}
+ public function setViewer($viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ public function getViewer() {
+ return $this->viewer;
+ }
+
final public function importFromSource() {
if (!$this->shouldPullDataFromSource()) {
return false;
diff --git a/src/applications/nuance/query/NuanceItemQuery.php b/src/applications/nuance/query/NuanceItemQuery.php
--- a/src/applications/nuance/query/NuanceItemQuery.php
+++ b/src/applications/nuance/query/NuanceItemQuery.php
@@ -6,6 +6,9 @@
private $ids;
private $phids;
private $sourcePHIDs;
+ private $itemTypes;
+ private $itemKeys;
+ private $containerKeys;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -22,6 +25,21 @@
return $this;
}
+ public function withItemTypes(array $item_types) {
+ $this->itemTypes = $item_types;
+ return $this;
+ }
+
+ public function withItemKeys(array $item_keys) {
+ $this->itemKeys = $item_keys;
+ return $this;
+ }
+
+ public function withItemContainerKeys(array $container_keys) {
+ $this->containerKeys = $container_keys;
+ return $this;
+ }
+
public function newResultObject() {
return new NuanceItem();
}
@@ -79,6 +97,27 @@
$this->phids);
}
+ if ($this->itemTypes !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'itemType IN (%Ls)',
+ $this->itemTypes);
+ }
+
+ if ($this->itemKeys !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'itemKey IN (%Ls)',
+ $this->itemKeys);
+ }
+
+ if ($this->containerKeys !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'itemContainerKey IN (%Ls)',
+ $this->containerKeys);
+ }
+
return $where;
}
diff --git a/src/applications/nuance/query/NuanceItemSearchEngine.php b/src/applications/nuance/query/NuanceItemSearchEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/nuance/query/NuanceItemSearchEngine.php
@@ -0,0 +1,81 @@
+<?php
+
+final class NuanceItemSearchEngine
+ extends PhabricatorApplicationSearchEngine {
+
+ public function getApplicationClassName() {
+ return 'PhabricatorNuanceApplication';
+ }
+
+ public function getResultTypeDescription() {
+ return pht('Nuance Items');
+ }
+
+ public function newQuery() {
+ return new NuanceItemQuery();
+ }
+
+ protected function buildQueryFromParameters(array $map) {
+ $query = $this->newQuery();
+
+ return $query;
+ }
+
+ protected function buildCustomSearchFields() {
+ return array(
+ );
+ }
+
+ protected function getURI($path) {
+ return '/nuance/item/'.$path;
+ }
+
+ protected function getBuiltinQueryNames() {
+ $names = array(
+ 'all' => pht('All Items'),
+ );
+
+ return $names;
+ }
+
+ public function buildSavedQueryFromBuiltin($query_key) {
+ $query = $this->newSavedQuery();
+ $query->setQueryKey($query_key);
+
+ switch ($query_key) {
+ case 'all':
+ return $query;
+ }
+
+ return parent::buildSavedQueryFromBuiltin($query_key);
+ }
+
+ protected function renderResultList(
+ array $items,
+ PhabricatorSavedQuery $query,
+ array $handles) {
+ assert_instances_of($items, 'NuanceItem');
+
+ $viewer = $this->requireViewer();
+
+ $list = new PHUIObjectItemListView();
+ $list->setUser($viewer);
+ foreach ($items as $item) {
+ $view = id(new PHUIObjectItemView())
+ ->setObjectName(pht('Item %d', $item->getID()))
+ ->setHeader($item->getDisplayName())
+ ->setHref($item->getURI());
+
+ $view->addIcon('none', $item->getItemType());
+
+ $list->addItem($view);
+ }
+
+ $result = new PhabricatorApplicationSearchResultView();
+ $result->setObjectList($list);
+ $result->setNoDataString(pht('No items found.'));
+
+ return $result;
+ }
+
+}
diff --git a/src/applications/nuance/source/NuanceSourceDefinition.php b/src/applications/nuance/source/NuanceSourceDefinition.php
--- a/src/applications/nuance/source/NuanceSourceDefinition.php
+++ b/src/applications/nuance/source/NuanceSourceDefinition.php
@@ -53,14 +53,15 @@
pht('This source has no input cursors.'));
}
+ $viewer = PhabricatorUser::getOmnipotentUser();
$source = $this->getSource();
$cursors = $this->newImportCursors();
$data = id(new NuanceImportCursorDataQuery())
- ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->setViewer($viewer)
->withSourcePHIDs(array($source->getPHID()))
->execute();
- $data = mpull($data, 'getCursorKey');
+ $data = mpull($data, null, 'getCursorKey');
$map = array();
foreach ($cursors as $cursor) {
@@ -102,14 +103,15 @@
$map[$key] = $cursor;
- $cursor->setSource($source);
-
$cursor_data = idx($data, $key);
if (!$cursor_data) {
$cursor_data = $cursor->newEmptyCursorData($source);
}
- $cursor->setCursorData($cursor_data);
+ $cursor
+ ->setViewer($viewer)
+ ->setSource($source)
+ ->setCursorData($cursor_data);
}
return $cursors;
diff --git a/src/applications/nuance/storage/NuanceImportCursorData.php b/src/applications/nuance/storage/NuanceImportCursorData.php
--- a/src/applications/nuance/storage/NuanceImportCursorData.php
+++ b/src/applications/nuance/storage/NuanceImportCursorData.php
@@ -1,7 +1,8 @@
<?php
final class NuanceImportCursorData
- extends NuanceDAO {
+ extends NuanceDAO
+ implements PhabricatorPolicyInterface {
protected $sourcePHID;
protected $cursorKey;
@@ -41,4 +42,29 @@
return $this;
}
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ );
+ }
+
+ public function getPolicy($capability) {
+ switch ($capability) {
+ case PhabricatorPolicyCapability::CAN_VIEW:
+ return PhabricatorPolicies::POLICY_USER;
+ }
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return null;
+ }
+
}
diff --git a/src/applications/nuance/storage/NuanceItem.php b/src/applications/nuance/storage/NuanceItem.php
--- a/src/applications/nuance/storage/NuanceItem.php
+++ b/src/applications/nuance/storage/NuanceItem.php
@@ -6,18 +6,21 @@
PhabricatorPolicyInterface,
PhabricatorApplicationTransactionInterface {
- const STATUS_OPEN = 0;
- const STATUS_ASSIGNED = 10;
- const STATUS_CLOSED = 20;
+ const STATUS_IMPORTING = 'importing';
+ const STATUS_OPEN = 'open';
+ const STATUS_ASSIGNED = 'assigned';
+ const STATUS_CLOSED = 'closed';
protected $status;
protected $ownerPHID;
protected $requestorPHID;
protected $sourcePHID;
- protected $sourceLabel;
+ protected $queuePHID;
+ protected $itemType;
+ protected $itemKey;
+ protected $itemContainerKey;
protected $data = array();
protected $mailKey;
- protected $queuePHID;
private $source = self::ATTACHABLE;
@@ -34,8 +37,12 @@
),
self::CONFIG_COLUMN_SCHEMA => array(
'ownerPHID' => 'phid?',
- 'sourceLabel' => 'text255?',
- 'status' => 'uint32',
+ 'requestorPHID' => 'phid?',
+ 'queuePHID' => 'phid?',
+ 'itemType' => 'text64',
+ 'itemKey' => 'text64',
+ 'itemContainerKey' => 'text64?',
+ 'status' => 'text32',
'mailKey' => 'bytes20',
),
self::CONFIG_KEY_SCHEMA => array(
@@ -51,6 +58,13 @@
'key_queue' => array(
'columns' => array('queuePHID', 'status'),
),
+ 'key_container' => array(
+ 'columns' => array('sourcePHID', 'itemContainerKey'),
+ ),
+ 'key_item' => array(
+ 'columns' => array('sourcePHID', 'itemKey'),
+ 'unique' => true,
+ ),
),
) + parent::getConfiguration();
}
@@ -72,15 +86,7 @@
}
public function getLabel(PhabricatorUser $viewer) {
- // this is generated at the time the item is created based on
- // the configuration from the item source. It is typically
- // something like 'Twitter'.
- $source_label = $this->getSourceLabel();
-
- return pht(
- 'Item via %s @ %s.',
- $source_label,
- phabricator_datetime($this->getDateCreated(), $viewer));
+ return pht('TODO: An Item');
}
public function getRequestor() {
@@ -99,11 +105,11 @@
$this->source = $source;
}
- public function getNuanceProperty($key, $default = null) {
+ public function getItemProperty($key, $default = null) {
return idx($this->data, $key, $default);
}
- public function setNuanceProperty($key, $value) {
+ public function setItemProperty($key, $value) {
$this->data[$key] = $value;
return $this;
}
@@ -135,17 +141,8 @@
return null;
}
- public function toDictionary() {
- return array(
- 'id' => $this->getID(),
- 'phid' => $this->getPHID(),
- 'ownerPHID' => $this->getOwnerPHID(),
- 'requestorPHID' => $this->getRequestorPHID(),
- 'sourcePHID' => $this->getSourcePHID(),
- 'sourceLabel' => $this->getSourceLabel(),
- 'dateCreated' => $this->getDateCreated(),
- 'dateModified' => $this->getDateModified(),
- );
+ public function getDisplayName() {
+ return pht('An Item');
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Oct 29, 2:21 PM (2 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6710516
Default Alt Text
D15440.id.diff (27 KB)
Attached To
Mode
D15440: Import raw GitHub event data into Nuance
Attached
Detach File
Event Timeline
Log In to Comment