diff --git a/.gitignore b/.gitignore index 3a2238d..8afdcb6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files +*.rsuser *.suo *.user *.userosscache @@ -10,48 +13,75 @@ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +# Mono auto generated files +mono_crash.* + # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ -[Xx]64/ -[Xx]86/ -[Bb]uild/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ +[Ll]og/ +[Ll]ogs/ -# Visual Studio 2015 cache/options directory +# Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ +# Visual Studio 2017 auto generated files +Generated\ Files/ + # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* -# NUNIT +# NUnit *.VisualState.xml TestResult.xml +nunit-*.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c -# DNX +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core project.lock.json +project.fragment.lock.json artifacts/ +# Tye +.tye/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio *_i.c *_p.c -*_i.h +*_h.h *.ilk *.meta *.obj +*.iobj *.pch *.pdb +*.ipdb *.pgc *.pgd *.rsp @@ -61,6 +91,7 @@ artifacts/ *.tlh *.tmp *.tmp_proj +*_wpftmp.csproj *.log *.vspscc *.vssscc @@ -81,6 +112,7 @@ ipch/ *.sdf *.cachefile *.VC.db +*.VC.VC.opendb # Visual Studio profiler *.psess @@ -88,6 +120,9 @@ ipch/ *.vspx *.sap +# Visual Studio Trace Files +*.e2e + # TFS 2012 Local Workspace $tf/ @@ -99,15 +134,25 @@ _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user -# JustCode is a .NET coding add-in -.JustCode - # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + # NCrunch _NCrunch_* .*crunch*.local.xml @@ -139,22 +184,27 @@ publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml - -# TODO: Un-comment the next line if you do not want to checkin -# your web deploy settings because they may include unencrypted -# passwords -#*.pubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml *.publishproj +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + # NuGet Packages *.nupkg +# NuGet Symbol Packages +*.snupkg # The packages folder can be ignored because of Package Restore -**/packages/* +**/[Pp]ackages/* # except build/, which is used as an MSBuild target. -!**/packages/build/ +!**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets @@ -166,31 +216,40 @@ csx/ ecf/ rcf/ -# Microsoft Azure ApplicationInsights config file -ApplicationInsights.config - -# Windows Store app package directory +# Windows Store app package directories and files AppPackages/ BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache -!*.[Cc]ache/ +!?*.[Cc]ache/ # Others ClientBin/ -[Ss]tyle[Cc]op.* ~$* *~ *.dbmdl *.dbproj.schemaview +*.jfm *.pfx *.publishsettings -node_modules/ orleans.codegen.cs +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + # RIA/Silverlight projects Generated_Code/ @@ -201,15 +260,22 @@ _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak # SQL Server files *.mdf *.ldf +*.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ @@ -219,6 +285,7 @@ FakesAssemblies/ # Node.js Tools for Visual Studio .ntvs_analysis.dat +node_modules/ # Visual Studio 6 build log *.plg @@ -226,6 +293,9 @@ FakesAssemblies/ # Visual Studio 6 workspace options file *.opt +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts @@ -234,12 +304,151 @@ FakesAssemblies/ **/*.Server/ModelManifest.xml _Pvt_Extensions -# LightSwitch generated files -GeneratedArtifacts/ -ModelManifest.xml - # Paket dependency manager .paket/paket.exe +paket-files/ # FAKE - F# Make -.fake/ \ No newline at end of file +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +## +## Visual studio for Mac +## + + +# globs +Makefile.in +*.userprefs +*.usertasks +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.tar.gz +tarballs/ +test-results/ + +# Mac bundle stuff +*.dmg +*.app + +# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# JetBrains Rider +.idea/ +*.sln.iml + +## +## Visual Studio Code +## +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json diff --git a/CSAUSBTool.Base/CSAUSBTool.Base.csproj b/CSAUSBTool.Base/CSAUSBTool.Base.csproj index 2206107..025dd07 100644 --- a/CSAUSBTool.Base/CSAUSBTool.Base.csproj +++ b/CSAUSBTool.Base/CSAUSBTool.Base.csproj @@ -1,17 +1,19 @@  - netstandard2.0 + netstandard2.1 Library false + latest + - + all - + \ No newline at end of file diff --git a/CSAUSBTool.Base/ControlSystemsSoftware.cs b/CSAUSBTool.Base/ControlSystemsSoftware.cs index 1a7d2c3..9dd06dc 100644 --- a/CSAUSBTool.Base/ControlSystemsSoftware.cs +++ b/CSAUSBTool.Base/ControlSystemsSoftware.cs @@ -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 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 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(@"({})({})({})", RegexOptions.Compiled | RegexOptions.IgnoreCase); - var matches = rx.Matches(Url); - // Use github latest + var rx = new Regex(@"github://({})/({})/({})", 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) @@ -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(); } } } \ No newline at end of file diff --git a/CSAUSBTool.Base/ExampleYear.json b/CSAUSBTool.Base/ExampleYear.json new file mode 100644 index 0000000..a95b9dd --- /dev/null +++ b/CSAUSBTool.Base/ExampleYear.json @@ -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" + } + ] +} \ No newline at end of file diff --git a/CSAUSBTool.Base/FIRSTSeason.cs b/CSAUSBTool.Base/FIRSTSeason.cs index 55b782e..7445838 100644 --- a/CSAUSBTool.Base/FIRSTSeason.cs +++ b/CSAUSBTool.Base/FIRSTSeason.cs @@ -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; } @@ -21,7 +22,6 @@ public class FIRSTSeason public FIRSTSeason(int year, FIRSTProgram program, string uri = "") { - Year = year; Program = program; if (uri.Equals("")) @@ -36,6 +36,9 @@ public List 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}"); @@ -45,39 +48,45 @@ public List GetWebList(string uri) } } - public List GetLocalList(string uri) + public List FromLocal(string uri) { var lines = new List(); using (var file = new StreamReader(uri)) { string line; - + while ((line = file.ReadLine()) != null) { lines.Add(line); } } + return GetFromCsv(lines); } - private static List GetFromCsv(List lines) + private static List FromCsv(List lines) { var ret = new List(); 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 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) @@ -91,4 +100,4 @@ public FTCSeason(int year, string uri = "") : base(year, FIRSTProgram.FTC, uri) { } } -} +} \ No newline at end of file diff --git a/CSAUSBTool.Base/HttpClientDownload.cs b/CSAUSBTool.Base/HttpClientDownload.cs index c82ca94..253a39d 100644 --- a/CSAUSBTool.Base/HttpClientDownload.cs +++ b/CSAUSBTool.Base/HttpClientDownload.cs @@ -41,8 +41,8 @@ private async Task 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 ProcessContentStream(long? totalDownloadSize, Stream contentStream, CancellationToken token) @@ -52,11 +52,11 @@ private async Task 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; @@ -64,7 +64,7 @@ private async Task ProcessContentStream(long? totalDownloadSize, Stream co continue; } - await fileStream.WriteAsync(buffer, 0, bytesRead); + await fileStream.WriteAsync(buffer, 0, bytesRead, token); totalBytesRead += bytesRead; readCount += 1; @@ -74,26 +74,22 @@ private async Task 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); diff --git a/CSAUSBTool.CrossPlatform.Desktop/CSAUSBTool.CrossPlatform.Desktop.csproj b/CSAUSBTool.CrossPlatform.Desktop/CSAUSBTool.CrossPlatform.Desktop.csproj new file mode 100644 index 0000000..9905354 --- /dev/null +++ b/CSAUSBTool.CrossPlatform.Desktop/CSAUSBTool.CrossPlatform.Desktop.csproj @@ -0,0 +1,20 @@ + + + WinExe + + net7.0 + enable + true + app.manifest + + + + + + + + + + + diff --git a/CSAUSBTool.CrossPlatform.Desktop/Program.cs b/CSAUSBTool.CrossPlatform.Desktop/Program.cs new file mode 100644 index 0000000..2c777bd --- /dev/null +++ b/CSAUSBTool.CrossPlatform.Desktop/Program.cs @@ -0,0 +1,24 @@ +using System; + +using Avalonia; +using Avalonia.ReactiveUI; + +namespace CSAUSBTool.CrossPlatform.Desktop; + +class Program +{ + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static void Main(string[] args) => BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace() + .UseReactiveUI(); +} diff --git a/CSAUSBTool.CrossPlatform.Desktop/app.manifest b/CSAUSBTool.CrossPlatform.Desktop/app.manifest new file mode 100644 index 0000000..e0ce8d0 --- /dev/null +++ b/CSAUSBTool.CrossPlatform.Desktop/app.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/CSAUSBTool.CrossPlatform/App.axaml b/CSAUSBTool.CrossPlatform/App.axaml new file mode 100644 index 0000000..f473fcb --- /dev/null +++ b/CSAUSBTool.CrossPlatform/App.axaml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/CSAUSBTool.CrossPlatform/App.axaml.cs b/CSAUSBTool.CrossPlatform/App.axaml.cs new file mode 100644 index 0000000..dca9ac4 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/App.axaml.cs @@ -0,0 +1,37 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +using CSAUSBTool.CrossPlatform.ViewModels; +using CSAUSBTool.CrossPlatform.Views; + +namespace CSAUSBTool.CrossPlatform; + +public partial class App : Application +{ + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + switch (ApplicationLifetime) + { + case IClassicDesktopStyleApplicationLifetime desktop: + desktop.MainWindow = new MainWindow + { + DataContext = new MainViewModel() + }; + break; + case ISingleViewApplicationLifetime singleViewPlatform: + singleViewPlatform.MainView = new MainView + { + DataContext = new MainViewModel() + }; + break; + } + + base.OnFrameworkInitializationCompleted(); + } +} diff --git a/CSAUSBTool.CrossPlatform/Assets/avalonia-logo.ico b/CSAUSBTool.CrossPlatform/Assets/avalonia-logo.ico new file mode 100644 index 0000000..da8d49f Binary files /dev/null and b/CSAUSBTool.CrossPlatform/Assets/avalonia-logo.ico differ diff --git a/CSAUSBTool.CrossPlatform/CSAUSBTool.CrossPlatform.csproj b/CSAUSBTool.CrossPlatform/CSAUSBTool.CrossPlatform.csproj new file mode 100644 index 0000000..355507c --- /dev/null +++ b/CSAUSBTool.CrossPlatform/CSAUSBTool.CrossPlatform.csproj @@ -0,0 +1,28 @@ + + + net7.0 + enable + latest + true + + + + + + + + + + + + + + + + + + + ProgramYearView.axaml + + + diff --git a/CSAUSBTool.CrossPlatform/Models/ControlSystemSoftware.cs b/CSAUSBTool.CrossPlatform/Models/ControlSystemSoftware.cs new file mode 100644 index 0000000..9a4537a --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Models/ControlSystemSoftware.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CSAUSBTool.CrossPlatform.Models +{ + public class ControlSystemSoftware + { + public string Name { get; set; } + public string Description { get; set; } + public List Tags { get; set; } + public string Uri { get; set; } + public string? Hash { get; set; } + public string Platform { get; set; } + + public ControlSystemSoftware() + { + + } + } +} diff --git a/CSAUSBTool.CrossPlatform/Models/ControlSystemSoftwareGroup.cs b/CSAUSBTool.CrossPlatform/Models/ControlSystemSoftwareGroup.cs new file mode 100644 index 0000000..00376d1 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Models/ControlSystemSoftwareGroup.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using ReactiveUI; + +namespace CSAUSBTool.CrossPlatform.Models; + +public class ControlSystemSoftwareGroup : ReactiveObject +{ + public string Tag { get; set; } + public string DisplayName { get; set; } + public List Software { get; set; } = new(); + + public ControlSystemSoftwareGroup() + + { + + } +} \ No newline at end of file diff --git a/CSAUSBTool.CrossPlatform/Models/SeasonSoftwareList.cs b/CSAUSBTool.CrossPlatform/Models/SeasonSoftwareList.cs new file mode 100644 index 0000000..1d40beb --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Models/SeasonSoftwareList.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CSAUSBTool.CrossPlatform.Models +{ + public class SeasonSoftwareList + { + public int Year { get; set; } + public string Program { get; set; } + public List Software { get; set; } = new(); + + + public List GetGroups() + { + var groups = new Dictionary(); + Software.ForEach(s => + { + // Yes, I know this is inefficient. + s.Tags.ForEach(tag => + { + if (!groups.ContainsKey(tag)) + { + groups.Add(tag, new ControlSystemSoftwareGroup(){DisplayName =tag, Tag=tag}); + } + + groups[tag].Software.Add(s); + }); + }); + return new List(groups.Values); + } + } +} diff --git a/CSAUSBTool.CrossPlatform/ViewModels/MainViewModel.cs b/CSAUSBTool.CrossPlatform/ViewModels/MainViewModel.cs new file mode 100644 index 0000000..6f7c3f2 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/ViewModels/MainViewModel.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace CSAUSBTool.CrossPlatform.ViewModels; + +public class MainViewModel : ViewModelBase +{ + // Add our SimpleViewModel. + // Note: We need at least a get-accessor for our Properties. + public ProgramYear ProgramYear { get; } = new ProgramYear(null, null); +} diff --git a/CSAUSBTool.CrossPlatform/ViewModels/ProgramYear.cs b/CSAUSBTool.CrossPlatform/ViewModels/ProgramYear.cs new file mode 100644 index 0000000..a7f8379 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/ViewModels/ProgramYear.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Json; +using System.Text.Json; +using System.Threading.Tasks; +using CSAUSBTool.CrossPlatform.Models; + + +namespace CSAUSBTool.CrossPlatform.ViewModels +{ + public class ProgramYear + { + public int Year { get; set; } + public string Program { get; set; } + + public List SoftwareGroups { get; set; } = new(); + public ProgramYear(int? year, string? program) + { + year ??= DateTime.Now.Year; + program ??= "FRC"; + Year = (int) year; + Program = program; + + DownloadSoftwareLists(); + } + public ProgramYear() + { + Year = DateTime.Now.Year; + Program = "FRC"; + } + + private void DownloadSoftwareLists() + { + var downloadUrl = + $"https://raw.githubusercontent.com/JamieSinn/CSA-USB-Tool/avalonia/Lists/{Program}{Year}.json"; + + using var client = new HttpClient(); + var software= client.GetFromJsonAsync(downloadUrl).Result; + + //await client.GetStreamAsync(downloadUrl)); + SoftwareGroups = software.GetGroups(); + } + } +} diff --git a/CSAUSBTool.CrossPlatform/ViewModels/ReactiveViewModel.cs b/CSAUSBTool.CrossPlatform/ViewModels/ReactiveViewModel.cs new file mode 100644 index 0000000..9738632 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/ViewModels/ReactiveViewModel.cs @@ -0,0 +1,40 @@ +using ReactiveUI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CSAUSBTool.CrossPlatform.ViewModels +{ + // Instead of implementing "INotifyPropertyChanged" on our own we use "ReactiveObject" as + // our base class. Read more about it here: https://www.reactiveui.net + public class ReactiveViewModel : ReactiveObject + { + public ReactiveViewModel() + { + // We can listen to any property changes with "WhenAnyValue" and do whatever we want in "Subscribe". + this.WhenAnyValue(o => o.Name) + .Subscribe(o => this.RaisePropertyChanged(nameof(Greeting))); + } + + private string? _name; // This is our backing field for Name + + public string? Name + { + get => _name; + set => + // We can use "RaiseAndSetIfChanged" to check if the value changed and automatically notify the UI + this.RaiseAndSetIfChanged(ref _name, value); + } + + // Greeting will change based on a Name. + public string Greeting => + string.IsNullOrEmpty(Name) ? + // If no Name is provided, use a default Greeting + "Hello World from Avalonia.Samples" : + // else Greet the User. + $"Hello {Name}"; + + } +} diff --git a/CSAUSBTool.CrossPlatform/ViewModels/SimpleViewModel.cs b/CSAUSBTool.CrossPlatform/ViewModels/SimpleViewModel.cs new file mode 100644 index 0000000..b749df5 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/ViewModels/SimpleViewModel.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace CSAUSBTool.CrossPlatform.ViewModels +{ + // This is our simple ViewModel. We need to implement the interface "INotifyPropertyChanged" + // in order to notify the View if any of our properties changed. + public class SimpleViewModel : INotifyPropertyChanged + { + // This event is implemented by "INotifyPropertyChanged" and is all we need to inform + // our View about changes. + public event PropertyChangedEventHandler? PropertyChanged; + + // For convenience we add a method which will raise the above event. + private void RaisePropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + // ---- Add some Properties ---- + + private string? _Name; // This is our backing field for Name + + public string? Name + { + get + { + return _Name; + } + set + { + // We only want to update the UI if the Name actually changed, so we check if the value is actually new + if (_Name != value) + { + // 1. update our backing field + _Name = value; + + // 2. We call RaisePropertyChanged() to notify the UI about changes. + // We can omit the property name here because [CallerMemberName] will provide it for us. + RaisePropertyChanged(); + + // 3. Greeting also changed. So let's notify the UI about it. + RaisePropertyChanged(nameof(Greeting)); + } + } + } + + + // Greeting will change based on a Name. + public string Greeting + { + get + { + if (string.IsNullOrEmpty(Name)) + { + // If no Name is provided, use a default Greeting + return "Hello World from Avalonia.Samples"; + } + else + { + // else Greet the User. + return $"Hello {Name}"; + } + } + } + } +} diff --git a/CSAUSBTool.CrossPlatform/ViewModels/ViewModelBase.cs b/CSAUSBTool.CrossPlatform/ViewModels/ViewModelBase.cs new file mode 100644 index 0000000..406332a --- /dev/null +++ b/CSAUSBTool.CrossPlatform/ViewModels/ViewModelBase.cs @@ -0,0 +1,7 @@ +using ReactiveUI; + +namespace CSAUSBTool.CrossPlatform.ViewModels; + +public class ViewModelBase : ReactiveObject +{ +} diff --git a/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareGroupView.axaml b/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareGroupView.axaml new file mode 100644 index 0000000..ed7f986 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareGroupView.axaml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareGroupView.axaml.cs b/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareGroupView.axaml.cs new file mode 100644 index 0000000..ccec24e --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareGroupView.axaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Avalonia.Controls; +using CSAUSBTool.CrossPlatform.Models; + +namespace CSAUSBTool.CrossPlatform.Views +{ + public partial class ControlSystemSoftwareGroupView : UserControl + { + public ControlSystemSoftwareGroupView() + { + InitializeComponent(); + SoftwareSelectionList.SelectionChanged += ListSelectionChanged; + } + + public void ListSelectionChanged(object? sender, SelectionChangedEventArgs e) + { + Details.Text = ""; + if (SoftwareSelectionList.SelectedItems == null) return; + foreach (var selectedItem in SoftwareSelectionList.SelectedItems) + { + var s = selectedItem as ControlSystemSoftware; + Details.Text += $"{s.Name}\n{s.Description}\n{s.Platform}\n\n"; + } + } + } +} diff --git a/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareView.axaml b/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareView.axaml new file mode 100644 index 0000000..fc20d8c --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareView.axaml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareView.axaml.cs b/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareView.axaml.cs new file mode 100644 index 0000000..7c8ca71 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Views/ControlSystemSoftwareView.axaml.cs @@ -0,0 +1,12 @@ +using Avalonia.Controls; + +namespace CSAUSBTool.CrossPlatform.Views +{ + public partial class ControlSystemSoftwareView : UserControl + { + public ControlSystemSoftwareView() + { + InitializeComponent(); + } + } +} diff --git a/CSAUSBTool.CrossPlatform/Views/MainView.axaml b/CSAUSBTool.CrossPlatform/Views/MainView.axaml new file mode 100644 index 0000000..4f903ff --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Views/MainView.axaml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/CSAUSBTool.CrossPlatform/Views/MainView.axaml.cs b/CSAUSBTool.CrossPlatform/Views/MainView.axaml.cs new file mode 100644 index 0000000..3834ab4 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Views/MainView.axaml.cs @@ -0,0 +1,17 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using Avalonia.Media.Imaging; +using Avalonia.Platform; +using ReactiveUI; +using System; + +namespace CSAUSBTool.CrossPlatform.Views; + +public partial class MainView : UserControl +{ + public MainView() + { + InitializeComponent(); + } +} diff --git a/CSAUSBTool.CrossPlatform/Views/MainWindow.axaml b/CSAUSBTool.CrossPlatform/Views/MainWindow.axaml new file mode 100644 index 0000000..caba0b5 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Views/MainWindow.axaml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CSAUSBTool.CrossPlatform/Views/MainWindow.axaml.cs b/CSAUSBTool.CrossPlatform/Views/MainWindow.axaml.cs new file mode 100644 index 0000000..a5e1ead --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Views/MainWindow.axaml.cs @@ -0,0 +1,11 @@ +using Avalonia.Controls; + +namespace CSAUSBTool.CrossPlatform.Views; + +public partial class MainWindow : Window +{ + public MainWindow() + { + InitializeComponent(); + } +} diff --git a/CSAUSBTool.CrossPlatform/Views/ProgramYearView.axaml b/CSAUSBTool.CrossPlatform/Views/ProgramYearView.axaml new file mode 100644 index 0000000..631ff14 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Views/ProgramYearView.axaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CSAUSBTool.CrossPlatform/Views/ProgramYearView.axaml.cs b/CSAUSBTool.CrossPlatform/Views/ProgramYearView.axaml.cs new file mode 100644 index 0000000..2de0a13 --- /dev/null +++ b/CSAUSBTool.CrossPlatform/Views/ProgramYearView.axaml.cs @@ -0,0 +1,25 @@ +using System; +using Avalonia.Controls; +using CSAUSBTool.CrossPlatform.Models; +using CSAUSBTool.CrossPlatform.ViewModels; +using System.Collections.Generic; + +namespace CSAUSBTool.CrossPlatform.Views +{ + public partial class ProgramYearView : UserControl + { + public ProgramYearView() + { + InitializeComponent(); + + DataContext = new ProgramYear(null, null); + Tabs.SelectionChanged += new EventHandler(TabChanged); + } + + private void TabChanged(object sender, SelectionChangedEventArgs e) + { + var selectedTab = Tabs.SelectedItem as ControlSystemSoftwareGroup; + } + + } +} \ No newline at end of file diff --git a/CSAUSBTool.Installer/CSAUSBTool.Installer.wapproj b/CSAUSBTool.Installer/CSAUSBTool.Installer.wapproj index d5e5a78..9a56854 100644 --- a/CSAUSBTool.Installer/CSAUSBTool.Installer.wapproj +++ b/CSAUSBTool.Installer/CSAUSBTool.Installer.wapproj @@ -108,11 +108,10 @@ - - + diff --git a/CSAUSBTool.Tests/CSAUSBTool.Tests.csproj b/CSAUSBTool.Tests/CSAUSBTool.Tests.csproj new file mode 100644 index 0000000..0b93b8e --- /dev/null +++ b/CSAUSBTool.Tests/CSAUSBTool.Tests.csproj @@ -0,0 +1,29 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/CSAUSBTool.Tests/UnitTest1.cs b/CSAUSBTool.Tests/UnitTest1.cs new file mode 100644 index 0000000..d671806 --- /dev/null +++ b/CSAUSBTool.Tests/UnitTest1.cs @@ -0,0 +1,16 @@ +namespace CSAUSBTool.Tests +{ + public class Tests + { + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Assert.Pass(); + } + } +} \ No newline at end of file diff --git a/CSAUSBTool.Tests/Usings.cs b/CSAUSBTool.Tests/Usings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/CSAUSBTool.Tests/Usings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file diff --git a/CSAUSBTool.sln b/CSAUSBTool.sln index 97acf65..9575a86 100644 --- a/CSAUSBTool.sln +++ b/CSAUSBTool.sln @@ -5,25 +5,35 @@ VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSAUSBTool", "CSAUSBTool\CSAUSBTool.csproj", "{51473C6A-94E1-4908-9F77-15A15EC118F6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSAUSBTool.Base", "CSAUSBTool.Base\CSAUSBTool.Base.csproj", "{5832E6E7-9A7C-49E1-945F-B37D3563EDC3}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CEE83079-35D3-480F-99E1-AC6BC51486AF}" ProjectSection(SolutionItems) = preProject 2018Password.txt = 2018Password.txt 2019Password.txt = 2019Password.txt 2020Password.txt = 2020Password.txt 2022Password.txt = 2022Password.txt + Lists\FRC2024.json = Lists\FRC2024.json FRCSoftware2017.csv = FRCSoftware2017.csv FRCSoftware2018.csv = FRCSoftware2018.csv FRCSoftware2019.csv = FRCSoftware2019.csv FRCSoftware2020.csv = FRCSoftware2020.csv FRCSoftware2022.csv = FRCSoftware2022.csv + FRCSoftware2023.csv = FRCSoftware2023.csv FTCSoftware2020.csv = FTCSoftware2020.csv + FTCSoftware2023.csv = FTCSoftware2023.csv + README.md = README.md Years.txt = Years.txt EndProjectSection EndProject Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "CSAUSBTool.Installer", "CSAUSBTool.Installer\CSAUSBTool.Installer.wapproj", "{55F8AF2B-E5E9-4B6F-87AE-22E12B3F5323}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSAUSBTool.CrossPlatform", "CSAUSBTool.CrossPlatform\CSAUSBTool.CrossPlatform.csproj", "{711B36C7-0C0E-46F8-8C71-15F55AA10AE8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSAUSBTool.CrossPlatform.Desktop", "CSAUSBTool.CrossPlatform.Desktop\CSAUSBTool.CrossPlatform.Desktop.csproj", "{FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSAUSBTool.Tests", "CSAUSBTool.Tests\CSAUSBTool.Tests.csproj", "{FC547A88-1927-481E-96A4-81CDFC604DC1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSAUSBTool.Base", "CSAUSBTool.Base\CSAUSBTool.Base.csproj", "{6E04964A-281A-4A0B-B068-2C98D0C24AD4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -58,26 +68,6 @@ Global {51473C6A-94E1-4908-9F77-15A15EC118F6}.Release|x64.Build.0 = Release|Any CPU {51473C6A-94E1-4908-9F77-15A15EC118F6}.Release|x86.ActiveCfg = Release|Any CPU {51473C6A-94E1-4908-9F77-15A15EC118F6}.Release|x86.Build.0 = Release|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Debug|ARM.ActiveCfg = Debug|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Debug|ARM.Build.0 = Debug|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Debug|ARM64.Build.0 = Debug|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Debug|x64.ActiveCfg = Debug|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Debug|x64.Build.0 = Debug|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Debug|x86.ActiveCfg = Debug|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Debug|x86.Build.0 = Debug|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Release|Any CPU.Build.0 = Release|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Release|ARM.ActiveCfg = Release|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Release|ARM.Build.0 = Release|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Release|ARM64.ActiveCfg = Release|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Release|ARM64.Build.0 = Release|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Release|x64.ActiveCfg = Release|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Release|x64.Build.0 = Release|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Release|x86.ActiveCfg = Release|Any CPU - {5832E6E7-9A7C-49E1-945F-B37D3563EDC3}.Release|x86.Build.0 = Release|Any CPU {55F8AF2B-E5E9-4B6F-87AE-22E12B3F5323}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {55F8AF2B-E5E9-4B6F-87AE-22E12B3F5323}.Debug|Any CPU.Build.0 = Debug|Any CPU {55F8AF2B-E5E9-4B6F-87AE-22E12B3F5323}.Debug|Any CPU.Deploy.0 = Debug|Any CPU @@ -108,6 +98,86 @@ Global {55F8AF2B-E5E9-4B6F-87AE-22E12B3F5323}.Release|x86.ActiveCfg = Release|x86 {55F8AF2B-E5E9-4B6F-87AE-22E12B3F5323}.Release|x86.Build.0 = Release|x86 {55F8AF2B-E5E9-4B6F-87AE-22E12B3F5323}.Release|x86.Deploy.0 = Release|x86 + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Debug|ARM.ActiveCfg = Debug|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Debug|ARM.Build.0 = Debug|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Debug|ARM64.Build.0 = Debug|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Debug|x64.ActiveCfg = Debug|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Debug|x64.Build.0 = Debug|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Debug|x86.ActiveCfg = Debug|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Debug|x86.Build.0 = Debug|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Release|Any CPU.Build.0 = Release|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Release|ARM.ActiveCfg = Release|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Release|ARM.Build.0 = Release|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Release|ARM64.ActiveCfg = Release|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Release|ARM64.Build.0 = Release|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Release|x64.ActiveCfg = Release|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Release|x64.Build.0 = Release|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Release|x86.ActiveCfg = Release|Any CPU + {711B36C7-0C0E-46F8-8C71-15F55AA10AE8}.Release|x86.Build.0 = Release|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Debug|ARM.ActiveCfg = Debug|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Debug|ARM.Build.0 = Debug|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Debug|ARM64.Build.0 = Debug|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Debug|x64.Build.0 = Debug|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Debug|x86.Build.0 = Debug|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Release|Any CPU.Build.0 = Release|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Release|ARM.ActiveCfg = Release|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Release|ARM.Build.0 = Release|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Release|ARM64.ActiveCfg = Release|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Release|ARM64.Build.0 = Release|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Release|x64.ActiveCfg = Release|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Release|x64.Build.0 = Release|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Release|x86.ActiveCfg = Release|Any CPU + {FA689B4D-CB1F-4BFA-83EA-4B5D7012B1EF}.Release|x86.Build.0 = Release|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Debug|ARM.ActiveCfg = Debug|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Debug|ARM.Build.0 = Debug|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Debug|ARM64.Build.0 = Debug|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Debug|x64.ActiveCfg = Debug|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Debug|x64.Build.0 = Debug|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Debug|x86.ActiveCfg = Debug|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Debug|x86.Build.0 = Debug|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Release|Any CPU.Build.0 = Release|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Release|ARM.ActiveCfg = Release|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Release|ARM.Build.0 = Release|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Release|ARM64.ActiveCfg = Release|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Release|ARM64.Build.0 = Release|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Release|x64.ActiveCfg = Release|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Release|x64.Build.0 = Release|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Release|x86.ActiveCfg = Release|Any CPU + {FC547A88-1927-481E-96A4-81CDFC604DC1}.Release|x86.Build.0 = Release|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Debug|ARM.ActiveCfg = Debug|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Debug|ARM.Build.0 = Debug|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Debug|ARM64.Build.0 = Debug|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Debug|x64.ActiveCfg = Debug|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Debug|x64.Build.0 = Debug|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Debug|x86.ActiveCfg = Debug|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Debug|x86.Build.0 = Debug|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Release|Any CPU.Build.0 = Release|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Release|ARM.ActiveCfg = Release|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Release|ARM.Build.0 = Release|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Release|ARM64.ActiveCfg = Release|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Release|ARM64.Build.0 = Release|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Release|x64.ActiveCfg = Release|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Release|x64.Build.0 = Release|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Release|x86.ActiveCfg = Release|Any CPU + {6E04964A-281A-4A0B-B068-2C98D0C24AD4}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CSAUSBTool/CSAUSBTool.csproj b/CSAUSBTool/CSAUSBTool.csproj index e519435..919e97d 100644 --- a/CSAUSBTool/CSAUSBTool.csproj +++ b/CSAUSBTool/CSAUSBTool.csproj @@ -76,14 +76,14 @@ - + - + - + @@ -97,9 +97,9 @@ - + all - + \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..5d8722e --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,6 @@ + + + enable + 11.0.2 + + diff --git a/Lists/FRC2024.json b/Lists/FRC2024.json new file mode 100644 index 0000000..cb7dffb --- /dev/null +++ b/Lists/FRC2024.json @@ -0,0 +1,181 @@ +{ + "Year": 2024, + "Program": "FRC", + "Software": [ + { + "Name": "NI Game Tools", + "Description": "Game Tools for FRC - DriverStation", + "Tags": [ + "Team", + "Event", + "FTA", + "CSA" + ], + "FileName": "ni-frc-2024-game-tools_24.0.1_offline.iso", + "Uri": "https://download.ni.com/support/nipkg/products/ni-f/ni-frc-2024-game-tools/24.0/offline/ni-frc-2024-game-tools_24.0.1_offline.iso", + "Hash": "68ece2bce407356c4395c77b52e4cd3c", + "Platform": "Windows" + }, + { + "Name": "NI LabVIEW", + "Description": "NI LabVIEW Base", + "Tags": [ + "Team", + "Event", + "FTA", + "CSA" + ], + "FileName": "ni-frc-2024-base-suite_24.0.0.49158-0+f6_offline.iso", + "Uri": "https://download.ni.com/support/nipkg/products/ni-f/ni-frc-2024-base-suite/24.0/offline/ni-frc-2024-base-suite_24.0.0.49158-0+f6_offline.iso", + "Hash": "147c547e41a7b57ca76a8c98d042fdf9", + "Platform": "Windows" + }, + { + "Name": "NI CompactRIO Driver", + "Description": "cRIO Driver - Rarely used, but can be helpful for recovering roboRIOs", + "Tags": [ + "FTA", + "CSA" + ], + "FileName": "ni-compactrio-device-drivers_24.0.0.49260-0+f108_offline.iso", + "Uri": "https://download.ni.com/support/nipkg/products/ni-c/ni-compactrio-device-drivers/24.0/offline/ni-compactrio-device-drivers_24.0.0.49260-0+f108_offline.iso", + "Hash": "a76eef4d5d81d9f01a1c2ea860ba170a", + "Platform": "Windows" + }, + { + "Name": "WPILibInstaller Windows64", + "Description": "WPILib Installer", + "Tags": [ + "Event", + "Team", + "CSA" + ], + "FileName": "WPILib_Windows-2024.3.1.iso", + "Uri": "https://packages.wpilib.workers.dev/installer/v2024.3.1/Win64/WPILib_Windows-2024.3.1.iso", + "Hash": "781408b02146fde5a8275f31bd55a23c", + "Platform": "Windows" + }, + { + "Name": "WPILib VS Code", + "Description": "WPILib Installer can source a specific VSCode version if needed.", + "Tags": [ + "Event", + "Team", + "CSA" + ], + "FileName": "VSCode-1.85.1-Windows.zip", + "Uri": "https://update.code.visualstudio.com/1.85.1/win32-x64-archive/stable", + "Hash": "5621fc9203a0468f9270e2151ac2cdea", + "Platform": "Windows" + }, + { + "Name": "Season Password", + "Description": "WPILib Installer", + "Tags": [ + "Event", + "Team", + "FTA", + "CSA" + ], + "FileName": "2024Password.txt", + "Uri": "https://raw.githubusercontent.com/JamieSinn/CSA-USB-Tool/master/2024Password.txt", + "Hash": "f7226fa16bbca941473c41beacf2dba4", + "Platform": "Windows" + }, + { + "Name": "CTRE Phoenix", + "Description": "Phoenix Offline Installer - Contains all data/supporting tools.", + "Tags": [ + "Event", + "Team", + "FTA", + "CSA" + ], + "FileName": "Phoenix-Offline_v24.2.0.exe", + "Uri": "https://github.com/CrossTheRoadElec/Phoenix-Releases/releases/download/v24.2.0/Phoenix-Offline_v24.2.0.exe", + "Hash": "f7226fa16bbca941473c41beacf2dba4", + "Platform": "Windows" + }, + { + "Name": "RadioConfigTool", + "Description": "Radio Configuration Tool", + "Tags": [ + "Event", + "Team", + "FTA", + "CSA" + ], + "FileName": "FRC_Radio_Configuration_24_0_1.zip", + "Uri": "https://firstfrc.blob.core.windows.net/frc2024/Radio/FRC_Radio_Configuration_24_0_1.zip", + "Hash": "b5b755f4947e79e43bc93dae281ba3e2", + "Platform": "Windows" + }, + { + "Name": "RadioConfigTool Israel", + "Description": "Radio Configuration Tool - Israel Firmware/Variant", + "Tags": [ + "Event", + "Team", + "FTA", + "CSA" + ], + "FileName": "FRC_Radio_Configuration_24_0_1_IL.zip", + "Uri": "https://firstfrc.blob.core.windows.net/frc2024/Radio/FRC_Radio_Configuration_24_0_1_IL.zip", + "Hash": "4309bff08b61bc6bfb36e946ed1cf6d7", + "Platform": "Windows" + }, + { + "Name": "2024 Game Manual", + "Description": "Season ", + "Tags": [ + "Event", + "Team", + "FTA", + "CSA" + ], + "FileName": "2024GameManual.pdf", + "Uri": "https://firstfrc.blob.core.windows.net/frc2024/Manual/2024GameManual.pdf", + "Hash": null, + "Platform": null + }, + { + "Name": "NavX Libraries", + "Description": "NavX Libraries for the MXP version.", + "Tags": [ + "Event", + "Team", + "CSA" + ], + "FileName": "navx-mxp.zip", + "Uri": "https://www.kauailabs.com/public_files/navx-mxp/navx-mxp.zip", + "Hash": null, + "Platform": null + }, + { + "Name": "REV Hardware Client", + "Description": "REV Hardware Client w/ FRC firmware.", + "Tags": [ + "Event", + "Team", + "CSA" + ], + "FileName": "REV-Hardware-Client-Setup-1.6.4-offline-FRC-2024-02-17.exe", + "Uri": "https://github.com/REVrobotics/REV-Software-Binaries/releases/download/rhc-1.6.4/REV-Hardware-Client-Setup-1.6.4-offline-FRC-2024-02-17.exe", + "Hash": "c03a4fcf1baafef68bf40db626125aee", + "Platform": "Windows" + }, + { + "Name": "REV Hardware Client", + "Description": "REV Hardware Client w/ FRC firmware.", + "Tags": [ + "Event", + "Team", + "CSA" + ], + "FileName": "REV-Hardware-Client-Setup-1.6.4-offline-FRC-2024-02-17.exe", + "Uri": "https://github.com/REVrobotics/REV-Software-Binaries/releases/download/rhc-1.6.4/REV-Hardware-Client-Setup-1.6.4-offline-FRC-2024-02-17.exe", + "Hash": "c03a4fcf1baafef68bf40db626125aee", + "Platform": "Windows" + } + ] +}