[GitHubGistBridge] Add new bridge
Adds a new bridge for https://gist.github.com The bridge generates feeds for comments on a particular gist based on the gist ID or full URI. For better readability the general behavior of code sections is manually restored with the original CSS styles from GitHub.
This commit is contained in:
parent
ce896b4247
commit
0d1923c52f
1 changed files with 164 additions and 0 deletions
164
bridges/GitHubGistBridge.php
Normal file
164
bridges/GitHubGistBridge.php
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class GitHubGistBridge extends BridgeAbstract {
|
||||||
|
|
||||||
|
const NAME = 'GitHubGist comment bridge';
|
||||||
|
const URI = 'https://gist.github.com';
|
||||||
|
const DESCRIPTION = 'Generates feeds for Gist comments';
|
||||||
|
const MAINTAINER = 'logmanoriginal';
|
||||||
|
const CACHE_TIMEOUT = 3600;
|
||||||
|
|
||||||
|
const PARAMETERS = array(array(
|
||||||
|
'id' => array(
|
||||||
|
'name' => 'Gist',
|
||||||
|
'type' => 'text',
|
||||||
|
'required' => true,
|
||||||
|
'title' => 'Insert Gist ID or URI',
|
||||||
|
'exampleValue' => '2646763, https://gist.github.com/2646763'
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
private $filename;
|
||||||
|
|
||||||
|
public function getURI() {
|
||||||
|
|
||||||
|
$id = $this->getInput('id') ?: '';
|
||||||
|
|
||||||
|
$urlpath = parse_url($id, PHP_URL_PATH);
|
||||||
|
|
||||||
|
if($urlpath) {
|
||||||
|
|
||||||
|
$components = explode('/', $urlpath);
|
||||||
|
$id = end($components);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::URI . '/' . $id;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return $this->filename ? $this->filename . ' - ' . static::NAME : static::NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collectData() {
|
||||||
|
|
||||||
|
$html = getSimpleHTMLDOM($this->getURI(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
DEFAULT_TARGET_CHARSET,
|
||||||
|
false, // Do NOT remove line breaks
|
||||||
|
DEFAULT_BR_TEXT,
|
||||||
|
DEFAULT_SPAN_TEXT)
|
||||||
|
or returnServerError('Could not request ' . $this->getURI());
|
||||||
|
|
||||||
|
$html = defaultLinkTo($html, static::URI);
|
||||||
|
|
||||||
|
$fileinfo = $html->find('[class="file-info"]', 0)
|
||||||
|
or returnServerError('Could not find file info!');
|
||||||
|
|
||||||
|
$this->filename = $fileinfo->plaintext;
|
||||||
|
|
||||||
|
$comments = $html->find('div[class="timeline-comment-wrapper"]');
|
||||||
|
|
||||||
|
if(is_null($comments)) { // no comments yet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($comments as $comment) {
|
||||||
|
|
||||||
|
$uri = $comment->find('a[href^=#gistcomment]', 0)
|
||||||
|
or returnServerError('Could not find comment anchor!');
|
||||||
|
|
||||||
|
$title = $comment->find('div[class="unminimized-comment"] h3[class="timeline-comment-header-text"]', 0)
|
||||||
|
or returnServerError('Could not find comment header text!');
|
||||||
|
|
||||||
|
$datetime = $comment->find('[datetime]', 0)
|
||||||
|
or returnServerError('Could not find comment datetime!');
|
||||||
|
|
||||||
|
$author = $comment->find('a.author', 0)
|
||||||
|
or returnServerError('Could not find author name!');
|
||||||
|
|
||||||
|
$message = $comment->find('[class="comment-body"]', 0)
|
||||||
|
or returnServerError('Could not find comment body!');
|
||||||
|
|
||||||
|
$item = array();
|
||||||
|
|
||||||
|
$item['uri'] = $this->getURI() . $uri->href;
|
||||||
|
$item['title'] = str_replace('commented', 'commented on', $title->plaintext);
|
||||||
|
$item['timestamp'] = strtotime($datetime->datetime);
|
||||||
|
$item['author'] = '<a href="' . $author->href . '">' . $author->plaintext . '</a>';
|
||||||
|
$item['content'] = $this->fixContent($message);
|
||||||
|
// $item['enclosures'] = array();
|
||||||
|
// $item['categories'] = array();
|
||||||
|
|
||||||
|
$this->items[] = $item;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Removes all unnecessary tags and adds formatting */
|
||||||
|
private function fixContent($content){
|
||||||
|
|
||||||
|
// Restore code (inside <pre />) highlighting
|
||||||
|
foreach($content->find('pre') as $pre) {
|
||||||
|
|
||||||
|
$pre->style = <<<EOD
|
||||||
|
padding: 16px;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 85%;
|
||||||
|
line-height: 1.45;
|
||||||
|
background-color: #f6f8fa;
|
||||||
|
border-radius: 3px;
|
||||||
|
word-wrap: normal;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
EOD;
|
||||||
|
|
||||||
|
$code = $pre->find('code', 0);
|
||||||
|
|
||||||
|
if($code) {
|
||||||
|
|
||||||
|
$code->style = <<<EOD
|
||||||
|
white-space: pre;
|
||||||
|
word-break: normal;
|
||||||
|
EOD;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// find <code /> not inside <pre /> (`inline-code`)
|
||||||
|
foreach($content->find('code') as $code) {
|
||||||
|
|
||||||
|
if($code->parent()->tag === 'pre') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$code->style = <<<EOD
|
||||||
|
background-color: rgba(27,31,35,0.05);
|
||||||
|
padding: 0.2em 0.4em;
|
||||||
|
border-radius: 3px;
|
||||||
|
EOD;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore text spacing
|
||||||
|
foreach($content->find('p') as $p) {
|
||||||
|
$p->style = 'margin-bottom: 16px;';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove unnecessary tags
|
||||||
|
$content = strip_tags(
|
||||||
|
$content->innertext,
|
||||||
|
'<p><a><img><ol><ul><li><table><tr><th><td><string><pre><code><br><hr><h>'
|
||||||
|
);
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue