Skip to content

Instantly share code, notes, and snippets.

@mozeryansky
Last active August 29, 2015 14:18
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 mozeryansky/9bcc2f9c7c34a7c35b53 to your computer and use it in GitHub Desktop.
Save mozeryansky/9bcc2f9c7c34a7c35b53 to your computer and use it in GitHub Desktop.
T-Square Wiki Reporting Tool
<?php
$teamURL = "";
$username = "";
$password = "";
if(empty($teamURL)){
echo "You can hard code your team's main site URL, along with all user inputs at the top of the source file.\n";
echo "To find your team's site, login to t-square, navigate to your team's site, and copy the current url.\n";
echo "It should look something like this: https://t-square.gatech.edu/portal/site/abcd1234-ab12-cd34-ad14-abcd1234a1b2\n";
echo "\n";
fwrite(STDOUT, "Team Site URL: ");
$teamURL = trim(fgets(STDIN));
}
if(empty($username)){
fwrite(STDOUT, "Username: ");
$username = trim(fgets(STDIN));
}
if(empty($password)){
fwrite(STDOUT, "Password: ");
$password = preg_replace('/\r?\n$/', '', `stty -echo; head -n1 ; stty echo`);
echo "\n";
}
$ckfile = tempnam("/tmp", "CURLCOOKIE");
$headers = array(
'User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: en-us,en;q=0.5',
'Accept-Encoding: gzip,deflate',
'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'Keep-Alive: 115',
'Connection: keep-alive'
);
function createCurlHandle($url)
{
global $headers, $ckfile;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);
curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile);
curl_setopt($ch, CURLOPT_HEADER, true);
//curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
return $ch;
}
function executeCurl($ch)
{
$output = curl_exec($ch);
if(curl_errno(($ch))){
echo 'Curl error: ' . curl_error($ch);
exit();
}
curl_close($ch);
return $output;
}
function say($message)
{
echo $message."\n";
}
/************ Get Login Page *****************/
say('Aquiring Login Page');
$tsquareLoginURL = 'https://t-square.gatech.edu/portal/login';
$output = executeCurl(createCurlHandle($tsquareLoginURL));
$doc = new DOMDocument();
@$doc->loadHTML($output);
$form = $doc->getElementById('fm1');
// get unique login url
$loginurl = 'https://login.gatech.edu'.$form->getAttribute('action');
// get the lt code. This is new and completely useless...
// probably just prevents non-targeted brute force logins
$inputs = $doc->getElementsByTagName('input');
foreach($inputs as $input){
if(trim($input->getAttribute('name')) == "lt"){
$lt = $input->getAttribute('value');
break;
}
}
/*************** Login ********************/
say('Loggin In');
$post = array(
'username' => $username,
'password' => $password,
'execution' => 'e1s1',
'lt' => $lt,
'_eventId' => 'submit',
'submit' => 'LOGIN'
);
$ch = createCurlHandle($loginurl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$output = executeCurl($ch);
/*************** Goto Team Page ********************/
say('Navigating to Team Site');
// Our Tsquare Site
$output = executeCurl(createCurlHandle($teamURL));
$doc = new DOMDocument();
@$doc->loadHTML($output);
$toolMenuLinks = $doc->getElementById('toolMenu')->getElementsByTagName('a');
foreach($toolMenuLinks as $link){
if(trim($link->getAttribute('class')) == "icon-sakai-rwiki"){
$wikiURL = $link->getAttribute('href');
break;
}
}
/*************** Select Wiki ********************/
say('Opening Wiki Page');
$output = executeCurl(createCurlHandle($wikiURL));
$doc = new DOMDocument();
@$doc->loadHTML($output);
$iframes = $doc->getElementsByTagName('iframe');
foreach($iframes as $iframe){
if(trim($iframe->getAttribute('title')) == "Wiki"){
$wikiIframeURL = $iframe->getAttribute('src');
break;
}
}
list($wikiBaseURL) = explode('?', $wikiIframeURL);// cheap method
/*************** Explore our Wiki ********************/
say('Begin exploring the Wiki');
$sayExploring = true;
function makeDoc($output)
{
$doc = new DOMDocument();
@$doc->loadHTML($output);
return $doc;
}
function getBody($doc)
{
$contentDivs = $doc->getElementById('rwiki_content')->getElementsByTagName('div');
$body = false;
foreach($contentDivs as $div){
if(strtolower(trim($div->getAttribute('class'))) == "rwikirenderedcontent"){
$body = $div;
break;
}
}
if($body === false){
echo "Could not find wiki body!";
exit;
}
return $body;
}
function getLinks($element)
{
global $wikiBaseURL;
$linksArr = array();
$links = $element->getElementsByTagName('a');
foreach($links as $link){
// skip anchors
if($link->getAttribute('class') == "anchorpoint"){
continue;
}
$url = $link->getAttribute('href');
$newLink = array(
'url' => $wikiBaseURL.$url,
'name' => $link->nodeValue,
'external' => false
);
// mark external links
if($url[0] != '?'){
$newLink['external'] = true;
}
$linksArr[] = $newLink;
}
return $linksArr;
}
function recursively_find_text_nodes($dom_element, $depth=1)
{
$return = array();
foreach ($dom_element->childNodes as $dom_child) {
switch ($dom_child->nodeType) {
case XML_TEXT_NODE:
if (trim($dom_child->nodeValue) !== '') {
$return[] = array (
'depth' => $depth,
'value' => $dom_child->nodeValue
);
}
break;
case XML_ELEMENT_NODE:
/*$return[] = array (
'depth' => $depth,
'value' => $dom_child
);*/
$return = array_merge($return, recursively_find_text_nodes($dom_child, $depth+1));
break;
}
}
return $return;
}
function getPageHistory($doc)
{
global $wikiBaseURL;
$historyURL = $wikiBaseURL.$doc->getElementById('historyLink')->getAttribute('href');
$output = executeCurl(createCurlHandle($historyURL));
$body = getBody(makeDoc($output));
$edits = array();
$rows = $body->getElementsByTagName('tr');
$rowsArr = array();
foreach($rows as $row){
$cells = $row->getElementsByTagName('td');
$cellArr = array();
foreach($cells as $cell){
$cellArr[] = trim($cell->textContent);
}
if(empty($cellArr)){
continue;
}
$name = $cellArr[1];
$rowsArr[] = $name;
$creator = $name;
if(!isset($edits[$name])){
$edits[$name] = 0;
}
$edits[$name]++;
}
$lastModifier = $rowsArr[0];
arsort($edits);
reset($edits);
$majority = key($edits);
$history = array(
'editors' => $rowsArr,
'edits' => count($rowsArr),
'creator' => $creator,
'lastModifier' => $lastModifier,
'majority' => $majority
);
return $history;
}
$pagesVisited = array();
function exploreWiki(&$wiki, $level)
{
global $pagesVisited, $sayExploring;
$tabs = str_repeat("\t", $level);
if($wiki['external']){
if($sayExploring){
say($tabs."External: ".$wiki['name']);
}
$wiki['explored'] = false;
return;
}
if(substr($wiki['name'], -1, 1) == '?'){
if($sayExploring){
say($tabs."Empty: ".$wiki['name']);
}
$wiki['emptyPage'] = true;
$wiki['explored'] = false;
return;
}
$wiki['emptyPage'] = false;
$url = $wiki['url'];
if(in_array($wiki['name'], $pagesVisited)){
$wiki['explored'] = false;
//say($tabs."Recursion: ".$wiki['name']);
return;// don't allow recursive links
}
$wiki['explored'] = true;
$pagesVisited[] = $wiki['name'];
if($sayExploring){
say($tabs."Exploring: ".$wiki['name']);
}
$output = executeCurl(createCurlHandle($url));
$doc = makeDoc($output);
$history = getPageHistory($doc);
$wiki['history'] = $history;
$body = getBody($doc);
// counts
$textnodes = recursively_find_text_nodes($body);
$words = 0;
$characters = 0;
foreach($textnodes as $node){
$words += substr_count($node['value'], " ")+1;
$characters += strlen($node['value']);
}
$wiki['lineCount'] = count($textnodes);
$wiki['wordCount'] = $words;
$wiki['characterCount'] = $characters;
// links
$newlinks = getLinks($body);
foreach($newlinks as $link){
// add to wiki structure
$name = $link['name'];
$url = $link['url'];
// build newWiki array
$newWiki = $link;
$newWiki['links'] = array();
// add reference
$wiki['links'][] = &$newWiki;
// explore
exploreWiki($newWiki, $level+1);
// unset the reference, to reuse this variable in the next loop
// silly php you're so advanced
unset($newWiki);
}
}
// create wiki strarting structure
$wiki = array(
array(
'name' => 'Home',
'url' => $wikiIframeURL,
'external' => false,
'links' => array()
)
);
// being exploring
exploreWiki($wiki[0], 0);
say('Finished exploring the Wiki');
// all raw data! Including SSN and passwords.
// print_r($wiki);
// create the final report
function reportOverview($wiki, &$info)
{
if(!$wiki['explored']){
return;
}
$info['pages']++;
$info['lines'] += $wiki['lineCount'];
$info['words'] += $wiki['wordCount'];
$info['characters'] += $wiki['characterCount'];
$info['edits'] += $wiki['history']['edits'];
$links = $wiki['links'];
foreach($links as $wiki){
reportOverview($wiki, $info);
}
}
function reportContentShare($wiki, &$share)
{
if(!$wiki['explored']){
return;
}
$shareArray = array(
'creator' => array(),
'lastModifier' => array(),
'majority' => array(),
'edits' => 0
);
$creator = $wiki['history']['creator'];
if(!isset($share[$creator])){
$share[$creator] = $shareArray;
}
$share[$creator]['creator'][] = $wiki['name'];
$lastModifier = $wiki['history']['lastModifier'];
if(!isset($share[$lastModifier])){
$share[$lastModifier] = $shareArray;
}
$share[$lastModifier]['lastModifier'][] = $wiki['name'];
$majority = $wiki['history']['majority'];
if(!isset($share[$majority])){
$share[$majority] = $shareArray;
}
$share[$majority]['majority'][] = $wiki['name'];
foreach($wiki['history']['editors'] as $editor){
if(!isset($share[$editor])){
$share[$editor] = $shareArray;
}
$share[$editor]['edits']++;
}
$links = $wiki['links'];
foreach($links as $wiki){
reportContentShare($wiki, $share);
}
}
function reportWikiStructure($wiki, $level)
{
if(!$wiki['explored'] && !$wiki['external']){
return;
}
$name = $wiki['name'];
$links = $wiki['links'];
$external = $wiki['external'];
$tabs = str_repeat("\t", $level);
$externalTxt = '';
if($external){
$externalTxt = 'External: ';
}
say($tabs.$externalTxt.$name);
foreach($links as $wiki){
reportWikiStructure($wiki, $level+1);
}
}
function reporDetailedStructure($wiki, $level)
{
if(!$wiki['explored'] && !$wiki['external']){
return;
}
$name = $wiki['name'];
$links = $wiki['links'];
$external = $wiki['external'];
$tabs = str_repeat("\t", $level);
$externalTxt = '';
if($external){
$externalTxt = 'External: ';
}
// title
say($tabs.$externalTxt.$name);
// details
if(isset($wiki['history'])){
say($tabs.' - Creator: '.$wiki['history']['creator']);
say($tabs.' - Last Editor: '.$wiki['history']['lastModifier']);
say($tabs.' - Majority Editor: '.$wiki['history']['majority']);
say($tabs.' - Edits: '.$wiki['history']['edits']);
}
if(isset($wiki['lineCount'])){
say($tabs.' - Lines: '.$wiki['lineCount']);
}
if(isset($wiki['wordCount'])){
say($tabs.' - Words: '.$wiki['wordCount']);
}
foreach($links as $wiki){
reporDetailedStructure($wiki, $level+1);
}
}
say('Creating report');
// create overview
say('Generating overview');
$info = array(
'pages' => 0,
'lines' => 0,
'words' => 0,
'characters' => 0,
'edits' => 0
);
reportOverview($wiki[0], $info);
say('Generating content share');
$share = array();
reportContentShare($wiki[0], $share);
ob_start();
foreach($share as $person=>$details){
say($person);
say('Total Edits: '.$details['edits']);
say('Creator');
foreach($details['creator'] as $page){
say("\t".$page);
}
say('Last Modifier');
foreach($details['lastModifier'] as $page){
say("\t".$page);
}
say('Majority Editor');
foreach($details['majority'] as $page){
say("\t".$page);
}
say('');
}
$detailedShare = ob_get_contents();
ob_end_clean();
ob_start();
say('Total Pages: '.$info['pages']);
say('Total Lines: '.$info['lines']);
say('Total Words: '.$info['words']);
say('Total Characters: '.$info['characters']);
say('Total Edits: '.$info['edits']);
say('');
say('=== Content Share ===');
say('');
foreach($share as $name=>$details){
say($name);
say("\t".'Total Edits: '.$details['edits']);
say("\t".'Created Pages: '.count($details['creator']));
say("\t".'Last To Modify Pages: '.count($details['lastModifier']));
say("\t".'Majority Editor Pages: '.count($details['majority']));
}
$overview = ob_get_contents();
ob_end_clean();
// general structure
say('Generating structure');
ob_start();
reportWikiStructure($wiki[0], 0);
$wikiStructure = ob_get_contents();
ob_end_clean();
// structure with details
say('Generating detailed structure');
ob_start();
reporDetailedStructure($wiki[0], 0);
$detailedStructure = ob_get_contents();
ob_end_clean();
// compile reports together
$filename = 'wiki_'.date('F_d_Y_h_i_a').'.txt';
say('Saving report: '.$filename);
$report = "=== Wiki Report ===\n\n";
$report .= date('F d, Y g:ia')."\n\n";
$report .= $overview."\n\n";
$report .= "=== Wiki Structure ===\n\n";
$report .= $wikiStructure."\n\n";
$report .= "=== Detailed Share Info ===\n\n";
$report .= $detailedShare."\n\n";
$report .= "=== Detailed Structure ===\n\n";
$report .= $detailedStructure;
// save report
@mkdir('reports');
file_put_contents('reports/'.$filename, $report);
say('Done');
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment