+2013-09-17 Christian Weiske <cweiske@cweiske.de>
+
+ * Add webhook support
+
2013-09-16 Elan Ruusamäe <glen@pld-linux.org>
* Disable editor on commit with --no-edit
- search across pastes: description, file names and file content
- options: quoting, logical and, or, not, partial words
+- webhook support - get notified when pastes are created, edited or deleted
============
http://cweiske.de/
+Notifications via webhooks
+==========================
+Depending on how you use phorkie, it might be nice to notify some other service
+when pastes are added or updated.
+Phorkie contains a simply mechanism to post data to a given URL which
+you can then use as needed.
+
+The data are json-encoded POSTed to the URLs contained in the
+``$GLOBALS['phorkie']['cfg']['webhooks']`` setting array, with
+a MIME type of ``application/vnd.phorkie.webhook+json``::
+
+ {
+ 'event': 'create',
+ 'author': {
+ 'name':'Anonymous',
+ 'email': 'anonymous@phorkie',
+ },
+ 'repository': {
+ 'name': 'webhooktest',
+ 'url': 'http://example.org/33',
+ 'description': 'webhooktest',
+ 'owner': {
+ 'name': 'Anonymous',
+ 'email': 'anonymous@phorkie',
+ }
+ }
+ }
+
+The event may be ``create``, ``edit`` or ``delete``.
+
+
=================
Technical details
=================
'geshi' => 'MediaWiki/geshi/geshi/geshi.php',
'index' => 'new',//"new" or "list"
'perPage' => 10,
+ 'webhooks' => array(
+ /* array of urls that get called when
+ a paste is created, edited or deleted */
+ )
);
$GLOBALS['phorkie']['auth'] = array(
// 0 = public, no authentication, 1 = protect adds/edits/deletes,
$new = $this->fork($repo->gitDir);
\copy($repo->gitDir . '/description', $new->gitDir . '/description');
$this->index($new);
+
+ $not = new Notificator();
+ $not->create($new);
+
return $new;
}
'Fork of ' . $originalUrl
);
$this->index($new);
+
+ $not = new Notificator();
+ $not->create($new);
+
return $new;
}
--- /dev/null
+<?php
+namespace phorkie;
+
+/**
+ * Send out webhook callbacks when something happens
+ */
+class Notificator
+{
+ /**
+ * A repository has been created
+ */
+ public function create(Repository $repo)
+ {
+ $this->send('create', $repo);
+ }
+
+ /**
+ * A repository has been modified
+ */
+ public function edit(Repository $repo)
+ {
+ $this->send('edit', $repo);
+ }
+
+ /**
+ * A repository has been deleted
+ */
+ public function delete(Repository $repo)
+ {
+ $this->send('delete', $repo);
+ }
+
+ /**
+ * Call webhook URLs with our payload
+ */
+ protected function send($event, Repository $repo)
+ {
+ if (count($GLOBALS['phorkie']['cfg']['webhooks']) == 0) {
+ return;
+ }
+
+ /* slightly inspired by
+ https://help.github.com/articles/post-receive-hooks */
+ $payload = (object) array(
+ 'event' => $event,
+ 'author' => array(
+ 'name' => $_SESSION['name'],
+ 'email' => $_SESSION['email']
+ ),
+ 'repository' => array(
+ 'name' => $repo->getTitle(),
+ 'url' => $repo->getLink('display', null, true),
+ 'description' => $repo->getDescription(),
+ 'owner' => $repo->getOwner()
+ )
+ );
+ foreach ($GLOBALS['phorkie']['cfg']['webhooks'] as $url) {
+ $req = new \HTTP_Request2($url);
+ $req->setMethod(\HTTP_Request2::METHOD_POST)
+ ->setHeader('Content-Type: application/vnd.phorkie.webhook+json')
+ ->setBody(json_encode($payload));
+ try {
+ $response = $req->send();
+ //FIXME log response codes != 200
+ } catch (HTTP_Request2_Exception $e) {
+ //FIXME log exceptions
+ }
+ }
+ }
+}
+?>
$db = new Database();
$db->getIndexer()->deleteRepo($this);
- return Tools::recursiveDelete($this->workDir)
+ $bOk = Tools::recursiveDelete($this->workDir)
&& Tools::recursiveDelete($this->gitDir);
+
+ $not = new Notificator();
+ $not->delete($this);
+
+ return $bOk;
}
public function getTitle()
//FIXME: index changed files only
//also handle file deletions
$db = new Database();
+ $not = new Notificator();
if ($bNew) {
$db->getIndexer()->addRepo($this->repo);
+ $not->create($this->repo);
} else {
$commits = $this->repo->getHistory();
$db->getIndexer()->updateRepo(
$commits[count($commits)-1]->committerTime,
$commits[0]->committerTime
);
+ $not->edit($this->repo);
}
}