#!/usr/bin/env php rows[] = $line; $line = array(); $value = ''; } if ($c == $enclose) { if (!$inQuotes) { $inQuotes = true; } else if ($pascalEscapes) { if ($quoteInQuote) { $quoteInQuote = false; $value .= $enclose; } else { $quoteInQuote = true; } } else { $inQuotes = false; } continue; } if ($inQuotes) { $value .= $c; continue; } if ($c == $terminate) { $line[] = iconv($charset, 'UTF-8//TRANSLIT', $value); $value = ''; } else if ($c == "\r") { $lastWasCR = true; } else if ($c == "\n") { $line[] = iconv($charset, 'UTF-8//TRANSLIT', $value); $result->rows[] = $line; $line = array(); $value = ''; $lastWasCR = false; } else { $value .= $c; } } if (!empty($value)) { $line[] = iconv($charset, 'UTF-8//TRANSLIT', $value); } if (!empty($line)) { $result->rows[] = $line; } return $result; } public function free() { $this->rows = array(); } public function countFields() { if ($this->rowValid()) { return count($this->currentRow()); } else if (!empty($this->rows)) { return count($this->rows[0]); } else { return 0; } } public function countRows() { return count($this->rows); } public function getFieldName($columnOffset) { if (isset($this->names[$columnOffset])) { return $this->names[$columnOffset]; } else { throw OutOfBoundsException('cannot determine name for column at offset '.$columnOffset); } } public function next($forSure = false) { ++$this->rowCursor; if ($this->rowValid()) { return true; } else if ($forSure) { throw new OutOfBoundsException('there is no next row in this result set'); } else { return false; } } public function has($columnOffset) { return $this->rowValid() && array_key_exists($columnOffset, $this->currentRow()); } public function get($columnOffset) { if (!isset($this->rows[$this->rowCursor])) { throw new OutOfBoundsException('cannot get column '.$columnOffset.' of row '.$this->rowCursor.': invalid row'); } if (!isset($this->rows[$this->rowCursor][$columnOffset])) { throw new OutOfBoundsException('cannot get column '.$columnOffset.' of row '.$this->rowCursor.': invalid column'); } return $this->rows[$this->rowCursor][$columnOffset]; } public function loadColumnNamesFromFirstRow() { if (isset($this->rows[0])) { $this->setColumnNames($this->rows[0]); } else { throw new RuntimeException('there is no first row'); } } public function setColumnNames($names) { $this->names = $names; } public function getNamed($name) { if (in_array($name, $this->names)) { return $this->get(array_search($name, $this->names)); } else { throw new OutOfBoundsException($name.' is not a valid column name'); } } public function getNamedInt($name) { return intval($this->getNamed($name)); } public function getRowNumber() { return $this->rowCursor + 1; } private function rowValid() { return $this->rowCursor > -1 && $this->rowCursor < $this->countRows(); } private function currentRow() { return $this->rows[$this->rowCursor]; } private $names = array(); private $rows = array(); private $rowCursor = -1; } function writeTicket(CSVReader $csv, $filename) { $file = fopen($filename, 'w'); fputs($file, $csv->getNamed('Tracker').' #'.$csv->getnamed('#') .' - '.$csv->getNamed('Subject').PHP_EOL.PHP_EOL); fputs($file, ' '.str_pad(' Status: '.$csv->getNamed('Status'), 35) .' Start date: '.$csv->getNamed('Start date').PHP_EOL); fputs($file, ' '.str_pad('Priority: '.$csv->getNamed('Priority'), 35) .' Due date: '.$csv->getNamed('Due date').PHP_EOL); fputs($file, ' '.str_pad('Assignee: '.$csv->getNamed('Assignee'), 35) .' Done: '.$csv->getNamed('% Done').'%'.PHP_EOL); fputs($file, ' '.str_pad('Category: '.$csv->getNamed('Category'), 35) .'Target version: '.$csv->getNamed('Target version').PHP_EOL.PHP_EOL); $description = $csv->getNamed('Description'); $description = wordwrap(trim(str_replace( array("\r\n", "\r", "\n"), array("\n", "\n", PHP_EOL), $description))); fputs($file, $description.PHP_EOL); fclose($file); $updated = DateTime::createFromFormat( 'm/d/Y h:i a', // 01/03/2013 05:56 am $csv->getNamed('Updated'), new DateTimeZone('Europe/Berlin'))->getTimestamp(); touch($filename, $updated); } $dir = dirname(dirname(__FILE__)).'/issues'; if (!is_dir($dir)) { echo 'creating: ', $dir, PHP_EOL; mkdir($dir); } $csv = CSVReader::readFile('http://luke.redirectme.net/redmine/projects/l2e/issues.csv?columns=all&description=1', '"', ',', '\\', true, 'CP1252'); $csv->loadColumnNamesFromFirstRow(); $csv->next(); $ids = array(); while ($csv->next()) { $ids[] = $csv->getNamed('#'); $filename = $csv->getNamed('#').' '.$csv->getNamed('Subject'); $filepath = $dir.'/'.$filename; if (!file_exists($filepath)) { echo 'writing: ', $filename, PHP_EOL; writeTicket($csv, $filepath); continue; } $modified = filemtime($filepath); $updated = DateTime::createFromFormat( 'm/d/Y h:i a', // 01/03/2013 05:56 am $csv->getNamed('Updated'), new DateTimeZone('Europe/Berlin'))->getTimestamp(); if ($updated > $modified) { echo 'updating: ', $filename, PHP_EOL; writeTicket($csv, $filepath); } } $existing = scandir($dir); foreach ($existing as $name) { if (!is_file($dir.'/'.$name)) continue; $id = intval($name); if ($id > 0 && !in_array($id, $ids)) { echo 'removing: ', $name, PHP_EOL; unlink($dir.'/'.$name); } } ?>