yaz/commit
ongoing conversion to new data model
author | Michiel Hildebrand |
---|---|
Wed Feb 2 16:23:33 2011 +0100 | |
committer | Michiel Hildebrand |
Wed Feb 2 16:23:33 2011 +0100 | |
commit | 0859f6f0378d1af5dd36945d80094145577e6f76 |
tree | 30f054a51b6b14f982cf3ca07f742c0eed4ad5ba |
parent | 0a03b05d1f7278aaf280f436b83c0a3e9a101556 |
Diff style: patch stat
diff --git a/applications/yaz_game.pl b/applications/yaz_game.pl index 613068e..02a538d 100644 --- a/applications/yaz_game.pl +++ b/applications/yaz_game.pl @@ -80,13 +80,12 @@ http_yaz_game(Request) :- nonvar(URL) -> create_game(URL, User, Game, [video(Video),title(Title)]), html_waiting_page(Game, URL, User) - ; setting(match_interval, Interval), - join_game(Game, User), + ; join_game(Game, User), game_video_start(Game, URL, PlayHead), PlayerObj = {player:P, name:Name, score:Score}, findall(PlayerObj, active_player(Game, P, Name, Score), Players), - TagObj = json([tag=Tag, label=Label, match=Match, type=Type, order=Order]), - findall(Time-TagObj, user_annotation(Game, User, Interval, Tag, Label, Time, Type, Match, Order), Tags0), + TagObj = json([annotation=A, label=Tag, time=Time, match=Match]), + findall(Time-TagObj, user_tag(Game, User, A, Tag, Time, Match), Tags0), keysort(Tags0, Tags1), reverse(Tags1, Tags2), pairs_values(Tags2, Tags), @@ -299,17 +298,16 @@ html_page_yui(Game, URL, User, PlayHead, Players, Tags) --> })), \js_support_functions(Game, User, DataServer), \js_call('Y.later'(RequestInterval, symbol('Y'), - symbol(fetchData), symbol({}), symbol(true))), + symbol(fetchData), symbol(null), symbol(true))), \js_call('videoPlayer.render'('#videoplayer')), \js_input_method ]). js_support_functions(Game, User, DataServer) --> - js_function_decl(fetchData, [tag], + js_function_decl(fetchData, [e], \[ ' var data = {game:"',Game,'",user:"',User,'",playhead:videoPlayer.getTime()*1000}; - if(tag.label) {data.tag = tag.label} - if(tag.uri) {data.taguri = tag.uri} + if(e) {data.tag=e.label;} Y.io("',DataServer,'", {data: data, on: {success:handleResponse} });\n' @@ -317,9 +315,9 @@ js_support_functions(Game, User, DataServer) --> js_function_decl(handleResponse, [id, o], \[ -' var data = Y.JSON.parse(o.responseText); - gamePlayers.updatePlayers(data.players); - gameInput.updateTags(data.tags);\n' +' var r = Y.JSON.parse(o.responseText); + gamePlayers.updatePlayers(r.players); + gameInput.updateTags(r.tags);\n' ]). js_input_method --> @@ -375,7 +373,8 @@ create_game(URL, Player, Game, _Options) :- create_game(URL, Player, Game, Options) :- option(video(Video), Options, _), option(title(Title), Options, _), - create_user_process([rdf:type=pprime:'Game', + create_user_process(Player, + [rdf:type=pprime:'Game', opmv:used=URL ], Game), new_player_score(Game, Player), @@ -415,7 +414,7 @@ game_video_start(_Game, '', 0). % for testing join_game(Game, Player) :- ( user_process_joined(Game, Player) -> set_active_process(Game) - ; join_user_process(Game), + ; join_user_process(Game, Player), debug(game, 'Game ~w joined by ~w', [Game, Player]), new_player_score(Game, Player) ). @@ -430,34 +429,16 @@ quit_game(Game, Player) :- left_game(Game, Player), !. quit_game(Game, Player) :- - debug(game, 'Quit game ~w by ~w', [Game, Player]), - get_time(Time), - rdf_bnode(QuitEvent), - player_score(Game, Player, Score), - rdf_transaction(assert_quit_event(QuitEvent, Game, Player, Score, Time)), - retractall(player_score(Game, Player, Score)), - debug(game, 'Game quit with event ~w', [QuitEvent]). - -assert_quit_event(ID, Game, Player, Score, Time) :- - get_time(Time), - rdf_assert(ID, sem:subEventOf, Game, Game), - rdf_assert(ID, rdf:type, pprime:'QuitGame', Game), - rdf_assert(ID, sem:hasActor, Player, Game), - rdf_assert(ID, sem:timeStampedAt, literal(Time), Game), - rdf_assert(ID, pprime:finalScore, literal(Score), Game). - - -%% add_tag(+Game, +Player, +Tag, +TagURI, +PlayHeadTime) + debug(game, 'Quit game ~w by ~w', [Game, Player]). + + +%% add_tag(+Game, +Player, +Tag, +PlayHeadTime, -AnnotationId) % % Asserts that User has entered a Tag. -add_tag(Game, Player, TagLabel, TagURI, PlayHead) :- +add_tag(Game, Player, Tag, PlayHead, AnnotationId) :- rdf(Game, opmv:used, URL), - ( nonvar(TagURI) - -> Tag = TagURI - ; Tag = TagLabel - ), - create_video_annotation(URL, literal(Tag), PlayHead, Player, AnnotationId), + create_video_annotation(URL, literal(Tag), PlayHead, Player, AnnotationId), debug(game, 'Added tag ~w at time ~w by ~w (~w)', [Tag, PlayHead, Player, AnnotationId]). %% active_player(+Game, -Player, -Name, Score) @@ -478,86 +459,51 @@ left_game(Game, Player) :- rdf(QuitEvent, sem:hasActor, Player, Game). -%% user_annotation(+Game, +User, +Interval, -Tag, -Time, -Type, -%% -Match, -Order) +%% user_tag(+Game, +User, -Annotation, -Tag, -Match) % % Tag is entered by User during Game. -user_annotation(Game, User, Interval, Tag, Label, Time, Type, Match, Order) :- +user_tag(Game, User, Annotation, Tag, Time, Match) :- rdf(Annotation, pprime:creator, User, Game), - rdf(Annotation, rdf:value, TagTerm), - rdf(Annotation, pprime:videoPlayhead, Time0), - literal_to_number(Time0, Time), - tag_type(TagTerm, Type, Tag, Label), - matching_type(Game, User, TagTerm, Time, Interval, Match, Order). + rdf(Annotation, rdf:value, literal(Tag)), + rdf(Annotation, pprime:videoPlayhead, literal(Time), _), + matched_json_term(Annotation, Match). -tag_type(literal(Tag), literal, Tag, Tag) :- !. -tag_type(Tag, uri, Tag, Label) :- - rdf(Tag, rdfs:label, literal(Label)). +matched_json_term(Annotation, json([type=Match, score=Score, order=Order])) :- + rdf(Annotation, pprime:match, literal(Match)), + !, + rdf(Annotation, pprime:score, literal(Score)), + rdf(Annotation, pprime:order, literal(Order)). +matched_json_term(_, @false). -%% user_matched_tag(+Game, +User, +PlayHead, +Interval, -Tag, -%% -Label, -Type, -Match, Order) +%% user_matched_tag(+Game, +User, +PlayHead, +Interval, +%% -Annotation, -Match, -Score) % % Tag is entered by User during Game. -user_matched_tag(Game, User, PlayHead, Interval, Tag, Label, Type, Match, Order) :- - rdf(Annotation, pprime:creator, User, Game), - rdf(Annotation, pprime:videoPlayhead, literal(Time0), Game), - literal_to_number(Time0, Time), - Time > PlayHead-Interval, - rdf(Annotation, rdf:value, TagTerm, Game), - tag_type(TagTerm, Type, Tag, Label), - matching_type(Game, User, TagTerm, Time, Interval, Match, Order), - Match \== @false. - -%% matching_type(+Game, +User, +Tag, +Time, +Interval, -MatchType, -%% -Order) -% -% Matchtype is one of [....] indicating how Tag can be matched. - -matching_type(Game, User, Tag, Time, Interval, MatchType, Order) :- - match_existing_tags(Game, User, Tag, Time, Interval, Matches), - ( Matches = [] - -> MatchType = @false, - Order = 0 - ; user_best_match(Matches, MatchType), - tag_order(Matches, 1, Order) - ). - -tag_order([], N, N). -tag_order([match(_, _, Diff, _)|_T], N, N) :- - Diff =< 0, !. -tag_order([_|T], N0, N) :- - N1 is N0+1, - tag_order(T, N1, N). - -%% tag_match(+Game, +User, +Tag, +Time, +Interval, -Player, -%% -Diff) +user_matched_tag(Game, User, Playhead, Interval, Annotation, Match) :- + Start is Playhead-Interval, + rdf(Annotation, pprime:videoPlayhead, literal(between(Start,Playhead), _), Game), + rdf(Annotation, pprime:creator, User), + matched_json_term(Annotation, Match). + +%% tag_match(+Game, +User, +Tag, +VideoTime, +Interval, +%% -Annotation, -Player, -Diff) % % Returns players that entered the same Tag within Interval of % Time. -tag_match(Game, User, Tag, PlayHead, Interval, Player, Diff, exact, Type) :- - matching_annotation(Game, Tag, Annotation, Type), - rdf(Annotation, pprime:videoPlayhead, literal(Time0), Game), +match_tag(Game, User, Tag, Playhead, Interval, Annotation, Player, Match, Diff) :- + Start is Playhead-Interval, + tag_match_(Tag, Game, Annotation, Match), + rdf(Annotation, pprime:videoPlayhead, literal(between(Start,Playhead), Time0)), + rdf(Annotation, pprime:creator, Player), + User \== Player, literal_to_number(Time0, Time), - Diff is PlayHead-Time, - Interval >= abs(Diff), - rdf(Annotation, pprime:creator, Player, Game), - User \== Player. - -matching_annotation(Game, Tag, Annotation, Type) :- - rdf(Annotation, rdf:value, Tag, Game), - ( Tag = literal(_) - -> Type = literal - ; Type = uri - ). -matching_annotation(Game, literal(Tag), Annotation, uri) :- !, - rdf(Annotation, rdf:value, TagURI, Game), - rdf(TagURI, rdfs:label, literal(exact(Tag),_)). -matching_annotation(Game, TagURI, Annotation, literal) :- - rdf(TagURI, rdfs:label, literal(Tag)), - rdf(Annotation, sem:involves, literal(exact(Tag),_), Game). + Diff is Playhead-Time. + +tag_match_(Tag, Game, Annotation, exact) :- + rdf(Annotation, rdf:value, literal(Tag), Game). :- http_handler(yaz('gamedata'), http_game_data, []). @@ -576,88 +522,66 @@ http_game_data(Request) :- [number, description('Current time of the video play head (in miliseconds)')]), tag(Tag, [optional(true), - description('Optionally a new tag can be added')]), - taguri(TagURI, - [optional(true), - description('Optionally the new tag can have a URI')]) + description('Optionally a new tag can be added')]) ]), setting(match_interval, Interval), ( nonvar(Tag) - -> add_tag(Game, User, Tag, TagURI, Playhead), - update_scores(Game, User, Tag, TagURI, Playhead, Interval) - ; true + -> add_tag(Game, User, Tag, Playhead, AnnotationId), + match_existing_tags(Game, User, Tag, Playhead, Interval, Matches), + update_scores(Matches, AnnotationId, Game, User) + ; true ), - PlayerObj = json([player=P, name=Name, score=Score]), findall(PlayerObj, active_player(Game, P, Name, Score), Players), - TagObj = json([tag=T, label=L, type=Type, match=Match, order=Order]), + TagObj = json([annotation=A, match=Match]), findall(TagObj, - user_matched_tag(Game, User, Playhead, Interval, T, L, Type, Match, Order), + user_matched_tag(Game, User, Playhead, Interval, A, Match), Tags), reply_json(json([user=User, players=Players, tags=Tags])). -%% update_scores(+Game, +User, +Tag, +TagURI, +Playhead, +Interval) -% -% Find matching tags within interval of PlayHead and update player -% scores. - -update_scores(Game, User, TagL, TagURI, Playhead, Interval) :- - ( nonvar(TagURI) - -> Tag = TagURI, - Type = uri - ; Tag = literal(TagL), - Type = literal - ), - match_existing_tags(Game, User, Tag, Playhead, Interval, Matches), - ( Matches = [] - -> true - ; length(Matches, C0), - Total is C0+1, - update_player_scores(Matches, 1, Total, Game), - user_best_match(Matches, Match), - tag_match_points(Match, Type, Total, 0, Total, Points), - update_player_score(Game, User, Points) - ). - -user_best_match(Matches, Match) :- - maplist(user_match, Matches, Pairs0), - keysort(Pairs0, Pairs1), - reverse(Pairs1, [_Points-Match|_]). - -user_match(match(Match,_,_,_), P-Match) :- - ( Match = generic - -> match_points(specific, P) - ; match_points(Match, P) - ). - %% match_existing_tags(+Game, +User, +Tag, +Playhead, +Interval, %% -Matches) % % Returns all matching tag within Interval of Playhead match_existing_tags(Game, User, Tag, Playhead, Interval, Matches) :- - findall(Diff-match(Match, Type, Diff, Player), - tag_match(Game, User, Tag, Playhead, Interval, Player, Diff, Match, Type), + findall(Diff-match(Annotation, Player, Match, Diff), + match_tag(Game, User, Tag, Playhead, Interval, Annotation, Player, Match, Diff), Matches0), keysort(Matches0, Matches1), reverse(Matches1, Matches2), pairs_values(Matches2, Matches). -%% update_players_scores(+Matches, +EntryOrder, +TotalMatches, -%% +Game) + +%% update_scores(+Matches, +Annotation, +Game, +User) % -% Compute the scores for each player in Matches and update -% their score according to the type of Match. +% Find matching tags within interval of PlayHead and update player +% scores. + +update_scores([], _, _, _) :- !. +update_scores(Matches, Annotation, Game, User) :- + length(Matches, C0), + Total is C0+1, + % score of newly added tag + maplist(user_match_points, Matches, Pairs0), + keysort(Pairs0, Pairs1), + reverse(Pairs1, [_-Match|_]), + tag_match_points(Match, Total, 0, Total, Points), + rdf_transaction(assert_match(Annotation, Game, Match, Points, Total)), + update_player_score(Game, User, Points), + % scores of other matches + rdf_transaction(update_player_scores(Matches, 1, Total, Game)). update_player_scores([], _, _, _). -update_player_scores([match(Match,Type,Diff,Player)|Ms], N, Count, Game) :- +update_player_scores([match(Annotation,Player,Match,Diff)|Ms], N, Count, Game) :- N1 is N + 1, - tag_match_points(Match, Type, N, Diff, Count, Points), + tag_match_points(Match, N, Diff, Count, Points), + assert_match(Annotation, Game, Match, Points, N), update_player_score(Game, Player, Points), update_player_scores(Ms, N1, Count, Game). @@ -667,13 +591,17 @@ update_player_score(Game, Player, Points) :- NewScore is OldScore+Points, assert(player_score(Game, Player, NewScore)). -tag_match_points(Match, Type, Order, _Diff, _Total, Points) :- +user_match_points(match(_,_,Match,_), Points-Match) :- + ( Match = generic + -> match_points(specific, Points) + ; match_points(Match, Points) + ). + +tag_match_points(Match, Order, _Diff, _Total, Points) :- match_points(Match, MatchPoints), - type_points(Type, TypePoints), - Points0 is MatchPoints + TypePoints, - ( Order = 1 - -> Points is Points0*2 - ; Points = Points0 + ( Order = 1 + -> Points is MatchPoints*2 + ; Points = MatchPoints ). match_points(exact, 50). @@ -682,8 +610,10 @@ match_points(specific, 100). match_points(generic, 20). match_points(related, 20). -type_points(uri, 50). -type_points(literal, 0). +assert_match(Annotation, Game, Match, Score, Order) :- + rdf_assert(Annotation, pprime:match, literal(Match), Game), + rdf_assert(Annotation, pprime:score, literal(Score), Game), + rdf_assert(Annotation, pprime:order, literal(Order), Game). :- http_handler(yaz('waitingdata'), http_waiting_data, []). diff --git a/applications/yaz_game_recap.pl b/applications/yaz_game_recap.pl index 09e008f..0c59789 100644 --- a/applications/yaz_game_recap.pl +++ b/applications/yaz_game_recap.pl @@ -34,13 +34,14 @@ % of it. http_yaz_game_recap(Request) :- - ensure_logged_on(_), + ensure_logged_on(User0), + user_property(User0, url(User)), http_parameters(Request, [ video(Video, [description('Current video')]), process(Process, [optional(true), desription('When set only annotations within this process are shown')]), - user(User, + user(Player, [optional(true), description('When set only annotations created by this user are shown')]), interval(Interval, [default(0), number, @@ -55,11 +56,11 @@ http_yaz_game_recap(Request) :- [default(0),description('Start time of the video')]) ]), Options = [process(Process), - user(User), + user(Player), interval(Interval), confirmed(Confirmed) ], - create_user_process([rdf:type=pprime:'GameRecap', + create_user_process(User, [rdf:type=pprime:'GameRecap', opmv:used=Video ], _Process), video_annotations(Video, Annotations0, Options), diff --git a/applications/yaz_mgarden.pl b/applications/yaz_mgarden.pl index 6c428bc..5670cc9 100644 --- a/applications/yaz_mgarden.pl +++ b/applications/yaz_mgarden.pl @@ -28,6 +28,11 @@ :- http_handler(yaz(mgarden), http_yaz_mgarden, []). :- http_handler(yaz('data/confirmmatch'), http_yaz_api_confirm_match, []). +:- http_handler(yaz('data/mgarden'), http_yaz_api_mgarden_data, []). + + +:- setting(request_interval, integer, 2000, + 'Interval between requests to the server (in miliseconds)'). %% http_yaz_mgarden(+Request) % @@ -35,47 +40,57 @@ % of it. http_yaz_mgarden(Request) :- - ensure_logged_on(_), + ensure_logged_on(User0), + user_property(User0, url(CurrentUser)), http_parameters(Request, [ video(Video, [description('Current video')]), process(Process, [optional(true), desription('When set only annotations within this process are shown')]), user(User, - [optional(true), description('When set only annotations created by this user are shown')]) + [default(CurrentUser), + description('When set only annotations created by this user are shown')]) ]), Options = [process(Process), user(User) ], - create_user_process([rdf:type=pprime:'mgarden', - opmv:used=Video - ], _Process), + create_user_process(CurrentUser, [rdf:type=pprime:'mgarden', + opmv:used=Video + ], _Process), video_annotations(Video, As0, Options), sort_by_arg(As0, 2, As), tag_matches(As, User, Process, 10000, Annotations), - html_video_page(Video, Annotations, 0, Options). + html_video_page(Video, CurrentUser, Annotations, 0, Options). tag_matches([], _, _, _, []). tag_matches([A0|As], User, Process, Interval, [A|Rest]) :- A0 = annotation(Value,Start,End,Entries), A = annotation(Value,Start,End,Entries,Match), - ( tag_match(Value, Start, User, Process, Interval, Match) + ( existing_match(Entries, Match) + -> true + ; tag_match(Value, Start, User, Process, Interval, Match) -> true ; Match = @false ), tag_matches(As, User, Process, Interval, Rest). +existing_match(Entries, Match) :- + findall(S, (member(E, Entries), + rdf(i(E,_), pprime:score, S) + ), + Ss), + ( max_list(Ss, Score) + -> Match = match(exact, score(Score)) + ; Match = @false + ). tag_match(literal(Tag), Time, User, Game, Interval, Match) :- - Match = match(Type, E, literal(Tag1)), + Match = match(Type, 0, E, literal(Tag1)), snowball(english, Tag, Stem0), downcase_atom(Stem0, Stem), findall(Concept, find_tag_concept(Tag, Concept, _), Cs), tagentry_in_interval(Game, User, Time, Interval, E), - ( rdf(E, rdf:value, literal(Tag)) - -> Type = exact, - Tag1 = Tag - ; rdf(E, rdf:value, literal(Tag1)), + ( rdf(E, rdf:value, literal(Tag1)), snowball(english, Tag1, Stem1), downcase_atom(Stem1, Stem) -> Type = stem @@ -101,11 +116,12 @@ tagentry_in_interval(Game, User, Time, Interval, E) :- -%% html_video_page(+Video, +Annotations, +StartTime, +Options) +%% html_video_page(+Video, +User, +Annotations, +StartTime, +%% +Options) % % Emit an HTML page with a video player and a tag carousel. -html_video_page(Video, Annotations, StartTime, Options) :- +html_video_page(Video, User, Annotations, StartTime, Options) :- reply_html_page(yaz, [ title(['YAZ - ', Video]) ], @@ -113,7 +129,7 @@ html_video_page(Video, Annotations, StartTime, Options) :- div(class('video-results'), \html_video_page_containers(Video, Options)), script(type('text/javascript'), - \html_video_page_yui(Video, Annotations, StartTime, Options)) + \html_video_page_yui(Video, User, Annotations, StartTime, Options)) ]). html_video_page_containers(Video, _Options) --> @@ -126,11 +142,12 @@ html_video_page_containers(Video, _Options) --> ]) ]). -html_video_page_yui(Video, Annotations, StartTime, _Options) --> +html_video_page_yui(Video, User, Annotations, StartTime, _Options) --> { video_source(Video, Src), http_absolute_location(js('videoplayer/'), FilePath, []), http_absolute_location(js('videoplayer/videoplayer.js'), VideoPlayer, []), http_absolute_location(js('tagcarousel/tagcarousel.js'), TagCarousel, []), + setting(request_interval, RequestInterval), annotation_to_json(Annotations, JSONTags) }, html_requires(js('videoplayer/swfobject.js')), @@ -161,9 +178,27 @@ html_video_page_yui(Video, Annotations, StartTime, _Options) --> \js_call('videoPlayer.render'('#videoplayer')), \js_call('tagCarousel.render'('#tagplayer')), \js_yui3_on(tagCarousel, itemSelect, \js_tag_select), - \js_yui3_on(tagCarousel, itemConfirm, \js_confirm) + \js_yui3_on(tagCarousel, itemConfirm, \js_confirm(User)), + \js_support_functions(User), + \js_call('Y.later'(RequestInterval, symbol('Y'), + symbol(fetchData), symbol({}), symbol(true))) ]). +js_support_functions(User) --> + { http_location_by_id(http_yaz_api_mgarden_data, DataServer) + }, + js_function_decl(fetchData, [], + \[ +' var data = {user:"',User,'"}; + Y.io("',DataServer,'", {data: data, + on: {success:handleResponse} + });\n' + ]), + js_function_decl(handleResponse, [id, o], + \[ +' var data = Y.JSON.parse(o.responseText);\n' + ]). + js_tag_select --> js_function([e], \[ @@ -173,7 +208,7 @@ js_tag_select --> }\n' ]). -js_confirm --> +js_confirm(User) --> { http_location_by_id(http_yaz_api_confirm_match, ConfirmServer) }, js_function([e], @@ -183,7 +218,8 @@ js_confirm --> target = e.annotation.match.uri, match = e.annotation.match.type;\n', \js_call('Y.io'(ConfirmServer, { - data:{source:symbol(source), + data:{user:User, + source:symbol(source), target:symbol(target), match:symbol(match)}, on:{success:symbol('function(id, o) @@ -201,9 +237,10 @@ js_confirm --> % Handler for GET submission of a tag modification. http_yaz_api_confirm_match(Request) :- - ensure_logged_on(_), - http_parameters(Request, - [ source(Source, + http_parameters(Request, + [ user(User, + [description('URL of the user')]), + source(Source, [description('URL of source')]), target(Target, [description('URL of the target')]), @@ -212,18 +249,78 @@ http_yaz_api_confirm_match(Request) :- ]), debug(yaz(update), 'confirm ~w match between ~w and ~w', [Match, Source, Target]), + + ( confirmed(Match, Source, Target, User) + -> match_score(Match, Score) + ; Score = 0 + ), + rdf_bnode(Confirm), rdfh_transaction((rdfh_assert(Confirm, pprime:match, literal(Match)), - rdfh_assert(Confirm, pprime:source, Source), - rdfh_assert(Confirm, pprime:target, Target))), - match_score(Match, Score), + rdfh_assert(Confirm, pprime:creator, User), + rdfh_assert(Confirm, pprime:matchSource, Source), + rdfh_assert(Confirm, pprime:matchTarget, Target))), + reply_json(json([source=Source, target=Target, match=Match, score=Score ])). + +confirmed(specific, Source, Target, User) :- + rdf(Confirm, pprime:match, literal(Match)), + \+ rdf(Confirm, pprime:creator, User), + ( Match = specific + -> confirmed_(Confirm, Source, Target) + ; Match = generic + -> confirmed_(Confirm, Target, Source) + ). +confirmed(generic, Source, Target, User) :- + rdf(Confirm, pprime:match, literal(Match)), + \+ rdf(Confirm, pprime:creator, User), + ( Match = generic + -> confirmed_(Confirm, Source, Target) + ; Match = specific + -> confirmed_(Confirm, Target, Source) + ). +confirmed(Match, Source, Target, User) :- + rdf(Confirm, pprime:match, literal(Match)), + \+ rdf(Confirm, pprime:creator, User), + ( confirmed_(Confirm, Source, Target) + ; confirmed_(Confirm, Target, Source) + ). + +confirmed_(Confirm, Source, Target) :- + rdf(Confirm, pprime:matchSource, Source), + rdf(Confirm, pprime:matchTarget, Target). + match_score(stem, 10). match_score(synonym, 15). match_score(specific, 20). +match_score(generic, 20). + + +%% http_yaz_api_mgarden_data(+Request) +% +% Handler for request of match data. + +http_yaz_api_mgarden_data(Request) :- + http_parameters(Request, + [ user(User, + [description('URL of the user')]) + ]), + current_user_process(Process), + Obj = json([match=Match, score=Score]), + findall(Obj, user_confirmed(User, Process, Match, Score), Confirmed), + reply_json(Confirmed). +user_confirmed(User, Process, Confirm, Score) :- + rdf(Confirm, pprime:creator, User, Process), + rdf(Confirm, pprime:match, literal(Match)), + rdf(Confirm, pprime:matchSource, Source), + rdf(Confirm, pprime:matchTarget, Target), + ( confirmed(Match, Source, Target, User) + -> match_score(Match, Score) + ; Score = 0 + ). diff --git a/applications/yaz_sgarden.pl b/applications/yaz_sgarden.pl index 271a609..6c1d77b 100644 --- a/applications/yaz_sgarden.pl +++ b/applications/yaz_sgarden.pl @@ -33,25 +33,44 @@ % of it. http_yaz_sgarden(Request) :- - ensure_logged_on(_), + ensure_logged_on(User0), + user_property(User0, url(CurrentUser)), http_parameters(Request, [ video(Video, [description('Current video')]), process(Process, - [optional(true), desription('When set only annotations within this process are shown')]), + [optional(true), + desription('When set only annotations within this process are shown')]), user(User, - [optional(true), description('When set only annotations created by this user are shown')]) + [default(CurrentUser), + description('When set only annotations created by this user are shown')]) ]), Options = [process(Process), user(User) ], - create_user_process([rdf:type=pprime:'sgarden', - opmv:used=Video - ], _Process), - video_annotations(Video, Annotations0, Options), - sort_by_arg(Annotations0, 2, Annotations), + create_user_process(CurrentUser, [rdf:type=pprime:'sgarden', + opmv:used=Video + ], _Process), + video_annotations(Video, As, Options), + tag_matches(As, As1), + sort_by_arg(As1, 2, Annotations), html_video_page(Video, Annotations, 0, Options). +tag_matches([], []). +tag_matches([A0|As], [A|Rest]) :- + A0 = annotation(Value,Start,End,Entries), + A = annotation(Value,Start,End,Entries,Match), + findall(S, (member(i(E,_),Entries), + rdf(E, pprime:score, S) + ), + Ss), + ( max_list(Ss, Score) + -> Match = match(exact, score(Score)) + ; Match = @false + ), + tag_matches(As, Rest). + + %% html_video_page(+Video, +Annotations, +StartTime, +Options) % diff --git a/applications/yaz_tag_garden.pl b/applications/yaz_tag_garden.pl index d4f7429..1b35c81 100644 --- a/applications/yaz_tag_garden.pl +++ b/applications/yaz_tag_garden.pl @@ -37,7 +37,8 @@ :- http_handler(yaz('data/frames'), http_data_frames, []). http_yaz_tag_garden(Request) :- - ensure_logged_on(_), + ensure_logged_on(User0), + user_property(User0, url(CurrentUser)), http_parameters(Request, [ video(Video, [description('Current video')]), @@ -60,9 +61,9 @@ http_yaz_tag_garden(Request) :- interval(Interval), confirmed(Confirmed) ], - create_user_process([rdf:type=pprime:'TagGarden', - opmv:used=Video - ], _Process), + create_user_process(CurrentUser, [rdf:type=pprime:'TagGarden', + opmv:used=Video + ], _Process), video_annotations(Video, Annotations, Options), group_annotations(Annotations, AnnotationGroups), html_garden_page(Video, AnnotationGroups, Options). diff --git a/lib/user_process.pl b/lib/user_process.pl index 5666dea..ebe6376 100644 --- a/lib/user_process.pl +++ b/lib/user_process.pl @@ -3,9 +3,9 @@ user_process_creator/2, % +ProcessURI, ?User user_process_joined/2, % +ProcessURI, ?User set_active_process/1, % +ProcessURI - create_user_process/2, % +Properties, -ProcessURI + create_user_process/3, % +User, +Properties, -ProcessURI start_user_process/1, % ?ProcessURI - join_user_process/1, % +ProcessURI + join_user_process/2, % +ProcessURI end_user_process/1, % +ProcessURI add_resource_properties/2, % +URI, +Properties:list(p=v) resource_properties/2 % +URI, ?Properties:list(p=v) @@ -13,6 +13,7 @@ :- use_module(library(http/http_session)). :- use_module(library(semweb/rdf_db)). +:- use_module(library(semweb/rdfs)). :- use_module(user(user_db)). /** <module> Creation of processes in which annotations are made/modified @@ -25,7 +26,7 @@ http://openprovenance.org/. */ :- rdf_meta - create_user_process(t, r). + create_user_process(r, t, r). %% current_user_process(-Process) % @@ -64,19 +65,18 @@ set_active_process(Process) :- % True if Process is the current process of User and has % Properties. Creates a new user process if it doesn't exist. -create_user_process(Properties, Process) :- +create_user_process(_User, Properties, Process) :- current_user_process(Process), \+ rdf(Process, opmv:wasStartedAt, _), resource_properties(Process, Properties), !, set_active_process(Process). -create_user_process(Properties, Process) :- +create_user_process(User, Properties, Process) :- ( var(Process) -> rdf_bnode(Process) ; true ), - current_user_url(User), - set_active_process(Process), + set_active_process(Process), http_session_id(Session), rdf_transaction((rdf_assert(Process, rdf:type, opmv:'Process', Process), rdf_assert(Process, opmv:wasControlledBy, User, Process), @@ -85,20 +85,12 @@ create_user_process(Properties, Process) :- )), debug(user_process, 'Process ~w created by ~w', [Process, User]). -%% start_user_process(?Process) +%% start_user_process(+Process) % -% Start a process by assert the start time. When Process is -% variable a new process is created. +% Start a process by assert the start time. start_user_process(Process) :- - var(Process), - !, - create_user_process([], Process), - start_user_process_(Process). -start_user_process(Process) :- - start_user_process_(Process). - -start_user_process_(Process) :- + rdfs_individual_of(Process, opmv:'Process'), get_time(StartTime0), format_iso_dateTime(StartTime0, StartTime), rdf_transaction(rdf_assert(Process, opmv:wasStartedAt, literal(type(xsd:date, StartTime)), Process)), @@ -109,18 +101,19 @@ start_user_process_(Process) :- % End a process, by asserting the endTime end_user_process(Process) :- + rdfs_individual_of(Process, opmv:'Process'), get_time(EndTime0), format_iso_dateTime(EndTime0, EndTime), rdf_transaction((rdf_assert(Process, opmv:wasEndedAt, literal(type(xsd:date, EndTime), Process), Process) )), debug(user_process, 'Process ~w ended at ~w', [Process, EndTime]). -%% join_user_process(+Process) +%% join_user_process(+Process, +User) % % Add current user agent to a Process. -join_user_process(Process) :- - current_user_url(User), +join_user_process(Process, User) :- + rdfs_individual_of(Process, opmv:'Process'), set_active_process(Process), rdf_transaction(rdf_assert(Process, opmv:wasPerformedBy, User, Process)), debug(user_process, 'Process ~w joined by ~w', [Process, User]). diff --git a/lib/yaz_util.pl b/lib/yaz_util.pl index 0fba75a..ad5f994 100644 --- a/lib/yaz_util.pl +++ b/lib/yaz_util.pl @@ -335,7 +335,8 @@ http:convert_parameter(jsonresource, Atom, Term) :- annotation(tag:_, tags:list, count:number), annotation(tag:_, startTime:number, endTime:number, annotations:list), annotation(tag:_, startTime:number, endTime:number, annotations:list, match:_), - match(type:atom, uri:_, value:_). + match(type:atom, score:_), + match(type:atom, score:_, uri:_, value:_).