From 6ee4cf3466ecd493ba7915d9eaf614384c63eaa3 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Wed, 16 Oct 2019 20:32:45 +0200 Subject: [PATCH] Bumping version to 1.6.0 --- .paket/Paket.Restore.targets | 98 +++++++++++++++---------- RELEASE_NOTES.md | 3 + src/Client/ReleaseNotes.fs | 5 +- src/Server/AzureTable.fs | 9 +-- src/Server/Server.fs | 97 ++++++------------------ src/Server/Server.fsproj | 1 - src/Server/Sonos.fs | 138 ----------------------------------- src/Shared/Shared.fs | 38 +--------- 8 files changed, 92 insertions(+), 297 deletions(-) delete mode 100644 src/Server/Sonos.fs diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets index 06e074f..3632ffe 100644 --- a/.paket/Paket.Restore.targets +++ b/.paket/Paket.Restore.targets @@ -7,7 +7,7 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) $(MSBuildVersion) - 15.0.0 + 15.0.0 false true @@ -27,44 +27,13 @@ $(PaketRootPath)paket.bootstrapper.exe $(PaketToolsPath)paket.bootstrapper.exe $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\ - - - - - $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - $(PaketToolsPath)paket.exe - $(_PaketBootStrapperExeDir)paket.exe - paket.exe - - - $(PaketRootPath)paket - $(PaketToolsPath)paket - $(PaketToolsPath)paket - - - $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - - - $(PaketBootStrapperExeDir)paket.exe - - - paket - - - <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) - dotnet "$(PaketExePath)" - $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" - "$(PaketExePath)" - - + "$(PaketBootStrapperExePath)" $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)" - + true true @@ -74,6 +43,57 @@ $(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/')) + + + + + + + + + + + dotnet paket + + + + + + $(PaketRootPath)paket.exe + $(PaketToolsPath)paket.exe + $(PaketToolsPath)paket.exe + $(_PaketBootStrapperExeDir)paket.exe + paket.exe + + + $(PaketRootPath)paket + $(PaketToolsPath)paket + $(PaketToolsPath)paket + + + $(PaketRootPath)paket.exe + $(PaketToolsPath)paket.exe + + + $(PaketBootStrapperExeDir)paket.exe + + + paket + + <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) + dotnet "$(PaketExePath)" + $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" + "$(PaketExePath)" + + + + + + + + + + @@ -81,7 +101,7 @@ - + @@ -203,7 +223,7 @@ $([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]) %(PaketReferencesFileLinesInfo.PackageVersion) @@ -246,7 +266,7 @@ - + <_NuspecFilesNewLocation Include="$(PaketIntermediateOutputPath)\$(Configuration)\*.nuspec"/> @@ -300,7 +320,7 @@ DevelopmentDependency="$(DevelopmentDependency)" BuildOutputInPackage="@(_BuildOutputInPackage)" TargetPathsToSymbols="@(_TargetPathsToSymbols)" - SymbolPackageFormat="symbols.nupkg" + SymbolPackageFormat="$(SymbolPackageFormat)" TargetFrameworks="@(_TargetFrameworks)" AssemblyName="$(AssemblyName)" PackageOutputPath="$(PackageOutputAbsolutePath)" @@ -347,7 +367,7 @@ DevelopmentDependency="$(DevelopmentDependency)" BuildOutputInPackage="@(_BuildOutputInPackage)" TargetPathsToSymbols="@(_TargetPathsToSymbols)" - SymbolPackageFormat="symbols.nupkg" + SymbolPackageFormat="$(SymbolPackageFormat)" TargetFrameworks="@(_TargetFrameworks)" AssemblyName="$(AssemblyName)" PackageOutputPath="$(PackageOutputAbsolutePath)" diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 9bbbd0a..940c9a6 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,8 @@ # Release Notes +## 1.6.0 - 2019-10-16 +* Removed Sonos support + ## 1.5.23 - 2019-08-22 * Sonos support * Removed Youtube diff --git a/src/Client/ReleaseNotes.fs b/src/Client/ReleaseNotes.fs index 6560709..c7e0398 100644 --- a/src/Client/ReleaseNotes.fs +++ b/src/Client/ReleaseNotes.fs @@ -1,12 +1,15 @@ module internal ReleaseNotes -let Version = "1.5.23" +let Version = "1.6.0" let IsPrerelease = false let Notes = """ # Release Notes +## 1.6.0 - 2019-10-16 +* Removed Sonos support + ## 1.5.23 - 2019-08-22 * Sonos support * Removed Youtube diff --git a/src/Server/AzureTable.fs b/src/Server/AzureTable.fs index 008fad7..c50e961 100644 --- a/src/Server/AzureTable.fs +++ b/src/Server/AzureTable.fs @@ -143,14 +143,7 @@ let mapTag (entity: DynamicTableEntity) : Tag = | Ok action -> action } let mapUser (entity: DynamicTableEntity) : User = - { UserID = entity.RowKey - SonosID = getStringProperty "SonosID" entity - SonosAccessToken = getStringProperty "SonosAccessToken" entity - SonosRefreshToken = getStringProperty "SonosRefreshToken" entity - SpeakerType = - match Decode.fromString SpeakerType.Decoder (getStringProperty "SpeakerType" entity) with - | Error msg -> failwith msg - | Ok action -> action } + { UserID = entity.RowKey } let mapRequest (entity: DynamicTableEntity) : Request = { UserID = entity.PartitionKey diff --git a/src/Server/Server.fs b/src/Server/Server.fs index d172c16..9cdc089 100644 --- a/src/Server/Server.fs +++ b/src/Server/Server.fs @@ -88,14 +88,6 @@ let uploadEndpoint (userID:string) = }) } -let sonosEventEndpoint = - pipeline { - set_header "Content-Type" "application/json" - plug (fun next ctx -> task { - let! body = ctx.ReadBodyFromRequestAsync() - return! failwithf "from sonos: %s" body - }) - } let previousFileEndpoint (userID,token) = pipeline { @@ -122,29 +114,14 @@ let previousFileEndpoint (userID,token) = Object = "" } task { return t } - match user.SpeakerType with - | SpeakerType.Local -> - let tag : TagForBox = { - Token = tag.Token - Object = tag.Object - Description = tag.Description - Action = TagActionForBox.GetFromTagAction(tag.Action,position) } - - let txt = TagForBox.Encoder tag |> Encode.toString 0 - return! setBodyFromString txt next ctx - | SpeakerType.Sonos -> - let logger = ctx.GetLogger "PreviousFile" - let! session = Sonos.createOrJoinSession logger user.SonosAccessToken Sonos.group - do! Sonos.playStream logger user.SonosAccessToken session tag position - - let tag : TagForBox = { - Token = tag.Token - Object = tag.Object - Description = tag.Description - Action = TagActionForBox.Ignore } - - let txt = TagForBox.Encoder tag |> Encode.toString 0 - return! setBodyFromString txt next ctx + let tag : TagForBox = { + Token = tag.Token + Object = tag.Object + Description = tag.Description + Action = TagActionForBox.GetFromTagAction(tag.Action,position) } + + let txt = TagForBox.Encoder tag |> Encode.toString 0 + return! setBodyFromString txt next ctx }) } @@ -177,29 +154,14 @@ let nextFileEndpoint (userID,token) = let! _ = AzureTable.savePlayListPosition userID token position - match user.SpeakerType with - | SpeakerType.Local -> - let tag : TagForBox = { - Token = tag.Token - Object = tag.Object - Description = tag.Description - Action = TagActionForBox.GetFromTagAction(tag.Action,position) } - - let txt = TagForBox.Encoder tag |> Encode.toString 0 - return! setBodyFromString txt next ctx - | SpeakerType.Sonos -> - let logger = ctx.GetLogger "NextFile" - let! session = Sonos.createOrJoinSession logger user.SonosAccessToken Sonos.group - do! Sonos.playStream logger user.SonosAccessToken session tag position - - let tag : TagForBox = { - Token = tag.Token - Object = tag.Object - Description = tag.Description - Action = TagActionForBox.Ignore } - - let txt = TagForBox.Encoder tag |> Encode.toString 0 - return! setBodyFromString txt next ctx + let tag : TagForBox = { + Token = tag.Token + Object = tag.Object + Description = tag.Description + Action = TagActionForBox.GetFromTagAction(tag.Action,position) } + + let txt = TagForBox.Encoder tag |> Encode.toString 0 + return! setBodyFromString txt next ctx }) } @@ -222,7 +184,7 @@ let volumeUpEndpoint userID = return! Response.notFound ctx userID | Some user -> let logger = ctx.GetLogger "VolumeUp" - do! Sonos.volumeUp logger user.SonosAccessToken Sonos.group + //do! Sonos.volumeUp logger user.SonosAccessToken Sonos.group return! Response.ok ctx userID }) } @@ -235,7 +197,7 @@ let volumeDownEndpoint userID = return! Response.notFound ctx userID | Some user -> let logger = ctx.GetLogger "VolumeDown" - do! Sonos.volumeDown logger user.SonosAccessToken Sonos.group + //do! Sonos.volumeDown logger user.SonosAccessToken Sonos.group return! Response.ok ctx userID }) } @@ -260,23 +222,11 @@ let startupEndpoint userID = | Some user -> let! sas = getSASMediaLink "d97cdddb-8a19-4690-8ba5-b8ea43d3641f" - match user.SpeakerType with - | SpeakerType.Local -> - let txt = - TagActionForBox.PlayMusik sas - |> TagActionForBox.Encoder - |> Encode.toString 0 - return! setBodyFromString txt next ctx - | SpeakerType.Sonos -> - let logger = ctx.GetLogger "Startup" - let! session = Sonos.createOrJoinSession logger user.SonosAccessToken Sonos.group - do! Sonos.playURL logger user.SonosAccessToken session "StartupSound" sas "StartupSound" - - let txt = - TagActionForBox.Ignore - |> TagActionForBox.Encoder - |> Encode.toString 0 - return! setBodyFromString txt next ctx + let txt = + TagActionForBox.PlayMusik sas + |> TagActionForBox.Encoder + |> Encode.toString 0 + return! setBodyFromString txt next ctx }) } @@ -311,7 +261,6 @@ let t = task { let webApp = router { getf "/api/nextfile/%s/%s" nextFileEndpoint - post "/sonosevent" sonosEventEndpoint getf "/api/previousfile/%s/%s" previousFileEndpoint getf "/api/usertags/%s" userTagsEndPoint getf "/api/volumeup/%s" volumeUpEndpoint diff --git a/src/Server/Server.fsproj b/src/Server/Server.fsproj index 93ad555..b4c0fea 100644 --- a/src/Server/Server.fsproj +++ b/src/Server/Server.fsproj @@ -10,7 +10,6 @@ - diff --git a/src/Server/Sonos.fs b/src/Server/Sonos.fs deleted file mode 100644 index 21338e0..0000000 --- a/src/Server/Sonos.fs +++ /dev/null @@ -1,138 +0,0 @@ -module Sonos - -let group = "RINCON_347E5CF009E001400:4129486752" - -open System.IO -open FSharp.Control.Tasks.ContextInsensitive -open ServerCore.Domain -open Thoth.Json.Net -open System.Net -open Microsoft.Extensions.Logging - -let post (log:ILogger) (url:string) headers (data:string) = task { - let req = HttpWebRequest.Create(url) :?> HttpWebRequest - req.ProtocolVersion <- HttpVersion.Version10 - req.Method <- "POST" - - for (name:string),(value:string) in headers do - req.Headers.Add(name,value) |> ignore - - let postBytes = System.Text.Encoding.UTF8.GetBytes(data) - req.ContentType <- "application/json; charset=utf-8" - req.ContentLength <- int64 postBytes.Length - - try - // Write data to the request - use reqStream = req.GetRequestStream() - do! reqStream.WriteAsync(postBytes, 0, postBytes.Length) - reqStream.Close() - - use resp = req.GetResponse() - use stream = resp.GetResponseStream() - use reader = new StreamReader(stream) - let! html = reader.ReadToEndAsync() - return html - with - | :? WebException as exn when not (isNull exn.Response) -> - use errorResponse = exn.Response :?> HttpWebResponse - use reader = new StreamReader(errorResponse.GetResponseStream()) - let error = reader.ReadToEnd() - log.LogError(sprintf "Request to %s failed with: %s %s" url exn.Message error) - return! raise exn -} - -type Session = - { ID : string } - - static member Decoder = - Decode.object (fun get -> - { ID = get.Required.Field "sessionId" Decode.string } - ) - -let playModeToSingle (log:ILogger) accessToken group = task { - let headers = ["Authorization", "Bearer " + accessToken] - let url = sprintf "https://api.ws.sonos.com/control/api/v1/groups/%s/playback/playMode" group - let body = """{ - "playModes": { - "repeat": false, - "repeatOne": false, - "crossfade": false, - "shuffle": false - } - }""" - - let! _result = post log url headers body - - () -} - -let createOrJoinSession (log:ILogger) accessToken group = task { - let headers = ["Authorization", "Bearer " + accessToken] - let url = sprintf "https://api.ws.sonos.com/control/api/v1/groups/%s/playbackSession" group - let body = """{ - "appId": "com.Forkmann.AudioHub", - "appContext": "1a2b3c", - "customData": "playlistid:12345" -}""" - - let! result = post log url headers body - - match Decode.fromString Session.Decoder result with - | Error msg -> return failwith msg - | Ok session -> - do! playModeToSingle log accessToken group - return session -} - -let volumeUp (log:ILogger) accessToken group = task { - let headers = ["Authorization", "Bearer " + accessToken] - let url = sprintf "https://api.ws.sonos.com/control/api/v1/groups/%s/groupVolume/relative" group - let body = """{ - "volumeDelta": 10 -}""" - - let! _result = post log url headers body - - () -} - -let volumeDown (log:ILogger) accessToken group = task { - let headers = ["Authorization", "Bearer " + accessToken] - let url = sprintf "https://api.ws.sonos.com/control/api/v1/groups/%s/groupVolume/relative" group - let body = """{ - "volumeDelta": -10 -}""" - - let! _result = post log url headers body - - () -} - - -let playURL (log:ILogger) accessToken (session:Session) itemID mediaURL description = task { - let headers = ["Authorization", "Bearer " + accessToken] - let url = sprintf "https://api.ws.sonos.com/control/api/v1/playbackSessions/%s/playbackSession/loadStreamUrl" session.ID - - let body = sprintf """{ - "streamUrl": "%s", - "playOnCompletion": true, - "stationMetadata": { - "name": "%s", - "type": "track" - }, - "itemId" : "%s" - }""" mediaURL description itemID - - - let! _result = post log url headers body - () -} - -let playStream (log:ILogger) accessToken (session:Session) (tag:Tag) position = task { - match tag.Action with - | TagAction.PlayMusik stream -> - let pos = System.Math.Abs(position % stream.Length) - do! playURL log accessToken session tag.Token stream.[pos] (tag.Object + " - " + tag.Description) - | _ -> - log.LogError(sprintf "TagAction %A can't be played on Sonos" tag.Action) -} diff --git a/src/Shared/Shared.fs b/src/Shared/Shared.fs index 118220d..6ab8af9 100644 --- a/src/Shared/Shared.fs +++ b/src/Shared/Shared.fs @@ -132,50 +132,16 @@ type Tag = Action = get.Required.Field "Action" TagAction.Decoder } ) -[] -type SpeakerType = -| Local -| Sonos - - static member Encoder (action : SpeakerType) = - match action with - | Local -> - Encode.object [ - "Local", Encode.nil - ] - | Sonos -> - Encode.object [ - "Sonos", Encode.nil - ] - - static member Decoder = - Decode.oneOf [ - Decode.field "Local" (Decode.succeed SpeakerType.Local) - Decode.field "Sonos" (Decode.succeed SpeakerType.Sonos) - ] - type User = - { UserID : string - SpeakerType : SpeakerType - SonosAccessToken : string - SonosRefreshToken : string - SonosID : string } + { UserID : string } static member Encoder (user : User) = Encode.object [ "UserID", Encode.string user.UserID - "SpeakerType", SpeakerType.Encoder user.SpeakerType - "SonosAccessToken", Encode.string user.SonosAccessToken - "SonosRefreshToken", Encode.string user.SonosRefreshToken - "SonosID", Encode.string user.SonosID ] static member Decoder = Decode.object (fun get -> - { UserID = get.Required.Field "UserID" Decode.string - SpeakerType = get.Required.Field "SpeakerType" SpeakerType.Decoder - SonosAccessToken = get.Required.Field "SonosAccessToken" Decode.string - SonosRefreshToken = get.Required.Field "SonosRefreshToken" Decode.string - SonosID = get.Required.Field "SonosID" Decode.string } + { UserID = get.Required.Field "UserID" Decode.string } ) type Request =