blob: 920c2bfb2c91d9b75e693a850196177248e20494 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
{ pkgs, getBins, writeExecline, writeHaskellInterpret }:
let
lib = pkgs.lib;
bins = getBins pkgs.httpie [ "http" ];
develop = true;
writeHaskell = name: { interpret ? false, withPackages }:
if interpret
then writeHaskellInterpret name { inherit withPackages; }
else pkgs.writers.writeHaskell name { libraries = withPackages pkgs.haskellPackages; };
# see https://hackage.haskell.org/package/aeson-schema-0.4.1.2/docs/Data-Aeson-Schema-Types.html#t:Schema
# for the schema format.
# The input is a json-encoding of that via quasi-quoter.
json-schema-validator = name: schema: writeHaskell name {
withPackages = hps: [ (pkgs.haskell.lib.doJailbreak (pkgs.haskell.lib.markUnbroken hps.aeson-schema)) hps.aeson ];
interpret = develop;
} ''
{-# language QuasiQuotes #-}
import qualified Data.ByteString.Lazy as BS
import Data.Aeson (eitherDecode')
import Data.Aeson.Schema
import System.Exit (die, exitSuccess)
main :: IO ()
main = do
stdin <- BS.getContents
case (eitherDecode' stdin) of
Left errs -> die errs
Right json -> do
let val = validate mempty schema json
if val == []
then BS.putStr stdin >> exitSuccess
else die (show val)
schema :: Schema ()
schema = [schemaQQ| ${lib.generators.toJSON {} schema} |]
'';
query-lastFm-album = writeExecline "query-lastFm-album" { readNArgs = 2; } [
bins.http
"GET"
"https://ws.audioscrobbler.com/2.0/"
"--"
"api_key==\${1}"
"method==album.search"
"album==\${2}"
"format==json"
];
schema = {
obj = { required ? true }: propsMap: {
type = "object";
inherit required;
properties = propsMap;
};
arr = { required ? true }: itemsSchema: {
type = "array";
inherit required;
items = itemsSchema;
};
};
validator = json-schema-validator "last-fm-album-output" (with schema; obj {} {
results = obj {} {
albummatches = obj {} {
album = arr {} (obj {} {
name = { type = "string"; };
artist = { type = "string"; };
});
};
};
});
query-and-validate = writeExecline "validate-lastfm-album-response" { } [
"pipeline" [ query-lastFm-album "$@" ]
"if" [ validator ]
];
# in validator
in {
inherit query-lastFm-album validator query-and-validate;
}
|