Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP - Avalonia Rewrite #104

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
271 changes: 240 additions & 31 deletions .gitignore

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions CSAUSBTool.Base/CSAUSBTool.Base.csproj
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>netstandard2.1</TargetFramework>
<OutputType>Library</OutputType>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="RestSharp" Version="110.2.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers" Version="0.3.261602">
<PackageReference Include="Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers" Version="0.4.421302">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Octokit" Version="0.50.0" />
<PackageReference Include="Octokit" Version="9.1.2" />
</ItemGroup>
</Project>
124 changes: 57 additions & 67 deletions CSAUSBTool.Base/ControlSystemsSoftware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,86 +14,86 @@ namespace CSAUSBTool.Base
{
public class ControlSystemsSoftware
{
public string Name { get; }
private string Url { get; set; }
private string Hash { get; }
public string Name { get; set; }
public string Description { get; set; }
public string FileName { get; set; }
private bool Unzip { get; }
private GitHubClient github;
public List<string> Tags { get; set; }
public string Uri { get; set; }
public string? Hash { get; set; }
public string Platform { get; set; }

public ControlSystemsSoftware(string name, string fileName, string url, string hash, bool unzip)
private Dictionary<string, string> DownloadableAssets { get; set; }

private GitHubClient github = new(new ProductHeaderValue("CSAUSBTool"));

public ControlSystemsSoftware()
{
if (url == "")
return;

Name = name;
FileName = fileName;
Url = url;
Hash = hash;
Unzip = unzip;
github = new GitHubClient(new ProductHeaderValue("CSAUSBTool"));
}

public async void Download(string path, AsyncCompletedEventHandler progress)
private async Task ParseGitHubRelease()
{
if (FileName == "") return;
//Org, repo, file Using match index to
var rx = new Regex(@"({<owner>})({<repo>})({<release>})", RegexOptions.Compiled | RegexOptions.IgnoreCase);
var matches = rx.Matches(Url);
// Use github latest
var rx = new Regex(@"github://({<owner>})/({<repo>})/({<release>})", RegexOptions.Compiled | RegexOptions.IgnoreCase);
var matches = rx.Matches(Uri);
foreach (Match match in matches)
{
Release gitHubRelease;
var collection = match.Groups;
var owner = collection["owner"].Value;
var repo = collection["repo"].Value;
var releaseMatch = collection["release"].Value;

var release = await github.Repository.Release.GetLatest(owner, repo);
foreach (var asset in release.Assets)
var tag = collection["release"].Value;
if (tag.Equals("latest"))
{
if(!asset.Name.Contains(releaseMatch) || matches.Count == 0)
continue;

FileName = asset.Name;
Url = asset.BrowserDownloadUrl;
gitHubRelease = await github.Repository.Release.GetLatest(owner, repo);
}
else
{
gitHubRelease = await github.Repository.Release.Get(owner, repo, tag);
}

foreach (var asset in gitHubRelease.Assets)
{
DownloadableAssets.Add(asset.Name, asset.BrowserDownloadUrl);
}
}

if (File.Exists($"{path}\\{FileName}") && IsValid(path))
}
public async void Download(string path, AsyncCompletedEventHandler progress)
{
foreach (var (filename, uri) in DownloadableAssets)
{
progress?.Invoke(null, null);
return;
}
if (filename.Equals("")) continue;

if (Url.StartsWith("local:"))
{
CopyLocal(Url.ToString().Replace("local:", ""), path);
progress?.Invoke(null, null);
if (!File.Exists($"{path}\\{filename}") || !IsValid(path)) continue;

if (uri.StartsWith("file://"))
{
CopyLocal(uri.Replace("file://", ""), path);
progress.Invoke(null, null);
return;
}
await DownloadHttp(uri, path, progress);
progress.Invoke(null, null);
return;
}

await DownloadHttp(path, progress);
}
}

private async Task DownloadHttp(string path, AsyncCompletedEventHandler handler)
private async Task DownloadHttp(string sourceUri, string destinationPath, AsyncCompletedEventHandler handler)
{
var noCancel = new CancellationTokenSource();

using (var client = new HttpClientDownloadWithProgress(Url,
$"{path}\\{FileName}"))
using var client = new HttpClientDownloadWithProgress(sourceUri,
$"{destinationPath}\\{FileName}");
client.ProgressChanged += (totalFileSize, totalBytesDownloaded, progressPercentage) =>
{
client.ProgressChanged += (totalFileSize, totalBytesDownloaded, progressPercentage) =>
if (progressPercentage == null) return;
if ((int) progressPercentage == 100)
{
if (progressPercentage == null) return;
if ((int) progressPercentage == 100)
{
handler?.Invoke(null, null);
}
};

await client.StartDownload(noCancel.Token);
}
handler?.Invoke(null, null);
}
};

await client.StartDownload(noCancel.Token);
}

public void CopyLocal(string sourcePath, string destPath)
Expand All @@ -108,22 +108,12 @@ public bool IsValid(string path)
return Hash == calc;
}

public void UnzipFile(string path)
{
if (!Unzip) return;
ZipFile.ExtractToDirectory($"{path}\\{FileName}", FileName);
}

