Skip to content

Commit

Permalink
Initial Version
Browse files Browse the repository at this point in the history
  • Loading branch information
0xc3u committed May 7, 2024
1 parent c1931c7 commit dc3c0cf
Show file tree
Hide file tree
Showing 32 changed files with 1,481 additions and 1 deletion.
19 changes: 19 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Build for CI

on:
push:
branches: [ "main" ]
paths-ignore:
- "**.md"
pull_request:
branches: [ "main" ]

jobs:
build-plugin-ci:

runs-on: windows-latest

steps:
- uses: actions/checkout@v3
- name: Build
run: dotnet build src\Indiko.OpenWeatherClient.sln -c Release
27 changes: 27 additions & 0 deletions .github/workflows/release-nuget.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Create a (Pre)release on NuGet

on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
- "v[0-9]+.[0-9]+.[0-9]+-preview[0-9]+"
jobs:
release-nuget:

runs-on: windows-latest

steps:
- uses: actions/checkout@v3
- name: Verify commit exists in origin/main
run: |
git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/*
git branch --remote --contains | grep origin/main
- name: Get version information from tag
id: get_version
uses: battila7/get-version-action@v2
- name: Pack
run: dotnet pack src\Indiko.OpenWeatherClient.sln -c Release -p:PackageVersion=${{ steps.get_version.outputs.version-without-v }}
- name: Push
run: dotnet nuget push src\Indiko.OpenWeatherClient\bin\Release\Indiko.OpenWeatherClient.${{ steps.get_version.outputs.version-without-v }}.nupkg -s https://api.nuget.org/v3/index.json -k ${{ secrets.NUGET_API_KEY }}
env:
GITHUB_TOKEN: ${{ secrets.NUGET_API_KEY }}
89 changes: 88 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,89 @@
![](nuget.png)

# Indiko.OpenWeatherClient
Another C# client for openweathermap.org API
The `Indiko.OpenWeatherClient` is a .NET library for interacting with the OpenWeatherMap APIs. It provides easy access to real-time weather data and map tiles, ensuring seamless integration with .NET applications.

## Build Status
![ci](https://github.com/0xc3u/Indiko.OpenWeatherClient/actions/workflows/ci.yml/badge.svg)

## Install Controls
[![NuGet](https://img.shields.io/nuget/v/Indiko.OpenWeatherClient.svg?label=NuGet)](https://www.nuget.org/packages/Indiko.OpenWeatherClient/)

Available on [NuGet](http://www.nuget.org/packages/Indiko.OpenWeatherClient).

Install with the dotnet CLI: `dotnet add package Indiko.OpenWeatherClient`, or through the NuGet Package Manager in Visual Studio.

## Features
- Fetch current weather, hourly forecast, and daily forecast.
- Access to weather map tiles.
- Supports Dependency Injection and manual instantiation.
- Configurable through a fluent API for building request parameters.


> **Important note**:
> To use this client wrapper for openweathermap.org you need have a valid api-key from https://openweathermap.org.
## Platform supported

| Platform | Version Supported | Reference |
|----------|--------------------------|-|
| .NET | 8.0 |


## API Coverage

- Weather Data: Access current weather, hourly forecast, daily forecast. (https://openweathermap.org/api/one-call-3)
- Maps API: Retrieve specific map tiles based on geographical and zoom parameters. (https://openweathermap.org/api/weathermaps)

> For detailed API usage and more examples, please refer to the official documentation or explore the OpenWeatherClient class definitions within the package.

### Dependency Injection

```csharp
// Add the service to the service collection
services.AddOpenWeatherClient();
```

```csharp
// Inject the service
public class MyClass
{
private readonly IOpenWeatherClient _openWeatherClient;

public MyClass(IOpenWeatherClient openWeatherClient)
{
_openWeatherClient = openWeatherClient;
}
}

```

### Manual instantiation

```csharp
// Create a new instance of the client
IOpenWeatherClient _openWeatherClient = new OpenWeatherClient();
```

### Usage

```csharp

// Get the current weather for a New York
var request = new OpenWeatherRequest
{
ApiKey = "YOUR_API_KEY_HERE",
Latitude = 40.712776,
Longitude = -74.005974,
Language = Constants.Languages.English,
Unit = Constants.Units.Metric,
Excludes = [Constants.Excludes.Minutely, Constants.Excludes.Daily, Constants.Excludes.Hourly]
};

var response = await openWeatherClient.GetWeatherAsync(request);

```


Binary file added nuget.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions src/Indiko.OpenWeatherClient.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34728.123
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Indiko.OpenWeatherClient", "Indiko.OpenWeatherClient\Indiko.OpenWeatherClient.csproj", "{C0DCC5AF-4C25-4BCA-AACE-095515D0C873}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{72619858-9C14-4668-8430-0A3BCFD33768}"
ProjectSection(SolutionItems) = preProject
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{FAE6981C-18D1-42A7-8F35-F4B249BCEDAE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{BFB88B54-1F7C-4529-8C92-AD66B8DF2EF5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Indiko.OpenWeatherClient.Tests", "..\tests\Indiko.OpenWeatherClient.Tests\Indiko.OpenWeatherClient.Tests.csproj", "{0584C53B-D607-439C-81D8-6D3D712B9944}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C0DCC5AF-4C25-4BCA-AACE-095515D0C873}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0DCC5AF-4C25-4BCA-AACE-095515D0C873}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0DCC5AF-4C25-4BCA-AACE-095515D0C873}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0DCC5AF-4C25-4BCA-AACE-095515D0C873}.Release|Any CPU.Build.0 = Release|Any CPU
{0584C53B-D607-439C-81D8-6D3D712B9944}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0584C53B-D607-439C-81D8-6D3D712B9944}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0584C53B-D607-439C-81D8-6D3D712B9944}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0584C53B-D607-439C-81D8-6D3D712B9944}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C0DCC5AF-4C25-4BCA-AACE-095515D0C873} = {FAE6981C-18D1-42A7-8F35-F4B249BCEDAE}
{0584C53B-D607-439C-81D8-6D3D712B9944} = {BFB88B54-1F7C-4529-8C92-AD66B8DF2EF5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B487E051-95D4-4F59-AE56-6F806E31652D}
EndGlobalSection
EndGlobal
135 changes: 135 additions & 0 deletions src/Indiko.OpenWeatherClient/Builder/OpenWeatherRequestBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
using Indiko.OpenWeatherClient.Constants;

namespace Indiko.OpenWeatherClient.Builder;

/// <summary>
/// Provides a builder pattern to create and configure an OpenWeather API request.
/// </summary>
/// <param name="apiKey">The API key to authenticate requests.</param>
public class OpenWeatherRequestBuilder(string apiKey)
{
private readonly string _apiKey = apiKey;
private string _language = Languages.English;
private string _unit = Units.Metric;
private string[] _excludes = [];
private double _latitude;
private double _longitude;
private string _city;
private string _country;
private DateTime? _date;
private bool _useGeoCoding;

/// <summary>
/// Specifies the date for the request, typically used for historical data.
/// </summary>
/// <param name="date">The date of interest.</param>
public OpenWeatherRequestBuilder WithDate(DateTime date)
{
_date = date;
return this;
}

/// <summary>
/// Specifies the language for the response data.
/// </summary>
/// <param name="language">The language code (ISO 639-1).</param>
public OpenWeatherRequestBuilder WithLanguage(string language)
{
_language = language;
return this;
}

/// <summary>
/// Specifies the unit of measurement for temperature and other values.
/// </summary>
/// <param name="unit">The unit system to use ('metric' or 'imperial').</param>
public OpenWeatherRequestBuilder WithUnit(string unit)
{
_unit = unit;
return this;
}
/// <summary>
/// Specifies the geographical coordinates for the weather data request.
/// </summary>
/// <param name="latitude">The latitude coordinate.</param>
/// <param name="longitude">The longitude coordinate.</param>
public OpenWeatherRequestBuilder WithLocation(double latitude, double longitude)
{
_latitude = latitude;
_longitude = longitude;
_useGeoCoding = false;
return this;
}

/// <summary>
/// Specifies the city and country for the weather data request.
/// </summary>
/// <param name="city">The name of the city.</param>
/// <param name="country">The country code (ISO 3166).</param>
public OpenWeatherRequestBuilder WithCity(string city, string country)
{
_city = city;
_country = country;
_useGeoCoding = true;
return this;
}

/// <summary>
/// Specifies the features to exclude from the response data.
/// </summary>
/// <param name="excludes">An array of features to exclude.</param>
public OpenWeatherRequestBuilder WithExcludes(string[] excludes)
{
_excludes = excludes;
return this;
}

/// <summary>
/// Builds the final URI for the OpenWeather API request based on the configured options.
/// Throws an exception if required parameters are not provided or incorrectly configured.
/// </summary>
/// <returns>The URI of the configured OpenWeather API request.</returns>
public Uri Build()
{
if (string.IsNullOrEmpty(_apiKey))
{
throw new ArgumentException("API Key must be provided");
}

string requestUrl = $"https://api.openweathermap.org/data/3.0/onecall?appid={_apiKey}&lang={_language}&units={_unit}";
if (_useGeoCoding)
{
if (_latitude != 0 && _longitude != 0)
{
throw new ArgumentException("Latitude and Longitude must be 0 when using city and country");
}
if (string.IsNullOrEmpty(_city) || string.IsNullOrEmpty(_country))
{
throw new ArgumentException("City and Country must be provided when using city and country");
}

requestUrl = $"{requestUrl}&q={_city},{_country}";
}
else
{
if (_latitude == 0 || _longitude == 0)
{
throw new ArgumentException("Latitude and Longitude must be provided when not using city and country");
}

requestUrl = $"{requestUrl}&lat={_latitude}&lon={_longitude}";
}

if (_date.HasValue)
{
requestUrl = $"{requestUrl}&date={_date.Value.ToShortDateString()}";
}

if (_excludes != null)
{
requestUrl = $"{requestUrl}&exclude={string.Join(",", _excludes)}";
}

return new Uri(requestUrl);
}
}
37 changes: 37 additions & 0 deletions src/Indiko.OpenWeatherClient/Constants/Excludes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace Indiko.OpenWeatherClient.Constants;

/// <summary>
/// Contains constant values that specify which data components to exclude from the responses in OpenWeather API requests.
/// </summary>
public static class Excludes
{
/// <summary>
/// Excludes the current weather data from the API response.
/// </summary>
public const string Current = "current";

/// <summary>
/// Excludes the minutely weather data (e.g., precipitation) from the API response.
/// </summary>
public const string Minutely = "minutely";

/// <summary>
/// Excludes the hourly forecast data from the API response.
/// </summary>
public const string Hourly = "hourly";

/// <summary>
/// Excludes the daily forecast data from the API response.
/// </summary>
public const string Daily = "daily";

/// <summary>
/// Excludes weather alerts from the API response.
/// </summary>
public const string Alerts = "alerts";

/// <summary>
/// Excludes all optional data components (current, minutely, hourly, daily, and alerts) from the API response.
/// </summary>
public const string All = "current,minutely,hourly,daily,alerts";
}
Loading

0 comments on commit dc3c0cf

Please sign in to comment.