Skip to content

Commit

Permalink
Cache API results
Browse files Browse the repository at this point in the history
  • Loading branch information
xezno committed Nov 3, 2022
1 parent 166d0e3 commit e04967a
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 36 deletions.
2 changes: 0 additions & 2 deletions code/AddToolDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,6 @@ private async Task DownloadTool()
info.CreateNoWindow = false;
info.WorkingDirectory = folder;

Log.Trace( info.FileName + " " + info.Arguments );

var process = new Process();
process.StartInfo = info;
process.Start();
Expand Down
14 changes: 12 additions & 2 deletions code/GithubApi.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Sandbox;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
Expand All @@ -11,6 +12,8 @@ public static class GithubApi
private static HttpClient httpClient;
private static RealTimeUntil TimeUntilRatelimitReset;

private static Dictionary<string, string> Cache = new();

private static HttpClient HttpClient
{
get
Expand Down Expand Up @@ -44,6 +47,11 @@ private static async Task<string> FetchText( string url )
return "{}";
}

if ( Cache.TryGetValue( url, out var cachedResponse ) )
{
return cachedResponse;
}

var content = await HttpClient.GetAsync( url );
var result = await content.Content.ReadAsStringAsync();

Expand All @@ -59,8 +67,10 @@ private static async Task<string> FetchText( string url )
var timestamp = DateTime.UnixEpoch.AddSeconds( resetTime );
TimeUntilRatelimitReset = (float)(timestamp - DateTime.Now).TotalSeconds;
}

Log.Trace( $"{url} query: {result}" );
else
{
Cache[url] = result;
}

return result;
}
Expand Down
8 changes: 4 additions & 4 deletions code/Header.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ protected override void OnPaint()
var r = Paint.DrawText( pos, Title );
pos.y = r.Bottom;

r.Left = r.Right;
r.Width = 32;
r.Top -= 4;
Paint.DrawIcon( r, "update", 16 );
//r.Left = r.Right;
//r.Width = 32;
//r.Top -= 4;
//Paint.DrawIcon( r, "update", 16 );
}
}
78 changes: 53 additions & 25 deletions code/Page.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Sandbox;
using System.Diagnostics;
using System.IO;
using System.Text.Json;

namespace Tools;

Expand All @@ -13,49 +13,50 @@ internal class Page : Widget
private Label LatestReleaseBody;

private Manifest Manifest;
private LocalProject Project;

private bool HasFetched = false;

public Page( LocalProject project, Widget parent = null, bool isDarkWindow = false ) : base( parent, isDarkWindow )
{
SetLayout( LayoutMode.TopToBottom );

this.Project = project;

Layout.Spacing = 8;
Layout.Margin = 24;

//
// Check if we have a tools manager manifest
//
var manifestPath = project.GetManifestPath();
Manifest = project.GetManifest();

if ( File.Exists( manifestPath ) )
if ( Manifest != null )
{
// Load manifest
Manifest = JsonSerializer.Deserialize<Manifest>( File.ReadAllText( manifestPath ) );

AddManifestWidgets( project );
AddManifestWidgets();
}
else
{
// Display sad face
AddNoManifestWidgets( project );
AddNoManifestWidgets();
}
}

private void AddManifestWidgets( LocalProject project )
private void AddManifestWidgets()
{
var config = project.Config;
var config = Project.Config;
Header = Layout.Add( new Header( config.Title ) );
Layout.AddSpacingCell( 8 );

{
ToolBar = new ToolBar( this );
ToolBar.SetIconSize( 16 );
var autoUpdateOption = new Option( "Toggle Auto-Updates", "file_download_off" );
autoUpdateOption.Triggered = () => ToggleAutoUpdates( autoUpdateOption );

var option = ToolBar.AddOption( autoUpdateOption );
ToolBar.AddOption( "Open in Explorer", "folder", () => Utility.OpenFolder( Path.GetDirectoryName( project.GetRootPath() ) ) );
// var autoUpdateOption = new Option( "Toggle Auto-Updates", Manifest.AutoUpdate ? "file_download" : "file_download_off" );
// autoUpdateOption.Triggered = () => ToggleAutoUpdates( autoUpdateOption );
// var option = ToolBar.AddOption( autoUpdateOption );

ToolBar.AddOption( "Open in Explorer", "folder", () => Utility.OpenFolder( Path.GetDirectoryName( Project.GetRootPath() ) ) );
ToolBar.AddOption( "Open on GitHub", "open_in_new", () => Utility.OpenFolder( $"https://github.com/{Manifest.Repo}" ) );
Layout.Add( ToolBar );
}
Expand All @@ -67,18 +68,42 @@ private void AddManifestWidgets( LocalProject project )

Layout.AddStretchCell();

var group = new Container( this );
group.SetLayout( LayoutMode.TopToBottom );
group.Layout.Margin = 10;
Layout.Add( group );
if ( Manifest.CheckUpdateAvailable() )
{
var group = new Container( this );
group.SetLayout( LayoutMode.TopToBottom );
group.Layout.Margin = 10;
Layout.Add( group );

group.Layout.Add( new Heading( "Update Available" ) );
LatestReleaseName = group.Layout.Add( new Subheading( $"Loading..." ) );
LatestReleaseBody = group.Layout.Add( new Label( $"Loading..." ) );

group.Layout.AddSpacingCell( 8f );

group.Layout.Add( new Button( "Download Update", "download" ) { Clicked = Update } );
}
}