private static string CalculateMd5(string filepath)
{
using (var md5 = MD5.Create())
{
using (var stream = File.OpenRead(filepath))
{
var hash = md5.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
}
using var md5 = MD5.Create();
using var stream = File.OpenRead(filepath);
var hash = md5.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
}
}
34 changes: 34 additions & 0 deletions CSAUSBTool.Base/ExampleYear.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"Year": 2024,
"Program": "FRC",
"Software": [
{
"Name": "NI Game Tools",
"Description": "Game Tools for FRC - DriverStation",
"Tags": [
"Team",
"Event",
"FTA",
"CSA"
],
"FileName": "",
"Uri": "",
"Hash": "",
"Platform": "Windows"
},
{
"Name": "Example GitHub Release",
"Description": "Example Software",
"Tags": [
"Team",
"Event",
"FTA",
"CSA"
],
"FileName": "",
"Uri": "github://CrossTheRoadElec/Phoenix-Releases/v24.2.0",
"Hash": null,
"Platform": "Windows"
}
]
}
29 changes: 19 additions & 10 deletions CSAUSBTool.Base/FIRSTSeason.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
using System;
using RestSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Text.Json;

namespace CSAUSBTool.Base
{
public enum FIRSTProgram
{
FRC,
FTC
FTC
}

public class FIRSTSeason
{
public int Year { get; set; }
Expand All @@ -21,7 +22,6 @@ public class FIRSTSeason

public FIRSTSeason(int year, FIRSTProgram program, string uri = "")
{

Year = year;
Program = program;
if (uri.Equals(""))
Expand All @@ -36,6 +36,9 @@ public List<ControlSystemsSoftware> GetWebList(string uri)
return GetLocalList(uri.Replace("local:", ""));
}

var client = new RestClient(uri);
var req = new RestRequest();
client.DownloadDataAsync(req);
using (var client = new WebClient())
{
Console.WriteLine($"{Program}{Year}:{uri}");
Expand All @@ -45,39 +48,45 @@ public List<ControlSystemsSoftware> GetWebList(string uri)
}
}

public List<ControlSystemsSoftware> GetLocalList(string uri)
public List<ControlSystemsSoftware> FromLocal(string uri)
{
var lines = new List<string>();
using (var file = new StreamReader(uri))
{
string line;

while ((line = file.ReadLine()) != null)
{
lines.Add(line);
}
}

return GetFromCsv(lines);
}

private static List<ControlSystemsSoftware> GetFromCsv(List<string> lines)
private static List<ControlSystemsSoftware> FromCsv(List<string> lines)
{
var ret = new List<ControlSystemsSoftware>();
lines.ForEach(line =>
{
if (line.Equals("") || line.StartsWith("#")) return;
var args = line.Split(',');
ret.Add(new ControlSystemsSoftware(args[0], args[1], args[2], args[3], bool.Parse(args[4])));
ret.Add(new ControlSystemsSoftware() { });
});

return ret;
}

private static List<ControlSystemsSoftware> FromJson(string json)
{
}

public override string ToString()
{
return $"{Program} - {Year}";
}
}

public class FRCSeason : FIRSTSeason
{
public FRCSeason(int year, string uri = "") : base(year, FIRSTProgram.FRC, uri)
Expand All @@ -91,4 +100,4 @@ public FTCSeason(int year, string uri = "") : base(year, FIRSTProgram.FTC, uri)
{
}
}
}
}
32 changes: 14 additions & 18 deletions CSAUSBTool.Base/HttpClientDownload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ private async Task<bool> DownloadFileFromHttpResponseMessage(HttpResponseMessage

var totalBytes = response.Content.Headers.ContentLength;

using (var contentStream = await response.Content.ReadAsStreamAsync())
return await ProcessContentStream(totalBytes, contentStream, token);
await using var contentStream = await response.Content.ReadAsStreamAsync();
return await ProcessContentStream(totalBytes, contentStream, token);
}

private async Task<bool> ProcessContentStream(long? totalDownloadSize, Stream contentStream, CancellationToken token)
Expand All @@ -52,19 +52,19 @@ private async Task<bool> ProcessContentStream(long? totalDownloadSize, Stream co
var buffer = new byte[8192];
var isMoreToRead = true;

using (var fileStream = new FileStream(_destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
await using (var fileStream = new FileStream(_destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
{
do
{
var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length, token);
if (bytesRead == 0)
{
isMoreToRead = false;
TriggerProgressChanged(totalDownloadSize, totalBytesRead);
continue;
}

await fileStream.WriteAsync(buffer, 0, bytesRead);
await fileStream.WriteAsync(buffer, 0, bytesRead, token);

totalBytesRead += bytesRead;
readCount += 1;
Expand All @@ -74,26 +74,22 @@ private async Task<bool> ProcessContentStream(long? totalDownloadSize, Stream co
}
while (isMoreToRead && !token.IsCancellationRequested);
}
if (token.IsCancellationRequested)

if (!token.IsCancellationRequested) return true;

try
{
File.Delete(_destinationFilePath);
}
catch (IOException)
{
try
{
File.Delete(_destinationFilePath);
}
catch (IOException)
{

}
return false;
}
return true;
return false;
}

private void TriggerProgressChanged(long? totalDownloadSize, long totalBytesRead)
{
if (ProgressChanged == null)
return;

double? progressPercentage = null;
if (totalDownloadSize.HasValue)
progressPercentage = Math.Round((double)totalBytesRead / totalDownloadSize.Value * 100, 2);
Expand Down
Loading