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

Configure Feed

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

at main 146 lines 3.6 kB view raw
1module Sources.Services.Ipfs.Parser exposing (Link, linkDecoder, parseDnsLookup, parseErrorResponse, parseTreeResponse, treeDecoder) 2 3import Dict 4import Json.Decode exposing (..) 5import Sources exposing (SourceData) 6import Sources.Pick exposing (isMusicFile) 7import Sources.Processing exposing (Marker(..), PrepationAnswer, TreeAnswer) 8import Sources.Services.Ipfs.Marker as Marker 9import String.Ext as String 10import Time 11 12 13 14-- PREPARATION 15 16 17parseDnsLookup : String -> Time.Posix -> SourceData -> Marker -> PrepationAnswer Marker 18parseDnsLookup response _ srcData _ = 19 case decodeString dnsResultDecoder response of 20 Ok path -> 21 srcData 22 |> Dict.insert "directoryHashFromDnsLink" (String.chopStart "/ipfs/" path) 23 |> (\s -> { sourceData = s, marker = TheEnd }) 24 25 Err _ -> 26 { sourceData = srcData, marker = TheEnd } 27 28 29dnsResultDecoder : Decoder String 30dnsResultDecoder = 31 oneOf 32 [ at [ "Path" ] string 33 , cloudflareDnsResultDecoder 34 ] 35 36 37cloudflareDnsResultDecoder : Decoder String 38cloudflareDnsResultDecoder = 39 string 40 |> at [ "Answer", "0", "data" ] 41 |> map 42 (\txt -> 43 txt 44 |> String.chopEnd "\"" 45 |> String.chopStart "\"" 46 |> String.chopStart "dnslink=/ipfs/" 47 ) 48 49 50 51-- TREE 52 53 54parseTreeResponse : String -> Marker -> TreeAnswer Marker 55parseTreeResponse response previousMarker = 56 let 57 prefix = 58 case previousMarker of 59 TheBeginning -> 60 "" 61 62 _ -> 63 response 64 |> decodeString prefixDecoder 65 |> Result.map 66 (String.chopStart "/ipfs/" 67 >> String.split "/" 68 >> List.drop 1 69 >> String.join "/" 70 ) 71 |> Result.map 72 (\s -> 73 if String.isEmpty s then 74 "" 75 76 else 77 s ++ "/" 78 ) 79 |> Result.withDefault "" 80 81 links = 82 case decodeString treeDecoder response of 83 Ok l -> 84 l 85 86 Err _ -> 87 [] 88 89 dirs = 90 links 91 |> List.filter (.typ >> (==) 1) 92 |> List.map (\l -> prefix ++ l.name) 93 94 files = 95 links 96 |> List.filter (.typ >> (==) 2) 97 |> List.filter (.name >> isMusicFile) 98 |> List.map (\l -> prefix ++ l.name) 99 in 100 { filePaths = 101 files 102 , marker = 103 previousMarker 104 |> Marker.removeOne 105 |> Marker.concat dirs 106 } 107 108 109prefixDecoder : Decoder String 110prefixDecoder = 111 field "Objects" <| index 0 <| field "Hash" <| string 112 113 114treeDecoder : Decoder (List Link) 115treeDecoder = 116 field "Objects" <| index 0 <| field "Links" <| list linkDecoder 117 118 119 120-- LINKS 121 122 123type alias Link = 124 { hash : String 125 , name : String 126 , typ : Int 127 } 128 129 130linkDecoder : Decoder Link 131linkDecoder = 132 map3 Link 133 (field "Hash" string) 134 (field "Name" string) 135 (field "Type" int) 136 137 138 139-- ERRORS 140 141 142parseErrorResponse : String -> Maybe String 143parseErrorResponse response = 144 response 145 |> decodeString (field "Message" string) 146 |> Result.toMaybe