Skip to content

Instantly share code, notes, and snippets.

@v9n
Last active January 27, 2023 21:04
Show Gist options
  • Save v9n/bacc696c0776503e9ee87cd0633161da to your computer and use it in GitHub Desktop.
Save v9n/bacc696c0776503e9ee87cd0633161da to your computer and use it in GitHub Desktop.
tree.ps1
#Variables that need to be set for each run
$startFolder = $args[0];
$destinationHTMLFile = "c:\\tree.html"; #The final html file that will be produced, #does not need to exist
$htmlLines = @();
#Function that creates a folder detail record
function CreateFolderDetailRecord
{
param([string]$FolderPath)
#Get the total size of the folder by recursively summing its children
$subFolderItems = Get-ChildItem $FolderPath -recurse -force | Where-Object {$_.PSIsContainer -eq $false} | Measure-Object -property Length -sum | Select-Object Sum
$folderSizeRaw = 0;
$folderSize = 0;
$units = "";
#Account for no children
if($subFolderItems.sum -gt 0)
{
$folderSizeRaw = $subFolderItems.sum;
}
#Determine units for a more friendly output
if(($subFolderItems.sum / 1GB) -ge 1)
{
$units = "GB"
$folderSize = [math]::Round(($subFolderItems.sum / 1GB),2)
}
else
{
if(($subFolderItems.sum / 1MB) -ge 1)
{
$units = "MB"
$folderSize = [math]::Round(($subFolderItems.sum / 1MB),2)
}
else
{
$units = "KB"
$folderSize = [math]::Round(($subFolderItems.sum / 1KB),2)
}
}
#Create an object with the given properties
$newFolderRecord = New-Object –TypeName PSObject
$newFolderRecord | Add-Member –MemberType NoteProperty –Name FolderPath –Value $FolderPath;
$newFolderRecord | Add-Member –MemberType NoteProperty –Name FolderSizeRaw –Value $folderSizeRaw
$newFolderRecord | Add-Member –MemberType NoteProperty –Name FolderSizeInUnits –Value $folderSize;
$newFolderRecord | Add-Member –MemberType NoteProperty –Name Units –Value $units;
return $newFolderRecord;
}
#Function that recursively creates the html for the output, given a starting location
function GetAllFolderDetails
{
param([string]$FolderPath)
$recursiveHTML = @();
#Get properties used for processing
$folderItem = Get-Item -Path $FolderPath
$folderDetails = CreateFolderDetailRecord -FolderPath $FolderPath
$subFolders = Get-ChildItem $FolderPath | Where-Object {$_.PSIsContainer -eq $true} | Sort-Object
$files = Get-ChildItem $FolderPath | Where-Object {$_.PSIsContainer -eq $false} | Sort-Object
#Recursively call this function for all subfolders
foreach($item in $files)
{
$recursiveHTML += "<li><a href='" + $folderPath + "'>" + $folderPath + "</a>\<a href='" + $folderPath + "\\" + $item.Name + "'><span class='caret'>" + $item.Name + "</span></a></li>"
}
#If has subfolders, create hmtl drilldown.
if($subFolders.Count -gt 0)
{
#$recursiveHTML += "<li><span class='caret'>" + $folderItem.Name + " (<span style='color:red'>" + $folderDetails.FolderSizeInUnits + " " + $folderDetails.Units + "</span>)" + "</span>"
$recursiveHTML += "<ul class='nested'>"
}
#Recursively call this function for all subfolders
foreach($subFolder in $subFolders)
{
$recursiveHTML += GetAllFolderDetails -FolderPath $subFolder.FullName;
}
#Close up all tags
if($subFolders.Count -gt 0)
{
$recursiveHTML += "</ul>";
}
$recursiveHTML += "</li>";
return $recursiveHTML
}
#Processing Starts Here
#Opening html
$htmlLines += @'
<html
lang="en"
class="route-documentation"
>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma-rtl.min.css">
<style>
,caret {
cursor: pointer;
-webkit-user-select: none; /* Safari 3.1+ */
-moz-user-select: none; /* Firefox 2+ */
-ms-user-select: none; /* IE 10+ */
user-select: none;
}
.caret::before {
content: "\25B6";
color: black;
display: inline-block;
margin-right: 6px;
}
.caret-down::before {
-ms-transform: rotate(90deg); /* IE 9 */
-webkit-transform: rotate(90deg); /* Safari */'
transform: rotate(90deg);
}
</style>
</head><body>
'@
$htmlLines += "<ul id='myUL'>"
#This function call will return all of the recursive html for the startign folder and below
$htmlLines += GetAllFolderDetails -FolderPath $startFolder
#Closing html
$htmlLines += "</ul>"
$htmlLines += "</body></html>"
#Get the html template, replace the template with generated code and write to the final html file
$htmlLines | Set-Content $destinationHTMLFile
import os
import sys
import csv
HtmlTree = "tree.html"
CSVTree = "treee.csv"
w = open(HtmlTree, "w")
w.write("""<html
lang="en"
class="route-documentation"
>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma-rtl.min.css">
<style>
.caret {
cursor: pointer;
-webkit-user-select: none; /* Safari 3.1+ */
-moz-user-select: none; /* Firefox 2+ */
-ms-user-select: none; /* IE 10+ */
user-select: none;
}
.caret::before {
content: "↳";
color: black;
display: inline-block;
margin-right: 6px;
}
.caret-down::before {
-ms-transform: rotate(90deg); /* IE 9 */
-webkit-transform: rotate(90deg); /* Safari */'
transform: rotate(90deg);
}
li { padding-bottom: 1em; }
li li { padding-bottom: 0.2em; padding-left: 2em; }
</style>
</head><body>
""")
with open(CSVTree, 'w', newline='') as csvfile:
tree = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
tree.writerow(["Dir name", "File name"])
for (dir_path, dir_names, file_names) in os.walk(sys.argv[1]):
if len(file_names) == 0:
continue
w.write("<li><a href='{}'>{}</a><ul>".format(dir_path, dir_path))
for f in file_names:
tree.writerow([dir_path, f])
w.write("<li><a href='{}'><span class='caret'>{}</span></a></li>\n".format(os.path.join(dir_path, f), f))
w.write("</ul></li>")
w.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment