View source with raw comments or as raw
    1/*  Part of ClioPatria SeRQL and SPARQL server
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (c)  2010-2018, University of Amsterdam,
    7                              VU University Amsterdam
    8    All rights reserved.
    9
   10    Redistribution and use in source and binary forms, with or without
   11    modification, are permitted provided that the following conditions
   12    are met:
   13
   14    1. Redistributions of source code must retain the above copyright
   15       notice, this list of conditions and the following disclaimer.
   16
   17    2. Redistributions in binary form must reproduce the above copyright
   18       notice, this list of conditions and the following disclaimer in
   19       the documentation and/or other materials provided with the
   20       distribution.
   21
   22    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   23    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   24    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   25    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   26    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   27    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   28    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   29    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   30    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   32    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   33    POSSIBILITY OF SUCH DAMAGE.
   34*/
   35
   36:- module(cpa_user, []).   37
   38:- use_module(rdfql(serql_xml_result)).   39:- use_module(library(http/http_open)).   40:- use_module(library(http/http_path)).   41:- use_module(library(http/html_head)).   42:- use_module(library(http/html_write)).   43:- use_module(library(http/js_write)).   44:- use_module(library(http/http_dispatch)).   45:- use_module(library(http/http_host)).   46:- use_module(library(http/cp_jquery)).   47:- use_module(api(rdflib)).   48:- use_module(user(user_db)).   49:- use_module(library(debug)).   50:- use_module(components(server_statistics)).   51:- use_module(components(query)).   52:- use_module(components(basics)).   53:- use_module(library(semweb/rdf_db)).   54:- use_module(library(semweb/rdf_library)).   55:- use_module(library(occurs)).

This module contains the main front-end of ClioPatria. It notably provides the HTTP-handlers for / and /home:

/
This handler, with id=root, redirects either to /home (id=home) or to id=create_admin. The latter is issued if there is no initialised user-db.
/home
Provides the default welcome page of ClioPatria.

If one develops an application on top of ClioPatria, it is adviced to redefine the handler for home, as in:

:- http_handler('/welcome', home, []).

home(Request) :-
    ...

If the application wants to provide a link to the generic ClioPatria administrative interface, it can do so by linking to the id=admin, as in:

    ...,
    { http_link_to_id(admin, [], AdminRef) },
    html(a(href(AdminRef), admin)),
    ...

*/

   92:- http_handler(root('.'),                           root,
   93                [ priority(-100) ]).   94:- http_handler(cliopatria(home),                    home,
   95                [ priority(-100) ]).   96:- http_handler(cliopatria(admin),                   home,
   97                [ id(admin) ]).   98:- http_handler(cliopatria('user/query'),            query_form,
   99                [id(sparql_query_form)]).  100:- http_handler(cliopatria('user/statistics'),       statistics,              []).  101:- http_handler(cliopatria('user/loadFile'),         load_file_form,          []).  102:- http_handler(cliopatria('user/loadURL'),          load_url_form,           []).  103:- http_handler(cliopatria('user/loadLibraryRDF'),   load_library_rdf_form,   []).  104:- http_handler(cliopatria('user/clearRepository'),  clear_repository_form,   []).  105:- http_handler(cliopatria('user/removeStatements'), remove_statements_form,  []).
 root(+Request)
Default ClioPatria handler for /. The default handler redirects to id=home, unless the use-info is not initialised. in that case it redirects to id=create_admin.
  114root(Request) :-
  115    redirect_create_admin(Request),
  116    http_redirect(moved_temporary,
  117                  location_by_id(home),
  118                  Request).
  119
  120redirect_create_admin(Request) :-
  121    \+ current_user(_),
  122    !,
  123    http_redirect(moved_temporary,
  124                  location_by_id(create_admin),
  125                  Request).
  126redirect_create_admin(_).
 home(+Request)
Reply with the normal welcome page. The welcome page is a decorated version of html('welcome.html').
  133home(Request) :-
  134    redirect_create_admin(Request),
  135    reply_decorated_file(html('welcome.html'), Request).
 reply_decorated_file(+Alias, +Request) is det
Present an HTML file embedded using the server styling. This is achieved by parsing the HTML and passing the parsed DOM to reply_html_page/3.
  144reply_decorated_file(Alias, _Request) :-
  145    absolute_file_name(Alias, Page, [access(read)]),
  146    load_html_file(Page, DOM),
  147    contains_term(element(title, _, Title), DOM),
  148    contains_term(element(body, _, Body), DOM),
  149    Style = element(style, _, _),
  150    findall(Style, sub_term(Style, DOM), Styles),
  151    append(Styles, Body, Content),
  152    reply_html_page(cliopatria(html_file),
  153                    title(Title), Content).
  154
  155
  156                 /*******************************
  157                 *          STATISTICS          *
  158                 *******************************/
 statistics(+Request)
