Call the configured download webhook when new downloads are created

or existing downloads are updated.

This feature is sponsored by Scilab.
develop
Thomas Keller 2011-09-26 00:51:33 +02:00
parent b29acd71cb
commit 7ff298af79
4 changed files with 53 additions and 10 deletions

View File

@ -299,6 +299,7 @@ class IDF_Commit extends Pluf_Model
'project_id' => $project->id, 'project_id' => $project->id,
'authkey' => $project->getWebHookKey(), 'authkey' => $project->getWebHookKey(),
'url' => $url, 'url' => $url,
'method' => 'POST',
); );
$item = new IDF_Queue(); $item = new IDF_Queue();
$item->type = 'new_commit'; $item->type = 'new_commit';

View File

@ -96,7 +96,7 @@ class IDF_Form_UpdateUpload extends Pluf_Form
$this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]); $this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]);
if (strpos($this->cleaned_data['label'.$i], ':') !== false) { if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2); list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(mb_strtolower(trim($class)), list($class, $name) = array(mb_strtolower(trim($class)),
trim($name)); trim($name));
} else { } else {
$class = 'other'; $class = 'other';
@ -146,6 +146,9 @@ class IDF_Form_UpdateUpload extends Pluf_Form
$this->upload->modif_dtime = gmdate('Y-m-d H:i:s'); $this->upload->modif_dtime = gmdate('Y-m-d H:i:s');
$this->upload->update(); $this->upload->update();
$this->upload->batchAssoc('IDF_Tag', $tags); $this->upload->batchAssoc('IDF_Tag', $tags);
// Send the notification
$this->upload->notify($this->project->getConf(), false);
/** /**
* [signal] * [signal]
* *
@ -166,7 +169,7 @@ class IDF_Form_UpdateUpload extends Pluf_Form
* *
*/ */
$params = array('upload' => $this->upload); $params = array('upload' => $this->upload);
Pluf_Signal::send('IDF_Upload::update', Pluf_Signal::send('IDF_Upload::update',
'IDF_Form_UpdateUpload', $params); 'IDF_Form_UpdateUpload', $params);
return $this->upload; return $this->upload;
} }

View File

@ -234,6 +234,45 @@ class IDF_Upload extends Pluf_Model
*/ */
public function notify($conf, $create=true) public function notify($conf, $create=true)
{ {
$project = $this->get_project();
$url = str_replace(array('%p', '%d'),
array($project->shortname, $this->id),
$conf->getVal('upload_webhook_url', ''));
$tags = array();
foreach ($this->get_tags_list() as $tag) {
$tags[] = $tag->class.':'.$tag->name;
}
$payload = array(
'to_send' => array(
'project' => $project->shortname,
'id' => $this->id,
'summary' => $this->summary,
'changelog' => $this->changelog,
'filename' => $this->file,
'filesize' => $this->filesize,
'md5sum' => $this->md5,
'tags' => $tags,
),
'project_id' => $project->id,
'authkey' => $project->getWebHookKey(),
'url' => $url,
);
if ($create === true) {
$payload['method'] = 'PUT';
$payload['to_send']['creation_date'] = $this->creation_dtime;
} else {
$payload['method'] = 'POST';
$payload['to_send']['update_date'] = $this->modif_dtime;
}
$item = new IDF_Queue();
$item->type = 'upload';
$item->payload = $payload;
$item->create();
if ('' == $conf->getVal('downloads_notification_email', '')) { if ('' == $conf->getVal('downloads_notification_email', '')) {
return; return;
} }

View File

@ -31,20 +31,20 @@
class IDF_Webhook class IDF_Webhook
{ {
/** /**
* Perform the POST request given the webhook payload. * Perform the request given the webhook payload.
* *
* @param array Payload * @param array Payload
* @return bool Success or error * @return bool Success or error
*/ */
public static function postNotification($payload) public static function processNotification($payload)
{ {
$data = json_encode($payload['to_send']); $data = json_encode($payload['to_send']);
$sign = hash_hmac('md5', $data, $payload['authkey']); $sign = hash_hmac('md5', $data, $payload['authkey']);
$params = array('http' => array( $params = array('http' => array(
'method' => 'POST', 'method' => empty($payload['method']) ? 'POST' : $payload['method'],
'content' => $data, 'content' => $data,
'user_agent' => 'Indefero Hook Sender (http://www.indefero.net)', 'user_agent' => 'Indefero Hook Sender (http://www.indefero.net)',
'max_redirects' => 0, 'max_redirects' => 0,
'timeout' => 15, 'timeout' => 15,
'header'=> 'Post-Commit-Hook-Hmac: '.$sign."\r\n" 'header'=> 'Post-Commit-Hook-Hmac: '.$sign."\r\n"
.'Content-Type: application/json'."\r\n", .'Content-Type: application/json'."\r\n",
@ -61,7 +61,7 @@ class IDF_Webhook
if (!isset($meta['wrapper_data'][0]) or $meta['timed_out']) { if (!isset($meta['wrapper_data'][0]) or $meta['timed_out']) {
return false; return false;
} }
if (0 === strpos($meta['wrapper_data'][0], 'HTTP/1.1 2') or if (0 === strpos($meta['wrapper_data'][0], 'HTTP/1.1 2') or
0 === strpos($meta['wrapper_data'][0], 'HTTP/1.1 3')) { 0 === strpos($meta['wrapper_data'][0], 'HTTP/1.1 3')) {
return true; return true;
} }
@ -76,11 +76,11 @@ class IDF_Webhook
public static function process($sender, &$params) public static function process($sender, &$params)
{ {
$item = $params['item']; $item = $params['item'];
if ($item->type != 'new_commit') { if (!in_array($item->type, array('new_commit', 'upload'))) {
// We do nothing. // We do nothing.
return; return;
} }
if (isset($params['res']['IDF_Webhook::process']) and if (isset($params['res']['IDF_Webhook::process']) and
$params['res']['IDF_Webhook::process'] == true) { $params['res']['IDF_Webhook::process'] == true) {
// Already processed. // Already processed.
return; return;
@ -90,7 +90,7 @@ class IDF_Webhook
return; return;
} }
// We have either to retry or to push for the first time. // We have either to retry or to push for the first time.
$res = self::postNotification($item->payload); $res = self::processNotification($item->payload);
if ($res) { if ($res) {
$params['res']['IDF_Webhook::process'] = true; $params['res']['IDF_Webhook::process'] = true;
} elseif ($item->trials >= 9) { } elseif ($item->trials >= 9) {