annotate cpack/dml/lib/webby.pl @ 0:718306e29690 tip

commiting public release
author Daniel Wolff
date Tue, 09 Feb 2016 21:05:06 +0100
parents
children
rev   line source
Daniel@0 1 /* Part of DML (Digital Music Laboratory)
Daniel@0 2 Copyright 2014-2015 Samer Abdallah, University of London
Daniel@0 3
Daniel@0 4 This program is free software; you can redistribute it and/or
Daniel@0 5 modify it under the terms of the GNU General Public License
Daniel@0 6 as published by the Free Software Foundation; either version 2
Daniel@0 7 of the License, or (at your option) any later version.
Daniel@0 8
Daniel@0 9 This program is distributed in the hope that it will be useful,
Daniel@0 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
Daniel@0 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Daniel@0 12 GNU General Public License for more details.
Daniel@0 13
Daniel@0 14 You should have received a copy of the GNU General Public
Daniel@0 15 License along with this library; if not, write to the Free Software
Daniel@0 16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Daniel@0 17 */
Daniel@0 18
Daniel@0 19 :- module(webby,
Daniel@0 20 [ webcall/3
Daniel@0 21 , restcall/4
Daniel@0 22 , parts_path/2
Daniel@0 23 , http_status/2
Daniel@0 24 ]).
Daniel@0 25 /** <module> Web API tools
Daniel@0 26
Daniel@0 27 ---+++ Types
Daniel@0 28 ==
Daniel@0 29 web_reader ---> json(-D:dict)
Daniel@0 30 ; nil.
Daniel@0 31
Daniel@0 32 web_method ---> get(+Params:list(param))
Daniel@0 33 ; post(+D:post_data)
Daniel@0 34 ; put(+D:post_data)
Daniel@0 35 ; delete(+D:post_data)
Daniel@0 36 .
Daniel@0 37
Daniel@0 38 post_data ---> form(list(param))
Daniel@0 39 ; json(dict)
Daniel@0 40 .
Daniel@0 41
Daniel@0 42 param ---> atom=_.
Daniel@0 43 ==
Daniel@0 44 */
Daniel@0 45
Daniel@0 46 :- multifile read_reply/2.
Daniel@0 47
Daniel@0 48 :- use_module(library(http/http_open)).
Daniel@0 49 :- use_module(library(http/http_header)).
Daniel@0 50 :- use_module(library(http/json)).
Daniel@0 51
Daniel@0 52 parts_path(Parts,Path) :-
Daniel@0 53 atomics_to_string([''|Parts],"/",Path).
Daniel@0 54
Daniel@0 55 %% webcall(+URL:url_spec, +Opt:options, +R:web_reader) is det.
Daniel@0 56 webcall(URL,Opts,Reader) :-
Daniel@0 57 debug(webby,"HTTP connecting to ~w, ~w",[URL,Opts]),
Daniel@0 58 setup_call_cleanup(
Daniel@0 59 http_open(URL,In,[status_code(SC)|Opts]),
Daniel@0 60 ( set_stream(In,encoding(utf8)), % !
Daniel@0 61 ( between(200,299,SC) -> read_reply(Reader,In)
Daniel@0 62 ; read_stream_to_codes(In,ErrorDoc),
Daniel@0 63 throw(http_bad_status(SC,codes(ErrorDoc))))),
Daniel@0 64 close(In)).
Daniel@0 65
Daniel@0 66 read_reply(json(Dict),In) :- json_read_dict(In,Dict).
Daniel@0 67 read_reply(nil,_).
Daniel@0 68
Daniel@0 69 %% post_data(+D:post_data,-D2:post_data) is det.
Daniel@0 70 post_data(json(Dict),codes('application/json',Codes)) :- !, atom_json_dict(Codes,Dict,[as(codes)]).
Daniel@0 71 post_data(Data,Data).
Daniel@0 72
Daniel@0 73 %% restcall(+M:web_method, +R:web_reader, +URL:url_spec, +Opts:options) is det.
Daniel@0 74 restcall(get(Params), Rdr, URL, Opts) :- webcall([search(Params)|URL], Opts, Rdr).
Daniel@0 75 restcall(post(D), Rdr, URL, Opts) :- post_data(D,Data), webcall(URL, [method(post),post(Data)|Opts], Rdr).
Daniel@0 76 restcall(delete(D), Rdr, URL, Opts) :- post_data(D,Data), webcall(URL, [method(delete),post(Data)|Opts], Rdr).
Daniel@0 77 restcall(put(D), Rdr, URL, Opts) :- post_data(D,Data), webcall(URL, [method(put),post(Data)|Opts], Rdr).
Daniel@0 78
Daniel@0 79 status_meaning(200,"OK").
Daniel@0 80 status_meaning(201,"Created").
Daniel@0 81 status_meaning(204,"No content").
Daniel@0 82 status_meaning(304,"Not modified").
Daniel@0 83 status_meaning(400,"Bad request").
Daniel@0 84 status_meaning(401,"Unauthorised").
Daniel@0 85 status_meaning(403,"Forbidden").
Daniel@0 86 status_meaning(404,"Not found").
Daniel@0 87 status_meaning(405,"Method not allowed").
Daniel@0 88 status_meaning(429,"Too many requests").
Daniel@0 89 status_meaning(500,"Internal server error").
Daniel@0 90 status_meaning(502,"Bad gateway").
Daniel@0 91 status_meaning(503,"Service unavailable").
Daniel@0 92
Daniel@0 93 http_status(Code,Meaning) :- status_meaning(Code,Meaning), !.
Daniel@0 94 http_status(_,"<Unrecognised status>").
Daniel@0 95
Daniel@0 96 prolog:message(http_bad_status(SC,codes(Doc))) -->
Daniel@0 97 {http_status(SC,Meaning)},
Daniel@0 98 ["HTTP call returned status ~w (~w)."-[SC,Meaning]],
Daniel@0 99 ["Reply document was |~s|"-[Doc]].