Mercurial > hg > dbtune-rdf-services
changeset 10:7902f428bc60
Add chord server
author | Chris Cannam |
---|---|
date | Thu, 02 Nov 2017 11:41:02 +0000 |
parents | 42416d3dc358 |
children | ec1540bbf2dc |
files | chord/urispace/README chord/urispace/chord_parser.pl chord/urispace/log.pl chord/urispace/run.pl chord/urispace/urispace.pl |
diffstat | 5 files changed, 576 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chord/urispace/README Thu Nov 02 11:41:02 2017 +0000 @@ -0,0 +1,58 @@ +ChordSpace +========== + +Author: Yves Raimond +Email: yves@dbtune.org + +Centre for Digital Music, Queen Mary University of London + +========= + +This program allows the creation of a service delivering RDF (designed +according to the chord ontology available at http://purl.org/ontology/chord/) +description of chord symbols, formatted using Christopher Harte's notation +(Harte, 2004, ISMIR). + +Then, for example (if the service is available at http://purl.org/ontology/chord/symbol/, which +is the case): + +$ curl -L -H "Accept: application/rdf+xml" "http://purl.org/ontology/chord/symbol/G:min(9)/b3" + + +<?xml version='1.0' encoding='UTF-8'?> +<!DOCTYPE rdf:RDF [ + <!ENTITY ns1 'http://purl.org/ontology/chord/'> + <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'> + <!ENTITY xsd 'http://www.w3.org/2001/XMLSchema#'> +]> + +<rdf:RDF + xmlns:ns1="&ns1;" + xmlns:rdf="&rdf;" + xmlns:xsd="&xsd;" +> +<ns1:Chord rdf:about="&ns1;symbol/G:min(9)/b3"> + <ns1:baseChord rdf:resource="&ns1;min"/> + <ns1:bass> + <ns1:ScaleInterval> + <ns1:degree rdf:datatype="&xsd;int">3</ns1:degree> + <ns1:modifier rdf:resource="&ns1;note/flat"/> + </ns1:ScaleInterval> + </ns1:bass> + <ns1:root rdf:resource="&ns1;note/G"/> + <ns1:with_interval> + <ns1:ScaleInterval> + <ns1:degree rdf:datatype="&xsd;int">9</ns1:degree> + </ns1:ScaleInterval> + </ns1:with_interval> +</ns1:Chord> + +</rdf:RDF> + + +========= + +Dependencies: + * SWI-Prolog and its semweb library + http://www.swi-prolog.org +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chord/urispace/chord_parser.pl Thu Nov 02 11:41:02 2017 +0000 @@ -0,0 +1,382 @@ +:- module(chord_parser,[chord/4,tokenise/2,parse/2]). + +/** + * A SWI DCG for parsing chord textual representation + * as defined in Harte, 2005 (ISMIR proceedings) + * + * Yves Raimond, C4DM, Queen Mary, University of London + */ + +:- use_module(library('semweb/rdf_db')). + + +parse(ChordSymbol,RDF) :- + tokenise(ChordSymbol,Tokens), + phrase(chord(ChordSymbol,RDF2),Tokens), + clean(RDF2,RDF3), + ((add_image_link(RDF3,RDF,[],_, ''),!);(RDF3=RDF)). + + +clean(Description,Rest) :- + member(rdf(A,'http://purl.org/ontology/chord/without_interval',I1),Description), + member(rdf(I1,'http://purl.org/ontology/chord/degree',D),Description), + member(rdf(I1,'http://purl.org/ontology/chord/modifier',M),Description), + select(rdf(A,'http://purl.org/ontology/chord/interval',I2),Description,R1), + select(rdf(I2,'http://purl.org/ontology/chord/degree',D),R1,R2), + select(rdf(I2,'http://purl.org/ontology/chord/modifier',M),R2,Rest),!. +clean(Description,Rest) :- + member(rdf(A,'http://purl.org/ontology/chord/without_interval',I1),Description), + member(rdf(I1,'http://purl.org/ontology/chord/degree',D),Description), + \+member(rdf(I1,'http://purl.org/ontology/chord/modifier',M),Description), + select(rdf(A,'http://purl.org/ontology/chord/interval',I2),Description,R1), + select(rdf(I2,'http://purl.org/ontology/chord/degree',D),R1,Rest), + \+member(rdf(I2,'http://purl.org/ontology/chord/modifier',M),Rest),!. +clean(Description,Description). + + +add_image_link(DescIn, DescOut, IntsIn, IntsOut, _) :- + member(rdf(_, 'http://purl.org/ontology/chord/interval', I), DescIn), + member(rdf(I,'http://purl.org/ontology/chord/degree',literal(type(_,D))),DescIn), + \+member(D, IntsIn), + append([D], IntsIn, I2), + add_image_link(DescIn, DescOut, I2, IntsOut). + +add_image_link(DescIn, DescOut, IntsIn, IntsIn) :- + member(rdf(C,'http://purl.org/ontology/chord/interval',_), DescIn), + %root_for_chord(DescIn,C,Root), + %sort(IntsIn, SortedInts), + %concat_atom(SortedInts,',',Ints), + atom_concat('http://purl.org/ontology/chord/symbol/',Symbol,C), + format(atom(Image),'http://rvw.doc.gold.ac.uk/omras2/widgets/chord/~w',[Symbol]), + append([rdf(C,'http://xmlns.com/foaf/0.1/depiction', Image)],DescIn, DescOut). + + +root_for_chord(RDF, C, Root) :- + member(rdf(C,'http://purl.org/ontology/chord/root',RNote), RDF), + atom_concat('http://purl.org/ontology/chord/note/',Root,RNote). + +root_for_chord(RDF, C, Root) :- + member(rdf(C,'http://purl.org/ontology/chord/root',RNote), RDF), + member(rdf(RNote,'http://purl.org/ontology/chord/natural',Natural), RDF), + atom_concat('http://purl.org/ontology/chord/note/',RootNat,Natural), + member(rdf(RNote,'http://purl.org/ontology/chord/modifier', M), RDF), + modifier(M,MText), + atom_concat(RootNat,MText,Root). + +modifier('http://purl.org/ontology/chord/flat', T) :- T='b'. +modifier('http://purl.org/ontology/chord/sharp', T) :- T='s'. +modifier('http://purl.org/ontology/chord/doubleflat', T) :- T='bb'. +modifier('http://purl.org/ontology/chord/doublesharp', T) :- T='ss'. + + +% DCG + +namespace('http://purl.org/ontology/chord/symbol/'). + +chord(Symbol, + [ + rdf(ID,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/Chord') + , rdf(ID,'http://www.w3.org/2002/07/owl#sameAs','http://purl.org/ontology/chord/noChord') + ] + ) --> + {namespace(NS),atom_concat(NS,Symbol,ID)}, + ['N']. +chord(Symbol, + [ + rdf(ID,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/Chord') + , rdf(ID,'http://purl.org/ontology/chord/root',NoteURI) + , rdf(ID,'http://purl.org/ontology/chord/base_chord',ShorthandURI) + | Tail + ] + ) --> + {namespace(NS),atom_concat(NS,Symbol,ID)}, + note(NoteURI,T1), + [':'], + shorthand(ShorthandURI), + optdegreelist(ID,T2), + optdegree(ID,T3), + !, + {shorthand_rdf(ID,ShorthandURI,ShorthandRDF),flatten([ShorthandRDF,T1,T2,T3],Tail)}. +chord(Symbol, + [ + rdf(ID,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/Chord') + , rdf(ID,'http://purl.org/ontology/chord/root',NoteURI) + | Tail + ] + ) --> + {namespace(NS),atom_concat(NS,Symbol,ID)}, + note(NoteURI,T1), + [':'], + ['('], + degreelist(ID,T2), + [')'], + optdegree(ID,T3),!, + {flatten([T1,T2,T3],Tail)}. +chord(Symbol, + [ + rdf(ID,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/Chord') + , rdf(ID,'http://purl.org/ontology/chord/root',NoteURI) + , rdf(ID,'http://purl.org/ontology/chord/base_chord','http://purl.org/ontology/chord/maj') + | Tail + ] + ) --> + {namespace(NS),atom_concat(NS,Symbol,ID)}, + note(NoteURI,T1), + optdegree(ID,T2),!, + {shorthand_rdf(ID,'http://purl.org/ontology/chord/maj',ShorthandRDF),flatten([T1,T2,ShorthandRDF],Tail)}. +chord([]) --> []. + +note(ID,[ + rdf(ID,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/Note') + , rdf(ID,'http://purl.org/ontology/chord/modifier',Modifier) + , rdf(ID,'http://purl.org/ontology/chord/natural',NoteURI) + ]) --> + {rdf_bnode(ID)}, + natural(NoteURI), + modifier(Modifier),!. +note(NoteURI,[]) --> + natural(NoteURI). + +optdegreelist(ID,Triples) --> + ['('],degreelist(ID,Triples),[')'],!. +optdegreelist(_,[]) --> []. + +optdegree(ID,[rdf(ID,'http://purl.org/ontology/chord/bass',BassNode),rdf(BassNode,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/ScaleInterval')|Triples]) --> + {rdf_bnode(BassNode)}, + ['/'],degree(BassNode,Triples),!. +optdegree(_,[]) --> []. + +natural('http://purl.org/ontology/chord/note/A') --> ['A']. +natural('http://purl.org/ontology/chord/note/B') --> ['B']. +natural('http://purl.org/ontology/chord/note/C') --> ['C']. +natural('http://purl.org/ontology/chord/note/D') --> ['D']. +natural('http://purl.org/ontology/chord/note/E') --> ['E']. +natural('http://purl.org/ontology/chord/note/F') --> ['F']. +natural('http://purl.org/ontology/chord/note/G') --> ['G']. + +modifier('http://purl.org/ontology/chord/doubleflat') --> ['b','b']. +modifier('http://purl.org/ontology/chord/doublesharp') --> ['s','s']. +modifier('http://purl.org/ontology/chord/flat') --> ['b']. +modifier('http://purl.org/ontology/chord/sharp') --> ['s']. %will perhaps have to change it + +degreelist(URI,[ + rdf(URI,'http://purl.org/ontology/chord/without_interval',Interval) + , rdf(Interval,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/ScaleInterval') + | Tail + ]) --> + {rdf_bnode(Interval)}, + ['*'], + degree(Interval,T1), + [','], + degreelist(URI,T2), + {append(T1,T2,Tail)}. +degreelist(URI,[ + rdf(URI,'http://purl.org/ontology/chord/without_interval',Interval) + , rdf(Interval,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/ScaleInterval') + | Tail + ]) --> + ['*'], + {rdf_bnode(Interval)}, + degree(Interval,Tail). +degreelist(URI,[ + rdf(URI,'http://purl.org/ontology/chord/interval',Interval) + , rdf(Interval,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/ScaleInterval') + | Tail + ]) --> + {rdf_bnode(Interval)}, + degree(Interval,T1), + [','], + degreelist(URI,T2), + {append(T1,T2,Tail)}. +degreelist(URI,[ + rdf(URI,'http://purl.org/ontology/chord/interval',Interval) + , rdf(Interval,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/ScaleInterval') + | Tail + ]) --> + {rdf_bnode(Interval)}, + degree(Interval,Tail). + + +degree(IntervalURI,[rdf(IntervalURI,'http://purl.org/ontology/chord/degree',literal(type('http://www.w3.org/2001/XMLSchema#int',Interval)))]) --> + interval(Interval). +%No more than two modifiers - hardcoded +degree(IntervalURI, + [ + rdf(IntervalURI,'http://purl.org/ontology/chord/modifier',ModifierURI) + , rdf(IntervalURI,'http://purl.org/ontology/chord/degree',literal(type('http://www.w3.org/2001/XMLSchema#int',Interval))) + ]) --> + modifier(ModifierURI), + interval(Interval). + + +interval(N) --> + [N], + {member(N,['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24'])}. + +shorthand('http://purl.org/ontology/chord/maj') --> + ['maj']. +shorthand('http://purl.org/ontology/chord/min') --> + ['min']. +shorthand('http://purl.org/ontology/chord/dim') --> + ['dim']. +shorthand('http://purl.org/ontology/chord/aug') --> + ['aug']. +shorthand('http://purl.org/ontology/chord/maj7') --> + ['maj7']. +shorthand('http://purl.org/ontology/chord/min7') --> + ['min7']. +shorthand('http://purl.org/ontology/chord/seventh') --> + ['7']. +shorthand('http://purl.org/ontology/chord/dim7') --> + ['dim7']. +shorthand('http://purl.org/ontology/chord/hdim7') --> + ['hdim7']. +shorthand('http://purl.org/ontology/chord/minmaj7') --> + ['minmaj7']. +shorthand('http://purl.org/ontology/chord/maj6') --> + ['maj6']. +shorthand('http://purl.org/ontology/chord/min6') --> + ['min6']. +shorthand('http://purl.org/ontology/chord/ninth') --> + ['9']. +shorthand('http://purl.org/ontology/chord/maj9') --> + ['maj9']. +shorthand('http://purl.org/ontology/chord/min9') --> + ['min9']. +shorthand('http://purl.org/ontology/chord/sus4') --> + ['sus4']. +shorthand('http://purl.org/ontology/chord/sus2') --> + ['sus2']. + + +shorthand_intervals('http://purl.org/ontology/chord/maj',['1','3','5']). +shorthand_intervals('http://purl.org/ontology/chord/min',['1',flat('3'),'5']). +shorthand_intervals('http://purl.org/ontology/chord/dim',['1',flat('3'),flat('5')]). +shorthand_intervals('http://purl.org/ontology/chord/aug',['1','3',sharp('5')]). +shorthand_intervals('http://purl.org/ontology/chord/maj7',['1','3','5','7']). +shorthand_intervals('http://purl.org/ontology/chord/seventh',['1','3','5',flat('7')]). +shorthand_intervals('http://purl.org/ontology/chord/min7',['1',flat('3'),'5',flat('7')]). +shorthand_intervals('http://purl.org/ontology/chord/dim7',['1',flat('3'),flat('5'),doubleflat('7')]). +shorthand_intervals('http://purl.org/ontology/chord/hdim7',['1',flat('3'),flat('5'),flat('7')]). +shorthand_intervals('http://purl.org/ontology/chord/minmaj7',['1',flat('3'),'5','7']). +shorthand_intervals('http://purl.org/ontology/chord/maj6',['1','3','5','6']). +shorthand_intervals('http://purl.org/ontology/chord/min6',['1',flat('3'),'5','6']). +shorthand_intervals('http://purl.org/ontology/chord/ninth',['1','3','5',flat('7'),'9']). +shorthand_intervals('http://purl.org/ontology/chord/maj9',['1','3','5','7','9']). +shorthand_intervals('http://purl.org/ontology/chord/min9',['1',flat('3'),'5',flat('7'),'9']). +shorthand_intervals('http://purl.org/ontology/chord/sus4',['1','4','5']). +shorthand_intervals('http://purl.org/ontology/chord/sus2',['1','2','5']). + +shorthand_rdf(Chord,Shorthand,RDF) :- + shorthand_intervals(Shorthand,Intervals), + intervals_to_rdf(Chord,Intervals,RDF). + +intervals_to_rdf(Chord,[flat(H)|T],[rdf(Chord,'http://purl.org/ontology/chord/interval',SI),rdf(SI,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/ScaleInterval'),rdf(SI,'http://purl.org/ontology/chord/degree',literal(type('http://www.w3.org/2001/XMLSchema#int',H))),rdf(SI,'http://purl.org/ontology/chord/modifier','http://purl.org/ontology/chord/flat')|T2]) :- + !,rdf_bnode(SI), + intervals_to_rdf(Chord,T,T2). + +intervals_to_rdf(Chord,[doubleflat(H)|T],[rdf(Chord,'http://purl.org/ontology/chord/interval',SI),rdf(SI,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/ScaleInterval'),rdf(SI,'http://purl.org/ontology/chord/degree',literal(type('http://www.w3.org/2001/XMLSchema#int',H))),rdf(SI,'http://purl.org/ontology/chord/modifier','http://purl.org/ontology/chord/doubleflat')|T2]) :- + !,rdf_bnode(SI), + intervals_to_rdf(Chord,T,T2). + +intervals_to_rdf(Chord,[sharp(H)|T],[rdf(Chord,'http://purl.org/ontology/chord/interval',SI),rdf(SI,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/ScaleInterval'),rdf(SI,'http://purl.org/ontology/chord/degree',literal(type('http://www.w3.org/2001/XMLSchema#int',H))),rdf(SI,'http://purl.org/ontology/chord/modifier','http://purl.org/ontology/chord/sharp')|T2]) :- + !,rdf_bnode(SI), + intervals_to_rdf(Chord,T,T2). + +intervals_to_rdf(Chord,[doublesharp(H)|T],[rdf(Chord,'http://purl.org/ontology/chord/interval',SI),rdf(SI,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/ScaleInterval'),rdf(SI,'http://purl.org/ontology/chord/degree',literal(type('http://www.w3.org/2001/XMLSchema#int',H))),rdf(SI,'http://purl.org/ontology/chord/modifier','http://purl.org/ontology/chord/doublesharp')|T2]) :- + !,rdf_bnode(SI), + intervals_to_rdf(Chord,T,T2). + +intervals_to_rdf(Chord,[H|T],[rdf(Chord,'http://purl.org/ontology/chord/interval',SI),rdf(SI,'http://www.w3.org/1999/02/22-rdf-syntax-ns#type','http://purl.org/ontology/chord/ScaleInterval'),rdf(SI,'http://purl.org/ontology/chord/degree',literal(type('http://www.w3.org/2001/XMLSchema#int',H)))|T2]) :- + rdf_bnode(SI), + intervals_to_rdf(Chord,T,T2). + +intervals_to_rdf(_,[],[]). + + + +%tokeniser + +%tokens - the order is actually important (longer first) + +token(minmaj7). +token(maj9). +token(maj7). +token(maj6). +token(maj). +token(min9). +token(min7). +token(min6). +token(min). +token(dim7). +token(dim). +token(aug). +token('7'). +token(hdim7). +token('9'). +token(sus4). +token(sus2). + +token('A'). +token('B'). +token('C'). +token('D'). +token('E'). +token('F'). +token('G'). + +token('10'). +token('11'). +token('12'). +token('13'). +token('14'). +token('15'). +token('16'). +token('17'). +token('18'). +token('19'). +token('1'). +token('20'). +token('21'). +token('22'). +token('23'). +token('24'). +token('2'). +token('3'). +token('4'). +token('5'). +token('6'). +token('7'). +token('8'). +token('9'). + +%token('#'). +token(s). +token(':'). +token('b'). +token('/'). +token('('). +token(')'). +token(','). +token('*'). +token('N'). + + +tokenise(Atom,Tokens) :- + atom_chars(Atom,Chars), + tokenise_l(Chars,Tokens),!. +tokenise_l([],[]) :- !. +tokenise_l(Chars,[Token|Tail]) :- + grab_token(Chars,Token,CharRest), + tokenise_l(CharRest,Tail). + +grab_token([H|T1],Atom,CharRest) :- + token(Token),atom_chars(Token,[H|T2]), + grab_token2(T1,T2,H,Atom,CharRest). +grab_token2(Tail,[],Atom,Atom,Tail) :- !. +grab_token2([H|T1],[H|T2],At,Atom,CharRest) :- + atom_concat(At,H,NewAt), + grab_token2(T1,T2,NewAt,Atom,CharRest). + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chord/urispace/log.pl Thu Nov 02 11:41:02 2017 +0000 @@ -0,0 +1,25 @@ +/** + * Some logging facilities + * Copyright Yves Raimond (c) 2006 + */ +:- module(log,[log/1,log/2]). + + +log_file('server.log'). + +log(MessageFormat,Vars) :- + sformat(String,MessageFormat,Vars), + log(String). + +log(Message) :- + get_time(A), + convert_time(A,Y,M,D,H,Min,S,_), + sformat(Stamp,'<~d/~d/~d-~d:~d:~d> ',[Y,M,D,H,Min,S]), + log_file(File), + open(File,append,Stream,[]), + write(Stream,Stamp), + write(Stream,Message), + write(Stream,'\n'), + close(Stream). + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chord/urispace/run.pl Thu Nov 02 11:41:02 2017 +0000 @@ -0,0 +1,4 @@ +#!/usr/local/bin/swipl -s + +:- [urispace]. +:- init.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chord/urispace/urispace.pl Thu Nov 02 11:41:02 2017 +0000 @@ -0,0 +1,107 @@ +:- module(urispace,[init/0]). + + +:- use_module(library('http/thread_httpd')). +:- use_module(library('semweb/rdf_db')). +:- use_module(log). +:- use_module(chord_parser). + +:- style_check(-discontiguous). + +server(Port, Options) :- + http_server(reply,[ port(Port),timeout(20)| Options]). + + + + +namespace('http://dbtune.org/chord'). + +/** + * Handles documents + */ +reply(Request) :- + member(path(Path),Request), + atom_concat(SymbolT,'.rdf',Path), + atom_concat('/',Symbol,SymbolT), + !, + (parse(Symbol,RDF) -> + ( + current_output(S), + set_stream(S,encoding(utf8)), + format('Content-type: application/rdf+xml; charset=UTF-8~n~n', []), + rdf_write_xml(S,RDF)); + ( + throw(http_reply(server_error('The specified chord symbol is not valid~n~n'))) + )). + +/** + * Sends back towards a png representation of the chord + */ +reply(Request) :- + member(path(Path),Request), + member(accept(AcceptHeader),Request), + log:log('Accept header: ~w ',[AcceptHeader]), + accept_png(AcceptHeader), + !, + atom_concat('/',Symbol,Path), + (parse(Symbol,RDF) -> + ( + member(rdf(_,'http://xmlns.com/foaf/0.1/depiction',Pic),RDF), + throw(http_reply(see_other(Pic),[]))); + ( + throw(http_reply(server_error('The specified chord symbol is not valid~n~n'))) + )). +accept_png('image/png'). + + + +/** + * Sends back 303 to RDF document describing the resource + */ +reply(Request) :- + member(path(Path),Request), + %member(accept(AcceptHeader),Request), + accept_rdf(AcceptHeader), + !, + namespace(NS), + format(atom(Redirect),'~w~w.rdf',[NS,Path]), + log:log('Sending a 303 towards ~w',Redirect), + throw(http_reply(see_other(Redirect),[])). + +accept_rdf('application/rdf+xml'). +accept_rdf('text/xml'). +accept_rdf(AcceptHeader) :- + sub_atom(AcceptHeader,_,_,_,'application/rdf+xml'). +accept_rdf(AcceptHeader) :- + sub_atom(AcceptHeader,_,_,_,'text/xml'). +accept_rdf(_). + + + +/** + * Sends back towards the default representation of the resource + * (usually html) + */ + +html('http://www4.wiwiss.fu-berlin.de/rdf_browser/?browse_uri='). +reply(Request) :- + member(path(Path),Request), + !, + html(Html),namespace(Namespace), + format(atom(Redirect),'~w~w~w',[Html,Namespace,Path]), + log:log('Sending a 303 towards ~w',Redirect), + throw(http_reply(see_other(Redirect),[])). + +port(1111). +init :- + port(P), + server(P,[]), + nl, + writeln(' - Server launched'),nl. + +:- + nl,writeln('----------------'),nl, + writeln(' - Launch the server on port 1111 by running ?-init.'), + nl,writeln('----------------'),nl. + +