Skip to content

Instantly share code, notes, and snippets.

@beberlei
Created September 17, 2009 20:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beberlei/188681 to your computer and use it in GitHub Desktop.
Save beberlei/188681 to your computer and use it in GitHub Desktop.
<?php
/**
* Copyright (c) 2009, Benjamin Eberlei
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the distribution.
* * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
require_once "Zend/Tool/Framework/Provider/Abstract.php";
class Whitewashing_Tool_Provider_Jira extends Zend_Tool_Framework_Provider_Abstract
{
private $httpClient = null;
/**
* @return Zend_Http_Client
*/
private function getHttpClient()
{
if($this->httpClient == null) {
$this->httpClient = new Zend_Http_Client();
}
return $this->httpClient;
}
public function showConfig($shortname)
{
$jiraInstanceOptions = $this->_loadJiraOptions($shortname);
$loader = Zend_Loader_Autoloader::getInstance();
$response = $this->_registry->getResponse();
$response->appendContent("Jira Caching Project: ".$jiraInstanceOptions['shortname']);
$response->appendContent("Instance Url: ".$jiraInstanceOptions['instanceUrl']);
$response->appendContent("Project Shortname: ".$jiraInstanceOptions['project']);
$response->appendContent("Output Directory: ".$jiraInstanceOptions['outputDirectory']);
}
public function cacheLatest($shortname)
{
$jiraInstanceOptions = $this->_loadJiraOptions($shortname);
$searchRequestString = $jiraInstanceOptions['instanceUrl']."/sr/jira.issueviews:searchrequest-xml/temp/SearchRequest.xml?&&pid=10000&updated%3Aprevious=-1w&sorter/field=updated&sorter/order=DESC&tempMax=100&reset=true&decorator=none";
if(!Zend_Uri::check($searchRequestString)) {
throw new Whitewashing_Tool_JiraException("Latest Jira Ticket Url is not valid: ".$searchRequestString);
}
$feed = Zend_Feed_Reader::import($searchRequestString);
foreach($feed AS $item) {
if($this->_registry->getRequest()->isVerbose()) {
$this->_registry->getResponse()->appendContent('Retrieving '.$item->getTitle());
}
$link = $item->getLink();
$parts = explode("/", $link);
list($project, $ticketNum) = explode("-", array_pop($parts));
$this->cacheTicket($shortname, $ticketNum);
}
$this->regenerateIndex($shortname);
}
public function cacheAll($shortname, $maxTicketNum=10000)
{
for($ticketNum = 1; $ticketNum <= $maxTicketNum; $ticketNum++) {
$this->cacheTicket($shortname, $ticketNum);
}
$this->regenerateIndex($shortname);
}
public function regenerateIndex($shortname)
{
$jiraInstanceOptions = $this->_loadJiraOptions($shortname);
$dir = new DirectoryIterator($jiraInstanceOptions['outputDirectory']);
$items = array();
foreach($dir AS $file) {
$jiraTicket = $file->getPathname();
if(strpos($jiraTicket, "html") !== false) {
$ticketContents = file_get_contents($jiraTicket);
if(preg_match('(<title>([^<]+)</title>)', $ticketContents, $match)) {
$title = $match[1];
$filename = $file->getFilename();
list($ticket, $ext) = explode(".", $filename);
$items[] = array(
'title' => $title,
'ticket' => $ticket,
);
}
}
}
$output = '<ul>';
foreach($items AS $item) {
$output .= '<li><a href="'.$item['ticket'].'.html">'.$item['title'].'</a></li>'."\n";
}
$output .= '</ul>';
file_put_contents($jiraInstanceOptions['outputDirectory']."/index.html", $output);
}
public function cacheTicket($shortname, $ticketNum)
{
$jiraInstanceOptions = $this->_loadJiraOptions($shortname);
$loader = Zend_Loader_Autoloader::getInstance();
$request = $this->_registry->getRequest();
$response = $this->_registry->getResponse();
$instanceUrl = $jiraInstanceOptions['instanceUrl'];
$project = $jiraInstanceOptions['project'];
$outputDirectory = $jiraInstanceOptions['outputDirectory'];
$httpClient = $this->getHttpClient();
$ticketUrl = sprintf('%s/browse/%s-%d', $instanceUrl, $project, $ticketNum);
if($request->isVerbose()) {
$response->appendContent("Retrieving Ticket: ".$ticketUrl);
}
$httpClient->setUri($ticketUrl);
$httpResponse = $httpClient->request('GET');
file_put_contents($outputDirectory."/".$ticketNum.".html", $httpResponse->getBody());
}
/**
* @param string $shortname
* @return array
*/
private function _loadJiraOptions($shortname)
{
if(!preg_match('(([a-zA-Z0-9]+))', $shortname)) {
throw new Whitewashing_Tool_JiraException("Invalid Jira Cache Shortname given!");
}
$jiraShortname = sprintf("jira_%s", $shortname);
$storage = $this->_registry->getStorage();
if(!$storage->has($jiraShortname)) {
throw new Whitewashing_Tool_JiraException("Jira Project Configuration for '".$shortname."' was not found in storage!");
}
$jiraOptions = Zend_Json::decode($storage->get($jiraShortname));
$this->_validateJiraOptions($jiraOptions['instanceUrl'], $jiraOptions['project'], $jiraOptions['outputDirectory']);
return $jiraOptions;
}
private function _validateJiraOptions($instanceUrl, $project, $outputDirectory)
{
if(!Zend_Uri::check($instanceUrl)) {
throw new Whitewashing_Tool_JiraException("Invalid Jira Instance Url");
}
if(!preg_match('(([a-zA-Z0-9]+))', $project)) {
throw new Whitewashing_Tool_JiraException("Invalid Project Shortname given!");
}
if(!file_exists($outputDirectory) || !is_writable($outputDirectory)) {
throw new Whitewashing_Tool_JiraException("Output directory is not writeable!");
}
}
public function createInstance($shortname, $instanceUrl, $project, $outputDirectory)
{
$loader = Zend_Loader_Autoloader::getInstance();
if(!preg_match('(([a-zA-Z0-9]+))', $shortname)) {
throw new Whitewashing_Tool_JiraException("Invalid Jira Cache Shortname given!");
}
$this->_validateJiraOptions($instanceUrl, $project, $outputDirectory);
if(substr($instanceUrl, -1) == "/") {
$instanceUrl = substr($instanceUrl, 0, strlen($instanceUrl)-1);
}
$jiraShortname = sprintf("jira_%s", $shortname);
$storage = $this->_registry->getStorage();
/* @var $storage Zend_Tool_Framework_Client_Storage */
if($storage->has($jiraShortname)) {
$resp = $this->_registry->getClient()->promptInteractiveInput("Overwrite existing jira project options?")->getContent();
if(strtolower($resp) !== "y") {
return;
}
}
$jiraProjectOptions = array(
'shortname' => $shortname,
'instanceUrl' => $instanceUrl,
'project' => $project,
'outputDirectory' => $outputDirectory,
);
$storage->put($jiraShortname, Zend_Json::encode($jiraProjectOptions));
$this->showConfig($shortname);
}
}
class Whitewashing_Tool_JiraException extends Exception
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment