Skip to content

Commit

Permalink
Small improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
nvigne committed Sep 18, 2024
1 parent 0f68de3 commit 3dd0e77
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 104 deletions.
2 changes: 1 addition & 1 deletion DesktopFlowCLI/DesktopFlowCLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>0.2.0</Version>
<Version>0.2.1</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
218 changes: 116 additions & 102 deletions DesktopFlowCLI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,57 @@
using System.Text;


var rootCommand = new RootCommand();
rootCommand.Description = "This tool will list all desktop flows in a Dataverse environment and sort them by size.";
internal class Program
{
private static async Task Main(string[] args)
{
var rootCommand = new RootCommand();
rootCommand.Description = "This tool will list all desktop flows in a Dataverse environment and sort them by size.";

var cServiceUri = new Option<string>("--service-uri", "The service uri.");
var maxSize = new Option<int>("--min-size", () => 0, "The minimum size to be displayed.");
var path = new Option<string>("--path", "The path to save the output file.");
var cServiceUri = new Option<string>("--service-uri", "The service uri.");
var maxSize = new Option<int>("--min-size", () => 0, "The minimum size to be displayed.");
var path = new Option<string>("--path", () => "desktopflow.csv", "The path to save the output file.");
var pageSize = new Option<int>("--page-size", () => 10, "The page size to retrieve records.");

var command = new Command("list", "List all desktop flows in a Dataverse environment and sort them by size.")
var command = new Command("list", "List all desktop flows in a Dataverse environment and sort them by size.")
{
maxSize,
cServiceUri,
path,
pageSize
};

command.SetHandler((string serviceUri, int maxSize, string path) =>
{
ListDesktopFlows(serviceUri, maxSize, path).Wait();
}, cServiceUri, maxSize, path);
command.SetHandler((string serviceUri, int maxSize, string path, int pageSize) =>
{
ListDesktopFlows(serviceUri, maxSize, path, pageSize).Wait();
}, cServiceUri, maxSize, path, pageSize);

rootCommand.Add(command);
rootCommand.Add(command);

await rootCommand.InvokeAsync(args);
await rootCommand.InvokeAsync(args);

async Task ListDesktopFlows(string serviceUri, int maxSize, string path)
{
var list = new List<DesktopFlow>();
async Task ListDesktopFlows(string serviceUri, int maxSize, string path, int pageSize)
{
var list = new List<DesktopFlow>();

var serviceClient = new ServiceClient(connectionOptions: new ConnectionOptions
{
LoginPrompt = Microsoft.PowerPlatform.Dataverse.Client.Auth.PromptBehavior.Auto,
AuthenticationType = Microsoft.PowerPlatform.Dataverse.Client.AuthenticationType.OAuth,
ServiceUri = new Uri(serviceUri),
RedirectUri = new Uri("http://localhost")
}, false, null);
var serviceClient = new ServiceClient(connectionOptions: new ConnectionOptions
{
LoginPrompt = Microsoft.PowerPlatform.Dataverse.Client.Auth.PromptBehavior.Auto,
AuthenticationType = Microsoft.PowerPlatform.Dataverse.Client.AuthenticationType.OAuth,
ServiceUri = new Uri(serviceUri),
RedirectUri = new Uri("http://localhost")
}, false, null);

serviceClient.Connect();
serviceClient.Connect();

Entity entity = new("workflow");
Entity entity = new("workflow");

var query = new QueryExpression
{
ColumnSet = new ColumnSet("workflowid", "name", "clientdata", "modifiedon"),
Criteria = new FilterExpression
{
Conditions =
var query = new QueryExpression
{
ColumnSet = new ColumnSet("workflowid", "name", "clientdata", "modifiedon"),
Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression
{
Expand All @@ -61,90 +67,98 @@ async Task ListDesktopFlows(string serviceUri, int maxSize, string path)
Values = { 6 }
},
}
},
PageInfo = new PagingInfo
{
Count = 100,
ReturnTotalRecordCount = true,
PageNumber = 1
},
EntityName = entity.LogicalName
};
LinkEntity link = query.AddLink("systemuser", "ownerid", "systemuserid", JoinOperator.Inner);
link.Columns.AddColumns("fullname");
link.Columns.AddColumn("internalemailaddress");
link.EntityAlias = "owner";

var results = await serviceClient.RetrieveMultipleAsync(query);
using var file = File.OpenWrite(path);
await file.WriteAsync(Encoding.UTF8.GetBytes("Name,Size,Owner,ModifiedOn\n"));

do
{
var tempList = new List<DesktopFlow>();
foreach (var recod in results.Entities)
{
var size = System.Text.Encoding.Unicode.GetByteCount(recod.GetAttributeValue<string>("clientdata"));
if (size < maxSize)
{
continue;
}
},
PageInfo = new PagingInfo
{
Count = pageSize,
ReturnTotalRecordCount = true,
PageNumber = 1
},
EntityName = entity.LogicalName
};
LinkEntity link = query.AddLink("systemuser", "ownerid", "systemuserid", JoinOperator.Inner);
link.Columns.AddColumns("fullname");
link.Columns.AddColumn("internalemailaddress");
link.EntityAlias = "owner";

var dektopFlow = new DesktopFlow
var results = await serviceClient.RetrieveMultipleAsync(query);
using var file = File.Open(path, FileMode.Create, FileAccess.Write);
Console.WriteLine(file.Name);
await file.WriteAsync(Encoding.UTF8.GetBytes("Name,Size,Owner,ModifiedOn\n"));

do
{
Id = recod.Id.ToString(),
Name = recod.GetAttributeValue<string>("name"),
Size = size,
OwnerName = recod.GetAttributeValue<AliasedValue>("owner.internalemailaddress").Value.ToString(),
ModifiedOn = recod.GetAttributeValue<DateTime>("modifiedon"),
};
var tempList = new List<DesktopFlow>();
foreach (var recod in results.Entities)
{
int size = Encoding.Unicode.GetByteCount(recod.GetAttributeValue<string>("clientdata"));

list.Add(dektopFlow);
tempList.Add(dektopFlow);
}
recod["clientdata"] = null;

Console.WriteLine($"Retrieved currently {list.Count} desktop flows from the environment.");
GC.Collect();

foreach (var item in tempList)
{
await file.WriteAsync(Encoding.UTF8.GetBytes($"{item.Name},{item.Size},{item.OwnerName},{item.ModifiedOn}\n"));
}
if (size < maxSize)
{
continue;
}

await file.FlushAsync();
var dektopFlow = new DesktopFlow
{
Id = recod.Id.ToString(),
Name = recod.GetAttributeValue<string>("name"),
Size = size,
OwnerName = recod.GetAttributeValue<AliasedValue>("owner.internalemailaddress").Value.ToString(),
ModifiedOn = recod.GetAttributeValue<DateTime>("modifiedon"),
};

if (results.MoreRecords)
{
Console.WriteLine("Getting more records...");
query.PageInfo.PagingCookie = results.PagingCookie;
query.PageInfo.PageNumber++;
results = await serviceClient.RetrieveMultipleAsync(query);
}
else
{
break;
}
} while (true);
list.Add(dektopFlow);
tempList.Add(dektopFlow);
}

Console.WriteLine($"Retrieved currently {list.Count} desktop flows from the environment.");

list = list.OrderByDescending(x => x.Size).ToList();
foreach (var item in tempList)
{
await file.WriteAsync(Encoding.UTF8.GetBytes($"{item.Name},{item.Size},{item.OwnerName},{item.ModifiedOn}\n"));
}

Console.WriteLine($"Display desktop flows by size on the environment {serviceClient.OrganizationDetail.FriendlyName}");
await file.FlushAsync();

foreach (var item in list)
{
Console.WriteLine($"DesktopFlow: {item.Name} with id: {item.Id}, Size: {BytesToString(item.Size)}, Owner: {item.OwnerName}, Last Modified date: {item.ModifiedOn}");
}
}
if (results.MoreRecords)
{
Console.WriteLine("Getting more records...");
query.PageInfo.PagingCookie = results.PagingCookie;
query.PageInfo.PageNumber++;
results = await serviceClient.RetrieveMultipleAsync(query);
}
else
{
break;
}
} while (true);


