David Given wrote:
[...]
> I think I can do better than that, anyway. What I'd really like is to be
> able to specify a particular Thing (is 'artifact' the right word here?)
> and get an RSS feed for that Thing --- be it a file, wiki page, ticket,
> branch etc. I'll need to study the schema to see what's feasible.

Okay, the attached patch (from trunk) allows the timeline to be filtered
by tag, ticket, filename and wiki name. Plus I fixed the error code
(thanks for that, cut-and-paste error).

The reason it's not checked in is that there's an unfortunate
consequence: specifying tag=trunk causes my fossil session to spin
endlessly evaluated the query, presumably because the select from
tagxref is returning a huge number of values. Any suggestions for
optimisation?

-- 
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────
│
│ 𝕻𝖍'𝖓𝖌𝖑𝖚𝖎 𝖒𝖌𝖑𝖜'𝖓𝖆𝖋𝖍 𝕮𝖙𝖍𝖚𝖑𝖍𝖚 𝕽'𝖑𝖞𝖊𝖍
𝖜𝖌𝖆𝖍'𝖓𝖆𝖌𝖑 𝖋𝖍𝖙𝖆𝖌𝖓.
│
--- src/rss.c
+++ src/rss.c
@@ -19,20 +19,48 @@
 */
 #include "config.h"
 #include <time.h>
 #include "rss.h"
 #include <assert.h>
+
+static int append_tag_filter(Blob* bSQL, const char* zName, const char* zType)
+{
+  if ( zName ){
+    int nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB '%s-%q*'",
+      zType, zName);
+    if ( nTagId == 0 ){
+      return 0;
+    }
+    blob_appendf(bSQL, " AND objid IN (SELECT rid FROM tagxref WHERE 
tagid=%d)", nTagId);
+  }
+  return 1;
+}
 
 /*
 ** WEBPAGE: timeline.rss
+** URL:  /timeline.rss/y=TYPE&n=LIMIT&tkt=UUID&tag=TAG&name=FILENAME&wiki=NAME
+**
+** Produce an RSS feed of the timeline.
+**
+** TYPE may be: all, ci (show checkins only), t (show tickets only),
+** w (show wiki only). LIMIT is the number of items to show.
+**
+** tkt=UUID filters for only those events for the specified ticket. tag=TAG
+** filters for a tag, and name=FILENAME for a file. Some combinations may be
+** used.
 */
+
 void page_timeline_rss(void){
   Stmt q;
   int nLine=0;
   char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0;
   Blob bSQL;
   const char *zType = PD("y","all"); /* Type of events.  All if NULL */
+  const char *zTicketUuid = PD("tkt",NULL);
+  const char *zTag = PD("tag",NULL);
+  const char *zFilename = PD("name",NULL);
+  const char *zWiki = PD("wiki",NULL);
   int nLimit = atoi(PD("n","20"));
   const char zSQL1[] =
     @ SELECT
     @   blob.rid,
     @   uuid,
@@ -62,10 +90,11 @@
     if( !g.perm.Read ){
       if( g.perm.RdTkt && g.perm.RdWiki ){
         blob_append(&bSQL, " AND event.type!='ci'", -1);
       }else if( g.perm.RdTkt ){
         blob_append(&bSQL, " AND event.type=='t'", -1);
+        
       }else{
         blob_append(&bSQL, " AND event.type=='w'", -1);
       }
     }else if( !g.perm.RdWiki ){
       if( g.perm.RdTkt ){
@@ -76,10 +105,27 @@
     }else if( !g.perm.RdTkt ){
       assert( !g.perm.RdTkt &&& g.perm.Read && g.perm.RdWiki );
       blob_append(&bSQL, " AND event.type!='t'", -1);
     }
   }
+
+  if( !append_tag_filter(&bSQL, zTicketUuid, "tkt") ){
+    return;
+  }
+  if( !append_tag_filter(&bSQL, zTag, "sym") ){
+    return;
+  }
+  if( !append_tag_filter(&bSQL, zWiki, "wiki") ){
+    return;
+  }
+
+  if ( zFilename ){
+    blob_appendf(&bSQL,
+      " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN 
(SELECT fnid FROM filename WHERE name=%Q %s)",
+        zFilename, filename_collation()
+    );
+  }
 
   blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );
 
   cgi_set_content_type("application/rss+xml");
 

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
fossil-users mailing list
fossil-users@lists.fossil-scm.org
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users

Reply via email to