Skip to content

Instantly share code, notes, and snippets.

@AddoSolutions
Last active October 22, 2015 15:22
Show Gist options
  • Save AddoSolutions/b01df1c73d09711a3b41 to your computer and use it in GitHub Desktop.
Save AddoSolutions/b01df1c73d09711a3b41 to your computer and use it in GitHub Desktop.
Standup Script

This is kinda hacked together for personal use, but at Casy's request, I put it up here.

  1. Download composer & run composer.phar install
  2. Go here and get an API key: https://trello.com/1/appKey/generate
  3. Update the $key and $secret on line 16 and 17 with that info
  4. Run the PHP file in the server (sudo php -S localhost:80 works, just make sure whatever you use is on port 80)
  5. Open the script in the browser, and authorize the app when prompted
  6. When it comes back, copy the oauth token and oauth secret to lines 19 and 20
  7. You can now use this script both in the CLI and in the browser if you wish.
  8. You should also update $gist on line 8 for your choice of gist file locations

Notes:

  • You can uncomment lines by 150 if you want it to only look at certain boards.
  • It should skip all archived boards, cards, and lists
  • Today:
  • This script scrubbs ALL of your boards for anything that is in Doing or in Today that you personally are assigned to
  • Yesterday:
  • Scrubbs each board activity for any card moved to either Done or QA

This is kinda nice too: alias standup='php -f ~/Sites/local.ethode/standup.php'