Provide elementary statistics on the server.
  164statistics(Request) :-
  165    http_current_host(Request, Host, _Port, [global(true)]),
  166    reply_html_page(cliopatria(default),
  167                    title('RDF statistics'),
  168                    [ div(id('rdf-statistics'),
  169                          [ h1([id(stattitle)], ['RDF statistics for ', Host]),
  170                            ol([id(toc)],
  171                               [ li(a(href('#ntriples'),    'Triples in database')),
  172                                 li(a(href('#callstats'),   'Call statistics')),
  173                                 li(a(href('#sessions'),    'Active sessions')),
  174                                 li(a(href('#serverstats'), 'Server statistics'))
  175                               ]),
  176                            h2([id(ntriples)], 'Triples in database'),
  177                            \triple_statistics,
  178                            h2([id(callstats)],'Call statistics'),
  179                            \rdf_call_statistics_table,
  180                            h2([id(sessions)], 'Active sessions'),
  181                            \http_session_table,
  182                            h2([id(serverstats)], 'Server statistics'),
  183                            h3('Static workers and statistics:'),
  184                            \http_server_statistics,
  185                            h3('Defined dynamic worker pools:'),
  186                            \http_server_pool_table
  187                          ])
  188                    ]).
  189
  190
  191triple_statistics -->
  192    { rdf_statistics(triples(Total)),
  193      graph_count(Count),
  194      http_link_to_id(list_graphs, [], ListGraphs)
  195    },
  196    html(p([ 'The RDF store contains ', \n(human, Total), ' triples in ',
  197             \n(human, Count), ' ', a(href(ListGraphs), graphs),
  198             \using_core])).
  199
  200:- if((rdf_version(V),V<30000)).  201using_core -->
  202    { rdf_statistics(core(Core)) },
  203    !,
  204    html([', using ', \n(human, Core), 'b memory']).
  205:- endif.  206using_core -->
  207    [].
  208
  209graph_count(Count) :-
  210    aggregate_all(count, rdf_graph(_), Count).
 query_form(+Request)
Provide a page for issuing a SELECT query.
  216query_form(_Request) :-
  217    reply_html_page(cliopatria(default),
  218                    title('Specify a query'),
  219                    [ \query_form([]),
  220                      \query_docs,
  221                      \warn_interactive
  222                    ]).
  223
  224
  225
  226warn_interactive -->
  227    { http_location_by_id(sparql_query, HREF),
  228      SparqlAPI = 'http://www.w3.org/TR/rdf-sparql-protocol/'
  229    },
  230    html([ br(clear(all)),
  231           p(class(footnote),
  232             [ 'This form is to test SPARQL queries ', i(interactively), '. ',
  233               'Machines should use ', b([HREF,'?query=...']),
  234               ', which provides a ',
  235               a(href(SparqlAPI), 'SPARQL compliant HTTP API'), '.'
  236             ])
  237         ]).
  238
  239query_docs -->
  240    html(ul([ li(a(href('http://www.w3.org/TR/rdf-sparql-query/'),
  241                   'SPARQL Documentation')),
  242              li(a(href('http://rdf4j.org/'),
  243                   'Sesame and SeRQL site'))
  244            ])).
 load_file_form(+Request)
