A music player that connects to your cloud/distributed storage.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Refactor Sources modules

+259 -180
+8 -2
src/App/Queue/Utils.elm
··· 4 4 import List.Extra as List 5 5 import Queue.Types exposing (..) 6 6 import Sources.Processing 7 - import Sources.Types exposing (Source) 7 + import Sources.Services 8 + import Sources.Types exposing (HttpMethod(..), Source) 8 9 import Tracks.Types exposing (Track) 9 10 import Types as TopLevel exposing (Illumination) 10 11 import Utils ··· 47 48 48 49 makeTrackUrl : Date -> Track -> Source -> String 49 50 makeTrackUrl timestamp track source = 50 - Sources.Processing.makeTrackUrl timestamp source track.path 51 + Sources.Services.makeTrackUrl 52 + source.service 53 + timestamp 54 + source.data 55 + Get 56 + track.path
+2 -14
src/App/Sources/Encoding.elm
··· 6 6 import Dict 7 7 import Json.Decode as Decode 8 8 import Json.Encode as Encode 9 + import Sources.Services as Services 9 10 import Sources.Types exposing (..) 10 11 11 12 ··· 54 55 55 56 serviceDecoder : Decode.Decoder Service 56 57 serviceDecoder = 57 - Decode.map serviceStringToType Decode.string 58 - 59 - 60 - serviceStringToType : String -> Service 61 - serviceStringToType str = 62 - case str of 63 - "AmazonS3" -> 64 - AmazonS3 65 - 66 - "Ipfs" -> 67 - Ipfs 68 - 69 - _ -> 70 - AmazonS3 58 + Decode.map Services.keyToType Decode.string
+13
src/App/Sources/Pick.elm
··· 1 + module Sources.Pick exposing (..) 2 + 3 + import Regex 4 + 5 + 6 + isMusicFile : String -> Bool 7 + isMusicFile = 8 + Regex.contains (Regex.regex "\\.(mp3|mp4|m4a)$") 9 + 10 + 11 + selectMusicFiles : List String -> List String 12 + selectMusicFiles = 13 + List.filter isMusicFile
+73 -100
src/App/Sources/Processing.elm
··· 4 4 , takeTreeStep 5 5 , takeTagsStep 6 6 -- 7 - , decodeError 8 7 , findTagsContextSource 9 - , makeTrackUrl 10 8 , tracksFromTagsContext 11 9 ) 12 10 ··· 31 29 import Maybe.Extra as Maybe 32 30 import Response.Ext exposing (do) 33 31 import Sources.Ports as Ports 32 + import Sources.Services as Services 34 33 import Sources.Types exposing (..) 35 34 import Tracks.Types exposing (TagUrls, Track, makeTrack) 36 35 37 36 38 - -- Services 39 - 40 - import Sources.Services.AmazonS3 as AmazonS3 41 - import Sources.Services.Ipfs as Ipfs 42 - 43 - 44 37 -- Settings 45 38 46 39 ··· 57 50 58 51 59 52 60 - -- {public} Steps 53 + -- {public} 1st step 61 54 62 55 63 56 takeFirstStep : Date -> Source -> Cmd Msg ··· 72 65 makeTree initialContext currentDate 73 66 74 67 75 - takeTreeStep : ProcessingContext -> String -> List Track -> CmdWithTimestamp 76 - takeTreeStep context response associatedTracks currentDate = 77 - let 78 - newContext = 79 - handleTreeResponse context response 80 - in 81 - case newContext.treeMarker of 82 - TheBeginning -> 83 - Cmd.none 84 68 85 - InProgress _ -> 86 - makeTree newContext currentDate 69 + -- {public} 2nd step 87 70 88 - TheEnd -> 89 - let 90 - filteredFiles = 91 - case newContext.source.service of 92 - AmazonS3 -> 93 - AmazonS3.postProcessTree newContext.filePaths 94 71 95 - Ipfs -> 96 - Ipfs.postProcessTree newContext.filePaths 72 + takeTreeStep : ProcessingContext -> String -> List Track -> Date -> Cmd Msg 73 + takeTreeStep context response associatedTracks currentDate = 74 + context 75 + |> handleTreeResponse response 76 + |> intoTreeCommand associatedTracks currentDate 97 77 98 - postContext = 99 - { newContext | filePaths = filteredFiles } 78 + 100 79 101 - ( pathsLeft, pathsToRemove, _ ) = 102 - separateTree postContext associatedTracks 103 - in 104 - Cmd.batch 105 - [ postContext 106 - |> selectNonExisting pathsLeft 107 - |> processingContextToTagsContext 108 - |> ProcessTagsStep 109 - |> do 110 - , pathsToRemove 111 - |> ProcessTreeStepRemoveTracks context.source.id 112 - |> do 113 - ] 80 + -- {public} 3rd step 114 81 115 82 116 83 takeTagsStep : Date -> ProcessingContextForTags -> Source -> Maybe (Cmd Msg) ··· 136 103 -- Tree 137 104 138 105 139 - handleTreeResponse : ProcessingContext -> String -> ProcessingContext 140 - handleTreeResponse context response = 106 + handleTreeResponse : String -> ProcessingContext -> ProcessingContext 107 + handleTreeResponse response context = 141 108 let 142 109 parsingFunc = 143 - case context.source.service of 144 - AmazonS3 -> 145 - AmazonS3.parseTreeResponse 146 - 147 - Ipfs -> 148 - Ipfs.parseTreeResponse 110 + Services.parseTreeResponse context.source.service 149 111 150 112 parsedResponse = 151 113 parsingFunc response context.treeMarker ··· 156 118 } 157 119 158 120 121 + intoTreeCommand : List Track -> Date -> ProcessingContext -> Cmd Msg 122 + intoTreeCommand associatedTracks currentDate context = 123 + case context.treeMarker of 124 + TheBeginning -> 125 + Cmd.none 126 + 127 + -- Still busy building the tree, 128 + -- carry on. 129 + -- 130 + InProgress _ -> 131 + makeTree context currentDate 132 + 133 + -- The tree's been build, 134 + -- let's continue to the next step. 135 + -- 136 + TheEnd -> 137 + let 138 + filteredFiles = 139 + Services.postProcessTree context.source.service context.filePaths 140 + 141 + postContext = 142 + { context | filePaths = filteredFiles } 143 + 144 + ( pathsAlreadyExist, pathsToRemove, _ ) = 145 + separateTree postContext associatedTracks 146 + in 147 + Cmd.batch 148 + [ -- Get tags from tracks 149 + postContext 150 + |> selectNonExisting pathsAlreadyExist 151 + |> processingContextToTagsContext 152 + |> ProcessTagsStep 153 + |> do 154 + 155 + -- Remove tracks 156 + , pathsToRemove 157 + |> ProcessTreeStepRemoveTracks context.source.id 158 + |> do 159 + ] 160 + 161 + 159 162 makeTree : ProcessingContext -> CmdWithTimestamp 160 163 makeTree context = 161 - let 162 - fn = 163 - case context.source.service of 164 - AmazonS3 -> 165 - AmazonS3.makeTree 166 - 167 - Ipfs -> 168 - Ipfs.makeTree 169 - in 170 - fn context.source.data context.treeMarker (ProcessTreeStep context) 164 + Services.makeTree 165 + context.source.service 166 + context.source.data 167 + context.treeMarker 168 + (ProcessTreeStep context) 171 169 172 170 173 171 separateTree : ProcessingContext -> List Track -> ( List String, List String, List String ) ··· 186 184 ( [], [], context.filePaths ) 187 185 tracks 188 186 187 + 188 + selectNonExisting : List String -> ProcessingContext -> ProcessingContext 189 + selectNonExisting existingPaths context = 190 + let 191 + notMember = 192 + flip List.notMember 193 + in 194 + { context 195 + | filePaths = List.filter (notMember existingPaths) context.filePaths 196 + } 189 197 190 198 199 + 191 200 -- Tags 192 201 193 202 ··· 195 204 makeTrackUrls currentDate source filePaths = 196 205 let 197 206 maker = 198 - case source.service of 199 - AmazonS3 -> 200 - AmazonS3.makeTrackUrl 201 - 202 - Ipfs -> 203 - Ipfs.makeTrackUrl 207 + Services.makeTrackUrl source.service 204 208 205 209 mapFn = 206 210 \path -> ··· 211 215 List.map mapFn filePaths 212 216 213 217 214 - selectNonExisting : List String -> ProcessingContext -> ProcessingContext 215 - selectNonExisting existingPaths context = 216 - let 217 - notMember = 218 - flip List.notMember 219 - in 220 - { context 221 - | filePaths = List.filter (notMember existingPaths) context.filePaths 222 - } 223 218 224 - 225 - 226 - -- {Public} Utils 227 - 228 - 229 - decodeError : Source -> String -> String 230 - decodeError source = 231 - case source.service of 232 - AmazonS3 -> 233 - AmazonS3.parseErrorResponse 234 - 235 - Ipfs -> 236 - Ipfs.parseErrorResponse 219 + -- {public} Utils 237 220 238 221 239 222 findTagsContextSource : ProcessingContextForTags -> List Source -> Maybe Source ··· 241 224 List.find (.id >> (==) tagsContext.sourceId) 242 225 243 226 244 - makeTrackUrl : Date -> Source -> String -> String 245 - makeTrackUrl currentDate source filePath = 246 - case source.service of 247 - AmazonS3 -> 248 - AmazonS3.makeTrackUrl currentDate source.data Get filePath 249 - 250 - Ipfs -> 251 - Ipfs.makeTrackUrl currentDate source.data Get filePath 252 - 253 - 254 227 tracksFromTagsContext : ProcessingContextForTags -> List Track 255 228 tracksFromTagsContext context = 256 229 context.receivedTags ··· 261 234 262 235 263 236 264 - -- {Private} Utils 237 + -- {private} Utils 265 238 266 239 267 240 processingContextToTagsContext : ProcessingContext -> ProcessingContextForTags
+134
src/App/Sources/Services.elm
··· 1 + module Sources.Services exposing (..) 2 + 3 + {-| Service functions used in other modules. 4 + -} 5 + 6 + import Date exposing (Date) 7 + import Sources.Types exposing (..) 8 + 9 + 10 + -- Services 11 + 12 + import Sources.Services.AmazonS3 as AmazonS3 13 + import Sources.Services.Ipfs as Ipfs 14 + 15 + 16 + -- Functions implemented by services 17 + 18 + 19 + initialData : Service -> SourceData 20 + initialData service = 21 + case service of 22 + AmazonS3 -> 23 + AmazonS3.initialData 24 + 25 + Ipfs -> 26 + Ipfs.initialData 27 + 28 + 29 + makeTrackUrl : Service -> Date -> SourceData -> HttpMethod -> String -> String 30 + makeTrackUrl service = 31 + case service of 32 + AmazonS3 -> 33 + AmazonS3.makeTrackUrl 34 + 35 + Ipfs -> 36 + Ipfs.makeTrackUrl 37 + 38 + 39 + makeTree : Service -> SourceData -> Marker -> (TreeStepResult -> msg) -> Date -> Cmd msg 40 + makeTree service = 41 + case service of 42 + AmazonS3 -> 43 + AmazonS3.makeTree 44 + 45 + Ipfs -> 46 + Ipfs.makeTree 47 + 48 + 49 + parseErrorResponse : Service -> String -> String 50 + parseErrorResponse service = 51 + case service of 52 + AmazonS3 -> 53 + AmazonS3.parseErrorResponse 54 + 55 + Ipfs -> 56 + Ipfs.parseErrorResponse 57 + 58 + 59 + parseTreeResponse : Service -> String -> Marker -> ParsedResponse Marker 60 + parseTreeResponse service = 61 + case service of 62 + AmazonS3 -> 63 + AmazonS3.parseTreeResponse 64 + 65 + Ipfs -> 66 + Ipfs.parseTreeResponse 67 + 68 + 69 + postProcessTree : Service -> List String -> List String 70 + postProcessTree service = 71 + case service of 72 + AmazonS3 -> 73 + AmazonS3.postProcessTree 74 + 75 + Ipfs -> 76 + Ipfs.postProcessTree 77 + 78 + 79 + properties : Service -> List ( String, String, String, Bool ) 80 + properties service = 81 + case service of 82 + AmazonS3 -> 83 + AmazonS3.properties 84 + 85 + Ipfs -> 86 + Ipfs.properties 87 + 88 + 89 + 90 + -- Utility functions 91 + 92 + 93 + makeSource : Service -> SourceData -> Source 94 + makeSource service data = 95 + { id = "change_me_please" 96 + , data = data 97 + , enabled = True 98 + , service = service 99 + } 100 + 101 + 102 + keyToType : String -> Service 103 + keyToType str = 104 + case str of 105 + "AmazonS3" -> 106 + AmazonS3 107 + 108 + "Ipfs" -> 109 + Ipfs 110 + 111 + _ -> 112 + Debug.crash "Invalid Service type string" 113 + 114 + 115 + typeToKey : Service -> String 116 + typeToKey service = 117 + case service of 118 + AmazonS3 -> 119 + "AmazonS3" 120 + 121 + Ipfs -> 122 + "Ipfs" 123 + 124 + 125 + {-| Service labels. 126 + 127 + Maps a service key to a label. 128 + 129 + -} 130 + labels : List ( String, String ) 131 + labels = 132 + [ ( typeToKey AmazonS3, "Amazon S3" ) 133 + , ( typeToKey Ipfs, "IPFS" ) 134 + ]
+2 -2
src/App/Sources/Services/AmazonS3.elm
··· 12 12 import Dict 13 13 import Http 14 14 import Regex 15 + import Sources.Pick 15 16 import Sources.Services.AmazonS3.Parser as Parser 16 17 import Sources.Services.AmazonS3.Presign exposing (..) 17 18 import Sources.Types exposing (..) 18 - import Sources.Utils 19 19 import Time 20 20 21 21 ··· 155 155 -} 156 156 postProcessTree : List String -> List String 157 157 postProcessTree = 158 - Sources.Utils.selectMusicFiles 158 + Sources.Pick.selectMusicFiles
+1 -1
src/App/Sources/Services/Ipfs/Parser.elm
··· 1 1 module Sources.Services.Ipfs.Parser exposing (..) 2 2 3 3 import Json.Decode exposing (..) 4 + import Sources.Pick exposing (isMusicFile) 4 5 import Sources.Services.Ipfs.Marker as Marker 5 6 import Sources.Types exposing (Marker(..), ParsedResponse) 6 - import Sources.Utils exposing (isMusicFile) 7 7 8 8 9 9 -- Tree
+23 -18
src/App/Sources/State.elm
··· 10 10 import Response.Ext exposing (do) 11 11 import Sources.Ports as Ports 12 12 import Sources.Processing as Processing 13 + import Sources.Services as Services exposing (makeSource) 13 14 import Sources.Types exposing (..) 14 15 import Sources.Utils exposing (..) 15 16 import Tracks.Types exposing (emptyTrack) 16 17 import Types as TopLevel 17 - 18 - 19 - -- Services 20 - 21 - import Sources.Services.AmazonS3 as AmazonS3 22 - import Sources.Services.Ipfs as Ipfs 23 18 24 19 25 20 -- 💧 ··· 42 37 43 38 initialSource : Source 44 39 initialSource = 45 - makeSource AmazonS3 AmazonS3.initialData 40 + makeSource AmazonS3 (Services.initialData AmazonS3) 46 41 47 42 48 43 ··· 134 129 [ Processing.takeTreeStep ctx resp associatedTracks model.timestamp ] 135 130 [] 136 131 132 + -- 133 + -- Error 134 + -- 137 135 ProcessTreeStep ctx (Err err) -> 138 136 let 139 137 publicError = ··· 145 143 "Source did not respond (timeout)" 146 144 147 145 BadStatus response -> 148 - Processing.decodeError ctx.source response.body 146 + Services.parseErrorResponse ctx.source.service response.body 149 147 150 148 _ -> 151 149 toString err ··· 158 156 [ do ProcessNextInLine ] 159 157 [] 160 158 159 + -- 160 + -- Remove tracks 161 + -- 161 162 ProcessTreeStepRemoveTracks sourceId filePaths -> 162 163 ($) 163 164 model ··· 212 213 ------------------------------------ 213 214 -- Forms 214 215 ------------------------------------ 216 + -- 217 + -- Set 218 + -- 215 219 SetNewSourceProperty source key value -> 216 220 let 217 221 newSource = ··· 219 223 in 220 224 (!) { model | newSource = newSource } [] 221 225 226 + -- 227 + -- Change 228 + -- 222 229 SetNewSourceType typeString -> 223 230 let 224 - newSource = 225 - case typeString of 226 - "AmazonS3" -> 227 - makeSource AmazonS3 AmazonS3.initialData 228 - 229 - "Ipfs" -> 230 - makeSource Ipfs Ipfs.initialData 231 + service = 232 + Services.keyToType typeString 231 233 232 - _ -> 233 - initialSource 234 + newSource = 235 + makeSource service (Services.initialData service) 234 236 in 235 237 (!) { model | newSource = newSource } [] 236 238 239 + -- 240 + -- Submit 241 + -- 237 242 SubmitNewSourceForm -> 238 243 let 239 244 ns = ··· 243 248 { ns | data = Dict.map (always String.trim) ns.data } 244 249 245 250 newCollection = 246 - setProperSourceId model newSource :: model.collection 251 + (setProperSourceId model newSource) :: model.collection 247 252 in 248 253 ($) 249 254 { model
-13
src/App/Sources/Types.elm
··· 120 120 type Page 121 121 = Index 122 122 | New 123 - 124 - 125 - 126 - -- 🌱 127 - 128 - 129 - makeSource : Service -> SourceData -> Source 130 - makeSource service data = 131 - { id = "change_me_please" 132 - , data = data 133 - , enabled = True 134 - , service = service 135 - }
-15
src/App/Sources/Utils.elm
··· 2 2 3 3 import Date 4 4 import Maybe.Extra as Maybe 5 - import Regex 6 5 import Response.Ext exposing (do) 7 6 import Sources.Encoding 8 7 import Sources.Types exposing (..) ··· 59 58 |> Tracks.Types.SetEnabledSourceIds 60 59 |> TopLevel.TracksMsg 61 60 |> do 62 - 63 - 64 - 65 - -- 🌱 66 - 67 - 68 - isMusicFile : String -> Bool 69 - isMusicFile = 70 - Regex.contains (Regex.regex "\\.(mp3|mp4|m4a)$") 71 - 72 - 73 - selectMusicFiles : List String -> List String 74 - selectMusicFiles = 75 - List.filter isMusicFile
+3 -15
src/App/Sources/View.elm
··· 17 17 import Material.Icons.Notification as Icons 18 18 import Navigation.View as Navigation 19 19 import Routing.Types exposing (Msg(..)) 20 + import Sources.Services as Services 20 21 import Sources.Types as Sources exposing (..) 21 22 import Types as TopLevel exposing (Model, Msg(..)) 22 23 import Utils exposing (cssClass) ··· 28 29 import Form.Styles as FormStyles 29 30 import List.Styles exposing (Classes(..)) 30 31 import Styles exposing (Classes(Button, ContentBox, InsulationContent, Intro)) 31 - 32 - 33 - -- Services 34 - 35 - import Sources.Services.AmazonS3 as AmazonS3 36 - import Sources.Services.Ipfs as Ipfs 37 32 38 33 39 34 -- 🍯 ··· 289 284 ] 290 285 [ text labe ] 291 286 ) 292 - [ ( "AmazonS3", "Amazon S3" ) 293 - , ( "Ipfs", "IPFS" ) 294 - ] 287 + (Services.labels) 295 288 ) 296 289 , Icons.expand_more (Color.greyscale 0.325) 20 297 290 ] ··· 350 343 351 344 renderSourceProperties : Source -> List (Html Sources.Msg) 352 345 renderSourceProperties source = 353 - case source.service of 354 - AmazonS3 -> 355 - List.map (propertyRenderer source) AmazonS3.properties 356 - 357 - Ipfs -> 358 - List.map (propertyRenderer source) Ipfs.properties 346 + List.map (propertyRenderer source) (Services.properties source.service)