Index: src/rss.c ================================================================== --- src/rss.c +++ src/rss.c @@ -160,11 +160,11 @@ @ %s(zPubDate) @ Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE) free(zPubDate); db_prepare(&q, blob_str(&bSQL)); blob_reset( &bSQL ); - while( db_step(&q)==SQLITE_ROW && nLine<=nLimit ){ + while( db_step(&q)==SQLITE_ROW && nLine @ + + if( zFreeProjectName != 0 ){ + free( zFreeProjectName ); + } +} + +/* +** COMMAND: rss +** +** The CLI variant of the /timeline.rss page, this produces an RSS +** feed of the timeline to stdout. Options: +** +** -type|y FLAG +** may be: all (default), 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 +** +** -wiki NAME +** Filters on a specific wiki page. +** +** Only one of -tkt, -tag, or -wiki may be used. +** +** -name FILENAME +** filters for a specific file. This may be combined with one of the other +** filters (useful for looking at a specific branch). +** +** -url STRING +** Sets the RSS feed's root URL to the given string. The default is +** "URL-PLACEHOLDER" (without quotes). +*/ +void cmd_timeline_rss(void){ + Stmt q; + int nLine=0; + char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0; + Blob bSQL; + const char *zType = find_option("type","y",1); /* Type of events. All if NULL */ + const char *zTicketUuid = find_option("tkt",NULL,1); + const char *zTag = find_option("tag",NULL,1); + const char *zFilename = find_option("name",NULL,1); + const char *zWiki = find_option("wiki",NULL,1); + const char *zLimit = find_option("limit", "n",1); + const char *zBaseURL = find_option("url", NULL, 1); + int nLimit = atoi( (zLimit && *zLimit) ? zLimit : "20" ); + int nTagId; + const char zSQL1[] = + @ SELECT + @ blob.rid, + @ uuid, + @ event.mtime, + @ coalesce(ecomment,comment), + @ coalesce(euser,user), + @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim), + @ (SELECT count(*) FROM plink WHERE cid=blob.rid) + @ FROM event, blob + @ WHERE blob.rid=event.objid + ; + if(!zType || !*zType){ + zType = "all"; + } + if(!zBaseURL || !*zBaseURL){ + zBaseURL = "URL-PLACEHOLDER"; + } + + db_find_and_open_repository(0, 0); + + blob_zero(&bSQL); + blob_append( &bSQL, zSQL1, -1 ); + + if( zType[0]!='a' ){ + blob_appendf(&bSQL, " AND event.type=%Q", zType); + } + + if( zTicketUuid ){ + nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'", + zTicketUuid); + if ( nTagId==0 ){ + nTagId = -1; + } + }else if( zTag ){ + nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'sym-%q*'", + zTag); + if ( nTagId==0 ){ + nTagId = -1; + } + }else if( zWiki ){ + nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'wiki-%q*'", + zWiki); + if ( nTagId==0 ){ + nTagId = -1; + } + }else{ + nTagId = 0; + } + + if( nTagId==-1 ){ + blob_appendf(&bSQL, " AND 0"); + }else if( nTagId!=0 ){ + blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref" + " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId); + } + + 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 ); + + zProjectName = db_get("project-name", 0); + if( zProjectName==0 ){ + zFreeProjectName = zProjectName = mprintf("Fossil source repository for: %s", + zBaseURL); + } + zProjectDescr = db_get("project-description", 0); + if( zProjectDescr==0 ){ + zProjectDescr = zProjectName; + } + + zPubDate = cgi_rfc822_datestamp(time(NULL)); + + fossil_print(""); + fossil_print(""); + fossil_print("\n"); + fossil_print("%h\n", zProjectName); + fossil_print("%s\n", zBaseURL); + fossil_print("%h\n", zProjectDescr); + fossil_print("%s\n", zPubDate); + fossil_print("Fossil version %s %s\n", + MANIFEST_VERSION, MANIFEST_DATE); + free(zPubDate); + db_prepare(&q, blob_str(&bSQL)); + blob_reset( &bSQL ); + while( db_step(&q)==SQLITE_ROW && nLine1 && nChild>1 ){ + zPrefix = "*MERGE/FORK* "; + }else if( nParent>1 ){ + zPrefix = "*MERGE* "; + }else if( nChild>1 ){ + zPrefix = "*FORK* "; + } + + fossil_print(""); + fossil_print("%s%h\n", zPrefix, zCom); + fossil_print("%s/info/%s\n", zBaseURL, zId); + fossil_print("%s%h\n", zPrefix, zCom); + fossil_print("%s\n", zDate); + fossil_print("%h\n", zAuthor); + fossil_print("%s/info/%s\n", g.zBaseURL, zId); + fossil_print("\n"); + free(zDate); + nLine++; + } + + db_finalize(&q); + fossil_print("\n"); + fossil_print("\n"); if( zFreeProjectName != 0 ){ free( zFreeProjectName ); } }