1module Sources.Services.AzureFile exposing (defaults, initialData, makeTrackUrl, makeTree, parseErrorResponse, parsePreparationResponse, parseTreeResponse, postProcessTree, prepare, properties)
2
3{-| Microsoft Azure File Service.
4
5Resources:
6
7 - <https://docs.microsoft.com/en-us/rest/api/storageservices/file-service-rest-api>
8
9-}
10
11import Common
12import Dict
13import Http
14import Sources exposing (Property, SourceData)
15import Sources.Pick
16import Sources.Processing exposing (..)
17import Sources.Services.Azure.Authorization exposing (..)
18import Sources.Services.Azure.FileMarker as FileMarker exposing (MarkerItem(..))
19import Sources.Services.Azure.FileParser as Parser
20import Sources.Services.Common exposing (cleanPath, noPrep)
21import Time
22
23
24
25-- PROPERTIES
26-- 📟
27
28
29defaults =
30 { name = "Music from Azure File Storage"
31 }
32
33
34{-| The list of properties we need from the user.
35
36Tuple: (property, label, placeholder, isPassword)
37Will be used for the forms.
38
39-}
40properties : List Property
41properties =
42 [ { key = "accountName"
43 , label = "Account name"
44 , placeholder = "myaccount"
45 , password = False
46 }
47 , { key = "accountKey"
48 , label = "Account key"
49 , placeholder = "MXFPDkaN4KBT"
50 , password = True
51 }
52 , { key = "container"
53 , label = "Share name"
54 , placeholder = "music"
55 , password = False
56 }
57 , { key = "directoryPath"
58 , label = "Directory (aka. Prefix, Optional)"
59 , placeholder = "/"
60 , password = False
61 }
62 ]
63
64
65{-| Initial data set.
66-}
67initialData : SourceData
68initialData =
69 Dict.fromList
70 [ ( "accountName", "" )
71 , ( "accountKey", "" )
72 , ( "container", "" )
73 , ( "directoryPath", "" )
74 , ( "name", defaults.name )
75 ]
76
77
78
79-- PREPARATION
80
81
82prepare : String -> SourceData -> Marker -> (Result Http.Error String -> msg) -> Maybe (Cmd msg)
83prepare _ _ _ _ =
84 Nothing
85
86
87
88-- TREE
89
90
91{-| Create a directory tree.
92
93List all the tracks in the container.
94Or a specific directory in the container.
95
96-}
97makeTree : SourceData -> Marker -> Time.Posix -> (Result Http.Error String -> msg) -> Cmd msg
98makeTree srcData marker currentTime resultMsg =
99 let
100 directoryPathFromSrcData =
101 srcData
102 |> Dict.get "directoryPath"
103 |> Maybe.withDefault ""
104 |> cleanPath
105
106 baseParams =
107 [ ( "maxresults", "1000" ) ]
108
109 ( directoryPath, params ) =
110 case FileMarker.takeOne marker of
111 Just (Directory directory) ->
112 Tuple.pair directory []
113
114 Just (Param param) ->
115 Tuple.pair param.directory [ ( "marker", param.marker ) ]
116
117 _ ->
118 Tuple.pair directoryPathFromSrcData []
119
120 url =
121 presignedUrl File List Get 1 currentTime srcData directoryPath (baseParams ++ params)
122 in
123 Http.get
124 { url = url
125 , expect = Http.expectStringResponse resultMsg Common.translateHttpResponse
126 }
127
128
129{-| Re-export parser functions.
130-}
131parsePreparationResponse : String -> Time.Posix -> SourceData -> Marker -> PrepationAnswer Marker
132parsePreparationResponse =
133 noPrep
134
135
136parseTreeResponse : String -> Marker -> TreeAnswer Marker
137parseTreeResponse =
138 Parser.parseTreeResponse
139
140
141parseErrorResponse : String -> Maybe String
142parseErrorResponse =
143 Parser.parseErrorResponse
144
145
146
147-- POST
148
149
150{-| Post process the tree results.
151
152!!! Make sure we only use music files that we can use.
153
154-}
155postProcessTree : List String -> List String
156postProcessTree =
157 Sources.Pick.selectMusicFiles
158
159
160
161-- TRACK URL
162
163
164{-| Create a public url for a file.
165
166We need this to play the track.
167(!) Creates a presigned url that's valid for 48 hours
168
169-}
170makeTrackUrl : Time.Posix -> String -> SourceData -> HttpMethod -> String -> String
171makeTrackUrl currentTime _ srcData _ pathToFile =
172 presignedUrl File Read Get 48 currentTime srcData pathToFile []