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