diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 49d19908..1888e4cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,21 +34,22 @@ jobs: path: reports/*.trx reporter: dotnet-trx - semver: - name: semver + release: + name: release needs: test runs-on: ubuntu-latest - outputs: - label: ${{steps.VERSION.outputs.label}} - semver: ${{steps.VERSION.outputs.semver}} - nuget: ${{steps.VERSION.outputs.nuget}} - prerelease: ${{steps.VERSION.outputs.prerelease}} - applicable: ${{steps.VERSION.outputs.applicable}} - previous: ${{steps.LAST.outputs.tag}} + if: github.event_name == 'push' + env: + nuget_key: ${{ secrets.NUGET_KEY }} steps: - name: Checkout code uses: actions/checkout@v3 - + + - name: Setup .NET 7 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: "7.0.x" + - name: Setup GitVersion run: dotnet tool install --global GitVersion.Tool @@ -65,23 +66,34 @@ jobs: - name: Update version run: dotnet-gitversion /updateprojectfiles /updateassemblyinfo /output buildserver + + - name: Build + run: dotnet build --configuration Release - - name: Set job output - id: VERSION - run: | - echo '::set-output name=label::${{env.GitVersion_PreReleaseLabel}}' - echo '::set-output name=semver::${{env.GitVersion_LegacySemVer}}' - echo '::set-output name=nuget::${{env.GitVersion_NuGetPreReleaseTagV2}}' - echo '::set-output name=prerelease::${{env.GitVersion_PreReleaseLabel == 'alpha' || env.GitVersion_PreReleaseLabel == 'beta' }}' - echo '::set-output name=applicable::${{github.ref == 'refs/heads/main' || env.GitVersion_PreReleaseLabel == 'alpha' || env.GitVersion_PreReleaseLabel == 'beta'}}' + - name: Pack + if: ${{env.nuget_key != ''}} + run: dotnet pack --configuration Release --output nupkgs --include-symbols --include-source + + - name: Create release + uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + with: + tag_name: ${{ env.GitVersion_LegacySemVer }} + name: v${{ env.GitVersion_LegacySemVer }} + prerelease: ${{ env.GitVersion_PreReleaseLabel == 'alpha' || env.GitVersion_PreReleaseLabel == 'beta' }} + - name: Publish project to NuGet + if: ${{env.nuget_key != ''}} + run: dotnet nuget push '**/*.nupkg' -k ${{ env.nuget_key }} -s https://api.nuget.org/v3/index.json --skip-duplicate + - name: Push version bump if: ${{env.GitVersion_PreReleaseLabel == '' || env.GitVersion_PreReleaseLabel == 'alpha' || env.GitVersion_PreReleaseLabel == 'beta'}} uses: EndBug/add-and-commit@v9 with: author_name: github-actions[bot] author_email: github-actions[bot]@users.noreply.github.com - message: "Bumped version to ${{env.GitVersion_LegacySemVer}}" + message: "Bumped version to ${{ env.GitVersion_LegacySemVer }}" approve: name: approve @@ -93,56 +105,4 @@ jobs: uses: juliangruber/approve-pull-request-action@v2.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} - number: ${{ github.event.number }} - - release: - name: release - needs: semver - runs-on: ubuntu-latest - if: github.event_name == 'push' && github.ref == 'refs/heads/main' - env: - nuget_key: ${{ secrets.NUGET_KEY }} - steps: - - name: Setup Ruby v3 - uses: ruby/setup-ruby@v1 - with: - ruby-version: "3.0" - - - name: Create release - uses: softprops/action-gh-release@v1 - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - with: - tag_name: ${{needs.semver.outputs.semver}} - name: v${{needs.semver.outputs.semver}} - prerelease: ${{needs.semver.outputs.prerelease}} - - publish: - name: publish - needs: semver - runs-on: ubuntu-latest - if: github.event_name == 'push' && needs.semver.outputs.applicable == 'true' - env: - nuget_key: ${{ secrets.NUGET_KEY }} - steps: - - name: Checkout code - if: ${{env.nuget_key != ''}} - uses: actions/checkout@v3 - - - name: Setup .NET 7 - if: ${{env.nuget_key != ''}} - uses: actions/setup-dotnet@v3 - with: - dotnet-version: "7.0.x" - - - name: Restore dependencies - if: ${{env.nuget_key != ''}} - run: dotnet restore - - - name: Pack - if: ${{env.nuget_key != ''}} - run: dotnet pack --configuration Release --output nupkgs --include-symbols --include-source - - - name: Publish project to NuGet - if: ${{env.nuget_key != ''}} - run: dotnet nuget push '**/*.nupkg' -k ${{env.nuget_key}} -s https://api.nuget.org/v3/index.json --skip-duplicate + number: ${{ github.event.number }} \ No newline at end of file diff --git a/EliteAPI.Web.Spansh/EliteAPI.Web.Spansh.csproj.DotSettings b/EliteAPI.Web.Spansh/EliteAPI.Web.Spansh.csproj.DotSettings new file mode 100644 index 00000000..fe4489fc --- /dev/null +++ b/EliteAPI.Web.Spansh/EliteAPI.Web.Spansh.csproj.DotSettings @@ -0,0 +1,3 @@ + + True + True \ No newline at end of file diff --git a/EliteAPI.Web.Spansh/Search/Requests/Bodies/BodiesRequest.cs b/EliteAPI.Web.Spansh/Search/Requests/Bodies/BodiesRequest.cs new file mode 100644 index 00000000..231706da --- /dev/null +++ b/EliteAPI.Web.Spansh/Search/Requests/Bodies/BodiesRequest.cs @@ -0,0 +1,42 @@ +using System.Runtime.Serialization; +using EliteAPI.Web.Models; +using EliteAPI.Web.Spansh.Search.Requests.Sort; +using Newtonsoft.Json; + +namespace EliteAPI.Web.Spansh.Search.Requests; + +public class BodiesRequest : IWebApiRequest +{ + [JsonProperty("filters")] + public FilterOptions Filters { get; init; } = new(); + + [JsonProperty("sort")] + public ICollection Sorting { get; init; } = new List { new() }.ToArray(); + + [JsonProperty("reference_system")] + public string ReferenceSystem { get; init; } = "Sol"; + + [JsonProperty("size")] + public long Size { get; init; } = 50; + + [JsonProperty("page")] + public long Page { get; init; } = 0; + + public class FilterOptions + { + [JsonProperty("atmosphere", NullValueHandling = NullValueHandling.Ignore)] + public AtmosphereFilter? Atmosphere { get; init; } + + [JsonProperty("distance", NullValueHandling = NullValueHandling.Ignore)] + public MinMaxFilter? Distance { get; init; } + } + + public class SortOption + { + [JsonProperty("distance")] + public DistanceSort Distance { get; init; } = new() { Direction = "asc" }; + } + + public string Endpoint => "bodies/search"; + public HttpMethod Method => HttpMethod.Post; +} \ No newline at end of file diff --git a/EliteAPI.Web.Spansh/Search/Requests/Bodies/Filters/AtmosphereFilter.cs b/EliteAPI.Web.Spansh/Search/Requests/Bodies/Filters/AtmosphereFilter.cs new file mode 100644 index 00000000..d6c92a59 --- /dev/null +++ b/EliteAPI.Web.Spansh/Search/Requests/Bodies/Filters/AtmosphereFilter.cs @@ -0,0 +1,264 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace EliteAPI.Web.Spansh.Search.Requests; + +public class AtmosphereFilter +{ + public AtmosphereFilter() + { + + } + + public AtmosphereFilter(ICollection atmospheres) + { + Atmospheres = atmospheres; + } + + public AtmosphereFilter(params Atmosphere[] atmospheres) + { + Atmospheres = atmospheres; + } + + [JsonProperty("value")] + public ICollection Atmospheres { get; init; } = new List(); + + [JsonConverter(typeof(StringEnumConverter))] + public enum Atmosphere + { + [EnumMember(Value = "Ammonia")] + Ammonia, + + [EnumMember(Value = "Ammonia and Oxygen")] + AmmoniaAndOxygen, + + [EnumMember(Value = "Ammonia-rich")] + AmmoniaRich, + + [EnumMember(Value = "Argon")] + Argon, + + [EnumMember(Value = "Argon-rich")] + ArgonRich, + + [EnumMember(Value = "Carbon dioxide")] + CarbonDioxide, + + [EnumMember(Value = "Carbon dioxide-rich")] + CarbonDioxideRich, + + [EnumMember(Value = "Helium")] + Helium, + + [EnumMember(Value = "Hot Argon")] + HotArgon, + + [EnumMember(Value = "Hot Argon-rich")] + HotArgonRich, + + [EnumMember(Value = "Hot Carbon dioxide")] + HotCarbonDioxide, + + [EnumMember(Value = "Hot Carbon dioxide-rich")] + HotCarbonDioxideRich, + + [EnumMember(Value = "Hot Metallic vapour")] + HotMetallicVapour, + + [EnumMember(Value = "Hot Silicate vapour")] + HotSilicateVapour, + + [EnumMember(Value = "Hot Sulphur dioxide")] + HotSulphurDioxide, + + [EnumMember(Value = "Hot Water")] + HotWater, + + [EnumMember(Value = "Hot Water-rich")] + HotWaterRich, + + [EnumMember(Value = "Hot thick Ammonia")] + HotThickAmmonia, + + [EnumMember(Value = "Hot thick Ammonia-rich")] + HotThickAmmoniaRich, + + [EnumMember(Value = "Hot thick Argon")] + HotThickArgon, + + [EnumMember(Value = "Hot thick Argon-rich")] + HotThickArgonRich, + + [EnumMember(Value = "Hot thick Carbon dioxide")] + HotThickCarbonDioxide, + + [EnumMember(Value = "Hot thick Carbon dioxide-rich")] + HotThickCarbonDioxideRich, + + [EnumMember(Value = "Hot thick Metallic vapour")] + HotThickMetallicVapour, + + [EnumMember(Value = "Hot thick Methane")] + HotThickMethane, + + [EnumMember(Value = "Hot thick Methane-rich")] + HotThickMethaneRich, + + [EnumMember(Value = "Hot thick Nitrogen")] + HotThickNitrogen, + + [EnumMember(Value = "Hot thick Silicate vapour")] + HotThickSilicateVapour, + + [EnumMember(Value = "Hot thick Sulphur dioxide")] + HotThickSulphurDioxide, + + [EnumMember(Value = "Hot thick Water")] + HotThickWater, + + [EnumMember(Value = "Hot thick Water-rich")] + HotThickWaterRich, + + [EnumMember(Value = "Hot thin Carbon dioxide")] + HotThinCarbonDioxide, + + [EnumMember(Value = "Hot thin Metallic vapour")] + HotThinMetallicVapour, + + [EnumMember(Value = "Hot thin Silicate vapour")] + HotThinSilicateVapour, + + [EnumMember(Value = "Hot thin Sulphur dioxide")] + HotThinSulphurDioxide, + + [EnumMember(Value = "Methane")] + Methane, + + [EnumMember(Value = "Methane-rich")] + MethaneRich, + + [EnumMember(Value = "Neon-rich")] + NeonRich, + + [EnumMember(Value = "Nitrogen")] + Nitrogen, + + [EnumMember(Value = "No atmosphere")] + NoAtmosphere, + + [EnumMember(Value = "Oxygen")] + Oxygen, + + [EnumMember(Value = "Suitable for water-based life")] + SuitableForWaterBasedLife, + + [EnumMember(Value = "Sulphur dioxide")] + SulphurDioxide, + + [EnumMember(Value = "Thick Ammonia")] + ThickAmmonia, + + [EnumMember(Value = "Thick Ammonia and Oxygen")] + ThickAmmoniaAndOxygen, + + [EnumMember(Value = "Thick Ammonia-rich")] + ThickAmmoniaRich, + + [EnumMember(Value = "Thick Argon")] + ThickArgon, + + [EnumMember(Value = "Thick Argon-rich")] + ThickArgonRich, + + [EnumMember(Value = "Thick Carbon dioxide")] + ThickCarbonDioxide, + + [EnumMember(Value = "Thick Carbon dioxide-rich")] + ThickCarbonDioxideRich, + + [EnumMember(Value = "Thick Helium")] + ThickHelium, + + [EnumMember(Value = "Thick Methane")] + ThickMethane, + + [EnumMember(Value = "Thick Methane-rich")] + ThickMethaneRich, + + [EnumMember(Value = "Thick Nitrogen")] + ThickNitrogen, + + [EnumMember(Value = "Thick No atmosphere")] + ThickNoAtmosphere, + + [EnumMember(Value = "Thick Suitable for water-based life")] + ThickSuitableForWaterBasedLife, + + [EnumMember(Value = "Thick Sulphur dioxide")] + ThickSulphurDioxide, + + [EnumMember(Value = "Thick Water")] + ThickWater, + + [EnumMember(Value = "Thick Water-rich")] + ThickWaterRich, + + [EnumMember(Value = "Thin Ammonia")] + ThinAmmonia, + + [EnumMember(Value = "Thin Ammonia and Oxygen")] + ThinAmmoniaAndOxygen, + + [EnumMember(Value = "Thin Ammonia-rich")] + ThinAmmoniaRich, + + [EnumMember(Value = "Thin Argon")] + ThinArgon, + + [EnumMember(Value = "Thin Argon-rich")] + ThinArgonRich, + + [EnumMember(Value = "Thin Carbon dioxide")] + ThinCarbonDioxide, + + [EnumMember(Value = "Thin Carbon dioxide-rich")] + ThinCarbonDioxideRich, + + [EnumMember(Value = "Thin Helium")] + ThinHelium, + + [EnumMember(Value = "Thin Methane")] + ThinMethane, + + [EnumMember(Value = "Thin Methane-rich")] + ThinMethaneRich, + + [EnumMember(Value = "Thin Neon")] + ThinNeon, + + [EnumMember(Value = "Thin Neon-rich")] + ThinNeonRich, + + [EnumMember(Value = "Thin Nitrogen")] + ThinNitrogen, + + [EnumMember(Value = "Thin Oxygen")] + ThinOxygen, + + [EnumMember(Value = "Thin Sulphur dioxide")] + ThinSulphurDioxide, + + [EnumMember(Value = "Thin Water")] + ThinWater, + + [EnumMember(Value = "Thin Water-rich")] + ThinWaterRich, + + [EnumMember(Value = "Water")] + Water, + + [EnumMember(Value = "Water-rich")] + WaterRich + } +} \ No newline at end of file diff --git a/EliteAPI.Web.Spansh/Search/Requests/Bodies/Filters/MinMaxFilter.cs b/EliteAPI.Web.Spansh/Search/Requests/Bodies/Filters/MinMaxFilter.cs new file mode 100644 index 00000000..f082f8d8 --- /dev/null +++ b/EliteAPI.Web.Spansh/Search/Requests/Bodies/Filters/MinMaxFilter.cs @@ -0,0 +1,28 @@ +using Newtonsoft.Json; + +namespace EliteAPI.Web.Spansh.Search.Requests; + +public class MinMaxFilter +{ + public MinMaxFilter() + { + + } + + public MinMaxFilter(double max) + { + Max = max; + } + + public MinMaxFilter(double min, double max) + { + Min = min; + Max = max; + } + + [JsonProperty("min")] + public double Min { get; init; } = 0; + + [JsonProperty("max")] + public double Max { get; init; } = 1000000; +} \ No newline at end of file diff --git a/EliteAPI.Web.Spansh/Search/Requests/Bodies/Sort/DistanceSort.cs b/EliteAPI.Web.Spansh/Search/Requests/Bodies/Sort/DistanceSort.cs new file mode 100644 index 00000000..dcb7b1d3 --- /dev/null +++ b/EliteAPI.Web.Spansh/Search/Requests/Bodies/Sort/DistanceSort.cs @@ -0,0 +1,9 @@ +using Newtonsoft.Json; + +namespace EliteAPI.Web.Spansh.Search.Requests.Sort; + +public class DistanceSort +{ + [JsonProperty("direction")] + public string Direction { get; init; } +} \ No newline at end of file diff --git a/EliteAPI.Web.Spansh/Search/Responses/Bodies/BodiesResponse.cs b/EliteAPI.Web.Spansh/Search/Responses/Bodies/BodiesResponse.cs new file mode 100644 index 00000000..53904fed --- /dev/null +++ b/EliteAPI.Web.Spansh/Search/Responses/Bodies/BodiesResponse.cs @@ -0,0 +1,294 @@ +using EliteAPI.Web.Models; +using EliteAPI.Web.Spansh.Search.Requests; +using Newtonsoft.Json; + +namespace EliteAPI.Web.Spansh.Search.Responses.Bodies; + +public class BodiesResponse : IWebApiResponse +{ + [JsonProperty("count")] + public long Count { get; init; } + + [JsonProperty("from")] + public long From { get; init; } + + [JsonProperty("reference")] + public SystemReference References { get; init; } + + [JsonProperty("results")] + public IReadOnlyCollection Bodies { get; init; } + + [JsonProperty("search")] + public BodiesRequest Search { get; init; } + + [JsonProperty("search_reference")] + public string SearchReference { get; init; } + + [JsonProperty("size")] + public long Size { get; init; } +} + +public class SystemReference +{ + [JsonProperty("id64")] + public long Id { get; init; } + + [JsonProperty("name")] + public string Name { get; init; } + + [JsonProperty("x")] + public long X { get; init; } + + [JsonProperty("y")] + public long Y { get; init; } + + [JsonProperty("z")] + public long Z { get; init; } +} + +public class Body +{ + [JsonProperty("arg_of_periapsis")] + public double ArgOfPeriapsis { get; init; } + + [JsonProperty("ascending_node")] + public double AscendingNode { get; init; } + + [JsonProperty("atmosphere")] + public string Atmosphere { get; init; } + + [JsonProperty("atmosphere_composition", NullValueHandling = NullValueHandling.Ignore)] + public IReadOnlyCollection AtmosphereComposition { get; init; } + + [JsonProperty("axis_tilt")] + public double AxisTilt { get; init; } + + [JsonProperty("body_id")] + public long BodyId { get; init; } + + [JsonProperty("distance")] + public long Distance { get; init; } + + [JsonProperty("distance_to_arrival")] + public double DistanceToArrival { get; init; } + + [JsonProperty("earth_masses")] + public double EarthMasses { get; init; } + + [JsonProperty("estimated_mapping_value")] + public long EstimatedMappingValue { get; init; } + + [JsonProperty("estimated_scan_value")] + public long EstimatedScanValue { get; init; } + + [JsonProperty("gravity")] + public double Gravity { get; init; } + + [JsonProperty("id")] + public string Id { get; init; } + + [JsonProperty("id64")] + public double Id64 { get; init; } + + [JsonProperty("is_landable")] + public bool IsLandable { get; init; } + + [JsonProperty("is_main_star")] + public object IsMainStar { get; init; } + + [JsonProperty("is_rotational_period_tidally_locked")] + public bool IsRotationalPeriodTidallyLocked { get; init; } + + [JsonProperty("mean_anomaly")] + public double MeanAnomaly { get; init; } + + [JsonProperty("name")] + public string Name { get; init; } + + [JsonProperty("orbital_eccentricity")] + public double OrbitalEccentricity { get; init; } + + [JsonProperty("orbital_inclination")] + public double OrbitalInclination { get; init; } + + [JsonProperty("orbital_period")] + public double OrbitalPeriod { get; init; } + + [JsonProperty("parents")] + public IReadOnlyCollection Parents { get; init; } + + [JsonProperty("radius")] + public double Radius { get; init; } + + [JsonProperty("reserve_level", NullValueHandling = NullValueHandling.Ignore)] + public string ReserveLevel { get; init; } + + [JsonProperty("rings", NullValueHandling = NullValueHandling.Ignore)] + public IReadOnlyCollection Rings { get; init; } + + [JsonProperty("rotational_period")] + public double RotationalPeriod { get; init; } + + [JsonProperty("semi_major_axis")] + public double SemiMajorAxis { get; init; } + + [JsonProperty("subtype")] + public string Subtype { get; init; } + + [JsonProperty("surface_pressure")] + public double SurfacePressure { get; init; } + + [JsonProperty("surface_temperature")] + public double SurfaceTemperature { get; init; } + + [JsonProperty("system_id64")] + public long SystemId64 { get; init; } + + [JsonProperty("system_name")] + public string SystemName { get; init; } + + [JsonProperty("system_region")] + public string SystemRegion { get; init; } + + [JsonProperty("system_x")] + public long SystemX { get; init; } + + [JsonProperty("system_y")] + public long SystemY { get; init; } + + [JsonProperty("system_z")] + public long SystemZ { get; init; } + + [JsonProperty("terraforming_state")] + public string TerraformingState { get; init; } + + [JsonProperty("type")] + public string Type { get; init; } + + [JsonProperty("updated_at")] + public string UpdatedAt { get; init; } + + [JsonProperty("landmark_value", NullValueHandling = NullValueHandling.Ignore)] + public long? LandmarkValue { get; init; } + + [JsonProperty("landmarks", NullValueHandling = NullValueHandling.Ignore)] + public IReadOnlyCollection? Landmarks { get; init; } + + [JsonProperty("materials", NullValueHandling = NullValueHandling.Ignore)] + public IReadOnlyCollection? Materials { get; init; } + + [JsonProperty("signal_count", NullValueHandling = NullValueHandling.Ignore)] + public long? SignalCount { get; init; } + + [JsonProperty("signals", NullValueHandling = NullValueHandling.Ignore)] + public IReadOnlyCollection? Signals { get; init; } + + [JsonProperty("signals_updated_at", NullValueHandling = NullValueHandling.Ignore)] + public string? SignalsUpdatedAt { get; init; } + + [JsonProperty("solid_composition", NullValueHandling = NullValueHandling.Ignore)] + public IReadOnlyCollection? SolidComposition { get; init; } + + [JsonProperty("stations", NullValueHandling = NullValueHandling.Ignore)] + public IReadOnlyCollection? Stations { get; init; } + + [JsonProperty("volcanism_type", NullValueHandling = NullValueHandling.Ignore)] + public string? VolcanismType { get; init; } +} + +public class AtmosphereComposition +{ + [JsonProperty("name")] + public string Name { get; init; } + + [JsonProperty("share")] + public double Share { get; init; } +} + +public class Landmark +{ + [JsonProperty("id")] + public long Id { get; init; } + + [JsonProperty("latitude")] + public double Latitude { get; init; } + + [JsonProperty("longitude")] + public double Longitude { get; init; } + + [JsonProperty("subtype")] + public string Subtype { get; init; } + + [JsonProperty("type")] + public string Type { get; init; } + + [JsonProperty("value")] + public long Value { get; init; } +} + +public class Parent +{ + [JsonProperty("id")] + public long Id { get; init; } + + [JsonProperty("type")] + public string Type { get; init; } +} + +public class Ring +{ + [JsonProperty("inner_radius")] + public long InnerRadius { get; init; } + + [JsonProperty("mass")] + public long Mass { get; init; } + + [JsonProperty("name")] + public string Name { get; init; } + + [JsonProperty("outer_radius")] + public long OuterRadius { get; init; } + + [JsonProperty("type")] + public string Type { get; init; } +} + +public class Signal +{ + [JsonProperty("count")] + public long Count { get; init; } + + [JsonProperty("name")] + public string Name { get; init; } +} + +public class Station +{ + [JsonProperty("distance_to_arrival")] + public double DistanceToArrival { get; init; } + + [JsonProperty("has_large_pad")] + public bool HasLargePad { get; init; } + + [JsonProperty("has_market")] + public bool HasMarket { get; init; } + + [JsonProperty("large_pads")] + public long LargePads { get; init; } + + [JsonProperty("market_id")] + public long MarketId { get; init; } + + [JsonProperty("medium_pads")] + public long MediumPads { get; init; } + + [JsonProperty("name")] + public string Name { get; init; } + + [JsonProperty("small_pads")] + public long SmallPads { get; init; } + + [JsonProperty("type")] + public string Type { get; init; } +} + \ No newline at end of file diff --git a/EliteAPI.Web.Spansh/Search/SearchApi.cs b/EliteAPI.Web.Spansh/Search/SearchApi.cs new file mode 100644 index 00000000..886ffafd --- /dev/null +++ b/EliteAPI.Web.Spansh/Search/SearchApi.cs @@ -0,0 +1,39 @@ +using EliteAPI.Web.Spansh.RoutePlanner.Requests; +using EliteAPI.Web.Spansh.RoutePlanner.Responses; +using EliteAPI.Web.Spansh.Search.Requests; +using EliteAPI.Web.Spansh.Search.Responses.Bodies; +using EliteAPI.Web.Spansh.Utilities.Responses; +using Microsoft.Extensions.Logging; +using Somfic.Common; + +namespace EliteAPI.Web.Spansh.Search; + +public class SearchApi : WebApiCategory +{ + private readonly ILogger _log; + + public SearchApi(WebApi api, ILogger log) : base(api) + { + _log = log; + } + + protected override string Endpoint => ""; + + public async Task> Neutron(NeutronRequest request) + { + var api = Api as SpanshApi; + var job = await Execute(request); + return await api.Utilities.FromJob(job); + } + + public async Task> Bodies(BodiesRequest request) + { + var api = Api as SpanshApi; + var response = await Execute(request); + + return response.Map>( + ok: x => x.Content, + error: x => x); + } + +} \ No newline at end of file diff --git a/EliteAPI.Web.Spansh/SpanshApi.cs b/EliteAPI.Web.Spansh/SpanshApi.cs index 26229861..0f068364 100644 --- a/EliteAPI.Web.Spansh/SpanshApi.cs +++ b/EliteAPI.Web.Spansh/SpanshApi.cs @@ -1,5 +1,6 @@ using EliteAPI.Web.Models; using EliteAPI.Web.Spansh.RoutePlanner; +using EliteAPI.Web.Spansh.Search; using EliteAPI.Web.Spansh.Utilities; using Newtonsoft.Json; @@ -10,12 +11,15 @@ public class SpanshApi : WebApi public SpanshApi(IServiceProvider services) : base(services) { Routes = AddCategory(); + Search = AddCategory(); Utilities = AddCategory(); } protected override string BaseUrl => "https://www.spansh.co.uk/api"; public RoutePlannerApi Routes { get; } + + public SearchApi Search { get; } internal UtilitiesApi Utilities { get; } } \ No newline at end of file diff --git a/EliteAPI.Web/Models/IWebApiRequest.cs b/EliteAPI.Web/Models/IWebApiRequest.cs index 6ddf0382..cea79d4f 100644 --- a/EliteAPI.Web/Models/IWebApiRequest.cs +++ b/EliteAPI.Web/Models/IWebApiRequest.cs @@ -1,5 +1,8 @@ -namespace EliteAPI.Web.Models; +using Newtonsoft.Json; +namespace EliteAPI.Web.Models; + +[JsonObject(MemberSerialization.OptIn)] public interface IWebApiRequest { /// The endpoint of the request, based on the category. diff --git a/EliteAPI.Web/WebApiCategory.cs b/EliteAPI.Web/WebApiCategory.cs index ac68aadf..b07e3ec2 100644 --- a/EliteAPI.Web/WebApiCategory.cs +++ b/EliteAPI.Web/WebApiCategory.cs @@ -1,11 +1,14 @@ using System.Reflection; +using System.Text; using System.Web; using EliteAPI.Web.Attributes; using EliteAPI.Web.Exceptions; using EliteAPI.Web.Models; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; namespace EliteAPI.Web; @@ -46,8 +49,14 @@ protected internal async Task>> Execute(); var requestMessage = BuildRequest(this, request); + + _log.LogDebug($"Sending {requestMessage.Method} request to {requestMessage.RequestUri}"); + _log.LogTrace(await requestMessage.Content.ReadAsStringAsync()); var response = await Http.SendAsync(requestMessage); + + _log.LogDebug($"Got response {response.StatusCode} from {requestMessage.RequestUri}"); + _log.LogTrace(await response.Content.ReadAsStringAsync()); if (!response.IsSuccessStatusCode) { @@ -103,9 +112,21 @@ private HttpRequestMessage BuildRequest(WebApiCategory category, IWebApiRequest var uri = uriBuilder.Uri; //todo: add headers - //todo: add body + + // Create the body from the JsonPropertyAttribute properties. Don't include the QueryParameterAttribute properties + var body = JObject.FromObject(request, new JsonSerializer + { + ContractResolver = new DefaultContractResolver + { + NamingStrategy = new SnakeCaseNamingStrategy() + }, + NullValueHandling = NullValueHandling.Ignore + }).ToString(Formatting.None); + + var r = new HttpRequestMessage(request.Method, uri); + r.Content = new StringContent(body, Encoding.UTF8, "application/json"); - return new HttpRequestMessage(request.Method, uri); + return r; } private string GetPropertyValue(PropertyInfo property, object instance) diff --git a/Examples/Example.Web/Program.cs b/Examples/Example.Web/Program.cs index e868d59c..ef77edd9 100644 --- a/Examples/Example.Web/Program.cs +++ b/Examples/Example.Web/Program.cs @@ -1,5 +1,6 @@ using EliteAPI.Web.Spansh; using EliteAPI.Web.Spansh.RoutePlanner.Requests; +using EliteAPI.Web.Spansh.Search.Requests; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -14,27 +15,27 @@ s.AddSimpleConsole(); s.AddFilter("Microsoft", LogLevel.Warning); s.AddFilter("System", LogLevel.Warning); - + s.SetMinimumLevel(LogLevel.Trace); + }) .Build() .Services .GetRequiredService(); -Console.WriteLine("Getting route ... "); -var response = await spansh.Routes.Trade(new TradeRequest("Shinrarta Dezhra", "Jameson Memorial", 50, 720)); +Console.WriteLine("Searching ... "); +var response = await spansh.Search.Bodies(new BodiesRequest +{ + Filters = new BodiesRequest.FilterOptions + { + Atmosphere = new AtmosphereFilter(AtmosphereFilter.Atmosphere.SuitableForWaterBasedLife), + Distance = new MinMaxFilter(1000) + }, + ReferenceSystem = "Fusang" +}); response.On( - ok: route => + ok: r => { - foreach (var stop in route) - { - Console.WriteLine(stop.System.Name + " - " + stop.System.Station); - foreach (var commodity in stop.Commodities) - { - Console.WriteLine($" - {commodity.Name} {commodity.Amount}x (+{commodity.TotalProfit:N0}cr)"); - } - - Console.WriteLine(); - } + Console.WriteLine(string.Join(", ", r.Bodies.Select(x => x.SystemName))); }, error: e => Console.WriteLine(e.Message)); \ No newline at end of file