Provide a form for uploading triples from a local file.
  250load_file_form(Request) :-
  251    authorized(write(default, load(posted))),
  252    reply_html_page(cliopatria(default),
  253                    title('Upload RDF'),
  254                    [ h1('Upload an RDF document'),
  255
  256                      \explain_file_form,
  257
  258                      form([ action(location_by_id(upload_data)),
  259                             method('POST'),
  260                             enctype('multipart/form-data')
  261                           ],
  262                           [ \hidden(resultFormat, html),
  263                             table(class(form),
  264                                   [tr([ th(class(label), 'File:'),
  265                                         td(input([ name(data),
  266                                                    id(filename),
  267                                                    type(file),
  268                                                    size(50)
  269                                                  ]))
  270                                       ]),
  271                                    tr([ th(class(label), 'Graph:'),
  272                                         td(input([ name(baseURI),
  273                                                    id(namedgraph),
  274                                                    size(50)
  275                                                  ]))
  276                                       ]),
  277                                    tr(class(buttons),
  278                                       [ th([align(right), colspan(2)],
  279                                            input([ type(submit),
  280                                                    value('Upload now')
  281                                                  ]))
  282                                       ])
  283                                   ])
  284                           ]),
  285                      \graph_script(Request)
  286                    ]).
  287
  288explain_file_form -->
  289    html({|html||
  290<p>Upload RDF to the ClioPatria triple store. The uploaded file may
  291contain <a href="http://www.w3.org/TR/REC-rdf-syntax/">RDF/XML</a>, <a
  292href="http://www.w3.org/TR/turtle/">Turtle</a> or <a
  293href="http://www.w3.org/TR/n-triples/">ntriples</a>. The file is
  294processed using <a href="http://www.libarchive.org/"> libarchive</a>,
  295which implies it can be a (nested) archive and may optionally be
  296compressed. </p>
  297
  298<p>
  299Alternatively you can use <a href="loadURL">loadURL</a> to load data from a web server.
  300</p>
  301         |}).
  302
  303
  304graph_script(Request) -->
  305    { http_public_host_url(Request, Host),
  306      http_absolute_location(root(data/uploaded), Location, []),
  307      string_concat(Host, Location, URL)
  308    },
  309    html_requires(jquery),
  310    js_script({|javascript(URL)||
  311$(function() {
  312  if ( $("#filename").val() ) {
  313    $("#namedgraph").val(URL+"/"+$("#filename").val());
  314  }
  315
  316  $("#filename").on("change", function(ev) {
  317    var filename = $(ev.target).val();
  318    console.log("Changed file", filename);
  319    $("#namedgraph").val(URL+"/"+filename);
  320  });
  321});
  322              |}).
 load_url_form(+Request)
Provide a form for uploading triples from a URL.
  329load_url_form(_Request) :-
  330    reply_html_page(cliopatria(default),
  331                    title('Load RDF from HTTP server'),
  332                    [ h1('Load RDF from HTTP server'),
  333
  334                      \explain_url_form,
  335
  336                      form([ action(location_by_id(upload_url)),
  337                             method('GET')
  338                           ],
  339                           [ \hidden(resultFormat, html),
  340                             table(class(form),
  341                                   [tr([ th(class(label), 'URL:'),
  342                                         td(input([ name(url),
  343                                                    id(url),
  344                                                    value('http://'),
  345                                                    size(50)
  346                                                  ]))
  347                                       ]),
  348                                    tr([ th(class(label), 'Graph:'),
  349                                         td(input([ name(baseURI),
  350                                                    id(namedgraph),
  351                                                    value('http://'),
  352                                                    size(50)
  353                                                  ]))
  354                                       ]),
  355                                    tr(class(buttons),
  356                                       [ td([align(right), colspan(2)],
  357                                            input([ type(submit),
  358                                                    value('Load RDF')
  359                                                  ]))
  360                                       ])
  361                                   ])
  362                           ]),
  363                      \url_graph_script
  364                    ]).
  365
  366
  367url_graph_script -->
  368    html_requires(jquery),
  369    js_script({|javascript||
  370$(function() {
  371  $("#url").on("change keyup", function(ev) {
  372    var url = $(ev.target).val();
  373    $("#namedgraph").val(url);
  374  });
  375});
  376              |}).
  377
  378
  379explain_url_form -->
  380    html({|html||
  381
  382<p>Download RDF from an URL and insert it into the ClioPatria triple
  383store. The downloaded document may contain <a
  384href="http://www.w3.org/TR/REC-rdf-syntax/">RDF/XML</a>, <a
  385href="http://www.w3.org/TR/turtle/">Turtle</a> or <a
  386href="http://www.w3.org/TR/n-triples/">ntriples</a>. The file is
  387processed using <a href="http://www.libarchive.org/"> libarchive</a>,
  388which implies it can be a (nested) archive and may optionally be
  389compressed. </p>
  390
  391<p>
  392Alternatively you can use <a href="loadFile">loadFile</a> to upload
  393a file through your browser.
  394</p>
  395         |}).
 load_library_rdf_form(+Request)
Provide a form for loading an ontology from the library. Libraries are made available through the file search path ontology. Directories found through this alias are searched recursively for files named Manifest.ttl.
See also
- file_search_path/2
- rdf_attach_library/1.
  407load_library_rdf_form(Request) :-
  408    authorized(read(status, listBaseOntologies)),
  409    get_base_ontologies(Request, Ontologies),
  410    reply_html_page(cliopatria(default),
  411                    title('Load server-side RDF library'),
  412                    [ h1('Load a registered RDF library'),
  413                      p('Select a resource from the registered libraries'),
  414                      \load_base_ontology_form(Ontologies)
  415                    ]).
 load_base_ontology_form(+Ontologies)//
