annotate jamendo/sparql-archived/SeRQL/http_user.pl @ 27:d95e683fbd35 tip

Enable CORS on urispace redirects as well
author Chris Cannam
date Tue, 20 Feb 2018 14:52:02 +0000
parents df9685986338
children
rev   line source
Chris@0 1 /* $Id$
Chris@0 2
Chris@0 3 Part of SWI-Prolog
Chris@0 4
Chris@0 5 Author: Jan Wielemaker
Chris@0 6 E-mail: wielemak@science.uva.nl
Chris@0 7 WWW: http://www.swi-prolog.org
Chris@0 8 Copyright (C): 1985-2007, University of Amsterdam
Chris@0 9
Chris@0 10 This program is free software; you can redistribute it and/or
Chris@0 11 modify it under the terms of the GNU General Public License
Chris@0 12 as published by the Free Software Foundation; either version 2
Chris@0 13 of the License, or (at your option) any later version.
Chris@0 14
Chris@0 15 This program is distributed in the hope that it will be useful,
Chris@0 16 but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 18 GNU General Public License for more details.
Chris@0 19
Chris@0 20 You should have received a copy of the GNU Lesser General Public
Chris@0 21 License along with this library; if not, write to the Free Software
Chris@0 22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Chris@0 23
Chris@0 24 As a special exception, if you link this library with other files,
Chris@0 25 compiled with a Free Software compiler, to produce an executable, this
Chris@0 26 library does not by itself cause the resulting executable to be covered
Chris@0 27 by the GNU General Public License. This exception does not however
Chris@0 28 invalidate any other reasons why the executable file might be covered by
Chris@0 29 the GNU General Public License.
Chris@0 30 */
Chris@0 31
Chris@0 32 :- module(http_user, []).
Chris@0 33
Chris@0 34 :- use_module(server).
Chris@0 35 :- use_module(xml_result).
Chris@0 36 :- use_module(library('http/http_open')).
Chris@0 37 :- use_module(library('http/thread_httpd')).
Chris@0 38 :- use_module(library('http/html_write')).
Chris@0 39 :- use_module(library('http/mimetype')).
Chris@0 40 :- use_module(library('http/http_dispatch')).
Chris@0 41 :- use_module(library('http/http_session')).
Chris@0 42 :- use_module(http_data).
Chris@0 43 :- use_module(library(settings)).
Chris@0 44 :- use_module(user_db).
Chris@0 45 :- use_module(library(debug)).
Chris@0 46 :- use_module(http_admin).
Chris@0 47 :- use_module(library('semweb/rdf_db')).
Chris@0 48 :- use_module(library(url)).
Chris@0 49
Chris@0 50 :- http_handler('/', home, []).
Chris@0 51 :- http_handler('/sidebar.html', sidebar, []).
Chris@0 52 :- http_handler('/welcome.html', welcome, []).
Chris@0 53 :- http_handler('/user/statistics', statistics, []).
Chris@0 54 :- http_handler('/user/construct', construct_form, []).
Chris@0 55 :- http_handler('/user/query', query_form, []).
Chris@0 56 :- http_handler('/user/select', select_form, []).
Chris@0 57 :- http_handler('/user/loadFile', load_file_form, []).
Chris@0 58 :- http_handler('/user/loadURL', load_url_form, []).
Chris@0 59 :- http_handler('/user/loadBaseOntology', load_base_ontology_form, []).
Chris@0 60 :- http_handler('/user/clearRepository', clear_repository_form, []).
Chris@0 61 :- http_handler('/user/removeStatements', remove_statements_form, []).
Chris@0 62
Chris@0 63 :- http_handler('/documentation.html',
Chris@0 64 http_reply_file(serql('serql.html'), []), []).
Chris@0 65 :- http_handler('/rdfql.css',
Chris@0 66 http_reply_file(serql('rdfql.css'), []), []).
Chris@0 67
Chris@0 68
Chris@0 69 %% home(+Request)
Chris@0 70 %
Chris@0 71 % Print the home page.
Chris@0 72 %
Chris@0 73 % NOTE: a frameset must _not_ have a body!
Chris@0 74
Chris@0 75 home(_Request) :-
Chris@0 76 ( setting(serql_parms:title, Title)
Chris@0 77 -> true
Chris@0 78 ; Title = 'SWI-Prolog Semantic Web Server'
Chris@0 79 ),
Chris@0 80 phrase(html([ head(title(Title)),
Chris@0 81 frameset([cols('200,*')],
Chris@0 82 [ frame([ src('sidebar.html'),
Chris@0 83 name(sidebar)
Chris@0 84 ]),
Chris@0 85 frame([ src('welcome.html'),
Chris@0 86 name(main)
Chris@0 87 ])
Chris@0 88 ])
Chris@0 89 ]), HTML),
Chris@0 90 format('Content-type: text/html~n~n'),
Chris@0 91 print_html(HTML).
Chris@0 92
Chris@0 93 %% sidebar(+Request)
Chris@0 94 %
Chris@0 95 % HTTP handler to emit the left bar menu (frame content).
Chris@0 96
Chris@0 97 sidebar(_Request) :-
Chris@0 98 findall(Path-Label, action(Path, Label), Actions),
Chris@0 99 reply_page('Sidebar',
Chris@0 100 [ \current_user,
Chris@0 101 hr([]),
Chris@0 102 \action('welcome.html', 'Home'),
Chris@0 103 \cond_action(login),
Chris@0 104 \cond_action(logout),
Chris@0 105 \cond_action(change_password),
Chris@0 106 hr([])
Chris@0 107 | \actions(Actions)
Chris@0 108 ]).
Chris@0 109
Chris@0 110 :- multifile
Chris@0 111 serql_http:sidebar_menu/2.
Chris@0 112
Chris@0 113 action('user/query', 'Query database').
Chris@0 114 action(-,-).
Chris@0 115 action('user/loadFile', 'Upload a file').
Chris@0 116 action('user/loadURL', 'Load from HTTP').
Chris@0 117 action('user/loadBaseOntology', 'Load base ontology').
Chris@0 118 action(-,-).
Chris@0 119 action('user/removeStatements', 'Remove statements').
Chris@0 120 action('user/clearRepository', 'Clear the repository').
Chris@0 121 action(-,-).
Chris@0 122 action('user/statistics', 'Statistics').
Chris@0 123 action('admin/listUsers', 'Users ...').
Chris@0 124 action('admin/settings', 'Settings ...').
Chris@0 125 action('documentation.html', 'Documentation').
Chris@0 126 action(Path, Label) :-
Chris@0 127 serql_http:sidebar_menu(Path, Label).
Chris@0 128
Chris@0 129
Chris@0 130 current_user -->
Chris@0 131 { catch(logged_on(User), _, fail),
Chris@0 132 ( user_property(User, realname(RealName))
Chris@0 133 -> true
Chris@0 134 ; RealName = User
Chris@0 135 ),
Chris@0 136 user_property(User, url(URL))
Chris@0 137 }, !,
Chris@0 138 html(center(i(a([target(main), href(URL)], RealName)))).
Chris@0 139 current_user -->
Chris@0 140 html(center(font(color(red), i('<not logged in>')))).
Chris@0 141
Chris@0 142 cond_action(login) -->
Chris@0 143 ( { catch(logged_on(_User), _, fail)
Chris@0 144 }
Chris@0 145 -> []
Chris@0 146 ; action('user/form/login', 'Login')
Chris@0 147 ).
Chris@0 148 cond_action(logout) -->
Chris@0 149 ( { catch(logged_on(_User), _, fail)
Chris@0 150 }
Chris@0 151 -> action('user/logout', 'Logout')
Chris@0 152 ; []
Chris@0 153 ).
Chris@0 154 cond_action(change_password) -->
Chris@0 155 ( { catch(logged_on(_User), _, fail)
Chris@0 156 }
Chris@0 157 -> action('admin/form/changePassword', 'Change password')
Chris@0 158 ; []
Chris@0 159 ).
Chris@0 160
Chris@0 161 %% welcome(+Request)
Chris@0 162 %
Chris@0 163 % Reply with the normal welcome page. If there is no user we
Chris@0 164 % reply with the `create admin user' page.
Chris@0 165
Chris@0 166 welcome(Request) :-
Chris@0 167 ( current_user(_)
Chris@0 168 -> http_reply_file(serql('welcome.html'), [cache(false)], Request)
Chris@0 169 ; throw(http_reply(moved_temporary('admin/form/createAdmin')))
Chris@0 170 ).
Chris@0 171
Chris@0 172
Chris@0 173 /*******************************
Chris@0 174 * STATISTICS *
Chris@0 175 *******************************/
Chris@0 176
Chris@0 177 %% statistics(+Request)
Chris@0 178 %
Chris@0 179 % Provide elementary statistics on the server.
Chris@0 180
Chris@0 181 statistics(_Request) :-
Chris@0 182 findall(File-Triples,
Chris@0 183 rdf_statistics(triples_by_file(File, Triples)),
Chris@0 184 UnsortedPairs),
Chris@0 185 findall(Index-Count,
Chris@0 186 rdf_statistics(lookup(Index, Count)),
Chris@0 187 Lookup),
Chris@0 188 rdf_statistics(triples(Total)),
Chris@0 189 rdf_statistics(core(Core)),
Chris@0 190 sort(UnsortedPairs, Pairs),
Chris@0 191 reply_page('RDF statistics',
Chris@0 192 [ h1([id(stattitle)], 'RDF statistics'),
Chris@0 193 ol([id(toc)],
Chris@0 194 [
Chris@0 195 li(a([href('#ntriples')],'Triples in database')),
Chris@0 196 li(a([href('#callstats')],'Call statistics')),
Chris@0 197 li(a([href('#sessions')],'Active sessions')),
Chris@0 198 li(a([href('#serverstats')],'Server statistics'))
Chris@0 199 ]),
Chris@0 200 h4([id(ntriples)], 'Triples in database'),
Chris@0 201 p('The RDF store contains ~D triples in ~D bytes memory'-[Total, Core]),
Chris@0 202 table([ id(filesourcetable),
Chris@0 203 border(1),
Chris@0 204 cellpadding(2)
Chris@0 205 ],
Chris@0 206 [ tr([ th('Source'), th(colspan(2), 'Triples') ])
Chris@0 207 | \triples_by_file(Pairs, Total)
Chris@0 208 ]),
Chris@0 209 h4([id(callstats)],'Call statistics'),
Chris@0 210 table([ border(1),
Chris@0 211 cellpadding(2)
Chris@0 212 ],
Chris@0 213 [ tr([ th(colspan(3), 'Indexed'),
Chris@0 214 th('Calls')
Chris@0 215 ]),
Chris@0 216 \lookup_statistics(Lookup)
Chris@0 217 ]),
Chris@0 218 \current_sessions,
Chris@0 219 \server_statistics
Chris@0 220 ]).
Chris@0 221
Chris@0 222 triples_by_file([], Total) -->
Chris@0 223 html(tr([ th([align(right), id(total)], 'Total:'),
Chris@0 224 \nc('~D', Total)
Chris@0 225 ])).
Chris@0 226 triples_by_file([File-Triples|T], Total) -->
Chris@0 227 html(tr([ td(align(right), a(href(File), File)),
Chris@0 228 \nc('~D', Triples),
Chris@0 229 td(\unload_button(File))
Chris@0 230 ])),
Chris@0 231 triples_by_file(T, Total).
Chris@0 232
Chris@0 233
Chris@0 234 unload_button(File) -->
Chris@0 235 { www_form_encode(File, Encoded),
Chris@0 236 atom_concat('../servlets/unloadSource?\
Chris@0 237 resultFormat=html&\
Chris@0 238 source=', Encoded, URL)
Chris@0 239 },
Chris@0 240 html(a(href(URL), 'Unload')).
Chris@0 241
Chris@0 242
Chris@0 243 lookup_statistics([]) -->
Chris@0 244 [].
Chris@0 245 lookup_statistics([rdf(S,P,O)-Count|T]) -->
Chris@0 246 html(tr([ td(S), td(P), td(O), \nc('~D', Count)])),
Chris@0 247 lookup_statistics(T).
Chris@0 248
Chris@0 249 % current_sessions//0
Chris@0 250 %
Chris@0 251 % Create a table of currently logged on users.
Chris@0 252
Chris@0 253 current_sessions -->
Chris@0 254 { findall(S, session(S), Sessions0),
Chris@0 255 sort(Sessions0, Sessions),
Chris@0 256 Sessions \== [], !
Chris@0 257 },
Chris@0 258 html([ h4([id(sessions)], 'Active sessions'),
Chris@0 259 table([ id(sessiontable),
Chris@0 260 border(1),
Chris@0 261 cellpadding(2)
Chris@0 262 ],
Chris@0 263 [ %caption('Active sessions'),
Chris@0 264 tr([th('User'), th('Real Name'), th('On since'), th('Idle'), th('From')])
Chris@0 265 | \sessions(Sessions)
Chris@0 266 ])
Chris@0 267 ]).
Chris@0 268 current_sessions -->
Chris@0 269 html(p('No users logged in')).
Chris@0 270
Chris@0 271 session(s(Idle, User, SessionID, Peer)) :-
Chris@0 272 http_current_session(SessionID, peer(Peer)),
Chris@0 273 http_current_session(SessionID, idle(Idle)),
Chris@0 274 ( user_property(User, session(SessionID))
Chris@0 275 -> true
Chris@0 276 ; User = (-)
Chris@0 277 ).
Chris@0 278
Chris@0 279 sessions([]) --> [].
Chris@0 280 sessions([H|T]) --> session(H), sessions(T).
Chris@0 281
Chris@0 282 session(s(Idle, -, _SessionID, Peer)) -->
Chris@0 283 html(tr([td(-), td(-), td(-), td(\idle(Idle)), td(\ip(Peer))])).
Chris@0 284 session(s(Idle, User, _SessionID, Peer)) -->
Chris@0 285 { ( user_property(User, realname(RealName))
Chris@0 286 -> true
Chris@0 287 ; RealName = '?'
Chris@0 288 ),
Chris@0 289 ( user_property(User, connection(OnSince, _Idle))
Chris@0 290 -> true
Chris@0 291 ; OnSince = 0
Chris@0 292 )
Chris@0 293 },
Chris@0 294 html(tr([td(User), td(RealName), td(\date(OnSince)), td(\idle(Idle)), td(\ip(Peer))])).
Chris@0 295
Chris@0 296 idle(Time) -->
Chris@0 297 { Secs is round(Time),
Chris@0 298 Min is Secs // 60,
Chris@0 299 Sec is Secs mod 60
Chris@0 300 },
Chris@0 301 html('~`0t~d~2|:~`0t~d~5|'-[Min, Sec]).
Chris@0 302
Chris@0 303 date(Date) -->
Chris@0 304 { format_time(string(S), '%+', Date)
Chris@0 305 },
Chris@0 306 html(S).
Chris@0 307
Chris@0 308 ip(ip(A,B,C,D)) --> !,
Chris@0 309 html('~d.~d.~d.~d'-[A,B,C,D]).
Chris@0 310 ip(IP) -->
Chris@0 311 html('~w'-[IP]).
Chris@0 312
Chris@0 313
Chris@0 314 % server_statistics//0
Chris@0 315 %
Chris@0 316 % Provide statistics on the HTTP server
Chris@0 317
Chris@0 318 server_statistics -->
Chris@0 319 { serql_server_property(port(Port)),
Chris@0 320 serql_server_property(started(StartTime)),
Chris@0 321 format_time(string(ST), '%+', StartTime),
Chris@0 322 http_workers(Port, NWorkers),
Chris@0 323 findall(ID, http_current_worker(Port, ID), Workers),
Chris@0 324 statistics(heapused, Heap)
Chris@0 325 },
Chris@0 326 html([ h4([id(serverstats)], 'Server statistics'),
Chris@0 327 table([ border(1),
Chris@0 328 cellpadding(2)
Chris@0 329 ],
Chris@0 330 [ tr([ th([align(right), colspan(3)], 'Port:'),
Chris@0 331 td(colspan(3), Port)
Chris@0 332 ]),
Chris@0 333 tr([ th([align(right), colspan(3)], 'Started:'),
Chris@0 334 td(colspan(3), ST)
Chris@0 335 ]),
Chris@0 336 tr([ th([align(right), colspan(3)], 'Heap memory:'),
Chris@0 337 \nc('~D', Heap, [align(left), colspan(3)])
Chris@0 338 ]),
Chris@0 339 tr([ th([align(right), colspan(3)], '# worker threads:'),
Chris@0 340 td(colspan(3), NWorkers)
Chris@0 341 ]),
Chris@0 342 tr(th(colspan(6), 'Statistics by worker')),
Chris@0 343 tr([ th('Thread'),
Chris@0 344 th('CPU'),
Chris@0 345 th(''),
Chris@0 346 th('Local'),
Chris@0 347 th('Global'),
Chris@0 348 th('Trail')
Chris@0 349 ])
Chris@0 350 | \http_workers(Workers)
Chris@0 351 ])
Chris@0 352 ]).
Chris@0 353
Chris@0 354 http_workers([]) -->
Chris@0 355 [].
Chris@0 356 http_workers([H|T]) -->
Chris@0 357 { thread_statistics(H, locallimit, LL),
Chris@0 358 thread_statistics(H, globallimit, GL),
Chris@0 359 thread_statistics(H, traillimit, TL),
Chris@0 360 thread_statistics(H, localused, LU),
Chris@0 361 thread_statistics(H, globalused, GU),
Chris@0 362 thread_statistics(H, trailused, TU),
Chris@0 363 thread_statistics(H, cputime, CPU),
Chris@0 364 sformat(Time, '~2f', [CPU])
Chris@0 365 },
Chris@0 366 html([ tr([ td(rowspan(2), H),
Chris@0 367 td([rowspan(2), align(right)], Time),
Chris@0 368 th('In use'),
Chris@0 369 \nc('~D', LU),
Chris@0 370 \nc('~D', GU),
Chris@0 371 \nc('~D', TU)
Chris@0 372 ]),
Chris@0 373 tr([ th('Limit'),
Chris@0 374 \nc('~D', LL),
Chris@0 375 \nc('~D', GL),
Chris@0 376 \nc('~D', TL)
Chris@0 377 ])
Chris@0 378 ]),
Chris@0 379 http_workers(T).
Chris@0 380
Chris@0 381 %% construct_form(+Request)
Chris@0 382 %
Chris@0 383 % Provide a page for issuing a =CONSTRUCT= query.
Chris@0 384
Chris@0 385 construct_form(_Request) :-
Chris@0 386 catch(logged_on(User), _, User=anonymous),
Chris@0 387 reply_page('Specify a query',
Chris@0 388 [ h1(align(center), 'Interactive SeRQL CONSTRUCT query'),
Chris@0 389
Chris@0 390 p(['A ', \serql_doc_link('CONSTRUCT'),
Chris@0 391 ' generates an RDF graph']),
Chris@0 392
Chris@0 393 form([ name(query),
Chris@0 394 action('../evaluateGraphQuery'),
Chris@0 395 method('GET')
Chris@0 396 ],
Chris@0 397 [ \hidden(repository, default),
Chris@0 398 table(align(center),
Chris@0 399 [ \store_recall(User, construct, 3-2),
Chris@0 400 tr([ td(colspan(6),
Chris@0 401 textarea([ name(query),
Chris@0 402 rows(15),
Chris@0 403 cols(80)
Chris@0 404 ],
Chris@0 405 'CONSTRUCT '))
Chris@0 406 ]),
Chris@0 407 tr([ td([ \small('QLang: '),
Chris@0 408 \query_language
Chris@0 409 ]),
Chris@0 410 td([ \small('Format: '),
Chris@0 411 \result_format
Chris@0 412 ]),
Chris@0 413 td([ \small('Serial.: '),
Chris@0 414 \serialization
Chris@0 415 ]),
Chris@0 416 td([ \small('Res.: '),
Chris@0 417 \resource_menu
Chris@0 418 ]),
Chris@0 419 td([ \small('Entail.: '),
Chris@0 420 \entailment
Chris@0 421 ]),
Chris@0 422 td(align(right),
Chris@0 423 [ input([ type(reset),
Chris@0 424 value('Reset')
Chris@0 425 ]),
Chris@0 426 input([ type(submit),
Chris@0 427 value('Go!')
Chris@0 428 ])
Chris@0 429 ])
Chris@0 430 ])
Chris@0 431 ])
Chris@0 432 ]),
Chris@0 433 \script
Chris@0 434 ]).
Chris@0 435
Chris@0 436 store_recall(anonymous, _, _) -->
Chris@0 437 [].
Chris@0 438 store_recall(User, Type, SL-SR) -->
Chris@0 439 html(tr([ td(colspan(SL),
Chris@0 440 [ b('Store as: '),
Chris@0 441 input([ name(storeAs),
Chris@0 442 size(40)
Chris@0 443 ])
Chris@0 444 ]),
Chris@0 445 td([ colspan(SR),
Chris@0 446 align(right)
Chris@0 447 ],
Chris@0 448 \recall(User, Type))
Chris@0 449 ])).
Chris@0 450
Chris@0 451
Chris@0 452 recall(User, Type) -->
Chris@0 453 { findall(Name-Query, stored_query(Name, User, Type, Query), Pairs),
Chris@0 454 Pairs \== []
Chris@0 455 },
Chris@0 456 html([ b('Recall: '),
Chris@0 457 select(name(recall),
Chris@0 458 [ option([selected], '')
Chris@0 459 | \stored_queries(Pairs, 1)
Chris@0 460 ])
Chris@0 461 ]).
Chris@0 462 recall(_, _) -->
Chris@0 463 [].
Chris@0 464
Chris@0 465 stored_queries([], _) -->
Chris@0 466 [].
Chris@0 467 stored_queries([Name-Query|T], I) -->
Chris@0 468 { I2 is I + 1,
Chris@0 469 atom_concat(f, I, FName),
Chris@0 470 js_quoted(Query, QuotedQuery),
Chris@0 471 sformat(Script,
Chris@0 472 'function ~w()\n\
Chris@0 473 { document.query.query.value=\'~w\';\n\
Chris@0 474 }\n',
Chris@0 475 [ FName, QuotedQuery ]),
Chris@0 476 assert(script_fragment(Script)),
Chris@0 477 sformat(Call, '~w()', [FName])
Chris@0 478 },
Chris@0 479 html(option([onClick(Call)], Name)),
Chris@0 480 stored_queries(T, I2).
Chris@0 481
Chris@0 482
Chris@0 483 :- thread_local
Chris@0 484 script_fragment/1.
Chris@0 485
Chris@0 486 script -->
Chris@0 487 { findall(S, retract(script_fragment(S)), Fragments),
Chris@0 488 Fragments \== []
Chris@0 489 }, !,
Chris@0 490 [ '\n<script language="JavaScript">\n'
Chris@0 491 ],
Chris@0 492 Fragments,
Chris@0 493 [ '\n</script>\n'
Chris@0 494 ].
Chris@0 495 script -->
Chris@0 496 [].
Chris@0 497
Chris@0 498 %% js_quoted(+Raw, -Quoted)
Chris@0 499 %
Chris@0 500 % Quote text for use in JavaScript. Quoted does _not_ include the
Chris@0 501 % leading and trailing quotes.
Chris@0 502
Chris@0 503 js_quoted(Raw, Quoted) :-
Chris@0 504 atom_codes(Raw, Codes),
Chris@0 505 phrase(js_quote_codes(Codes), QuotedCodes),
Chris@0 506 atom_codes(Quoted, QuotedCodes).
Chris@0 507
Chris@0 508 js_quote_codes([]) -->
Chris@0 509 [].
Chris@0 510 js_quote_codes([0'\r,0'\n|T]) --> !,
Chris@0 511 "\\n",
Chris@0 512 js_quote_codes(T).
Chris@0 513 js_quote_codes([H|T]) -->
Chris@0 514 js_quote_code(H),
Chris@0 515 js_quote_codes(T).
Chris@0 516
Chris@0 517 js_quote_code(0'') --> !,
Chris@0 518 "\\'".
Chris@0 519 js_quote_code(0'\\) --> !,
Chris@0 520 "\\\\".
Chris@0 521 js_quote_code(0'\n) --> !,
Chris@0 522 "\\n".
Chris@0 523 js_quote_code(0'\r) --> !,
Chris@0 524 "\\r".
Chris@0 525 js_quote_code(0'\t) --> !,
Chris@0 526 "\\t".
Chris@0 527 js_quote_code(C) -->
Chris@0 528 [C].
Chris@0 529
Chris@0 530 %% query_form(+Request)
Chris@0 531 %
Chris@0 532 % Provide a page for issuing a =SELECT= query.
Chris@0 533
Chris@0 534 query_form(_Request) :-
Chris@0 535 catch(logged_on(User), _, User=anonymous),
Chris@0 536 reply_page('Specify a query',
Chris@0 537 [ form([ name(query),
Chris@0 538 action('../evaluateQuery'),
Chris@0 539 method('GET')
Chris@0 540 ],
Chris@0 541 [ \hidden(repository, default),
Chris@0 542 \hidden(serialization, rdfxml),
Chris@0 543 h1(align(center),
Chris@0 544 [ 'Interactive ',
Chris@0 545 \query_language,
Chris@0 546 ' query'
Chris@0 547 ]),
Chris@0 548 table(align(center),
Chris@0 549 [ \store_recall(User, select, 3-2),
Chris@0 550 tr([ td(colspan(5),
Chris@0 551 textarea([ name(query),
Chris@0 552 rows(15),
Chris@0 553 cols(80)
Chris@0 554 ],
Chris@0 555 ''))
Chris@0 556 ]),
Chris@0 557 tr([ td([ \small('Result format: '),
Chris@0 558 \result_format
Chris@0 559 ]),
Chris@0 560 td([ \small('Resource: '),
Chris@0 561 \resource_menu
Chris@0 562 ]),
Chris@0 563 td([ \small('Entailment: '),
Chris@0 564 \entailment
Chris@0 565 ]),
Chris@0 566 td(align(right),
Chris@0 567 [ input([ type(reset),
Chris@0 568 value('Reset')
Chris@0 569 ]),
Chris@0 570 input([ type(submit),
Chris@0 571 value('Go!')
Chris@0 572 ])
Chris@0 573 ])
Chris@0 574 ])
Chris@0 575 ])
Chris@0 576 ]),
Chris@0 577 \script
Chris@0 578 ]).
Chris@0 579
Chris@0 580
Chris@0 581 %% select_form(+Request)
Chris@0 582 %
Chris@0 583 % Provide a page for issuing a =SELECT= query
Chris@0 584
Chris@0 585 select_form(_Request) :-
Chris@0 586 catch(logged_on(User), _, User=anonymous),
Chris@0 587 reply_page('Specify a query',
Chris@0 588 [ h1(align(center), 'Interactive SeRQL SELECT query'),
Chris@0 589
Chris@0 590 p(['A ', \serql_doc_link('SELECT'),
Chris@0 591 ' generates a table']),
Chris@0 592
Chris@0 593 form([ name(query),
Chris@0 594 action('../servlets/evaluateTableQuery'),
Chris@0 595 method('GET')
Chris@0 596 ],
Chris@0 597 [ \hidden(repository, default),
Chris@0 598 \hidden(serialization, rdfxml),
Chris@0 599 table(align(center),
Chris@0 600 [ \store_recall(User, select, 3-2),
Chris@0 601 tr([ td(colspan(6),
Chris@0 602 textarea([ name(query),
Chris@0 603 rows(15),
Chris@0 604 cols(80)
Chris@0 605 ],
Chris@0 606 'SELECT '))
Chris@0 607 ]),
Chris@0 608 tr([ td([ \small('Result format: '),
Chris@0 609 \result_format
Chris@0 610 ]),
Chris@0 611 td([ \small('Language: '),
Chris@0 612 \query_language
Chris@0 613 ]),
Chris@0 614 td([ \small('Resource: '),
Chris@0 615 \resource_menu
Chris@0 616 ]),
Chris@0 617 td([ \small('Entailment: '),
Chris@0 618 \entailment
Chris@0 619 ]),
Chris@0 620 td(align(right),
Chris@0 621 [ input([ type(reset),
Chris@0 622 value('Reset')
Chris@0 623 ]),
Chris@0 624 input([ type(submit),
Chris@0 625 value('Go!')
Chris@0 626 ])
Chris@0 627 ])
Chris@0 628 ])
Chris@0 629 ])
Chris@0 630 ]),
Chris@0 631 \script
Chris@0 632 ]).
Chris@0 633
Chris@0 634
Chris@0 635 serql_doc_link(Label) -->
Chris@0 636 { setting(serql_parms:serql_documentation_url, URL)
Chris@0 637 },
Chris@0 638 html(a([href(URL)], Label)).
Chris@0 639
Chris@0 640 serialization -->
Chris@0 641 html(select(name(serialization),
Chris@0 642 [ option([selected], rdfxml),
Chris@0 643 option([], ntriples),
Chris@0 644 option([], n3)
Chris@0 645 ])).
Chris@0 646
Chris@0 647 result_format -->
Chris@0 648 html(select(name(resultFormat),
Chris@0 649 [ option([], xml),
Chris@0 650 option([selected], html)/*,
Chris@0 651 option([], rdf)*/
Chris@0 652 ])).
Chris@0 653
Chris@0 654 query_language -->
Chris@0 655 html(select(name(queryLanguage),
Chris@0 656 [ option([selected], 'SeRQL'),
Chris@0 657 option([], 'SPARQL')
Chris@0 658 ])).
Chris@0 659
Chris@0 660 resource_menu -->
Chris@0 661 html(select(name(resourceFormat),
Chris@0 662 [ option([value(plain)], plain),
Chris@0 663 option([value(ns), selected], 'ns:local'),
Chris@0 664 option([value(nslabel)], 'ns:label')
Chris@0 665 ])).
Chris@0 666
Chris@0 667 entailment -->
Chris@0 668 { findall(E, serql:entailment(E, _), Es)
Chris@0 669 },
Chris@0 670 html(select(name(entailment),
Chris@0 671 \entailments(Es))).
Chris@0 672
Chris@0 673 entailments([]) -->
Chris@0 674 [].
Chris@0 675 entailments([E|T]) -->
Chris@0 676 ( { setting(serql_parms:default_entailment, E)
Chris@0 677 }
Chris@0 678 -> html(option([selected], E))
Chris@0 679 ; html(option([], E))
Chris@0 680 ),
Chris@0 681 entailments(T).
Chris@0 682
Chris@0 683 small(Text) -->
Chris@0 684 html(font(size(-1), Text)).
Chris@0 685
Chris@0 686
Chris@0 687 %% load_file_form(+Request)
Chris@0 688 %
Chris@0 689 % Provide a form for uploading triples from a local file.
Chris@0 690
Chris@0 691 load_file_form(_Request) :-
Chris@0 692 reply_page('Upload RDF',
Chris@0 693 [ h3(align(center), 'Upload an RDF document'),
Chris@0 694
Chris@0 695 p(['Upload a document using POST to /servlets/uploadData. \
Chris@0 696 Alternatively you can use ',
Chris@0 697 a(href=loadURL,loadURL), ' to load data from a \
Chris@0 698 web server.'
Chris@0 699 ]),
Chris@0 700
Chris@0 701 form([ action('../servlets/uploadData'),
Chris@0 702 method('POST'),
Chris@0 703 enctype('multipart/form-data')
Chris@0 704 ],
Chris@0 705 [ \hidden(resultFormat, html),
Chris@0 706 table([tr([ td(align(right), 'File:'),
Chris@0 707 td(input([ name(data),
Chris@0 708 type(file),
Chris@0 709 size(50)
Chris@0 710 ]))
Chris@0 711 ]),
Chris@0 712 tr([ td(align(right), 'BaseURI:'),
Chris@0 713 td(input([ name(baseURI),
Chris@0 714 size(50)
Chris@0 715 ]))
Chris@0 716 ]),
Chris@0 717 tr([ td([align(right), colspan(2)],
Chris@0 718 input([ type(submit),
Chris@0 719 value('Upload now')
Chris@0 720 ]))
Chris@0 721 ])
Chris@0 722 ])
Chris@0 723 ])
Chris@0 724 ]).
Chris@0 725
Chris@0 726
Chris@0 727 %% load_url_form(+Request)
Chris@0 728 %
Chris@0 729 % Provide a form for uploading triples from a URL.
Chris@0 730
Chris@0 731 load_url_form(_Request) :-
Chris@0 732 reply_page('Load RDF from HTTP server',
Chris@0 733 [ h3(align(center), 'Load RDF from HTTP server'),
Chris@0 734 form([ action('../servlets/uploadURL'),
Chris@0 735 method('GET')
Chris@0 736 ],
Chris@0 737 [ \hidden(resultFormat, html),
Chris@0 738 table([tr([ td(align(right), 'URL:'),
Chris@0 739 td(input([ name(url),
Chris@0 740 value('http://'),
Chris@0 741 size(50)
Chris@0 742 ]))
Chris@0 743 ]),
Chris@0 744 tr([ td(align(right), 'BaseURI:'),
Chris@0 745 td(input([ name(baseURI),
Chris@0 746 size(50)
Chris@0 747 ]))
Chris@0 748 ]),
Chris@0 749 tr([ td([align(right), colspan(2)],
Chris@0 750 input([ type(submit),
Chris@0 751 value('Upload now')
Chris@0 752 ]))
Chris@0 753 ])
Chris@0 754 ])
Chris@0 755 ])
Chris@0 756 ]).
Chris@0 757
Chris@0 758
Chris@0 759 %% load_base_ontology_form(+Request)
Chris@0 760 %
Chris@0 761 % Provide a form for loading an ontology from the archive.
Chris@0 762
Chris@0 763 load_base_ontology_form(_Request) :- !,
Chris@0 764 authorized(read(status, listBaseOntologies)),
Chris@0 765 reply_page('Load base ontology',
Chris@0 766 [ h3(align(center), 'Load ontology from repository'),
Chris@0 767
Chris@0 768 p('This page allows loading one of the ontologies \
Chris@0 769 provided with the toolkit.'),
Chris@0 770
Chris@0 771 form([ action('../servlets/loadBaseOntology'),
Chris@0 772 method('GET')
Chris@0 773 ],
Chris@0 774 [ \hidden(resultFormat, html),
Chris@0 775 b('Ontology'),
Chris@0 776 select(name(ontology),
Chris@0 777 [ option([], '')
Chris@0 778 | \base_ontologies
Chris@0 779 ]),
Chris@0 780 input([ type(submit),
Chris@0 781 value('Load')
Chris@0 782 ])
Chris@0 783 ])
Chris@0 784 ]).
Chris@0 785
Chris@0 786
Chris@0 787 base_ontologies -->
Chris@0 788 { get_base_ontologies(Rows)
Chris@0 789 },
Chris@0 790 base_ontologies(Rows).
Chris@0 791
Chris@0 792 get_base_ontologies(List) :-
Chris@0 793 catch(findall(row(O), serql_base_ontology(O), List), _, fail), !.
Chris@0 794 get_base_ontologies(Rows) :-
Chris@0 795 server_url('/servlets/listBaseOntologies?resultFormat=xml', URL),
Chris@0 796 debug(base_ontologies, 'Opening ~w', [URL]),
Chris@0 797 http_open(URL, In,
Chris@0 798 [ % request_header('Cookie', Cookie)
Chris@0 799 ]),
Chris@0 800 debug(base_ontologies, '--> Reading from ~w', [In]),
Chris@0 801 xml_read_result_table(In, Rows, _VarNames).
Chris@0 802
Chris@0 803 base_ontologies([]) -->
Chris@0 804 [].
Chris@0 805 base_ontologies([row(H)|T]) -->
Chris@0 806 html(option([], H)),
Chris@0 807 base_ontologies(T).
Chris@0 808
Chris@0 809
Chris@0 810 %% clear_repository_form(+Request)
Chris@0 811 %
Chris@0 812 % HTTP handle presenting a form to clear the repository.
Chris@0 813
Chris@0 814 clear_repository_form(_Request) :-
Chris@0 815 reply_page('Load base ontology',
Chris@0 816 [ h3(align(center), 'Clear entire repository'),
Chris@0 817
Chris@0 818 p(['This operation removes ', b(all), ' triples from \
Chris@0 819 the RDF store.']),
Chris@0 820
Chris@0 821 form([ action('../servlets/clearRepository'),
Chris@0 822 method('GET')
Chris@0 823 ],
Chris@0 824 [ \hidden(repository, default),
Chris@0 825 \hidden(resultFormat, html),
Chris@0 826 input([ type(submit),
Chris@0 827 value('Clear repository now')
Chris@0 828 ])
Chris@0 829 ])
Chris@0 830 ]).
Chris@0 831
Chris@0 832
Chris@0 833 %% remove_statements_form(+Request)
Chris@0 834 %
Chris@0 835 % HTTP handler providing a form to remove RDF statements.
Chris@0 836
Chris@0 837 remove_statements_form(_Request) :-
Chris@0 838 reply_page('Load base ontology',
Chris@0 839 [ h3(align(center), 'Remove statements'),
Chris@0 840
Chris@0 841 p('Remove matching triples from the database. The three \
Chris@0 842 fields are in ntriples notation. Omitted fields \
Chris@0 843 match any value.'),
Chris@0 844
Chris@0 845 form([ action('../servlets/removeStatements'),
Chris@0 846 method('GET')
Chris@0 847 ],
Chris@0 848 [ \hidden(repository, default),
Chris@0 849 \hidden(resultFormat, html),
Chris@0 850 table([ tr([ th(align(right), 'Subject: '),
Chris@0 851 td(input([ name(subject),
Chris@0 852 size(50)
Chris@0 853 ]))
Chris@0 854 ]),
Chris@0 855 tr([ th(align(right), 'Predicate: '),
Chris@0 856 td(input([ name(predicate),
Chris@0 857 size(50)
Chris@0 858 ]))
Chris@0 859 ]),
Chris@0 860 tr([ th(align(right), 'Object: '),
Chris@0 861 td(input([ name(object),
Chris@0 862 size(50)
Chris@0 863 ]))
Chris@0 864 ]),
Chris@0 865 tr([ td([ align(right),
Chris@0 866 colspan(2)
Chris@0 867 ],
Chris@0 868 input([ type(submit),
Chris@0 869 value('Remove')
Chris@0 870 ]))
Chris@0 871 ])
Chris@0 872 ])
Chris@0 873 ])
Chris@0 874 ]).
Chris@0 875
Chris@0 876
Chris@0 877 /*******************************
Chris@0 878 * UTIL *
Chris@0 879 *******************************/
Chris@0 880
Chris@0 881 actions([]) -->
Chris@0 882 [].
Chris@0 883 actions([Path-Label|T]) -->
Chris@0 884 action(Path, Label),
Chris@0 885 actions(T).
Chris@0 886
Chris@0 887 %% action(+URL, +Label)// is det
Chris@0 888 %
Chris@0 889 % Add an action to the sidebar. URL is one of
Chris@0 890 %
Chris@0 891 % $ =-= :
Chris@0 892 % Add a horizontal rule (<hr>)
Chris@0 893 % $ Atom :
Chris@0 894 % Create a link to the given URL, targetting the main
Chris@0 895 % window.
Chris@0 896 % $ HTML DOM :
Chris@0 897 % Insert given HTML
Chris@0 898
Chris@0 899 action(-, -) --> !,
Chris@0 900 html(hr([])).
Chris@0 901 action(-, Label) --> !,
Chris@0 902 html([ hr([]),
Chris@0 903 center(b(Label)),
Chris@0 904 hr([])
Chris@0 905 ]).
Chris@0 906 action(URL, Label) -->
Chris@0 907 { atom(URL) }, !,
Chris@0 908 html([a([target=main, href=URL], Label), br([])]).
Chris@0 909 action(Action, _) -->
Chris@0 910 html(Action),
Chris@0 911 html(br([])).
Chris@0 912
Chris@0 913 %% nc(+Format, +Value)// is det.
Chris@0 914 %
Chris@0 915 % Numeric cell. The value is formatted using Format and
Chris@0 916 % right-aligned in a table cell (td).
Chris@0 917
Chris@0 918 nc(Fmt, Value) -->
Chris@0 919 nc(Fmt, Value, []).
Chris@0 920
Chris@0 921 nc(Fmt, Value, Options) -->
Chris@0 922 { sformat(Txt, Fmt, [Value]),
Chris@0 923 ( memberchk(align(_), Options)
Chris@0 924 -> Opts = Options
Chris@0 925 ; Opts = [align(right)|Options]
Chris@0 926 )
Chris@0 927 },
Chris@0 928 html(td(Opts, Txt)).
Chris@0 929
Chris@0 930
Chris@0 931 %% hidden(+Name, +Value)// is det.
Chris@0 932 %
Chris@0 933 % Create a hidden input field with given name and value
Chris@0 934
Chris@0 935 hidden(Name, Value) -->
Chris@0 936 html(input([ type(hidden),
Chris@0 937 name(Name),
Chris@0 938 value(Value)
Chris@0 939 ])).
Chris@0 940
Chris@0 941
Chris@0 942 server_url(Local, URL) :-
Chris@0 943 setting(http:server_url, Base),
Chris@0 944 atom_concat(Base, Local, URL).
Chris@0 945
Chris@0 946
Chris@0 947 /*******************************
Chris@0 948 * EMIT *
Chris@0 949 *******************************/
Chris@0 950
Chris@0 951 reply_page(Title, Content) :-
Chris@0 952 phrase(page(title(Title), Content), HTML),
Chris@0 953 format('Content-type: text/html~n~n'),
Chris@0 954 print_html(HTML).
Chris@0 955
Chris@0 956
Chris@0 957 /*******************************
Chris@0 958 * PCEEMACS SUPPORT *
Chris@0 959 *******************************/
Chris@0 960
Chris@0 961 :- multifile
Chris@0 962 emacs_prolog_colours:goal_colours/2,
Chris@0 963 prolog:called_by/2.
Chris@0 964
Chris@0 965
Chris@0 966 emacs_prolog_colours:goal_colours(reply_page(_, HTML),
Chris@0 967 built_in-[classify, Colours]) :-
Chris@0 968 catch(html_write:html_colours(HTML, Colours), _, fail).
Chris@0 969
Chris@0 970 prolog:called_by(reply_page(_, HTML), Called) :-
Chris@0 971 catch(phrase(html_write:called_by(HTML), Called), _, fail).