Files
Beam/Beam.Dynamic/DataProviders/ManyComposeDataProviders.cs
qwsdcvghyu89 18c5ad83da Refactor data providers and update abstractions
- Removed obsolete data providers: `AnchorCollectionDataProvider`, `ContentsDataProvider`, and others, consolidating logic into new composable providers.
- Added `ComposeDataProviders`, `SelectDataProvider`, and `RelationalDataProvider` for improved flexibility and reusability.
- Introduced `IManySelectionComposableDataProvider` interface to support multiple-node selection.
- Enhanced `UnitDownloader` with more robust progress tracking.
- Updated package references and project dependencies for consistency.
- Improved error handling in `StealthConfig` initialization for better fallback on browser drivers.
- Incremented project version to 2.4.5.
2025-11-14 03:41:13 +11:00

80 lines
2.8 KiB
C#

using Beam.Abstractions;
using HtmlAgilityPack;
namespace Beam.Dynamic;
public class ManyComposeDataProviders<T> : IManySelectionComposableDataProvider<T> {
public required IManySelectionComposableDataProvider<object>[] SelectWith { get; init; }
public required IManySelectionComposableDataProvider<T> GetWith { get; init; }
private ManyComposeDataProviders() {}
public static ManyComposeDataProviders<T> Create(IManySelectionComposableDataProvider<object> selectWith, IManySelectionComposableDataProvider<T> getWith) {
return new ManyComposeDataProviders<T>() {
GetWith = getWith,
SelectWith = [selectWith]
};
}
public static ManyComposeDataProviders<T> Create(IManySelectionComposableDataProvider<object>[] selectWiths, IManySelectionComposableDataProvider<T> getWith) {
return new ManyComposeDataProviders<T>() {
GetWith = getWith,
SelectWith = selectWiths
};
}
/// <summary>
/// Composes the data providers, first selecting a node with <see cref="SelectWith"/>, then getting the data with <see cref="GetWith"/>.
/// </summary>
/// <exception cref="Exception">Throws when <see cref="SelectWith"/> returns a null value.</exception>
/// <param name="document"></param>
/// <returns></returns>
public T Get(HtmlDocument document) {
var selected = SelectMany(document);
if (selected is null)
throw new Exception("Selection operation failed.");
return GetWith.ManyGet(selected);
}
/// <summary>
/// Uses the <see cref="GetWith"/> data provider to get the data from the supplied node.
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public T ManyGet(HtmlNode[] node) {
return GetWith.ManyGet(node);
}
/// <summary>
/// Uses the <see cref="SelectWith"/> data provider to select a node from the supplied document.
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
public HtmlNode[]? SelectMany(HtmlDocument doc) {
var selected = SelectWith[0].SelectMany(doc);
foreach(var provider in SelectWith.Skip(1)) {
if (selected is null)
return null;
selected = provider.SelectMany(selected);
}
return selected;
}
/// <summary>
/// Uses the <see cref="SelectWith"/> data provider to select a node from the supplied document.
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
public HtmlNode[]? SelectMany(HtmlNode[] node) {
var selected = SelectWith[0].SelectMany(node);
foreach(var provider in SelectWith.Skip(1)) {
if (selected is null)
return null;
selected = provider.SelectMany(selected);
}
return selected;
}
}