amalgame/commit
splitup overly complicated and large applications/startpage.pl into several pieces
author | Jacco van Ossenbruggen |
---|---|
Mon Aug 11 15:25:27 2014 +0200 | |
committer | Jacco van Ossenbruggen |
Mon Aug 11 15:25:27 2014 +0200 | |
commit | 60cdb25e523ef55ed4ad90c2ccf6bb9d5f5c5c17 |
tree | a2b50e536882e205cdb719beb3210ef15d067286 |
parent | b13432e048d6afc312907f426751b07861e9c715 |
Diff style: patch stat
diff --git a/api/form/amalgame/startpage.pl b/api/form/amalgame/startpage.pl new file mode 100644 index 0000000..eca168c --- /dev/null +++ b/api/form/amalgame/startpage.pl @@ -0,0 +1,221 @@ +:- module(ag_form_startpage, + [ + ]). + +:- use_module(library(http/http_dispatch)). +:- use_module(library(http/http_parameters)). + +:- use_module(library(semweb/rdf_file_type)). +:- use_module(user(user_db)). + +:- use_module(library(amalgame/rdf_util)). +:- use_module(library(amalgame/ag_provenance)). +:- use_module(library(amalgame/util)). + +% handlers for the different forms on the start page. +% most handle the form request and then redirect to some other page, +% such as the strategy builder or back to the start page: + +:- http_handler(amalgame(form/new), http_ag_form_new_strategy, []). +:- http_handler(amalgame(form/select), http_ag_form_select_strategy, []). +:- http_handler(amalgame(form/url), http_ag_form_upload_strategy_resource, []). +:- http_handler(amalgame(form/data), http_ag_form_upload_strategy_data, []). +:- http_handler(amalgame(form/reference), http_ag_form_upload_reference, []). + +%% http_ag_form_select_strategy(+Request) +% +% Execute action on selected strategy and redirect to +% appropriate page. + +http_ag_form_select_strategy(Request) :- + http_parameters(Request, + [ + strategy(Strategies, + [list(uri), + description('URI of the selected strategy')]), + submit(Action, + [oneof(['View selected', + 'Merge selected', + 'Delete selected']), + description('Action to be performed on this strategy'), + default('View selected') + ]) + ]), + ( Action == 'View selected' + -> build_redirect(Request, Strategies) + ; Action == 'Merge selected' + -> merge_redirect(Request, Strategies) + ; Action == 'Delete selected' + -> delete_redirect(Request, Strategies) + ). + +%% http_ag_form_new_strategy(+Request) +% +% Handle form data to create a new strategy + +http_ag_form_new_strategy(Request) :- + http_parameters(Request, + [ scheme(Schemes, + [zero_or_more, + description('Zero or more concept schemes')]) + ]), + new_strategy(Graph, [schemes(Schemes), comment('New strategy')]), + build_redirect(Request, [Graph]). + + + +%% http_ag_form_upload_strategy_data(+Request) is det. +% +% Handler for strategy form data import. + +http_ag_form_upload_strategy_data(Request) :- + authorized(write(default, _)), + http_parameters(Request, + [ data(Data, + [ description('RDF data to be loaded') + ]) + ]), + rdf_bnode(TmpGraph), + atom_to_memory_file(Data, MemFile), + setup_call_cleanup(open_memory_file(MemFile, read, Stream), + rdf_guess_format_and_load(Stream, [graph(TmpGraph)]), + ( close(Stream), + free_memory_file(MemFile) + )), + cp_strategy_from_tmp(Request, TmpGraph). + +%% http_ag_form_upload_strategy_resource(+Request) is det. +% +% Handler for strategy form resource import. + +http_ag_form_upload_strategy_resource(Request) :- + authorized(write(default, _)), + http_parameters(Request, + [ url(URL, []) + ]), + rdf_bnode(TmpGraph), + rdf_load(URL, [graph(TmpGraph)]), + cp_strategy_from_tmp(Request, TmpGraph). + +%% http_ag_form_upload_reference(+Request) is det. +% +% Handle form to upload an existing strategy +http_ag_form_upload_reference(Request) :- + authorized(write(default, _)), + http_parameters(Request, + [ data(Data, + [ description('RDF data to be loaded') + ]) + ]), + new_reference_name(NamedGraph), + atom_to_memory_file(Data, MemFile), + setup_call_cleanup(open_memory_file(MemFile, read, Stream), + rdf_guess_format_and_load(Stream, [graph(NamedGraph)]), + ( close(Stream), + free_memory_file(MemFile) + )), + rdf_equal(amalgame:'LoadedMapping', LMGraph), + rdf_assert(NamedGraph, rdf:type, amalgame:'LoadedMapping', LMGraph), + + http_link_to_id(list_graph, [graph(NamedGraph)], ListGraph), + http_redirect(moved, ListGraph, Request). + + + +cp_strategy_from_tmp(Request, TmpGraph) :- + rdf(Strategy, rdf:type, amalgame:'AlignmentStrategy', TmpGraph),!, + cp_graph(TmpGraph, Strategy, true), + rdf_unload_graph(TmpGraph), + build_redirect(Request, [Strategy]). + +build_redirect(Request, [Strategy|_]) :- + http_link_to_id(http_ag_build, [strategy(Strategy)], Redirect), + http_redirect(moved, Redirect, Request). + +delete_redirect(Request, Strategies) :- + authorized(write(default, _)), + forall(member(Strategy, Strategies), + ( ( provenance_graph(Strategy, Prov) + -> rdf_unload_graph(Prov) + ; true + ), + rdf_unload_graph(Strategy) + ) + ), + http_link_to_id(http_amalgame_main_page, [], Redirect), + http_redirect(moved, Redirect, Request). + +merge_redirect(Request, Strategies) :- + % Create comment + maplist(scheme_label, Strategies, Labeled), + keysort(Labeled, Sorted), + pairs_keys(Sorted, Labels), + atomic_list_concat(Labels, ', ', LabelsAtom), + atomic_concat('Strategy merged from ', LabelsAtom, Comment), + + % Create merged strategy + new_strategy(New, [comment(Comment)]), + cp_graphs(Strategies, New), + merge_strategy_nodes(Strategies, New), + + % Redirect to builder + http_link_to_id(http_ag_build, [strategy(New)], Redirect), + http_redirect(moved, Redirect, Request). + +new_reference_name(Reference) :- + setting(amalgame:default_publish_namespace, NS), + reset_gensym(reference_alignment), + repeat, + gensym(reference_alignment, Local), + atomic_list_concat([NS,Local], Reference), + \+ rdf_graph(Reference), + !. + + +merge_strategy_nodes([], _New) :- !. +merge_strategy_nodes([H|T], New) :- + findall(rdf(H,P,O), + rdf(H,P,O,New), + Triples), + forall(member(rdf(_,P,O), Triples), + rdf_assert(New,P,O,New)), + merge_strategy_nodes(T, New). + +%% new_strategy(-StrategyURI, Options) +% +% Assert a new strategy graph. + +new_strategy(S, Options) :- + authorized(write(default, _)), + new_strategy_name(S, NS), + rdf_assert(S, rdf:type, amalgame:'AlignmentStrategy', S), + rdf_assert(S, rdf:type, prov:'Plan', S), + rdf_assert(S, amalgame:publish_ns, NS, S), + assert_user_provenance(S, S), + + ( option(schemes(Schemes), Options) + -> add_schemes(Schemes, S) + ; true), + + ( option(comment(C), Options) + -> rdf_assert(S, rdfs:comment, literal(C), S) + ; true + ). + +scheme_label(URI, Key-URI) :- + rdf_graph_label(URI, CasedKey), + downcase_atom(CasedKey, Key). + +add_schemes([], _). +add_schemes([Scheme|Ss], Strategy) :- + rdf_assert(Strategy, amalgame:includes, Scheme, Strategy), + add_schemes(Ss, Strategy). + +new_strategy_name(Strategy, NS) :- + setting(amalgame:default_publish_namespace, NS), + reset_gensym(strategy), + repeat, + gensym(strategy, Local), + atomic_list_concat([NS,Local], Strategy), + \+ rdf_graph(Strategy), + !. diff --git a/applications/startpage.pl b/applications/startpage.pl index b16854a..67a348d 100644 --- a/applications/startpage.pl +++ b/applications/startpage.pl @@ -2,26 +2,18 @@ [html_schemes_only//0 % for backward compat with europeana demo ]). -:- use_module(library(option)). + :- use_module(library(http/http_dispatch)). -:- use_module(library(http/http_parameters)). :- use_module(library(http/http_path)). :- use_module(library(http/html_head)). :- use_module(library(http/html_write)). -:- use_module(library(semweb/rdf_db)). -:- use_module(library(semweb/rdf_label)). -:- use_module(library(semweb/rdf_file_type)). - -:- use_module(user(user_db)). :- use_module(library(yui3_beta)). -:- use_module(components(label)). :- use_module(library(amalgame/util)). -:- use_module(library(amalgame/voc_stats)). -:- use_module(library(amalgame/ag_provenance)). :- use_module(applications(skos_browser)). -:- use_module(components(amalgame/util)). +:- use_module(components(amalgame/startpage)). +:- use_module(api(form/amalgame/startpage)). % main http handler for amalgame: :- http_handler(amalgame(.), http_amalgame_main_page, []). @@ -30,14 +22,6 @@ :- http_handler(amalgame(eq), http_redirect(moved, amalgame(.)), []). :- http_handler(amalgame(app/main), http_redirect(moved, amalgame(.)), []). -% handlers for the different forms on the main page. -% most handle the form request and then redirect to some other page, -% such as the strategy builder or the main page: -:- http_handler(amalgame(form/new), http_ag_form_new_strategy, []). -:- http_handler(amalgame(form/select), http_ag_form_select_strategy, []). -:- http_handler(amalgame(form/url), http_ag_form_upload_strategy_resource, []). -:- http_handler(amalgame(form/data), http_ag_form_upload_strategy_data, []). -:- http_handler(amalgame(form/reference), http_ag_form_upload_reference, []). %% http_amalgame_main_page(+Request) is det. % @@ -47,123 +31,15 @@ http_amalgame_main_page(Request) :- html_main_page(Request). - -%% http_ag_form_select_strategy(+Request) -% -% Execute action on selected strategy and redirect to -% appropriate page. - -http_ag_form_select_strategy(Request) :- - http_parameters(Request, - [ - strategy(Strategies, - [list(uri), - description('URI of the selected strategy')]), - submit(Action, - [oneof(['View selected', - 'Merge selected', - 'Delete selected']), - description('Action to be performed on this strategy'), - default('View selected') - ]) - ]), - ( Action == 'View selected' - -> build_redirect(Request, Strategies) - ; Action == 'Merge selected' - -> merge_redirect(Request, Strategies) - ; Action == 'Delete selected' - -> delete_redirect(Request, Strategies) - ). - -%% http_ag_form_new_strategy(+Request) -% -% Handle form data to create a new strategy - -http_ag_form_new_strategy(Request) :- - http_parameters(Request, - [ scheme(Schemes, - [zero_or_more, - description('Zero or more concept schemes')]) - ]), - new_strategy(Graph, [schemes(Schemes), comment('New strategy')]), - build_redirect(Request, [Graph]). - - - -%% http_ag_form_upload_strategy_data(+Request) is det. -% -% Handler for strategy form data import. - -http_ag_form_upload_strategy_data(Request) :- - authorized(write(default, _)), - http_parameters(Request, - [ data(Data, - [ description('RDF data to be loaded') - ]) - ]), - rdf_bnode(TmpGraph), - atom_to_memory_file(Data, MemFile), - setup_call_cleanup(open_memory_file(MemFile, read, Stream), - rdf_guess_format_and_load(Stream, [graph(TmpGraph)]), - ( close(Stream), - free_memory_file(MemFile) - )), - cp_strategy_from_tmp(Request, TmpGraph). - -%% http_ag_form_upload_strategy_resource(+Request) is det. -% -% Handler for strategy form resource import. - -http_ag_form_upload_strategy_resource(Request) :- - authorized(write(default, _)), - http_parameters(Request, - [ url(URL, []) - ]), - rdf_bnode(TmpGraph), - rdf_load(URL, [graph(TmpGraph)]), - cp_strategy_from_tmp(Request, TmpGraph). - -%% http_ag_form_upload_reference(+Request) is det. -% -% Handle form to upload an existing strategy -http_ag_form_upload_reference(Request) :- - authorized(write(default, _)), - http_parameters(Request, - [ data(Data, - [ description('RDF data to be loaded') - ]) - ]), - new_reference_name(NamedGraph), - atom_to_memory_file(Data, MemFile), - setup_call_cleanup(open_memory_file(MemFile, read, Stream), - rdf_guess_format_and_load(Stream, [graph(NamedGraph)]), - ( close(Stream), - free_memory_file(MemFile) - )), - rdf_equal(amalgame:'LoadedMapping', LMGraph), - rdf_assert(NamedGraph, rdf:type, amalgame:'LoadedMapping', LMGraph), - - http_link_to_id(list_graph, [graph(NamedGraph)], ListGraph), - http_redirect(moved, ListGraph, Request). - - -find_schemes(Schemes) :- - findall(C, - ( is_vocabulary(C), - voc_property(C, virtual(false)) - ), - All), - maplist(scheme_label, All, Labeled), - keysort(Labeled, Sorted), - pairs_values(Sorted, Schemes). - -scheme_label(URI, Key-URI) :- - graph_label(URI, CasedKey), - downcase_atom(CasedKey, Key). +html_schemes_only --> + { + amalgame_alignable_schemes(ConceptSchemes) + }, + html_new(ConceptSchemes). html_main_page(_Request) :- findall(A-S, amalgame_strategy_schemes(A, S), Alignments), - find_schemes(ConceptSchemes), + amalgame_alignable_schemes(ConceptSchemes), reply_html_page(cliopatria(main), [ title(['Amalgame - strategies']) ], @@ -193,313 +69,6 @@ html_main_page(_Request) :- ]). -html_schemes_only --> - { - find_schemes(ConceptSchemes) - }, - html_new(ConceptSchemes). - -%% html_new -% -% - -html_new([]) --> - html_acc_item(new, - 'new alignment strategy: no (SKOS) vocabularies found', - div([style('padding: 1%')],[ - 'Please use the Repository drop-down menu to load ', - 'the vocabularies you would like to align ', - 'into the repository/triple store.' - ]), - [active] - ). - -html_new(Schemes) --> - { has_write_permission, !, - ButtonsBottom = div(\html_submit('Start')), - length(Schemes, N), - ( N > 7 - -> ButtonsTop = ButtonsBottom - ; ButtonsTop = div([],[]) - ) - }, - html_acc_item(new, - 'new alignment strategy', - [ form(action(location_by_id(http_ag_form_new_strategy)), - [ ButtonsTop, - \html_vocab_table(Schemes), - ButtonsBottom - ]) - ], - [active] - ). - -html_new(_) --> - { - http_location_by_id(http_amalgame_main_page, This), - http_link_to_id(cliopatria_openid:login_page, - ['openid.return_to'(This)], Login) - }, - html_acc_item(new, - 'please login to access other functions', - [ - div(a([class(login), href(Login)], ['login'])) - ], - [inactive] - ). - -html_vocab_table(Vs) --> - html([ - \html_requires(sortable), - table([class(sortable)], - [thead(tr(\html_vocab_head)), - tbody(\html_vocab_rows(Vs)) - ]) - ]). - -html_vocab_head --> - html([th([]), - th(class(name), name), - th(class(version), version), - th(class(count), 'estimated #concepts'), - th(class(preflangs), 'prefLabels'), - th(class(altlangs), 'altLabels') - ]). - -html_vocab_rows([]) --> !. -html_vocab_rows([Scheme|Vs]) --> { - ( voc_property(Scheme, numberOfConcepts(ConceptCount), [compute(false)]) - -> true - ; rdf_estimate_complexity(_, skos:inScheme, Scheme, ConceptCount) - ), - voc_property(Scheme, languages(skos:prefLabel, PrefLangs)), - voc_property(Scheme, languages(skos:altLabel, AltLangs)), - voc_property(Scheme, version(Version0)), - ( Version0 == '' - -> voc_property(Scheme, revision(Version)) - ; Version = Version0 - ) -}, - html(tr([td(input([type(checkbox), autocomplete(off), class(option), - name(scheme), value(Scheme)])), - td(class(name), \html_scheme_name(Scheme)), - td(class(version), Version), - td(class(count), ConceptCount), - td([span(class(preflangs), \html_showlist(PrefLangs))]), - td([span(class(altlangs), \html_showlist(AltLangs) )]) - - ])), - html_vocab_rows(Vs). - - -%% html_open(+Alignments) -% -% -html_open([]) --> - html_acc_item(open, - div([style('font-style: italic; color: gray')], - 'no strategies have been created yet'), - [], - [inactive]), - !. -html_open(Alignments) --> - { ButtonsBottom = div([ \html_submit('View selected'), - \html_submit('Merge selected'), - \html_submit('Delete selected') - ]), - length(Alignments, N), - ( N > 7 - -> ButtonsTop = ButtonsBottom - ; ButtonsTop = div([],[]) - ) - }, - html_acc_item(open, - 'edit/delete pre-loaded alignment strategy', - [ form(action(location_by_id(http_ag_form_select_strategy)), - [ - ButtonsTop, - \html_strategy_table(Alignments, - [linkto(http_ag_build)]), - ButtonsBottom - - ]) - ], - [active] - ). -html_publish([]) --> - html_acc_item(open, - div([style('font-style: italic; color: gray')], - 'no mappings have been created yet'), - [], - [inactive]), - !. -html_publish(Strategies) --> - { - has_write_permission, - L=http_ag_publish_form, - ! - }, - html_acc_item(publish, - 'publish alignment strategy results', - [ form(action(location_by_id(L)), - [ \html_strategy_table(Strategies, [linkto(L)]), - \html_submit('Publish') - ]) - ], - [inactive]). -html_publish(_) --> !. - - -%% html_strategy_table(+Graphs, +Options) -% -% Emit HTML table with strategy graph properties. - -html_strategy_table(Strategies, Options) --> - html([ - \html_requires(sortable), - table( - [class(sortable)], - [ thead(tr(\html_alignment_head)), - tbody(\html_alignment_rows(Strategies, Options)) - ]) - ]). - -html_alignment_head --> - html([th([]), - th(name), - th(includes), - th('Created by:'), - th('Comment:') - ]). - -html_alignment_rows([],_) --> !. -html_alignment_rows([URI-Schemes|Gs], Options) --> - { - ( rdf(URI, dcterms:creator, Author, URI) - -> true - ; Author = anonymous - ), - ( rdf(URI, rdfs:comment, CommentR, URI) - -> literal_text(CommentR, Comment) - ; Comment = '' - ) - }, - html(tr([td(input([type(checkbox), autocomplete(off), class(option), name(strategy), value(URI)])), - td(\html_strategy_name(URI, Options)), - td(\html_scheme_labels(Schemes)), - td(\turtle_label(Author)), - td([class(comment)],Comment) - ])), - html_alignment_rows(Gs, Options). - -html_scheme_labels([]) --> !. -html_scheme_labels([S|Ss]) --> - html(div(\turtle_label(S))), - html_scheme_labels(Ss). - -html_strategy_name(Graph, Options) --> - { graph_label(Graph, Label), - option(linkto(LinkTo), Options, http_ag_build), - http_link_to_id(LinkTo, [strategy(Graph)], Link) - }, - html(a([href(Link)],Label)). - -html_scheme_name(Graph) --> - { graph_label(Graph, Label), - http_link_to_id(http_skos_browser, [scheme(Graph)], Link) - }, - html(a([href(Link)],Label)). - -graph_label(Graph, Label) :- - rdf_display_label(Graph, Lit), - literal_text(Lit, Label),!. -graph_label(Graph, Graph). - -html_reference --> - { has_write_permission, - ! - }, - html_acc_item(reference, - 'upload existing/reference alignment', - form([action(location_by_id(http_ag_form_upload_reference)), - method('POST'), - enctype('multipart/form-data') ], - [ p(['Upload an exisiting alignment to build upon, ', - 'or to use as reference (ground truth)' ]), - input([type(file), name(data), - size(50), autocomplete(off) - ]), - input([type(submit), value('Upload')]) - ]), - [inactive] - ). - -html_reference --> !. - -html_import --> - { - has_write_permission, - ! - }, - html_acc_item(import, - 'upload strategy or clone execution trace', - [ form([action(location_by_id(http_ag_form_upload_strategy_resource)), - method('POST') - ], - [ 'URL: ', - input([type(text), name(url), value('http://'), - autocomplete(off), size(50) - ]), - input([type(submit), value('Upload')]) - ]), - form([action(location_by_id(http_ag_form_upload_strategy_data)), - method('POST'), - enctype('multipart/form-data') - ], - [ 'File: ', - input([type(file), name(data), - size(50)%, autocomplete(off) - ]), - input([type(submit), value('Upload')]) - ]) - ], - [inactive]). - -html_import --> !. - -%% html_submit(+Label) -% -% - -html_submit(Label) --> - html(span(class(controls), - [ input([type(submit), autocomplete(off), class(start), - name(submit), disabled(true), value(Label)]) - ])). - - -%% html_acc_item(+Id, +Label, +HTMLBody, +Options) -% -% Emit html markup for a YUI3 accordion item. -% Options: -% -% * active/inactive - -html_acc_item(Id, Label, Body, Options) --> - { ( option(active, Options) - -> Class = 'yui3-accordion-item yui3-accordion-item-active' - ; Class = 'yui3-accordion-item' - ) - }, - html(div([class(Class), id(Id)], - [ div(class('yui3-accordion-item-hd'), - a([href('javascript:{}'), class('yui3-accordion-item-trigger')], - Label)), - div(class('yui3-accordion-item-bd'), - Body) - ])). - - %% yui_script % % Emit YUI object. @@ -528,108 +97,9 @@ js_module(startpage, json([fullpath(Path), http_absolute_location(js('startpage.js'), Path, []). -%% new_strategy(-StrategyURI, Options) -% -% Assert a new strategy graph. - -new_strategy(S, Options) :- - authorized(write(default, _)), - new_strategy_name(S, NS), - rdf_assert(S, rdf:type, amalgame:'AlignmentStrategy', S), - rdf_assert(S, rdf:type, prov:'Plan', S), - rdf_assert(S, amalgame:publish_ns, NS, S), - assert_user_provenance(S, S), - - ( option(schemes(Schemes), Options) - -> add_schemes(Schemes, S) - ; true), - - ( option(comment(C), Options) - -> rdf_assert(S, rdfs:comment, literal(C), S) - ; true - ). - -add_schemes([], _). -add_schemes([Scheme|Ss], Strategy) :- - rdf_assert(Strategy, amalgame:includes, Scheme, Strategy), - add_schemes(Ss, Strategy). - -new_strategy_name(Strategy, NS) :- - setting(amalgame:default_publish_namespace, NS), - reset_gensym(strategy), - repeat, - gensym(strategy, Local), - atomic_list_concat([NS,Local], Strategy), - \+ rdf_graph(Strategy), - !. -new_reference_name(Reference) :- - setting(amalgame:default_publish_namespace, NS), - reset_gensym(reference_alignment), - repeat, - gensym(reference_alignment, Local), - atomic_list_concat([NS,Local], Reference), - \+ rdf_graph(Reference), - !. - -cp_strategy_from_tmp(Request, TmpGraph) :- - rdf(Strategy, rdf:type, amalgame:'AlignmentStrategy', TmpGraph),!, - cp_graph(TmpGraph, Strategy, true), - rdf_unload_graph(TmpGraph), - build_redirect(Request, [Strategy]). - -build_redirect(Request, [Strategy|_]) :- - http_link_to_id(http_ag_build, [strategy(Strategy)], Redirect), - http_redirect(moved, Redirect, Request). - -delete_redirect(Request, Strategies) :- - authorized(write(default, _)), - forall(member(Strategy, Strategies), - ( ( provenance_graph(Strategy, Prov) - -> rdf_unload_graph(Prov) - ; true - ), - rdf_unload_graph(Strategy) - ) - ), - http_link_to_id(http_amalgame_main_page, [], Redirect), - http_redirect(moved, Redirect, Request). - -merge_redirect(Request, Strategies) :- - % Create comment - maplist(scheme_label, Strategies, Labeled), - keysort(Labeled, Sorted), - pairs_keys(Sorted, Labels), - atomic_list_concat(Labels, ', ', LabelsAtom), - atomic_concat('Strategy merged from ', LabelsAtom, Comment), - % Create merged strategy - new_strategy(New, [comment(Comment)]), - cp_graphs(Strategies, New), - merge_strategy_nodes(Strategies, New), - % Redirect to builder - http_link_to_id(http_ag_build, [strategy(New)], Redirect), - http_redirect(moved, Redirect, Request). -merge_strategy_nodes([], _New) :- !. -merge_strategy_nodes([H|T], New) :- - findall(rdf(H,P,O), - rdf(H,P,O,New), - Triples), - forall(member(rdf(_,P,O), Triples), - rdf_assert(New,P,O,New)), - merge_strategy_nodes(T, New). -cp_graphs([], _Target) :- !. -cp_graphs([Head|Tail], Target) :- - cp_graph(Head, Target, false), - cp_graphs(Tail, Target). -cp_graph(Source, Target, true) :- - rdf_unload_graph(Target), % Delete old graphs under the same name - cp_graph(Source, Target, false). -cp_graph(Source, Target, false) :- - findall(rdf(S,P,O), rdf(S,P,O,Source), Triples), - forall(member(rdf(S,P,O), Triples), - rdf_assert(S,P,O,Target)). diff --git a/components/amalgame/startpage.pl b/components/amalgame/startpage.pl new file mode 100644 index 0000000..d01b08f --- /dev/null +++ b/components/amalgame/startpage.pl @@ -0,0 +1,318 @@ +:- module(ag_component_startpage, + [ html_new//1, % +Schemes + html_open//1, % +Strategies + html_publish//1, % +Strategies + html_reference//0, + html_import//0 + ]). + +:- use_module(library(option)). +:- use_module(library(semweb/rdf_db)). +:- use_module(library(http/http_dispatch)). +:- use_module(library(http/html_head)). +:- use_module(library(http/html_write)). + +:- use_module(library(semweb/rdf_label)). +:- use_module(components(label)). + +:- use_module(library(amalgame/util)). +:- use_module(library(amalgame/voc_stats)). +:- use_module(components(amalgame/util)). + +html_new([]) --> + html_acc_item(new, + 'new alignment strategy: no (SKOS) vocabularies found', + div([style('padding: 1%')],[ + 'Please use the Repository drop-down menu to load ', + 'the vocabularies you would like to align ', + 'into the repository/triple store.' + ]), + [active] + ). + +html_new(Schemes) --> + { has_write_permission, !, + ButtonsBottom = div(\html_submit('Start')), + length(Schemes, N), + ( N > 7 + -> ButtonsTop = ButtonsBottom + ; ButtonsTop = div([],[]) + ) + }, + html_acc_item(new, + 'new alignment strategy', + [ form(action(location_by_id(http_ag_form_new_strategy)), + [ ButtonsTop, + \html_vocab_table(Schemes), + ButtonsBottom + ]) + ], + [active] + ). + +html_new(_) --> + { + http_location_by_id(http_amalgame_main_page, This), + http_link_to_id(cliopatria_openid:login_page, + ['openid.return_to'(This)], Login) + }, + html_acc_item(new, + 'please login to access other functions', + [ + div(a([class(login), href(Login)], ['login'])) + ], + [inactive] + ). + +%% html_open(+Alignments) +% +% +html_open([]) --> + html_acc_item(open, + div([style('font-style: italic; color: gray')], + 'no strategies have been created yet'), + [], + [inactive]), + !. +html_open(Strategies) --> + { ButtonsBottom = div([ \html_submit('View selected'), + \html_submit('Merge selected'), + \html_submit('Delete selected') + ]), + length(Strategies, N), + ( N > 7 + -> ButtonsTop = ButtonsBottom + ; ButtonsTop = div([],[]) + ) + }, + html_acc_item(open, + 'edit/delete pre-loaded alignment strategy', + [ form(action(location_by_id(http_ag_form_select_strategy)), + [ + ButtonsTop, + \html_strategy_table(Strategies, + [linkto(http_ag_build)]), + ButtonsBottom + + ]) + ], + [active] + ). +html_publish([]) --> + html_acc_item(open, + div([style('font-style: italic; color: gray')], + 'no mappings have been created yet'), + [], + [inactive]), + !. +html_publish(Strategies) --> + { + has_write_permission, + L=http_ag_publish_form, + ! + }, + html_acc_item(publish, + 'publish alignment strategy results', + [ form(action(location_by_id(L)), + [ \html_strategy_table(Strategies, [linkto(L)]), + \html_submit('Publish') + ]) + ], + [inactive]). +html_publish(_) --> !. + + +html_reference --> + { has_write_permission, + ! + }, + html_acc_item(reference, + 'upload existing/reference alignment', + form([action(location_by_id(http_ag_form_upload_reference)), + method('POST'), + enctype('multipart/form-data') ], + [ p(['Upload an exisiting alignment to build upon, ', + 'or to use as reference (ground truth)' ]), + input([type(file), name(data), + size(50), autocomplete(off) + ]), + input([type(submit), value('Upload')]) + ]), + [inactive] + ). + +html_reference --> !. + +html_import --> + { + has_write_permission, + ! + }, + html_acc_item(import, + 'upload strategy or clone execution trace', + [ form([action(location_by_id(http_ag_form_upload_strategy_resource)), + method('POST') + ], + [ 'URL: ', + input([type(text), name(url), value('http://'), + autocomplete(off), size(50) + ]), + input([type(submit), value('Upload')]) + ]), + form([action(location_by_id(http_ag_form_upload_strategy_data)), + method('POST'), + enctype('multipart/form-data') + ], + [ 'File: ', + input([type(file), name(data), + size(50)%, autocomplete(off) + ]), + input([type(submit), value('Upload')]) + ]) + ], + [inactive]). + +html_import --> !. + +/* Helper rules to implement the stuff above: */ + +html_vocab_table(Vs) --> + html([ + \html_requires(sortable), + table([class(sortable)], + [thead(tr(\html_vocab_head)), + tbody(\html_vocab_rows(Vs)) + ]) + ]). + +html_vocab_head --> + html([th([]), + th(class(name), name), + th(class(version), version), + th(class(count), 'estimated #concepts'), + th(class(preflangs), 'prefLabels'), + th(class(altlangs), 'altLabels') + ]). + +html_vocab_rows([]) --> !. +html_vocab_rows([Scheme|Vs]) --> { + ( voc_property(Scheme, numberOfConcepts(ConceptCount), [compute(false)]) + -> true + ; rdf_estimate_complexity(_, skos:inScheme, Scheme, ConceptCount) + ), + voc_property(Scheme, languages(skos:prefLabel, PrefLangs)), + voc_property(Scheme, languages(skos:altLabel, AltLangs)), + voc_property(Scheme, version(Version0)), + ( Version0 == '' + -> voc_property(Scheme, revision(Version)) + ; Version = Version0 + ) +}, + html(tr([td(input([type(checkbox), autocomplete(off), class(option), + name(scheme), value(Scheme)])), + td(class(name), \html_scheme_name(Scheme)), + td(class(version), Version), + td(class(count), ConceptCount), + td([span(class(preflangs), \html_showlist(PrefLangs))]), + td([span(class(altlangs), \html_showlist(AltLangs) )]) + + ])), + html_vocab_rows(Vs). + + + + +%% html_strategy_table(+Graphs, +Options) +% +% Emit HTML table with strategy graph properties. + +html_strategy_table(Strategies, Options) --> + html([ + \html_requires(sortable), + table( + [class(sortable)], + [ thead(tr(\html_alignment_head)), + tbody(\html_alignment_rows(Strategies, Options)) + ]) + ]). + +html_alignment_head --> + html([th([]), + th(name), + th(includes), + th('Created by:'), + th('Comment:') + ]). + +html_alignment_rows([],_) --> !. +html_alignment_rows([URI-Schemes|Gs], Options) --> + { + ( rdf(URI, dcterms:creator, Author, URI) + -> true + ; Author = anonymous + ), + ( rdf(URI, rdfs:comment, CommentR, URI) + -> literal_text(CommentR, Comment) + ; Comment = '' + ) + }, + html(tr([td(input([type(checkbox), autocomplete(off), class(option), name(strategy), value(URI)])), + td(\html_strategy_name(URI, Options)), + td(\html_scheme_labels(Schemes)), + td(\turtle_label(Author)), + td([class(comment)],Comment) + ])), + html_alignment_rows(Gs, Options). + +html_scheme_labels([]) --> !. +html_scheme_labels([S|Ss]) --> + html(div(\turtle_label(S))), + html_scheme_labels(Ss). + +html_strategy_name(Graph, Options) --> + { rdf_graph_label(Graph, Label), + option(linkto(LinkTo), Options, http_ag_build), + http_link_to_id(LinkTo, [strategy(Graph)], Link) + }, + html(a([href(Link)],Label)). + +html_scheme_name(Graph) --> + { rdf_graph_label(Graph, Label), + http_link_to_id(http_skos_browser, [scheme(Graph)], Link) + }, + html(a([href(Link)],Label)). + + +%% html_submit(+Label) +% +% + +html_submit(Label) --> + html(span(class(controls), + [ input([type(submit), autocomplete(off), class(start), + name(submit), disabled(true), value(Label)]) + ])). + + +%% html_acc_item(+Id, +Label, +HTMLBody, +Options) +% +% Emit html markup for a YUI3 accordion item. +% Options: +% +% * active/inactive + +html_acc_item(Id, Label, Body, Options) --> + { ( option(active, Options) + -> Class = 'yui3-accordion-item yui3-accordion-item-active' + ; Class = 'yui3-accordion-item' + ) + }, + html(div([class(Class), id(Id)], + [ div(class('yui3-accordion-item-hd'), + a([href('javascript:{}'), class('yui3-accordion-item-trigger')], + Label)), + div(class('yui3-accordion-item-bd'), + Body) + ])). + + diff --git a/lib/amalgame/rdf_util.pl b/lib/amalgame/rdf_util.pl new file mode 100644 index 0000000..041dfe4 --- /dev/null +++ b/lib/amalgame/rdf_util.pl @@ -0,0 +1,34 @@ +:- module(ag_rdf_util, [ + cp_graphs/2, + cp_graph/3 + ]). + +:- use_module(library(lists)). +:- use_module(library(semweb/rdf_db)). + + +%% cp_graphs(+GraphList, Target) is det. +% +% Copy all triples in the named graphs in GraphList to the named +% graph Target. + +cp_graphs([], _Target) :- !. +cp_graphs([Head|Tail], Target) :- + cp_graph(Head, Target, false), + cp_graphs(Tail, Target). + +%% cp_graph(+Source, +Target, +Overwrite) is det. +% +% Copy all triples from Source to Target. +% If Overwrite is true, existing triples in Target are removed +% first. + +cp_graph(Source, Target, true) :- + rdf_unload_graph(Target), % Delete old graphs under the same name + cp_graph(Source, Target, false). + +cp_graph(Source, Target, false) :- + findall(rdf(S,P,O), rdf(S,P,O,Source), Triples), + forall(member(rdf(S,P,O), Triples), + rdf_assert(S,P,O,Target)). + diff --git a/lib/amalgame/util.pl b/lib/amalgame/util.pl index 4e7b891..7cb3171 100644 --- a/lib/amalgame/util.pl +++ b/lib/amalgame/util.pl @@ -1,6 +1,7 @@ :- module(ag_utils, [ mint_node_uri/3, amalgame_strategy_schemes/2, + amalgame_alignable_schemes/1, js_mappings_metadata/3, js_focus_node/3, @@ -8,6 +9,7 @@ rdf_lang/3, rdf_lang/4, + rdf_graph_label/2, assert_user_provenance/2, @@ -38,6 +40,7 @@ :- use_module(library(amalgame/ag_stats)). :- use_module(library(amalgame/ag_reference)). :- use_module(library(amalgame/ag_evaluation)). +:- use_module(library(amalgame/voc_stats)). :- multifile ag:menu_item/2. @@ -64,6 +67,31 @@ mint_node_uri(Strategy, Type, URI) :- \+ rdf_graph(URI), !. +%% amalgame_alignable_schemes(-Schemes) is det. +% +% Schemes is unified with a sorted list of urls of +% skos:ConceptSchemes or other alignable objects. +% +% Sorting is based on case insensitive scheme labels. + +amalgame_alignable_schemes(Schemes) :- + findall(C, + ( is_vocabulary(C), + voc_property(C, virtual(false)) + ), + All), + maplist(scheme_label, All, Labeled), + keysort(Labeled, Sorted), + pairs_values(Sorted, Schemes). + +scheme_label(URI, Key-URI) :- + rdf_graph_label(URI, CasedKey), + downcase_atom(CasedKey, Key). + +rdf_graph_label(Graph, Label) :- + rdf_display_label(Graph, Lit), + literal_text(Lit, Label),!. +rdf_graph_label(Graph, Graph). my_atom_json_dict(Json, Dict, Options) :- var(Dict),!, @@ -168,8 +196,21 @@ mapping_metadata(Strategy, M, _) :- js_focus_node(Strategy, URI, NodeProps) :- findall(Type-Value, node_prop(Strategy, URI, Type, Value), Pairs), - dict_pairs(NodeProps, node, Pairs). + group_pairs_by_key_if_needed(Pairs, Grouped), + dict_pairs(NodeProps, node, Grouped). + +group_pairs_by_key_if_needed([], []). +group_pairs_by_key_if_needed([M-N|T0], [M-Result|T]) :- + same_key(M, T0, TN, T1), + ( TN == [] + -> Result = N + ; Result = [N|TN] + ), + group_pairs_by_key_if_needed(T1, T). +same_key(M, [M-N|T0], [N|TN], T) :- !, + same_key(M, T0, TN, T). +same_key(_, L, [], L). %% js_strategy_nodes(+Strategy, -Nodes) % % Nodes contains all nodes in alignment Strategy with their type @@ -193,7 +234,8 @@ graph_resource(Graph, R) :- node_data(Strategy, R, R-Props) :- findall(Type-Value, node_prop(Strategy, R, Type, Value), Pairs), - dict_pairs(Props, node, Pairs). + group_pairs_by_key_if_needed(Pairs, Grouped), + dict_pairs(Props, node, Grouped). node_prop(_, R, uri, R). node_prop(S, R, label, Label) :-