Skip to content

Commit 19dff74

Browse files
authored
Merge pull request #1450 from Microsoft/staging
Merging into master for 2.0
2 parents e684405 + 6e90c75 commit 19dff74

File tree

612 files changed

+23543
-8753
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

612 files changed

+23543
-8753
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,11 @@ BundleArtifacts
214214
!/build
215215
/build/tools/GitVersion.CommandLine
216216
AppPackages
217+
218+
# NuGet V3 artifacts
219+
*-packages.config
220+
*.nuget.props
221+
*.nuget.targets
222+
project.lock.json
223+
msbuild.binlog
224+
*.project.lock.json
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// ******************************************************************
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// This code is licensed under the MIT License (MIT).
4+
// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
5+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7+
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
8+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
9+
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
10+
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
11+
// ******************************************************************
12+
13+
using System;
14+
using System.Collections.Generic;
15+
using System.Linq;
16+
using System.Threading.Tasks;
17+
using Microsoft.Toolkit.Services.Exceptions;
18+
using System.Net.Http;
19+
20+
namespace Microsoft.Toolkit.Services
21+
{
22+
/// <summary>
23+
/// Base class for data providers in this library.
24+
/// </summary>
25+
/// <typeparam name="TConfig">Query configuration type for given provider.</typeparam>
26+
public abstract class DataProviderBase<TConfig>
27+
{
28+
/// <summary>
29+
/// Constructor
30+
/// </summary>
31+
public DataProviderBase()
32+
{
33+
34+
}
35+
36+
/// <summary>
37+
/// Load data from provider endpoint.
38+
/// </summary>
39+
/// <typeparam name="TSchema">Strong typed object to parse the response items into.</typeparam>
40+
/// <param name="config">Query configuration.</param>
41+
/// <param name="maxRecords">Upper record limit.</param>
42+
/// <param name="pageIndex">The zero-based index of the page that corresponds to the items to retrieve.</param>
43+
/// <param name="parser">Parser to use for results.</param>
44+
/// <returns>Strong typed list of results.</returns>
45+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an async method, so nesting generic types is necessary.")]
46+
public async Task<IEnumerable<TSchema>> LoadDataAsync<TSchema>(TConfig config, int maxRecords, int pageIndex, IParser<TSchema> parser)
47+
where TSchema : SchemaBase
48+
{
49+
if (config == null)
50+
{
51+
throw new ConfigNullException();
52+
}
53+
54+
if (parser == null)
55+
{
56+
throw new ParserNullException();
57+
}
58+
59+
ValidateConfig(config);
60+
61+
var result = await GetDataAsync(config, maxRecords, pageIndex, parser);
62+
if (result != null)
63+
{
64+
return result
65+
.Take(maxRecords)
66+
.ToList();
67+
}
68+
69+
return Array.Empty<TSchema>();
70+
}
71+
72+
private static HttpClient httpClient;
73+
74+
/// <summary>
75+
/// Static instance of HttpClient.
76+
/// </summary>
77+
public static HttpClient HttpClient
78+
{
79+
get { return httpClient ?? (httpClient = new HttpClient()); }
80+
set { httpClient = value; }
81+
}
82+
83+
/// <summary>
84+
/// Derived classes will have to implement this method to return provider data
85+
/// </summary>
86+
/// <param name="config">Configuration to use</param>
87+
/// <param name="maxRecords">Maximum number of records to return</param>
88+
/// <param name="pageIndex">The zero-based index of the page that corresponds to the items to retrieve.</param>
89+
/// <param name="parser">Parser to use</param>
90+
/// <typeparam name="TSchema">Schema defining data returned</typeparam>
91+
/// <returns>List of data</returns>
92+
protected abstract Task<IEnumerable<TSchema>> GetDataAsync<TSchema>(TConfig config, int maxRecords, int pageIndex, IParser<TSchema> parser)
93+
where TSchema : SchemaBase;
94+
95+
/// <summary>
96+
/// Method provided by derived class to validate specified configuration
97+
/// </summary>
98+
/// <param name="config">Configuration to validate</param>
99+
protected abstract void ValidateConfig(TConfig config);
100+
}
101+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// ******************************************************************
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// This code is licensed under the MIT License (MIT).
4+
// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
5+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7+
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
8+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
9+
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
10+
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
11+
// ******************************************************************
12+
13+
using System.Collections.Generic;
14+
using System.Threading.Tasks;
15+
16+
namespace Microsoft.Toolkit.Services
17+
{
18+
/// <summary>
19+
/// Base class for data providers in this library.
20+
/// </summary>
21+
/// <typeparam name="TConfig">Strong typed query configuration object.</typeparam>
22+
/// <typeparam name="TSchema">Strong typed object to parse the response items into.</typeparam>
23+
public abstract class DataProviderBase<TConfig, TSchema> : DataProviderBase<TConfig>
24+
where TSchema : SchemaBase
25+
{
26+
/// <summary>
27+
/// Load data from provider endpoint.
28+
/// </summary>
29+
/// <param name="config">Query configuration.</param>
30+
/// <param name="maxRecords">Upper record limit.</param>
31+
/// <param name="pageIndex">The zero-based index of the page that corresponds to the items to retrieve.</param>
32+
/// <returns>List of strong typed objects.</returns>
33+
public Task<IEnumerable<TSchema>> LoadDataAsync(TConfig config, int maxRecords = 20, int pageIndex = 0)
34+
{
35+
return LoadDataAsync(config, maxRecords, pageIndex, GetDefaultParser(config));
36+
}
37+
38+
/// <summary>
39+
/// Default parser abstract method.
40+
/// </summary>
41+
/// <param name="config">Query configuration object.</param>
42+
/// <returns>Strong typed default parser.</returns>
43+
protected abstract IParser<TSchema> GetDefaultParser(TConfig config);
44+
}
45+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// ******************************************************************
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// This code is licensed under the MIT License (MIT).
4+
// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
5+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7+
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
8+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
9+
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
10+
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
11+
// ******************************************************************
12+
13+
using System;
14+
using System.Net;
15+
using System.Reflection;
16+
using System.Text.RegularExpressions;
17+
using Microsoft.Toolkit.Services.Bing;
18+
19+
namespace Microsoft.Toolkit.Services.Core
20+
{
21+
/// <summary>
22+
/// This class offers general purpose methods.
23+
/// </summary>
24+
public static class ExtensionMethods
25+
{
26+
/// <summary>
27+
/// Regular expression of HTML tags to remove.
28+
/// </summary>
29+
private static readonly Regex RemoveHtmlTagsRegex = new Regex(@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>");
30+
31+
/// <summary>
32+
/// Converts object into string.
33+
/// </summary>
34+
/// <param name="value">Object value.</param>
35+
/// <returns>Returns string value.</returns>
36+
public static string ToSafeString(this object value)
37+
{
38+
return value?.ToString();
39+
}
40+
41+
/// <summary>
42+
/// Decode HTML string.
43+
/// </summary>
44+
/// <param name="htmlText">HTML string.</param>
45+
/// <returns>Returns decoded HTML string.</returns>
46+
public static string DecodeHtml(this string htmlText)
47+
{
48+
if (htmlText == null)
49+
{
50+
return null;
51+
}
52+
53+
var ret = htmlText.FixHtml();
54+
55+
// Remove html tags
56+
ret = RemoveHtmlTagsRegex.Replace(ret, string.Empty);
57+
58+
return WebUtility.HtmlDecode(ret);
59+
}
60+
61+
/// <summary>
62+
/// Converts between country code and country name.
63+
/// </summary>
64+
/// <param name="value">BingCountry enumeration.</param>
65+
/// <returns>Returns country code.</returns>
66+
public static string GetStringValue(this BingCountry value)
67+
{
68+
return GetStringValue((Enum)value);
69+
}
70+
71+
/// <summary>
72+
/// Converts between language code and language name.
73+
/// </summary>
74+
/// <param name="value">BingLanguage enumeration.</param>
75+
/// <returns>Returns language code.</returns>
76+
public static string GetStringValue(this BingLanguage value)
77+
{
78+
return GetStringValue((Enum)value);
79+
}
80+
81+
/// <summary>
82+
/// Converts between enumeration value and string value.
83+
/// </summary>
84+
/// <param name="value">Enumeration.</param>
85+
/// <returns>Returns string value.</returns>
86+
private static string GetStringValue(Enum value)
87+
{
88+
string output = null;
89+
Type type = value.GetType();
90+
91+
FieldInfo fi = type.GetRuntimeField(value.ToString());
92+
StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
93+
if (attrs != null && attrs.Length > 0)
94+
{
95+
output = attrs[0].Value;
96+
}
97+
98+
return output;
99+
}
100+
}
101+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// ******************************************************************
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// This code is licensed under the MIT License (MIT).
4+
// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
5+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7+
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
8+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
9+
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
10+
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
11+
// ******************************************************************
12+
13+
using System.Collections.Generic;
14+
using System.Threading.Tasks;
15+
16+
namespace Microsoft.Toolkit.Services.Core
17+
{
18+
/// <summary>
19+
/// Generic interface that all deployed service providers implement.
20+
/// </summary>
21+
/// <typeparam name="T">Reference to underlying data service provider.</typeparam>
22+
/// <typeparam name="U">Strongly-typed schema for data returned in list query.</typeparam>
23+
/// <typeparam name="V">Configuration type specifying query parameters.</typeparam>
24+
public interface IDataService<T, U, V>
25+
{
26+
/// <summary>
27+
/// Gets the underlying data service provider.
28+
/// </summary>
29+
T Provider { get; }
30+
31+
/// <summary>
32+
/// Makes a request for a list of data from the given service provider.
33+
/// </summary>
34+
/// <param name="config">Describes the query on the list data request.</param>
35+
/// <param name="maxRecords">Specifies an upper limit to the number of records returned.</param>
36+
/// <param name="pageIndex">The zero-based index of the page that corresponds to the items to retrieve.</param>
37+
/// <returns>Returns a strongly typed list of results from the service.</returns>
38+
Task<List<U>> RequestAsync(V config, int maxRecords, int pageIndex = 0);
39+
}
40+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// ******************************************************************
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// This code is licensed under the MIT License (MIT).
4+
// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
5+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7+
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
8+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
9+
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
10+
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
11+
// ******************************************************************
12+
13+
using System.Collections.Generic;
14+
15+
namespace Microsoft.Toolkit.Services
16+
{
17+
/// <summary>
18+
/// Parser interface.
19+
/// </summary>
20+
/// <typeparam name="T">Type to parse into.</typeparam>
21+
public interface IParser<out T>
22+
where T : SchemaBase
23+
{
24+
/// <summary>
25+
/// Parse method which all classes must implement.
26+
/// </summary>
27+
/// <param name="data">Data to parse.</param>
28+
/// <returns>Strong typed parsed data.</returns>
29+
IEnumerable<T> Parse(string data);
30+
}
31+
}

0 commit comments

Comments
 (0)