Permalink
Browse files

Allow filtering by state or label

  • Loading branch information...
ZJ committed Oct 6, 2014
1 parent a929be1 commit 268b0a3dd56be7eb7e6eed6c751af73c66fe493d
@@ -71,47 +71,63 @@ public function checkIssuesCache( $apiURL, $page ) {
// return true if still fresh. Otherwise you'll confuse the bears
public function checkCacheFreshness($apiURL, &$cache=NULL) {
//msg('In checkCacheFreshness'.time(),-1);
if ( !isset($cache) ) {
$cache = new cache_ghissues_api($apiURL);
}
// Check if we've done a cached API call recently. If you have, the cache is plenty fresh
if ( $cache->sniffETag($this->getConf['ghissuerefresh']) ) return true;
if ( $cache->sniffETag($this->getConf('ghissuerefresh')) ) return true;
// Old cache, time to check in with GH.
return $this->callGithubAPI($apiURL, $cache);
}
// return true if no update since the last time we asked.
public function callGithubAPI($apiURL, &$cache=NULL) {
//msg('In callGithubAPI'.time(),-1);
if ( !isset($cache) ) {
$cache = new cache_ghissues_api($apiURL);
}
//msg('Make HTTP Client'.time(),-1);
$http = new DokuHTTPClient();
//msg('Made HTTP Client'.time(),-1);
$http->agent = substr($http->agent,-1).' via ghissue plugin from user '.$this->getConf('ghissueuser').')';
$http->headers['Accept'] = 'application/vnd.github.v3.text+json';
//msg('Set Base Headers'.time(),-1);
$lastETag = $cache->retrieveETag();
//msg('Cache etag retrieval'.time(),-1);
if ( !empty($lastETag) ) {
$http->headers['If-None-Match'] = $lastETag;
}
//msg('Start request'.time(),-1);
$apiResp = $http->get($apiURL);
$apiHead = array();
//msg('madeRequest'.time(),-1);
$apiHead = $http->resp_headers;
$this->_GH_API_limit = intval($apiHead['x-ratelimit-remaining']);
$apiStatus = substr($apiHead['status'],0,3);
if ( $apiStatus == '304' ) { // No modification
$cache->storeETag($apiHead['etag']); // Update the last time we checked
return true;
} else if ( $apiStatus == '200' ) { // Updated content! But will the table change?
// TODO: Need a call to handle multi-page results
// Collate results if GitHub paginated them. (Walk the URL ladder)
if ( !empty($apiHead['link']) ) {
$nextLink = $apiHead['link'];
$matches = array();
if(preg_match('/<(.*?)>; rel="next"/', $nextLink, $matches)) {
$apiResp = substr($apiResp,0,-1);
$apiResp .= $this->_chaseGithubNextLinks($http, $matches[1]);
}
};
// Build the actual table using the response, then make sure it has changed.
// Because we don't use all information from the resopnse, it is possible only
@@ -131,7 +147,6 @@ public function callGithubAPI($apiURL, &$cache=NULL) {
} else { // Some other HTTP status, we're not handling. Save old table plus error message
// Don't update when we checked in case it was a temporary thing (it probably wasn't though)
// $cache->storeETag($apiHead['etag']); // Update the last time we checked
var_dump($http);
$errorTable = '<div class=ghissues_plugin_api_err">';
$errorTable .= htmlentities(strftime($conf['dformat']));
$errorTable .= sprintf($this->getLang('badhttpstatus'), htmlentities($apiHead['status']));
@@ -148,8 +163,16 @@ public function callGithubAPI($apiURL, &$cache=NULL) {
}
public function formatApiResponse($rawJSON) {
//msg('In formatApiResponse'.time(),-1);
global $conf;
if ($rawJSON == '[]') {
$outputXML = '<div class="ghissues_plugin_issue_line ghissues_plugin_issue_title">';
$outputXML .= $this->getLang('noIssues');
$outputXML .= '</div>'."\n";
return $outputXML;
}
$json = new JSON();
$response = $json->decode($rawJSON);
@@ -170,15 +193,18 @@ public function formatApiResponse($rawJSON) {
$outputXML .= '<div class="ghissues_plugin_issue_report">'."\n";
$outputXML .= sprintf($this->getLang('reporter'),htmlentities($issue->user->login));
$outputXML .= htmlentities(strftime($conf['dformat'],strtotime($issue->created_at)));
$outpulXML .= '</div>'."\n".'</li>'."\n";
}
$outputXML .= '</div></ul>'."\n";
$outputXML .= '</ul>'."\n";
return $outputXML;
}
public function getRenderedRequest($apiURL) {
//msg('In getRenderedRequest'.time(),-1);
$outputCache = new cache_ghissues_api($apiURL);
// Make sure we've got a good copy
$this->checkCacheFreshness($apiURL, $outputCache);
return $outputCache->retrieveCache();
}
@@ -198,6 +224,34 @@ private function _getSpanClassFromBG($htmlbg) {
return '"ghissues_dark"';
}
}
private function _chaseGithubNextLinks(&$http, $apiURL) {
//msg('In _chaseGithubNextLinks'.time(),-1);
$http->agent = substr($http->agent,-1).' via ghissue plugin from user '.$this->getConf('ghissueuser').')';
$http->headers['Accept'] = 'application/vnd.github.v3.text+json';
unset($http->headers['If-None-Match']);
$apiNext = $http->get($apiURL);
$apiHead = array();
$apiHead = $http->resp_headers;
$this->_GH_API_limit = intval($apiHead['x-ratelimit-remaining']);
$apiStatus = substr($apiHead['status'],0,3);
// If request somehow failed, do it quietly since the first one didn't
if ( $apiStatus != '200' ) return ']';
// If we're on the last page, there will be no "next"
if ( !empty($apiHead['link']) ) {
$nextLink = $apiHead['link'];
$matches = array();
if(preg_match('/<(.*?)>; rel="next"/', $nextLink, $matches)) {
return ','.substr($apiNext,1,-1).$this->_chaseGithubNextLinks($http, $matches[1]);
}
};
return ','.substr($apiNext,1);
}
}
class cache_ghissues_api extends cache {
@@ -223,8 +277,7 @@ public function storeETag($etagValue) {
public function sniffETag($expireInterval) {
if ( $expireInterval < 0 ) return true;
if ( $expireInterval == 0 ) return false;
if (!($this->_etag_time = @filemtime($this->cache))) return false; // Check if cache is there
if (!($this->_etag_time = @filemtime($this->etag))) return false; // Check if cache is there
if ( (time() - $this->_etag_time) > $expireInterval ) return false; // Past Sell-By
return true;
}
@@ -6,8 +6,15 @@
*/
// custom language strings for the plugin
$lang['reporter'] = "Reported by: %s on "; // Message giving who reported the issue on GH
$lang['badhttpstatus'] = "Server Error: Status %s"; // Message reporting server error on API response
$lang['reporter'] = "Reported by: %s on "; // Message giving who reported the issue on GH
$lang['badhttpstatus'] = "Server Error: Status %s"; // Message reporting server error on API response
$lang['noIssues'] = "No Issues Found!"; // Message for when a repo has no issues under that filter
$lang['issuesIn'] = " Issues in "; // Part of header, for 'Open/Closed/All Issues in...'
$lang['open'] = "Open"; // Part of header, for 'Open Issues in...'
$lang['closed'] = "Closed"; // Part of header, for 'Closed Issues in...'
$lang['all'] = "All"; // Part of header, for 'All Issues in...'
$lang['viewOnGH'] = "View this list on GitHub"; // Footer, holds link to GH's version of listing
$lang['and'] = " and "; // And
$lang['withLabel'] = " with label "; // Part of header, for '...Issue with label ___"
$lang['withLabels'] = " with labels "; // plural form of above
//Setup VIM: ex: et ts=4 :
@@ -7,7 +7,7 @@
// keys need to match the config setting name
$lang['ghissueuser'] = "GitHub Account Username"; // Github Username, used for User-Agent and Authentication
$meta['ghissuerefresh'] = "GitHub Cache Expiry Interval (seconds)"; // Min time between API calls (per unique request URL)
$lang['ghissuerefresh'] = "GitHub Cache Expiry Interval (seconds)"; // Min time between API calls (per unique request URL)
//Setup VIM: ex: et ts=4 :
@@ -2,6 +2,9 @@
list-style-type: none;
padding: 0px;
margin: 0px;
border:__border__;
border-style:none none solid none;
border-width:1px;
}
.ghissues_plugin_labels {
@@ -33,6 +36,7 @@
border-width:1.5px;
border-radius:5px;
padding:0px;
margin:1em 0em 1em 0em;
}
.ghissues_plugin_box_header {
@@ -47,7 +51,6 @@
.ghissues_plugin_box_footer {
color:__text__;
font-size:smaller;
border-style:none;
margin:0.1em;
padding:0.1em 0.1em 0.1em 0.7em;
}
@@ -55,17 +55,61 @@ public function handle($match, $state, $pos, Doku_Handler &$handler){
$repoPath = htmlentities($exploded[0]);
unset($exploded[0]);
$theRest = '';
foreach($exploded as $item) {
$theRest .= $item.' ';
}
$theRest = implode(" ",$exploded);
$filters='';
// Check if we're filtering based on issue state
$headerState = $this->getLang('open');
$matches = array();
if ( preg_match("/\bstate:(open|closed|all)\b/", $theRest, $matches) ) {
switch($matches[1]) {
case "open":
$filters="?state=open";
break;
case "closed":
$filters="?state=closed";
$headerState = $this->getLang('closed');
break;
case "all":
$filters="?state=all";
$headerState = $this->getLang('all');
break;
}
}
// Now check for label processing, matches "label:" through end of line
$headerLabel = '';
$matches = array();
$codedLabels = array();
if ( preg_match("/\blabels?:(.*\z)/", $theRest, $matches) ) {
if( $filters == '' ) {
$filters = '?labels=';
} else {
$filters .= '&labels=';
}
$rawLabels = array();
$rawLabels = preg_split('~\\\\.(*SKIP)(*FAIL)|,~s', trim($matches[1]));
if ( count($rawLabels) > 1 ) {
$headerLabel = $this->getLang('withLabels');
} else {
$headerLabel = $this->getLang('withLabel');
}
foreach ($rawLabels as $thisIndex => $thisLabel) {
$codedLabels[$thisIndex] = urlencode($thisLabel);
}
$headerLabel .= htmlentities(implode($this->getLang('and'),$rawLabels));
$filters .= implode(',',$codedLabels);
}
$wholeHeader = 'Open Issues in /'.htmlentities($repoPath.' Plus:'.$theRest);
$url = 'https://api.github.com/repos/'.$repoPath.'/issues'.$filters;
$urlHash = hash('sha1',$url);
$data = array( 'header' => $wholeHeader, 'url' => $url, 'hash' => $urlHash );
$httpUrl = 'http://www.github.com/'.$repoPath.'/issues'.$filters;
$buildHeader = $headerState.$this->getLang('issuesIn');
$wholeHeader = $buildHeader.htmlentities($repoPath).$headerLabel;
$wholeFooter = $this->external_link($httpUrl, $this->getLang('viewOnGH'), NULL, '_blank');
$data = array( 'header' => $wholeHeader, 'url' => $url, 'footer' => $wholeFooter );
return $data;
}
@@ -84,7 +128,6 @@ public function render($mode, Doku_Renderer &$renderer, $data) {
$hashpair = array( $data['url'] => hash('md5', $data['url']) );
if (!isset($renderer->meta['plugin_ghissues_apicalls'])) $renderer->meta['plugin_ghissues_apicalls'] = array();
//$renderer->meta['plugin_ghissues_apicalls'] = array();
$renderer->meta['plugin_ghissues_apicalls'] = array_unique(array_merge($renderer->meta['plugin_ghissues_apicalls'], $hashpair));
return true;
@@ -102,7 +145,7 @@ public function render($mode, Doku_Renderer &$renderer, $data) {
}
$renderOutput .= $loadFromCache->getRenderedRequest($data['url']);
$renderOutput .= '<div class="ghissues_plugin_box_footer">I just want to see what happens if there is text here</div>';
$renderOutput .= '<div class="ghissues_plugin_box_footer">'.$data['footer'].'</div>';
$renderOutput .= '</div>';
$renderer->doc .= $renderOutput;

0 comments on commit 268b0a3

Please sign in to comment.