private void Update()
{
GithubApi.FetchLatestRelease( $"{Manifest.Repo}" ).ContinueWith( t =>
{
var release = t.Result ?? default;

var folder = Project.GetRootPath();

group.Layout.Add( new Heading( "Update Available" ) );
LatestReleaseName = group.Layout.Add( new Subheading( $"Loading..." ) );
LatestReleaseBody = group.Layout.Add( new Label( $"Loading..." ) );
Log.Trace( folder );

group.Layout.AddSpacingCell( 8f );
ProcessStartInfo info = new( "git", $"checkout -B \"{release.TagName}\" --force" );
info.UseShellExecute = false;
info.CreateNoWindow = false;
info.WorkingDirectory = folder;

group.Layout.Add( new Button( "Download Update", "download" ) );
var process = new Process();
process.StartInfo = info;
process.Start();
} );
}

private void ToggleAutoUpdates( Option option )
Expand All @@ -87,10 +112,10 @@ private void ToggleAutoUpdates( Option option )
option.Icon = Manifest.AutoUpdate ? "file_download" : "file_download_off";
}

private void AddNoManifestWidgets( LocalProject project )
private void AddNoManifestWidgets()
{
Layout.Add( new Label.Title( "😔" ) ).SetStyles( "font-size: 64px;" );
Layout.Add( new Label.Body( $"'{project.Config.Title}' does not have a manifest file, because you didn't import " +
Layout.Add( new Label.Body( $"'{Project.Config.Title}' does not have a manifest file, because you didn't import " +
"it through Tools Manager. Remove the tool and re-add it from GitHub by clicking \"Add Tool...\" " +
"in the bottom left." ) );

Expand All @@ -110,6 +135,9 @@ protected override void OnPaint()
{
var latestRelease = t.Result ?? default;

if ( LatestReleaseName == null || LatestReleaseBody == null )
return;

LatestReleaseName.Text = latestRelease.Name;
LatestReleaseBody.Text = latestRelease.Body;
} );
Expand Down
45 changes: 42 additions & 3 deletions code/ToolsManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Tools;

[Tool( "Tools Manager", "hardware", "Manages your tools." )]
Expand Down Expand Up @@ -59,7 +60,9 @@ public void CreateUI()
if ( config.PackageType == Sandbox.Package.Type.Tool )
{
var option = toolsList.AddPage( config.Title, "hardware", new Page( project ) );
option.OnPaintOverride = () => PaintPageOption( option );
var manifest = project.GetManifest();

option.OnPaintOverride = () => PaintPageOption( option, manifest );
}
}

Expand All @@ -73,7 +76,7 @@ public void CreateUI()
update.Clicked = () => ToolUpdateNotice.Open( 4 );
}

private bool PaintPageOption( NavigationView.Option option )
private bool PaintPageOption( NavigationView.Option option, Manifest manifest )
{
var fg = Theme.White.WithAlpha( 0.5f );

Expand Down Expand Up @@ -106,7 +109,7 @@ private bool PaintPageOption( NavigationView.Option option )
iconRect.Left = inner.Right - 32;
iconRect.Top -= 2;

if ( option.IsSelected )
if ( manifest.CheckUpdateAvailable() )
{
Paint.SetPen( fg );
Paint.DrawIcon( iconRect, "update", 14, TextFlag.Center );
Expand All @@ -116,4 +119,40 @@ private bool PaintPageOption( NavigationView.Option option )

return true;
}

//
// I'm going to use this event because it's a decent one
// that runs when the editor starts plus infrequently
// while developing, making it quite useful
//
[Sandbox.Event( "tools.compilemgr.start" )]
public static void OnCompileMgrStart()
{
var count = CheckForUpdates().Result;

if ( count > 0 )
ToolUpdateNotice.Open( count );
}

private static async Task<int> CheckForUpdates()
{
int count = 0;

foreach ( var project in Utility.Projects.GetAll() )
{
var manifest = project.GetManifest();

if ( manifest == null )
continue;

Log.Trace( manifest );

var latest = await GithubApi.FetchLatestRelease( manifest.Repo );

if ( manifest.CheckUpdateAvailable( latest ) )
count++;
}

return count;
}
}
6 changes: 6 additions & 0 deletions code/Types/Manifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,10 @@ public bool CheckUpdateAvailable( Release latestRelease )
{
return latestRelease.TagName != ReleaseVersion;
}

public bool CheckUpdateAvailable()
{
var latestRelease = GithubApi.FetchLatestRelease( Repo ).Result;
return CheckUpdateAvailable( latestRelease );
}
}
15 changes: 15 additions & 0 deletions code/Utils/LocalProjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.IO;
using System.Text.Json;

namespace Tools;

Expand All @@ -8,4 +9,18 @@ public static string GetManifestPath( this Sandbox.LocalProject localProject )
{
return Path.Combine( localProject.GetRootPath(), "tm-manifest.json" );
}

public static Manifest GetManifest( this Sandbox.LocalProject localProject )
{
if ( localProject.Config.PackageType != Sandbox.Package.Type.Tool )
return null;

if ( !File.Exists( localProject.GetManifestPath() ) )
return null;

var manifestStr = File.ReadAllText( localProject.GetManifestPath() );
var manifest = JsonSerializer.Deserialize<Manifest>( manifestStr );

return manifest;
}
}

0 comments on commit e04967a

Please sign in to comment.