<> <> <> <> <<>> <> <<>> <<>> 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]; TapCommandsImpl: CEDAR PROGRAM IMPORTS Atom, Commander, IO, LoganQuery, Rope, TapFilter, UserProfile ~ BEGIN ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; <> 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; < {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]; <<>> <> 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]; <<>> <> 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; <> s _ IO.RIS[cmd.commandLine]; filterName _ IO.GetTokenRope[stream: s ! IO.EndOfStream => GOTO Usage].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; }; 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] ~ { <> <<>> 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; <> s _ IO.RIS[cmd.commandLine]; <> 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 { <> 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]; }; <> 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]]; END.