HTML component that emits a form to load a base-ontology and its dependencies. Ontologies is a list of ontology-identifiers as used by rdf_load_library/1.
  424load_base_ontology_form(Ontologies) -->
  425    html(form([ action(location_by_id(load_library_ontology)),
  426                method('GET')
  427              ],
  428              [ \hidden(resultFormat, html),
  429                table(class(form),
  430                      [ tr([ th('Ontology:'),
  431                             td(select(name(ontology),
  432                                       [ option([], '')
  433                                       | \emit_base_ontologies(Ontologies)
  434                                       ]))
  435                           ]),
  436                        tr(class(buttons),
  437                           td([colspan(2), align(right)],
  438                              input([ type(submit),
  439                                      value('Load')
  440                                    ])))
  441                      ])
  442              ])).
  443
  444
  445emit_base_ontologies([]) -->
  446    [].
  447emit_base_ontologies([H|T]) -->
  448    (   { rdf_library_index(H, title(Title)) }
  449    ->  html(option([value(H)], [H, ' -- ', Title]))
  450    ;   html(option([value(H)], H))
  451    ),
  452    emit_base_ontologies(T).
  453
  454
  455get_base_ontologies(_Request, List) :-
  456    catch(findall(O, library_ontology(O), List0), _, fail),
  457    !,
  458    sort(List0, List).
  459get_base_ontologies(Request, List) :-
  460    http_current_host(Request, Host, Port, []),
  461    http_location_by_id(list_base_ontologies, ListBaseOntos),
  462    debug(base_ontologies, 'Opening http://~w:~w~w',
  463          [Host, Port, ListBaseOntos]),
  464    http_open([ protocol(http),
  465                host(Host),
  466                port(Port),
  467                path(ListBaseOntos),
  468                search([resultFormat(xml)])
  469              ],
  470              In,
  471              [ % request_header('Cookie', Cookie)
  472              ]),
  473    debug(base_ontologies, '--> Reading from ~w', [In]),
  474    xml_read_result_table(In, Rows, _VarNames),
  475    maplist(arg(1), Rows, List).
 clear_repository_form(+Request)
HTTP handle presenting a form to clear the repository.
  481clear_repository_form(_Request) :-
  482    reply_html_page(cliopatria(default),
  483                    title('Clear triple store'),
  484                    [ h1('Clear entire repository'),
  485
  486                      p(['This operation removes ', b(all), ' triples from \c
  487                          the RDF store.']),
  488
  489                      form([ action(location_by_id(clear_repository)),
  490                             method('GET')
  491                           ],
  492                           [ \hidden(repository, default),
  493                             \hidden(resultFormat, html),
  494                             input([ type(submit),
  495                                     value('Clear repository now')
  496                                   ])
  497                           ])
  498                    ]).
 remove_statements_form(+Request)
HTTP handler providing a form to remove RDF statements.
  505remove_statements_form(_Request) :-
  506    reply_html_page(cliopatria(default),
  507                    title('Remove triples from store'),
  508                    [ h1('Remove statements'),
  509
  510                      p(['Remove matching triples from the database.  The three ',
  511                         'fields are in ntriples/Turtle notation.  Omitted fields ',
  512                         'match any value.'
  513                        ]),
  514
  515                      \remove_statements_form
  516                    ]).
  517
  518remove_statements_form -->
  519    html(form([ action(location_by_id(remove_statements)),
  520                method('GET')
  521              ],
  522              [ \hidden(repository, default),
  523                \hidden(resultFormat, html),
  524                table([ class(form)
  525                      ],
  526                      [ tr([ th(class(label), 'Subject:'),
  527                             td(input([ name(subject),
  528                                        size(50)
  529                                      ]))
  530                           ]),
  531                        tr([ th(class(label), 'Predicate:'),
  532                             td(input([ name(predicate),
  533                                        size(50)
  534                                      ]))
  535                           ]),
  536                        tr([ th(class(label), 'Object:'),
  537                             td(input([ name(object),
  538                                        size(50)
  539                                      ]))
  540                           ]),
  541                        tr(class(buttons),
  542                           [ td([ align(right),
  543                                  colspan(2)
  544                                ],
  545                                input([ type(submit),
  546                                        value('Remove')
  547                                      ]))
  548                           ])
  549                      ])
  550              ]))