Browse Source

[KernelBugTracker] Add new bridge

This adds a bridge for bugzilla.kernel.org to provide feeds for
bug comments without the need of registering an email address.

This implementation makes use of the print preview feature that
reduces bandwidth by a small margin.

Provides options to specify the number of comments to return as
well as the sorting order (latest first or oldest first)
logmanoriginal 7 years ago
parent
commit
6ddcedb53f
1 changed files with 152 additions and 0 deletions
  1. 152 0
      bridges/KernelBugTrackerBridge.php

+ 152 - 0
bridges/KernelBugTrackerBridge.php

@@ -0,0 +1,152 @@
+<?php
+class KernelBugTrackerBridge extends BridgeAbstract {
+
+	const NAME = 'Kernel Bug Tracker';
+	const URI = 'https://bugzilla.kernel.org';
+	const DESCRIPTION = 'Returns feeds for bug comments';
+	const MAINTAINER = 'logmanoriginal';
+	const PARAMETERS = array(
+		'Bug comments' => array(
+			'id' => array(
+				'name' => 'Bug tracking ID',
+				'type' => 'number',
+				'required' => true,
+				'title' => 'Insert bug tracking ID',
+				'exampleValue' => 121241
+			),
+			'limit' => array(
+				'name' => 'Number of comments to return',
+				'type' => 'number',
+				'required' => false,
+				'title' => 'Specify number of comments to return',
+				'defaultValue' => -1
+			),
+			'sorting' => array(
+				'name' => 'Sorting',
+				'type' => 'list',
+				'required' => false,
+				'title' => 'Defines the sorting order of the comments returned',
+				'defaultValue' => 'of',
+				'values' => array(
+					'Oldest first' => 'of',
+					'Latest first' => 'lf'
+				)
+			)
+		)
+	);
+
+	private $bugid = '';
+	private $bugdesc = '';
+
+	public function collectData(){
+		$limit = $this->getInput('limit');
+		$sorting = $this->getInput('sorting');
+
+		// We use the print preview page for simplicity
+		$html = getSimpleHTMLDOMCached($this->getURI() . '&format=multiple'
+		, 86400
+		, false
+		, null
+		, 0
+		, null
+		, true
+		, true
+		, DEFAULT_TARGET_CHARSET
+		, false // Do NOT remove line breaks
+		, DEFAULT_BR_TEXT
+		, DEFAULT_SPAN_TEXT);
+
+		if($html === false)
+			returnServerError('Failed to load page!');
+
+		// Store header information into private members
+		$this->bugid = $html->find('#bugzilla-body', 0)->find('a', 0)->innertext;
+		$this->bugdesc = $html->find('table.bugfields', 0)->find('tr', 0)->find('td', 0)->innertext;
+
+		// Get and limit comments
+		$comments = $html->find('div.bz_comment');
+
+		if($limit > 0 && count($comments) > $limit){
+			$comments = array_slice($comments, count($comments) - $limit, $limit);
+		}
+
+		// Order comments
+		switch($sorting){
+			case 'lf': $comments = array_reverse($comments, true);
+			case 'of':
+			default: // Nothing to do, keep original order
+		}
+
+		foreach($comments as $comment){
+			$comment = $this->inlineStyles($comment);
+
+			$item = array();
+			$item['uri'] = $this->getURI() . '#' . $comment->id;
+			$item['author'] = $comment->find('span.bz_comment_user', 0)->innertext;
+			$item['title'] = $comment->find('span.bz_comment_number', 0)->find('a', 0)->innertext;
+			$item['timestamp'] = strtotime($comment->find('span.bz_comment_time', 0)->innertext);
+			$item['content'] = $comment->find('pre.bz_comment_text', 0)->innertext;
+
+			// Fix line breaks (they use LF)
+			$item['content'] = str_replace("\n", '<br>', $item['content']);
+
+			// Fix relative URIs
+			$item['content'] = $this->replaceRelativeURI($item['content']);
+
+			$this->items[] = $item;
+		}
+
+	}
+
+	public function getURI(){
+		switch($this->queriedContext){
+			case 'Bug comments':
+				return parent::getURI()
+				. '/show_bug.cgi?id='
+				. $this->getInput('id');
+				break;
+			default: return parent::getURI();
+		}
+	}
+
+	public function getName(){
+		switch($this->queriedContext){
+			case 'Bug comments':
+				return 'Bug '
+				. $this->bugid
+				. ' tracker for '
+				. $this->bugdesc
+				. ' - '
+				. parent::getName();
+				break;
+			default: return parent::getName();
+		}
+	}
+
+	/**
+	 * Replaces all relative URIs with absolute ones
+	 *
+	 * @param string $content The source string
+	 * @return string Returns the source string with all relative URIs replaced
+	 * by absolute ones.
+	 */
+	private function replaceRelativeURI($content){
+		return preg_replace('/href="(?!http)/', 'href="' . self::URI . '/', $content);
+	}
+
+	/**
+	 * Adds styles as attributes to tags with known classes
+	 *
+	 * @param object $html A simplehtmldom object
+	 * @return object Returns the original object with styles added as
+	 * attributes.
+	 */
+	private function inlineStyles($html){
+		foreach($html->find('.bz_obsolete') as $element){
+			$element->style = 'text-decoration:line-through;';
+		}
+
+		return $html;
+	}
+
+}