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.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
using Beam.Abstractions;
|
||||
using HtmlAgilityPack;
|
||||
|
||||
namespace Beam.Dynamic;
|
||||
|
||||
/// <summary>
|
||||
/// Allows composition of different data providers to adapt to different types of data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class ComposeDataProviders<T> : IComposableDataProvider<T> {
|
||||
public required IComposableDataProvider<object>[] SelectWith { get; init; }
|
||||
public required IComposableDataProvider<T> GetWith { get; init; }
|
||||
|
||||
private ComposeDataProviders() {}
|
||||
|
||||
public static ComposeDataProviders<T> Create(IComposableDataProvider<object> selectWith, IComposableDataProvider<T> getWith) {
|
||||
return new ComposeDataProviders<T>() {
|
||||
GetWith = getWith,
|
||||
SelectWith = [selectWith]
|
||||
};
|
||||
}
|
||||
|
||||
public static ComposeDataProviders<T> Create(IComposableDataProvider<object>[] selectWiths, IComposableDataProvider<T> getWith) {
|
||||
return new ComposeDataProviders<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 = Select(document);
|
||||
if (selected is null)
|
||||
throw new Exception("Selection operation failed.");
|
||||
return GetWith.Get(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 Get(HtmlNode node) {
|
||||
return GetWith.Get(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? Select(HtmlDocument doc) {
|
||||
var selected = SelectWith[0].Select(doc);
|
||||
foreach(var provider in SelectWith.Skip(1)) {
|
||||
if (selected is null)
|
||||
return null;
|
||||
selected = provider.Select(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? Select(HtmlNode node) {
|
||||
var selected = SelectWith[0].Select(node);
|
||||
foreach(var provider in SelectWith.Skip(1)) {
|
||||
if (selected is null)
|
||||
return null;
|
||||
selected = provider.Select(selected);
|
||||
}
|
||||
|
||||
return selected;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user