diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 66218b2..47a3922 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "paket": { - "version": "6.0.0-rc002", + "version": "7.2.1", "commands": [ "paket" ] diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets index e55904b..e230bb2 100644 --- a/.paket/Paket.Restore.targets +++ b/.paket/Paket.Restore.targets @@ -159,7 +159,7 @@ This value should match the version in the props generated by paket If they differ, this means we need to do a restore in order to ensure correct dependencies --> - + true @@ -236,13 +236,16 @@ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[6]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[7]) %(PaketReferencesFileLinesInfo.PackageVersion) All - runtime - runtime + runtime + $(ExcludeAssets);contentFiles + $(ExcludeAssets);build;buildMultitargeting;buildTransitive true true @@ -362,7 +365,9 @@ PackageLicenseFile="$(PackageLicenseFile)" PackageLicenseExpression="$(PackageLicenseExpression)" PackageLicenseExpressionVersion="$(PackageLicenseExpressionVersion)" - PackageReadmeFile="$(PackageReadmeFile)" /> + Readme="$(PackageReadmeFile)" + NoDefaultExcludes="$(NoDefaultExcludes)"/> + + PackageLicenseExpressionVersion="$(PackageLicenseExpressionVersion)" + NoDefaultExcludes="$(NoDefaultExcludes)" /> Exe - net5.0 + net7.0 diff --git a/README.md b/README.md index 62d656f..1531a21 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ In this exercise you'll learn some F# through modifying and extending a web app You'll need to install the following pre-requisites in order to build SAFE applications -* [.NET Core SDK](https://www.microsoft.com/net/download) 5.0 or higher +* [.NET SDK](https://www.microsoft.com/net/download) check the version defined in [global.json] * [Node LTS](https://nodejs.org/en/download/) You can use any editor, for this exercise we recommend diff --git a/global.json b/global.json index 2c4c450..b516c79 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "5.0.100", + "version": "7.0.304", "rollForward": "latestMinor" } } \ No newline at end of file diff --git a/paket.dependencies b/paket.dependencies index ac512b9..1e9e167 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -1,5 +1,5 @@ source https://api.nuget.org/v3/index.json -framework: net5.0 + storage: none nuget Elmish.SweetAlert diff --git a/paket.lock b/paket.lock index 9044f90..5dd1ff6 100644 --- a/paket.lock +++ b/paket.lock @@ -1,5 +1,4 @@ STORAGE: NONE -RESTRICTION: == net5.0 NUGET remote: https://api.nuget.org/v3/index.json Elmish.SweetAlert (3.4) diff --git a/src/Client/Client.fsproj b/src/Client/Client.fsproj index 414cc35..ed23296 100644 --- a/src/Client/Client.fsproj +++ b/src/Client/Client.fsproj @@ -1,7 +1,7 @@ - net5.0 + net7.0 FABLE_COMPILER diff --git a/src/Server/Api.fs b/src/Server/Api.fs index e86f19d..6ce288a 100644 --- a/src/Server/Api.fs +++ b/src/Server/Api.fs @@ -31,17 +31,47 @@ let getLocationResponse postcode = async { return response } -let private asWeatherResponse (weather: Weather.MetaWeatherLocation.Root) = - { WeatherType = - weather.ConsolidatedWeather - |> Array.countBy(fun w -> w.WeatherStateName) - |> Array.maxBy snd - |> fst - |> WeatherType.Parse - - AverageTemperature = - weather.ConsolidatedWeather - |> Array.sumBy (fun r -> float r.TheTemp) } +let private asWeatherResponse (weather: Weather.OpenMeteoSearch.Root) = + let averageTemp = + weather.Hourly.Temperature2m + |> Array.average + |> float + + let (|LessOrEqual|_|) threshold v = + if v <= threshold then Some () + else None + + let weatherType = + // WMO Weather interpretation codes (WW) + // https://open-meteo.com/en/docs + (* +0 Clear sky +1, 2, 3 Mainly clear, partly cloudy, and overcast +45, 48 Fog and depositing rime fog +51, 53, 55 Drizzle: Light, moderate, and dense intensity +56, 57 Freezing Drizzle: Light and dense intensity +61, 63, 65 Rain: Slight, moderate and heavy intensity +66, 67 Freezing Rain: Light and heavy intensity +71, 73, 75 Snow fall: Slight, moderate, and heavy intensity +77 Snow grains +80, 81, 82 Rain showers: Slight, moderate, and violent +85, 86 Snow showers slight and heavy +95 * Thunderstorm: Slight or moderate +96, 99 * Thunderstorm with slight and heavy hail + *) + match weather.CurrentWeather.Weathercode with + | LessOrEqual 0 -> WeatherType.Clear + | LessOrEqual 3 -> WeatherType.Hail + // have fun filling the blanks if you know weather english lexical + // and above table makes sense + | LessOrEqual 48 -> WeatherType.Showers + | LessOrEqual 67 -> WeatherType.Sleet + | LessOrEqual 86 -> WeatherType.Snow + | LessOrEqual 95 -> WeatherType.Thunder + | _ -> WeatherType.Apocalyptic + + { WeatherType = weatherType + AverageTemperature = averageTemp } let getWeather postcode = async { let! loc = GeoLocation.getLocation postcode diff --git a/src/Server/DataAccess.fs b/src/Server/DataAccess.fs index 45e2462..68cba19 100644 --- a/src/Server/DataAccess.fs +++ b/src/Server/DataAccess.fs @@ -10,7 +10,7 @@ module GeoLocation = type PostcodesIO = JsonProvider<"http://api.geonames.org/postalCodeLookupJSON?postalcode=1011&country=NL&username=dsyme"> let getLocation postcode = async { - let! info = + let! info = $"http://api.geonames.org/postalCodeLookupJSON?postalcode={postcode}&country=NL&username=dsyme" |> PostcodesIO.AsyncLoad if info.Postalcodes.Length > 0 then @@ -34,6 +34,7 @@ module GeoLocation = let a = sin (deltaPhi / 2.0) * sin (deltaPhi / 2.0) + cos phi1 * cos phi2 * sin (deltaLambda / 2.0) * sin (deltaLambda / 2.0) let c = 2.0 * atan2 (sqrt a) (sqrt (1.0 - a)) r * c * 1. +#if METAWEATHER_ALIVE [] module Weather = @@ -48,4 +49,18 @@ module Weather = return! bestLocationId |> sprintf "https://www.metaweather.com/api/location/%d" - |> MetaWeatherLocation.AsyncLoad } \ No newline at end of file + |> MetaWeatherLocation.AsyncLoad } + +#else + +module Weather = + + type OpenMeteoSearch = JsonProvider<"https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t_weather=true&hourly=temperature_2m,relativehumidity_2m,windspeed_10m"> + + let getWeatherForPosition location = async { + let uri = $"https://api.open-meteo.com/v1/forecast?latitude={location.Latitude}&longitude={location.Longitude}¤t_weather=true&hourly=temperature_2m,relativehumidity_2m,windspeed_10m" + let! result = OpenMeteoSearch.AsyncLoad uri + + return result + } +#endif \ No newline at end of file diff --git a/src/Server/Server.fsproj b/src/Server/Server.fsproj index dc7fce4..0a58973 100644 --- a/src/Server/Server.fsproj +++ b/src/Server/Server.fsproj @@ -2,7 +2,7 @@ Exe - net5.0 + net7.0 diff --git a/src/Shared/Shared.fs b/src/Shared/Shared.fs index e43649b..d64b5e5 100644 --- a/src/Shared/Shared.fs +++ b/src/Shared/Shared.fs @@ -25,6 +25,7 @@ type WeatherType = | HeavyCloud | LightCloud | Clear + | Apocalyptic static member Parse = let weatherTypes = FSharp.Reflection.FSharpType.GetUnionCases typeof @@ -56,7 +57,7 @@ type IDojoApi = module Validation = open System.Text.RegularExpressions - let isValidPostcode country postcode = + let isValidPostcode country (postcode: string) = match country with | "NL" -> Regex.IsMatch(postcode, @"^[1-9][0-9]{3}\s*(?:[a-zA-Z]{2})?$") | "GB" -> Regex.IsMatch(postcode, @"([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))\s?[0-9][A-Za-z]{2})") diff --git a/src/Shared/Shared.fsproj b/src/Shared/Shared.fsproj index f5319d3..3c8b51a 100644 --- a/src/Shared/Shared.fsproj +++ b/src/Shared/Shared.fsproj @@ -1,7 +1,7 @@ - net5.0 + net7.0 diff --git a/tests/Client/Client.Tests.fsproj b/tests/Client/Client.Tests.fsproj index 95bf005..17aa2b4 100644 --- a/tests/Client/Client.Tests.fsproj +++ b/tests/Client/Client.Tests.fsproj @@ -1,7 +1,7 @@ - net5.0 + net7.0 diff --git a/tests/Server/Server.Tests.fsproj b/tests/Server/Server.Tests.fsproj index 02d64d9..c1052fd 100644 --- a/tests/Server/Server.Tests.fsproj +++ b/tests/Server/Server.Tests.fsproj @@ -2,7 +2,7 @@ Exe - net5.0 + net7.0 diff --git a/tests/Shared/Shared.Tests.fsproj b/tests/Shared/Shared.Tests.fsproj index f0c849e..2286939 100644 --- a/tests/Shared/Shared.Tests.fsproj +++ b/tests/Shared/Shared.Tests.fsproj @@ -1,6 +1,6 @@ - net5.0 + net7.0