DIRECTORY
Atom USING [GetPName],
Commander USING [CommandProc, Register],
IO USING [atom, rope, STREAM, EndOfStream, GetRope, GetTokenRope, PutChar, PutF, PutFR, PutRope, RIS],
LoganQuery USING [AttributePatterns, PatternsToEntry, ReadAttributePatterns, SyntaxError],
Rope USING [ROPE, Cat, Concat, Find, Substr],
TapFilter USING [Annotation, AddFilter, DeleteFilter, FilterInfo, LookupFilter, LookupAllFilters, Query, Error],
UserProfile USING [Token];
Filters
usageAddFilter: ROPE = "usage: TapAddFilter name {field(matcher): pattern}* -> {tag: value}*\n e.g. TapAddFilter msgsFromDoug from: *Terry* -> Level: 99";
AddFilterCmd: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
filterDBName, userName: ROPE ← NIL;
filterName, query, noteRope, filterID: ROPE;
s: STREAM;
loc: INT;
ap: LoganQuery.AttributePatterns;
note: TapFilter.Annotation;
Parse command line as: name {field(matcher): pattern}* -> {tag: value}*.
loc ← Rope.Find[s1: cmd.commandLine, s2: "->"];
IF loc < 0
THEN
GOTO Usage;
s ← IO.RIS[Rope.Substr[base: cmd.commandLine, start: 0, len: loc]];
filterName ← IO.GetTokenRope[stream: s ! IO.EndOfStream => GOTO Usage].token;
query ← IO.GetRope[s];
noteRope ← Rope.Substr[base: cmd.commandLine, start: loc+2];
Check that query and annotations are syntactically correct.
s ← IO.RIS[query];
ap ← LoganQuery.ReadAttributePatterns[s
! LoganQuery.SyntaxError => {msg ← IO.PutFR["Query syntax error: %g\n", IO.rope[explanation]]; GOTO End}];
s ← IO.RIS[noteRope];
ap ← LoganQuery.ReadAttributePatterns[s
! LoganQuery.SyntaxError => {msg ← IO.PutFR["Annotation syntax error: %g\n", IO.rope[explanation]]; GOTO End}];
note ← LoganQuery.PatternsToEntry[ap];
Add new filter.
filterDBName ← UserProfile.Token[key: "Tapestry.FilterDB"];
IF filterDBName =
NIL
THEN {
msg ← "No user profile entry for Tapestry.FilterDB\n";
GOTO End;
};
userName ← UserProfile.Token[key: "Tapestry.UserName"];
IF userName =
NIL
THEN {
msg ← "No user profile entry for Tapestry.UserName\n";
GOTO End;
};
filterID ← TapFilter.AddFilter[filterDB: filterDBName, user: userName, filterName: filterName, query: query, annot: note
! TapFilter.Error => {msg ← IO.PutFR["Can't add filter: %g - %g\n", IO.atom[ec], IO.rope[explanation]]; GOTO End}];
msg ← Rope.Concat["Added filter: ", filterID];
EXITS
End => RETURN[$Failure, msg];
Usage => RETURN[$Failure, usageAddFilter];
};
usageDeleteFilter: ROPE = "usage: TapDeleteFilter filterName \n e.g. TapDeleteFilter msgsFromDoug";
DeleteFilterCmd: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
filterDBName, userName: ROPE ← NIL;
filterName, filterID: ROPE;
s: STREAM;
Parse command line as: FilterName
s ← IO.RIS[cmd.commandLine];
filterName ← IO.GetTokenRope[stream: s ! IO.EndOfStream => GOTO Usage].token;
Look in User Profile entry.
filterDBName ← UserProfile.Token[key: "Tapestry.FilterDB"];
IF filterDBName =
NIL
THEN {
msg ← "No user profile entry for Tapestry.FilterDB\n";
GOTO End;
};
userName ← UserProfile.Token[key: "Tapestry.UserName"];
IF userName =
NIL
THEN {
msg ← "No user profile entry for Tapestry.UserName\n";
GOTO End;
};
filterID ← Rope.Cat[userName, "$", filterName];
[] ← TapFilter.DeleteFilter[filterDB: filterDBName, filterID: filterID !
TapFilter.Error => {msg ← IO.PutFR["Can't delete filter: '%g.' %g - %g\n", IO.rope[filterName], IO.atom[ec], IO.rope[explanation]]; GOTO End}];
msg ← Rope.Concat["Deleted filter: ", filterID];
EXITS
End => RETURN[$Failure, msg];
Usage => RETURN[$Failure, usageDeleteFilter];
};
usageListFilter: ROPE = "usage: TapListFilter {FilterName | }\n e.g. TapListFilter msgsFromDoug \n TapListFilter";
ListFilterCmd: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
PrintInfo:
PROC [name:
ROPE, user:
ROPE, query: TapFilter.Query, note: TapFilter.Annotation] ~ {
Print information
IO.PutF[cmd.out, "Filter name: %g\nUser: %g\nQuery: %g\n", IO.rope[name], IO.rope[user], IO.rope[query]];
IO.PutRope[cmd.out, "Annotation:\n"];
FOR aL: TapFilter.Annotation ← note, aL.rest
WHILE aL#
NIL
DO
IF aL.first.type#
NIL
THEN {
IO.PutRope[cmd.out, " "];
IO.PutRope[cmd.out, Atom.GetPName[aL.first.type]];
IO.PutRope[cmd.out, ": "];
IO.PutRope[cmd.out, aL.first.value];
IO.PutChar[cmd.out, '\n];
};
ENDLOOP;
IO.PutChar[cmd.out, '\n];
};
filterDBName, userName: ROPE ← NIL;
filterName, filterID: ROPE;
s: STREAM;
note: TapFilter.Annotation;
user: ROPE;
query: TapFilter.Query;
filterName ← NIL;
Parse command line as: FilterName
s ← IO.RIS[cmd.commandLine];
If filterName is NIL then user wants to list all filters; otherwise, just list the specific filter
filterName ← IO.GetTokenRope[stream: s ! IO.EndOfStream => CONTINUE].token;
filterDBName ← UserProfile.Token[key: "Tapestry.FilterDB"];
IF filterDBName =
NIL
THEN {
msg ← "No user profile entry for Tapestry.FilterDB\n";
GOTO End;
};
userName ← UserProfile.Token[key: "Tapestry.UserName"];
IF userName =
NIL
THEN {
msg ← "No user profile entry for Tapestry.UserName\n";
GOTO End;
};
IF filterName =
NIL
THEN {
List all filters
stuff: LIST OF TapFilter.FilterInfo;
stuff ← TapFilter.LookupAllFilters[filterDB: filterDBName !
TapFilter.Error => {msg ← IO.PutFR["Can't list filter: %g - %g\n", IO.atom[ec], IO.rope[explanation]]; GOTO End}];
IF stuff =
NIL
THEN {
msg ← "No filters\n";
GOTO End;
};
FOR info:
LIST
OF TapFilter.FilterInfo ← stuff, info.rest
WHILE info#
NIL
DO
PrintInfo[info.first.filterName, info.first.user, info.first.query, info.first.annot];
ENDLOOP;
}
ELSE {
-- just list the filter named
name: ROPE;
filterID ← Rope.Cat[userName, "$", filterName];
[name, user, query, note] ← TapFilter.LookupFilter[filterDB: filterDBName, filterID: filterID];
IF name =
NIL
THEN {
msg ← IO.PutFR["No such filter %g\n", IO.rope[filterName]];
GOTO End;
};
PrintInfo[name: name, user: user, query: query, note: note];
};
EXITS
End => RETURN[$Failure, msg];
};
Command registrations
Commander.Register[key: "TapAddFilter", proc: AddFilterCmd, doc: Rope.Concat["Add a new Tapestry filter.\n", usageAddFilter]];
Commander.Register[key: "TapDeleteFilter", proc: DeleteFilterCmd, doc: Rope.Concat["Delete a Tapestry filter.\n", usageDeleteFilter]];
Commander.Register[key: "TapListFilter", proc: ListFilterCmd, doc: Rope.Concat["List a specific Tapestry filter, or list all filters.\n", usageListFilter]];