Skip to content

Commit

Permalink
Use IAsyncEnumerable in PackageHandlers when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
yoshiask committed Jul 25, 2023
1 parent 9d43226 commit 582578d
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 122 deletions.
12 changes: 6 additions & 6 deletions FluentStore.SDK/PackageHandlerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
using FluentStore.Services;
using Flurl;
using Garfoot.Utilities.FluentUrn;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

namespace FluentStore.SDK
{
public abstract class PackageHandlerBase : IEqualityComparer<PackageHandlerBase>
{
protected static readonly List<PackageBase> _emptyPackageList = new(0);

/// <summary>
/// Initializes a new instance of <see cref="PackageHandlerBase"/>.
/// </summary>
Expand Down Expand Up @@ -75,17 +75,17 @@ public ImageBase Image
/// <summary>
/// Gets a list of featured packages.
/// </summary>
public abstract Task<List<PackageBase>> GetFeaturedPackagesAsync();
public virtual IAsyncEnumerable<PackageBase> GetFeaturedPackagesAsync() => Array.Empty<PackageBase>().ToAsyncEnumerable();

/// <summary>
/// Performs a search using the given query.
/// </summary>
public abstract Task<List<PackageBase>> SearchAsync(string query);
public virtual IAsyncEnumerable<PackageBase> SearchAsync(string query) => Array.Empty<PackageBase>().ToAsyncEnumerable();

/// <summary>
/// Gets search suggestions for the given query.
/// </summary>
public abstract Task<List<PackageBase>> GetSearchSuggestionsAsync(string query);
public virtual IAsyncEnumerable<PackageBase> GetSearchSuggestionsAsync(string query) => Array.Empty<PackageBase>().ToAsyncEnumerable();

/// <summary>
/// Gets the package with the specified <paramref name="packageUrn"/>.
Expand Down Expand Up @@ -117,7 +117,7 @@ public ImageBase Image
/// This method will return a list of <see cref="PackageBase{TModel}"/>s that implement <see cref="Packages.IPackageCollection"/>,
/// such as <see cref="Packages.GenericPackageCollection{TModel}"/>.
/// </remarks>
public virtual Task<List<PackageBase>> GetCollectionsAsync() => Task.FromResult(_emptyPackageList);
public virtual IAsyncEnumerable<PackageBase> GetCollectionsAsync() => Array.Empty<PackageBase>().ToAsyncEnumerable();

/// <summary>
/// Gets the review summary for the specified package.
Expand Down
14 changes: 7 additions & 7 deletions FluentStore.SDK/PackageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public async IAsyncEnumerable<HandlerPackageListPair> GetFeaturedPackagesAsync()
List<PackageBase> results;
try
{
results = await handler.GetFeaturedPackagesAsync();
results = await handler.GetFeaturedPackagesAsync().ToListAsync();
}
catch { continue; }

Expand All @@ -87,7 +87,7 @@ public async Task<IEnumerable<PackageBase>> SearchAsync(string query)
List<PackageBase> results;
try
{
results = await handler.SearchAsync(query);
results = await handler.SearchAsync(query).ToListAsync();
}
catch { continue; }

Expand All @@ -111,10 +111,10 @@ public async Task<List<PackageBase>> GetSearchSuggestionsAsync(string query)
List<PackageBase> results;
try
{
results = await handler.GetSearchSuggestionsAsync(query);
results = await handler.GetSearchSuggestionsAsync(query).ToListAsync();
}
catch { continue; }
// Filter results already in list

packages.AddRange(results);
}

Expand Down Expand Up @@ -196,14 +196,14 @@ public async IAsyncEnumerable<PackageBase> GetCollectionsAsync()
{
if (!handler.IsEnabled) continue;

List<PackageBase> results;
IAsyncEnumerable<PackageBase> results;
try
{
results = await handler.GetCollectionsAsync();
results = handler.GetCollectionsAsync();
}
catch { continue; }

foreach (var result in results)
await foreach (var result in results)
yield return result;
}
}
Expand Down
13 changes: 3 additions & 10 deletions Sources/FluentStore.Sources.Chocolatey/ChocolateyHandler.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Chocolatey;
using Chocolatey.Models;
using CommunityToolkit.Diagnostics;
using FluentStore.SDK;
using FluentStore.SDK.Images;
Expand Down Expand Up @@ -28,8 +27,6 @@ public ChocolateyHandler(IPasswordVaultService passwordVaultService) : base(pass

public override string DisplayName => "Chocolatey";

public override Task<List<PackageBase>> GetFeaturedPackagesAsync() => Task.FromResult(_emptyPackageList);

public override async Task<PackageBase> GetPackage(Urn packageUrn, SDK.PackageStatus status = SDK.PackageStatus.Details)
{
Guard.IsEqualTo(packageUrn.NamespaceIdentifier, NAMESPACE_CHOCO, nameof(packageUrn));
Expand All @@ -44,16 +41,12 @@ public override async Task<PackageBase> GetPackage(Urn packageUrn, SDK.PackageSt
return new ChocolateyPackage(this, package);
}

public override Task<List<PackageBase>> GetSearchSuggestionsAsync(string query) => Task.FromResult(_emptyPackageList);

public override async Task<List<PackageBase>> SearchAsync(string query)
public override async IAsyncEnumerable<PackageBase> SearchAsync(string query)
{
List<PackageBase> packages = new();
var results = await Choco.SearchAsync(query);
foreach (Package chocoPackage in results)
packages.Add(new ChocolateyPackage(this, chocoPackage));

return packages;
foreach (var chocoPackage in results)
yield return new ChocolateyPackage(this, chocoPackage);
}

public override ImageBase GetImage()
Expand Down
14 changes: 5 additions & 9 deletions Sources/FluentStore.Sources.FluentStore/FluentStoreHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ public FluentStoreHandler(IPasswordVaultService passwordVaultService) : base(pas

public override string DisplayName => "Fluent Store";

public override Task<List<PackageBase>> GetFeaturedPackagesAsync() => Task.FromResult(_emptyPackageList);

public override async Task<PackageBase> GetPackage(Urn urn, PackageStatus status)
{
if (urn.NamespaceIdentifier == NAMESPACE_COLLECTION)
Expand Down Expand Up @@ -78,18 +76,16 @@ public override async Task<PackageBase> GetPackage(Urn urn, PackageStatus status
return null;
}

public override Task<List<PackageBase>> GetSearchSuggestionsAsync(string query) => Task.FromResult(_emptyPackageList);

public override Task<List<PackageBase>> SearchAsync(string query) => Task.FromResult(_emptyPackageList);

public override async Task<List<PackageBase>> GetCollectionsAsync()
public override async IAsyncEnumerable<PackageBase> GetCollectionsAsync()
{
// Get current user
if (!AccountHandler.IsLoggedIn)
return _emptyPackageList;
yield break;

var collections = await FSApi.GetCollectionsAsync(AccountHandler.CurrentUser.Id);
return collections.Select(c => (PackageBase)new CollectionPackage(this, c) { Status = PackageStatus.BasicDetails }).ToList();

foreach (var coll in collections)
yield return new CollectionPackage(this, coll) { Status = PackageStatus.BasicDetails };
}

public override ImageBase GetImage() => GetImageStatic();
Expand Down
16 changes: 0 additions & 16 deletions Sources/FluentStore.Sources.GitHub/GitHubHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using Flurl;
using Garfoot.Utilities.FluentUrn;
using Octokit;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

Expand All @@ -30,11 +29,6 @@ public GitHubHandler(IPasswordVaultService passwordVaultService) : base(password

public override string DisplayName => "GitHub";

public override Task<List<PackageBase>> GetFeaturedPackagesAsync()
{
return Task.FromResult(new List<PackageBase>());
}

public override ImageBase GetImage()
{
return new FileImage("ms-appx:///Assets/PackageHandlerIcons/GitHubHandler/GitHub-Mark.png");
Expand Down Expand Up @@ -64,21 +58,11 @@ public override async Task<PackageBase> GetPackageFromUrl(Url url)
return null;
}

public override Task<List<PackageBase>> GetSearchSuggestionsAsync(string query)
{
return Task.FromResult(new List<PackageBase>());
}

public override Url GetUrlFromPackage(PackageBase package)
{
return $"https://github.com/{package.PublisherId}/{package.Title}";
}

public override Task<List<PackageBase>> SearchAsync(string query)
{
return Task.FromResult(new List<PackageBase>());
}

public static Task<IReadOnlyList<Release>> GetReleases(Repository repo)
{
return _client.Repository.Release.GetAll(repo.Id);
Expand Down
56 changes: 25 additions & 31 deletions Sources/FluentStore.Sources.MicrosoftStore/MicrosoftStoreHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,65 +38,55 @@ public MicrosoftStoreHandler(IPasswordVaultService passwordVaultService) : base(

public override string DisplayName => "Microsoft Store";

public override async Task<List<PackageBase>> GetFeaturedPackagesAsync()
public override async IAsyncEnumerable<PackageBase> GetFeaturedPackagesAsync()
{
var packages = new List<PackageBase>();
var page = await StorefrontApi.GetHomeSpotlight(options: GetSystemOptions());
packages.AddRange(
page.Cards.Where(card => card.ProductId.Length == 12 && card.TypeTag == "app")
.Select(card => new MicrosoftStorePackage(this, card) { Status = PackageStatus.BasicDetails })
);

return packages;
var packages = page.Cards.Where(card => card.ProductId.Length == 12 && card.TypeTag == "app")
.Select(card => new MicrosoftStorePackage(this, card) { Status = PackageStatus.BasicDetails });

foreach (var package in packages)
yield return package;
}

public override async Task<List<PackageBase>> SearchAsync(string query)
public override async IAsyncEnumerable<PackageBase> SearchAsync(string query)
{
var packages = new List<PackageBase>();

var page = (await StorefrontApi.Search(query, "apps", GetSystemOptions())).Payload;
AddToResults();

for (int p = 1; p < 3 && page.NextUri != null; p++)
{
page = (await StorefrontApi.NextSearchPage(page)).Payload;
AddToResults();
}

return packages;

void AddToResults()
do
{
foreach (var details in page.HighlightedResults)
{
var package = MicrosoftStorePackageBase.Create(this, details.ProductId, product: details);
package.Status = PackageStatus.BasicDetails;

packages.Add(package);
yield return package;
}
foreach (var card in page.SearchResults)
{
var package = MicrosoftStorePackageBase.Create(this, card.ProductId, card);
package.Status = PackageStatus.BasicDetails;

packages.Add(package);
yield return package;
}

page = page.NextUri is null
? null : (await StorefrontApi.NextSearchPage(page)).Payload;
}
while (page.NextUri is not null);
}

public override async Task<List<PackageBase>> GetSearchSuggestionsAsync(string query)
public override async IAsyncEnumerable<PackageBase> GetSearchSuggestionsAsync(string query)
{
var suggs = await StorefrontApi.GetSearchSuggestions(query, GetSystemOptions());
var packages = new List<PackageBase>();

foreach (var summ in suggs.Payload.AssetSuggestions)
{
var package = MicrosoftStorePackageBase.Create(this, summ.ProductId, summary: summ);
package.Status = PackageStatus.BasicDetails;

packages.Add(package);
yield return package;
}

return packages;
}

public override async Task<PackageBase> GetPackage(Urn packageUrn, PackageStatus status = PackageStatus.Details)
Expand All @@ -122,13 +112,17 @@ public override async Task<PackageBase> GetPackage(Urn packageUrn, PackageStatus
}
}

public override async Task<List<PackageBase>> GetCollectionsAsync()
public override async IAsyncEnumerable<PackageBase> GetCollectionsAsync()
{
var collectionDetail = (await StorefrontApi.GetCollections(options: GetSystemOptions())).Payload;
return collectionDetail.Cards.Select(c => (PackageBase)new MicrosoftStorePackage(this, c)

foreach (var coll in collectionDetail.Cards)
{
Urn = new(NAMESPACE_COLLECTION, new RawNamespaceSpecificString(c.ProductId))
}).ToList();
yield return new MicrosoftStorePackage(this, coll)
{
Urn = new(NAMESPACE_COLLECTION, new RawNamespaceSpecificString(coll.ProductId))
};
}
}

public override ImageBase GetImage()
Expand Down
23 changes: 4 additions & 19 deletions Sources/FluentStore.Sources.UwpCommunity/UwpCommunityHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,19 @@ public UwpCommunityHandler(IPasswordVaultService passwordVaultService) : base(pa

public override string DisplayName => "UWP Community";

public override async Task<List<PackageBase>> GetFeaturedPackagesAsync()
public override async IAsyncEnumerable<PackageBase> GetFeaturedPackagesAsync()
{
string launchYearStr = GetLastLaunchYear().ToString();
var projects = (await BASE_URL.AppendPathSegments("projects", "launch", launchYearStr)
.GetJsonAsync()).projects;

List<PackageBase> packages = new(projects.Count);
foreach (dynamic project in projects)
{
UwpCommunityPackage package = new(this, project)
yield return new UwpCommunityPackage(this, project)
{
Status = PackageStatus.BasicDetails
};
packages.Add(package);
}

return packages;
}

public override async Task<PackageBase> GetPackage(Urn urn, PackageStatus status)
Expand Down Expand Up @@ -155,22 +151,11 @@ public async Task<GenericPackageCollection<dynamic>> GetLaunchCollection(string
return listPackage;
}

public override Task<List<PackageBase>> GetSearchSuggestionsAsync(string query) => Task.FromResult(_emptyPackageList);

public override Task<List<PackageBase>> SearchAsync(string query) => Task.FromResult(_emptyPackageList);

public override async Task<List<PackageBase>> GetCollectionsAsync()
public override async IAsyncEnumerable<PackageBase> GetCollectionsAsync()
{
int lastLaunchYear = GetLastLaunchYear();
List<PackageBase> collections = new(lastLaunchYear - 2019);

for (int launchYear = 2019; launchYear <= lastLaunchYear; launchYear++)
{
var launchCollection = await GetLaunchCollection(launchYear.ToString(), PackageStatus.BasicDetails);
collections.Add(launchCollection);
}

return collections;
yield return await GetLaunchCollection(launchYear.ToString(), PackageStatus.BasicDetails);
}

public override ImageBase GetImage()
Expand Down
Loading

0 comments on commit 582578d

Please sign in to comment.