list = list.OrderByDescending(x => x.Size).ToList();

static String BytesToString(long byteCount)
{
string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB
if (byteCount == 0)
return "0" + suf[0];
long bytes = Math.Abs(byteCount);
int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
double num = Math.Round(bytes / Math.Pow(1024, place), 1);
return (Math.Sign(byteCount) * num).ToString() + suf[place];
Console.WriteLine($"Display desktop flows by size on the environment {serviceClient.OrganizationDetail.FriendlyName}");

foreach (var item in list)
{
Console.WriteLine($"DesktopFlow: {item.Name} with id: {item.Id}, Size: {BytesToString(item.Size)}, Owner: {item.OwnerName}, Last Modified date: {item.ModifiedOn}");
}
}



static string BytesToString(long byteCount)
{
string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB
if (byteCount == 0)
return "0" + suf[0];
long bytes = Math.Abs(byteCount);
int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
double num = Math.Round(bytes / Math.Pow(1024, place), 1);
return (Math.Sign(byteCount) * num).ToString() + suf[place];
}
}
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Run the tool

DesktopFlowCLI.exe list --service-uri "url of the Dataverse instance" --min-size 1000000 --path "path to output folder"
DesktopFlowCLI.exe list --service-uri "url of the Dataverse instance" --min-size 1000000 --path "path to output folder" --page-size 10

0 comments on commit 3dd0e77

Please sign in to comment.