Fossil SCM

merged in rss-cli.

stephan 2014-01-21 17:43 trunk merge
Commit 4d910042718484bfa1dff20f1b20cb8a0d47bdd1
1 file changed +176 -1
+176 -1
--- src/rss.c
+++ src/rss.c
@@ -160,11 +160,11 @@
160160
@ <pubDate>%s(zPubDate)</pubDate>
161161
@ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
162162
free(zPubDate);
163163
db_prepare(&q, blob_str(&bSQL));
164164
blob_reset( &bSQL );
165
- while( db_step(&q)==SQLITE_ROW && nLine<=nLimit ){
165
+ while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
166166
const char *zId = db_column_text(&q, 1);
167167
const char *zCom = db_column_text(&q, 3);
168168
const char *zAuthor = db_column_text(&q, 4);
169169
char *zPrefix = "";
170170
char *zDate;
@@ -196,10 +196,185 @@
196196
}
197197
198198
db_finalize(&q);
199199
@ </channel>
200200
@ </rss>
201
+
202
+ if( zFreeProjectName != 0 ){
203
+ free( zFreeProjectName );
204
+ }
205
+}
206
+
207
+/*
208
+** COMMAND: rss
209
+**
210
+** The CLI variant of the /timeline.rss page, this produces an RSS
211
+** feed of the timeline to stdout. Options:
212
+**
213
+** -type|y FLAG
214
+** may be: all (default), ci (show checkins only), t (show tickets only),
215
+** w (show wiki only). LIMIT is the number of items to show.
216
+**
217
+** -tkt UUID
218
+** Filters for only those events for the specified ticket.
219
+**
220
+** -tag TAG
221
+** filters for a tag
222
+**
223
+** -wiki NAME
224
+** Filters on a specific wiki page.
225
+**
226
+** Only one of -tkt, -tag, or -wiki may be used.
227
+**
228
+** -name FILENAME
229
+** filters for a specific file. This may be combined with one of the other
230
+** filters (useful for looking at a specific branch).
231
+**
232
+** -url STRING
233
+** Sets the RSS feed's root URL to the given string. The default is
234
+** "URL-PLACEHOLDER" (without quotes).
235
+*/
236
+void cmd_timeline_rss(void){
237
+ Stmt q;
238
+ int nLine=0;
239
+ char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0;
240
+ Blob bSQL;
241
+ const char *zType = find_option("type","y",1); /* Type of events. All if NULL */
242
+ const char *zTicketUuid = find_option("tkt",NULL,1);
243
+ const char *zTag = find_option("tag",NULL,1);
244
+ const char *zFilename = find_option("name",NULL,1);
245
+ const char *zWiki = find_option("wiki",NULL,1);
246
+ const char *zLimit = find_option("limit", "n",1);
247
+ const char *zBaseURL = find_option("url", NULL, 1);
248
+ int nLimit = atoi( (zLimit && *zLimit) ? zLimit : "20" );
249
+ int nTagId;
250
+ const char zSQL1[] =
251
+ @ SELECT
252
+ @ blob.rid,
253
+ @ uuid,
254
+ @ event.mtime,
255
+ @ coalesce(ecomment,comment),
256
+ @ coalesce(euser,user),
257
+ @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim),
258
+ @ (SELECT count(*) FROM plink WHERE cid=blob.rid)
259
+ @ FROM event, blob
260
+ @ WHERE blob.rid=event.objid
261
+ ;
262
+ if(!zType || !*zType){
263
+ zType = "all";
264
+ }
265
+ if(!zBaseURL || !*zBaseURL){
266
+ zBaseURL = "URL-PLACEHOLDER";
267
+ }
268
+
269
+ db_find_and_open_repository(0, 0);
270
+
271
+ blob_zero(&bSQL);
272
+ blob_append( &bSQL, zSQL1, -1 );
273
+
274
+ if( zType[0]!='a' ){
275
+ blob_appendf(&bSQL, " AND event.type=%Q", zType);
276
+ }
277
+
278
+ if( zTicketUuid ){
279
+ nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
280
+ zTicketUuid);
281
+ if ( nTagId==0 ){
282
+ nTagId = -1;
283
+ }
284
+ }else if( zTag ){
285
+ nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'sym-%q*'",
286
+ zTag);
287
+ if ( nTagId==0 ){
288
+ nTagId = -1;
289
+ }
290
+ }else if( zWiki ){
291
+ nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'wiki-%q*'",
292
+ zWiki);
293
+ if ( nTagId==0 ){
294
+ nTagId = -1;
295
+ }
296
+ }else{
297
+ nTagId = 0;
298
+ }
299
+
300
+ if( nTagId==-1 ){
301
+ blob_appendf(&bSQL, " AND 0");
302
+ }else if( nTagId!=0 ){
303
+ blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
304
+ " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
305
+ }
306
+
307
+ if( zFilename ){
308
+ blob_appendf(&bSQL,
309
+ " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
310
+ zFilename, filename_collation()
311
+ );
312
+ }
313
+
314
+ blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );
315
+
316
+ zProjectName = db_get("project-name", 0);
317
+ if( zProjectName==0 ){
318
+ zFreeProjectName = zProjectName = mprintf("Fossil source repository for: %s",
319
+ zBaseURL);
320
+ }
321
+ zProjectDescr = db_get("project-description", 0);
322
+ if( zProjectDescr==0 ){
323
+ zProjectDescr = zProjectName;
324
+ }
325
+
326
+ zPubDate = cgi_rfc822_datestamp(time(NULL));
327
+
328
+ fossil_print("<?xml version=\"1.0\"?>");
329
+ fossil_print("<rss xmlns:dc=\"http://purl.org/dc/elements/1.1/\" version=\"2.0\">");
330
+ fossil_print("<channel>\n");
331
+ fossil_print("<title>%h</title>\n", zProjectName);
332
+ fossil_print("<link>%s</link>\n", zBaseURL);
333
+ fossil_print("<description>%h</description>\n", zProjectDescr);
334
+ fossil_print("<pubDate>%s</pubDate>\n", zPubDate);
335
+ fossil_print("<generator>Fossil version %s %s</generator>\n",
336
+ MANIFEST_VERSION, MANIFEST_DATE);
337
+ free(zPubDate);
338
+ db_prepare(&q, blob_str(&bSQL));
339
+ blob_reset( &bSQL );
340
+ while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
341
+ const char *zId = db_column_text(&q, 1);
342
+ const char *zCom = db_column_text(&q, 3);
343
+ const char *zAuthor = db_column_text(&q, 4);
344
+ char *zPrefix = "";
345
+ char *zDate;
346
+ int nChild = db_column_int(&q, 5);
347
+ int nParent = db_column_int(&q, 6);
348
+ time_t ts;
349
+
350
+ ts = (time_t)((db_column_double(&q,2) - 2440587.5)*86400.0);
351
+ zDate = cgi_rfc822_datestamp(ts);
352
+
353
+ if( nParent>1 && nChild>1 ){
354
+ zPrefix = "*MERGE/FORK* ";
355
+ }else if( nParent>1 ){
356
+ zPrefix = "*MERGE* ";
357
+ }else if( nChild>1 ){
358
+ zPrefix = "*FORK* ";
359
+ }
360
+
361
+ fossil_print("<item>");
362
+ fossil_print("<title>%s%h</title>\n", zPrefix, zCom);
363
+ fossil_print("<link>%s/info/%s</link>\n", zBaseURL, zId);
364
+ fossil_print("<description>%s%h</description>\n", zPrefix, zCom);
365
+ fossil_print("<pubDate>%s</pubDate>\n", zDate);
366
+ fossil_print("<dc:creator>%h</dc:creator>\n", zAuthor);
367
+ fossil_print("<guid>%s/info/%s</guid>\n", g.zBaseURL, zId);
368
+ fossil_print("</item>\n");
369
+ free(zDate);
370
+ nLine++;
371
+ }
372
+
373
+ db_finalize(&q);
374
+ fossil_print("</channel>\n");
375
+ fossil_print("</rss>\n");
201376
202377
if( zFreeProjectName != 0 ){
203378
free( zFreeProjectName );
204379
}
205380
}
206381
--- src/rss.c
+++ src/rss.c
@@ -160,11 +160,11 @@
160 @ <pubDate>%s(zPubDate)</pubDate>
161 @ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
162 free(zPubDate);
163 db_prepare(&q, blob_str(&bSQL));
164 blob_reset( &bSQL );
165 while( db_step(&q)==SQLITE_ROW && nLine<=nLimit ){
166 const char *zId = db_column_text(&q, 1);
167 const char *zCom = db_column_text(&q, 3);
168 const char *zAuthor = db_column_text(&q, 4);
169 char *zPrefix = "";
170 char *zDate;
@@ -196,10 +196,185 @@
196 }
197
198 db_finalize(&q);
199 @ </channel>
200 @ </rss>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
202 if( zFreeProjectName != 0 ){
203 free( zFreeProjectName );
204 }
205 }
206
--- src/rss.c
+++ src/rss.c
@@ -160,11 +160,11 @@
160 @ <pubDate>%s(zPubDate)</pubDate>
161 @ <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
162 free(zPubDate);
163 db_prepare(&q, blob_str(&bSQL));
164 blob_reset( &bSQL );
165 while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
166 const char *zId = db_column_text(&q, 1);
167 const char *zCom = db_column_text(&q, 3);
168 const char *zAuthor = db_column_text(&q, 4);
169 char *zPrefix = "";
170 char *zDate;
@@ -196,10 +196,185 @@
196 }
197
198 db_finalize(&q);
199 @ </channel>
200 @ </rss>
201
202 if( zFreeProjectName != 0 ){
203 free( zFreeProjectName );
204 }
205 }
206
207 /*
208 ** COMMAND: rss
209 **
210 ** The CLI variant of the /timeline.rss page, this produces an RSS
211 ** feed of the timeline to stdout. Options:
212 **
213 ** -type|y FLAG
214 ** may be: all (default), ci (show checkins only), t (show tickets only),
215 ** w (show wiki only). LIMIT is the number of items to show.
216 **
217 ** -tkt UUID
218 ** Filters for only those events for the specified ticket.
219 **
220 ** -tag TAG
221 ** filters for a tag
222 **
223 ** -wiki NAME
224 ** Filters on a specific wiki page.
225 **
226 ** Only one of -tkt, -tag, or -wiki may be used.
227 **
228 ** -name FILENAME
229 ** filters for a specific file. This may be combined with one of the other
230 ** filters (useful for looking at a specific branch).
231 **
232 ** -url STRING
233 ** Sets the RSS feed's root URL to the given string. The default is
234 ** "URL-PLACEHOLDER" (without quotes).
235 */
236 void cmd_timeline_rss(void){
237 Stmt q;
238 int nLine=0;
239 char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0;
240 Blob bSQL;
241 const char *zType = find_option("type","y",1); /* Type of events. All if NULL */
242 const char *zTicketUuid = find_option("tkt",NULL,1);
243 const char *zTag = find_option("tag",NULL,1);
244 const char *zFilename = find_option("name",NULL,1);
245 const char *zWiki = find_option("wiki",NULL,1);
246 const char *zLimit = find_option("limit", "n",1);
247 const char *zBaseURL = find_option("url", NULL, 1);
248 int nLimit = atoi( (zLimit && *zLimit) ? zLimit : "20" );
249 int nTagId;
250 const char zSQL1[] =
251 @ SELECT
252 @ blob.rid,
253 @ uuid,
254 @ event.mtime,
255 @ coalesce(ecomment,comment),
256 @ coalesce(euser,user),
257 @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim),
258 @ (SELECT count(*) FROM plink WHERE cid=blob.rid)
259 @ FROM event, blob
260 @ WHERE blob.rid=event.objid
261 ;
262 if(!zType || !*zType){
263 zType = "all";
264 }
265 if(!zBaseURL || !*zBaseURL){
266 zBaseURL = "URL-PLACEHOLDER";
267 }
268
269 db_find_and_open_repository(0, 0);
270
271 blob_zero(&bSQL);
272 blob_append( &bSQL, zSQL1, -1 );
273
274 if( zType[0]!='a' ){
275 blob_appendf(&bSQL, " AND event.type=%Q", zType);
276 }
277
278 if( zTicketUuid ){
279 nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
280 zTicketUuid);
281 if ( nTagId==0 ){
282 nTagId = -1;
283 }
284 }else if( zTag ){
285 nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'sym-%q*'",
286 zTag);
287 if ( nTagId==0 ){
288 nTagId = -1;
289 }
290 }else if( zWiki ){
291 nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'wiki-%q*'",
292 zWiki);
293 if ( nTagId==0 ){
294 nTagId = -1;
295 }
296 }else{
297 nTagId = 0;
298 }
299
300 if( nTagId==-1 ){
301 blob_appendf(&bSQL, " AND 0");
302 }else if( nTagId!=0 ){
303 blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
304 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
305 }
306
307 if( zFilename ){
308 blob_appendf(&bSQL,
309 " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
310 zFilename, filename_collation()
311 );
312 }
313
314 blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );
315
316 zProjectName = db_get("project-name", 0);
317 if( zProjectName==0 ){
318 zFreeProjectName = zProjectName = mprintf("Fossil source repository for: %s",
319 zBaseURL);
320 }
321 zProjectDescr = db_get("project-description", 0);
322 if( zProjectDescr==0 ){
323 zProjectDescr = zProjectName;
324 }
325
326 zPubDate = cgi_rfc822_datestamp(time(NULL));
327
328 fossil_print("<?xml version=\"1.0\"?>");
329 fossil_print("<rss xmlns:dc=\"http://purl.org/dc/elements/1.1/\" version=\"2.0\">");
330 fossil_print("<channel>\n");
331 fossil_print("<title>%h</title>\n", zProjectName);
332 fossil_print("<link>%s</link>\n", zBaseURL);
333 fossil_print("<description>%h</description>\n", zProjectDescr);
334 fossil_print("<pubDate>%s</pubDate>\n", zPubDate);
335 fossil_print("<generator>Fossil version %s %s</generator>\n",
336 MANIFEST_VERSION, MANIFEST_DATE);
337 free(zPubDate);
338 db_prepare(&q, blob_str(&bSQL));
339 blob_reset( &bSQL );
340 while( db_step(&q)==SQLITE_ROW && nLine<nLimit ){
341 const char *zId = db_column_text(&q, 1);
342 const char *zCom = db_column_text(&q, 3);
343 const char *zAuthor = db_column_text(&q, 4);
344 char *zPrefix = "";
345 char *zDate;
346 int nChild = db_column_int(&q, 5);
347 int nParent = db_column_int(&q, 6);
348 time_t ts;
349
350 ts = (time_t)((db_column_double(&q,2) - 2440587.5)*86400.0);
351 zDate = cgi_rfc822_datestamp(ts);
352
353 if( nParent>1 && nChild>1 ){
354 zPrefix = "*MERGE/FORK* ";
355 }else if( nParent>1 ){
356 zPrefix = "*MERGE* ";
357 }else if( nChild>1 ){
358 zPrefix = "*FORK* ";
359 }
360
361 fossil_print("<item>");
362 fossil_print("<title>%s%h</title>\n", zPrefix, zCom);
363 fossil_print("<link>%s/info/%s</link>\n", zBaseURL, zId);
364 fossil_print("<description>%s%h</description>\n", zPrefix, zCom);
365 fossil_print("<pubDate>%s</pubDate>\n", zDate);
366 fossil_print("<dc:creator>%h</dc:creator>\n", zAuthor);
367 fossil_print("<guid>%s/info/%s</guid>\n", g.zBaseURL, zId);
368 fossil_print("</item>\n");
369 free(zDate);
370 nLine++;
371 }
372
373 db_finalize(&q);
374 fossil_print("</channel>\n");
375 fossil_print("</rss>\n");
376
377 if( zFreeProjectName != 0 ){
378 free( zFreeProjectName );
379 }
380 }
381

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button