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)). 56
91
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, []). 106
107
113
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(_).
127
132
133home(Request) :-
134 redirect_create_admin(Request),
135 reply_decorated_file(html('welcome.html'), Request).
136
137
143
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 159
163
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).
211
215
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 ])).
245
249
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 |}).
323
324
328
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 |}).
396
406
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 ]).
416
417
423
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 [ 472 ]),
473 debug(base_ontologies, '--> Reading from ~w', [In]),
474 xml_read_result_table(In, Rows, _VarNames),
475 maplist(arg(1), Rows, List).
476
480
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 ]).
499
500
504
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 ]))