{
"require": {
"mattzuba/php-trello": "*"
}
}
<?php
header("Content-Type: text/json; charset=UTF-8");
date_default_timezone_set('America/New_York');
require 'vendor/autoload.php';
$gist = "https://gist.githubusercontent.com/AddoSolutions/b01df1c73d09711a3b41/raw/standup.txt";
class AppTrello{
private static $trello;
function getTrello(){
if(self::$trello) return self::$trello;
$key = '';
$secret = '';
$token="";
$osecret = "";
$trello = null;
if($token){
$trello = new \Trello\Trello($key, $secret, $token, $osecret);
}else{
$trello = new \Trello\Trello($key, $secret);
$trello->authorize(array(
'expiration' => 'never',
'scope' => array(
'read' => true,
),
'name' => 'My Daily Standup'
));
print_r($trello);
die();
}
self::$trello = $trello;
return $trello;
}
function getBoards(){
$trello = $this->getTrello();
return $trello->members->get('my/boards', array(
"filter"=>"open"
));
}
function processCardlist($cards){
$lastBoard = false;
$s = "";
foreach($cards as $card){
if(!$lastBoard || $lastBoard->id != $card->board->id){
$s .= $this->getBoardString($card->board);
$lastBoard = $card->board;
}
$s .= $this->getCardString($card);
}
return $s;
}
function filterLine($line, $lineIndent){
$count = 60-strlen($lineIndent);
return implode(str_split($line,$count),$lineIndent);
}
function getBoardString($board){
$s = $board->name;
return " - ".$this->filterLine($s,"\n ")."\n";
}
function getCardString($card){
$s = $card->name;
$labels = array();
if($card->labels){
foreach($card->labels as $label){
if($label->name) $labels[] = $label->name;
}
if(count($labels) > 0) $labels = " (".implode($labels,", ").")";
}
$s.=$labels;
$seperator = "\n ";
$url = implode('/', array_slice(explode('/', $card->url), 0, -1));
return " : - ".$this->filterLine($s,$seperator).$seperator.$url."\n";
}
}
$app = new AppTrello();
$trello = $app->getTrello();
$me = $trello->members->get("me");
$boards = $app->getBoards();
$output = file_get_contents($gist);
$data = array(
"today" => array(),
"yesterday" => array()
);
$replace = $data;
$i=0;
$dow = date("N")%7;
while($i<7){
$marker = "X";
if($i==$dow) $marker = ">";
if($i > $dow) $marker = "o";
$i++;
$replace["day$i"] = $marker;
}
$yesterday = strtotime("yesterday");
foreach($boards as $board){
/*
if(!preg_match("/MyPraize/", $board->name)){
echo "Skipping Board: ".$board->name."\n";
continue;
}
*/
echo "Loading Board: ".$board->name."\n";
$lists = $trello->boards->get($board->id."/lists", array(
"cards"=>"open"
));
foreach ($lists as $list){
$listName = $list->name;
$reflist = clone $list;
unset($reflist->cards);
//We only want todays stuff
if(stripos($listName, "Today") === false && stripos($listName, "Doing") === false ){
echo " - Skipping: " . $listName."\n";
continue;
}
foreach($list->cards as $card){
//Only my cards matter
if(!in_array($me->id, $card->idMembers)){
continue;
}
$card->list = $reflist;
$card->board = $board;
$data['today'][] = $card;
}
}
$activityFeed = $trello->boards->get($board->id."/actions", array(
"cards"=>"open",
"entities"=>"true",
//"before"=>strtotime("today")
));
foreach($activityFeed as $activity){
//Again, only MY cards
if($me->id != $activity->idMemberCreator){
continue;
}
if(!$activity->data->listAfter) $listName = false;
else $listName = $activity->data->listAfter->name;
//We only want completed cards
if(!$listName || (!preg_match("/Done/",$listName) && $listNmypame!="QA")){
//echo " - No List After: ".$listName."\n";
continue;
}
//print_r($activity);
//die();
$date = strtotime($activity->date);
if($date < $yesterday) continue;
$card = $trello->boards->get($board->id."/cards/".$activity->data->card->id);
$card->board = $board;
$data['yesterday'][] = $card;
}
}
//print_r($data);
$replace["today"] = $app->processCardlist($data["today"]);
$replace["yesterday"] = $app->processCardlist($data["yesterday"]);
//print_r($replace);
foreach($replace as $n=>$v){
$output = str_replace("{{data.".$n."}}",$v, $output);
}
//print_r($me);
/*print_r(
$trello->boards->get($board->id."/lists", array(
"cards"=>"all"
))
);
print_r(
$trello->boards->get($board->id."/actions", array(
"cards"=>"all"
))
);*/
/*
Card Object:
(
[id] => 51a7b35535089960140064eb
[checkItemStates] => Array
(
)
[closed] =>
[dateLastActivity] => 2013-05-30T20:15:17.317Z
[desc] => Why use Addo? What makes us special? What sets up apart? Why do we rock?
[descData] =>
[email] =>
[idBoard] => 51a76e3d0aabcf35330017ad
[idList] => 51a76e3d0aabcf35330017ae
[idMembersVoted] => Array
(
)
[idShort] => 5
[idAttachmentCover] =>
[manualCoverAttachment] =>
[idLabels] => Array
(
[0] => 545c12e274d650d5673566b0
)
[name] => Company Key Points
[pos] => 16384
[shortLink] => Icm6pT18
[badges] => stdClass Object
(
[votes] => 0
[viewingMemberVoted] =>
[subscribed] => 1
[fogbugz] =>
[checkItems] => 0
[checkItemsChecked] => 0
[comments] => 2
[attachments] => 0
[description] => 1
[due] =>
)
[due] =>
[idChecklists] => Array
(
)
[idMembers] => Array
(
[0] => 517fe350d7cd147469000d1a
[1] => 51a76fb78ffb80af45000ae0
)
[labels] => Array
(
[0] => stdClass Object
(
[id] => 545c12e274d650d5673566b0
[idBoard] => 51a76e3d0aabcf35330017ad
[name] =>
[color] => blue
[uses] => 4
)
)
[shortUrl] => https://trello.com/c/Icm6pT18
[subscribed] => 1
[url] => https://trello.com/c/Icm6pT18/5-company-key-points
)
Activity Object:
(
[id] => 5466b3d94c235aec1770d723
[idMemberCreator] => 517fe350d7cd147469000d1a
[data] => stdClass Object
(
[listAfter] => stdClass Object
(
[name] => Doing
[id] => 5464f1cf5ee15c7c082b6195
)
[listBefore] => stdClass Object
(
[name] => To Do
[id] => 5464f1cd4c1b3a623292a1d0
)
[board] => stdClass Object
(
[shortLink] => TGIEVQTP
[name] => Artman App
[id] => 5464f1a446f0536f14843cec
)
[card] => stdClass Object
(
[shortLink] => RKl1lU87
[idShort] => 14
[name] => Migrations
[id] => 546551e8491f8d1586c5cc68
[idList] => 5464f1cf5ee15c7c082b6195
)
[old] => stdClass Object
(
[idList] => 5464f1cd4c1b3a623292a1d0
)
)
[type] => updateCard
[date] => 2014-11-15T02:00:57.166Z
[memberCreator] => stdClass Object
(
[id] => 517fe350d7cd147469000d1a
[avatarHash] => 8252c3921f6926bacf6f1b928e53d297
[fullName] => Nick Artman
[initials] => NA
[username] => nickartman
)
)
*/
echo "\n\n==============================================\n\n\n\n\n```\n".$output."\n```\n\n";
( (
)\ ) ) ( )\ ) (
(()/(( /( ) )\ ) ( (()/( ) ( )\(
/(_))\()| /( ( (()/( ))\ ` ) /(_)) ( /( )\((_)\ )
(_))(_))/)(_)) )\ ) ((_))((_)/(/( (_))_ )(_)|(_)_(()/(
/ __| |_((_)_ _(_/( _| (_))(((_)_\ | \((_)_ (_) |)(_))
\__ \ _/ _` | ' \)) _` | || | '_ \) | |) / _` || | | || |
|___/\__\__,_|_||_|\__,_|\_,_| .__/ |___/\__,_||_|_|\_, |
|_| |__/
YESTERDAY ({{data.yesterdate}})
-----------------------------------------------------------
{{data.yesterday}}
TODAY
-----------------------------------------------------------
{{data.today}}
BLOCKERS
-----------------------------------------------------------
- Life
SCHEDULE
-----------------------------------------------------------
{{data.day2}} M: Working Offsite
{{data.day3}} T: Medina
{{data.day4}} W: Medina
{{data.day5}} H: Medina
{{data.day6}} F: Working Offsite
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment