Fossil SCM

timeline.rss with single-ticket support, based on David Given's patch.

stephan 2013-02-12 10:08 trunk
Commit 1bc09124bd80b0ee7dba063e165e53e68dc356fb
2 files changed +4 -2 +46
+4 -2
--- src/info.c
+++ src/info.c
@@ -1723,11 +1723,11 @@
17231723
const char *zUuid;
17241724
char zTktName[UUID_SIZE+1];
17251725
Manifest *pTktChng;
17261726
int modPending;
17271727
const char *zModAction;
1728
-
1728
+ char *zTktTitle;
17291729
login_check_credentials();
17301730
if( !g.perm.RdTkt ){ login_needed(); return; }
17311731
rid = name_to_rid_www("name");
17321732
if( rid==0 ){ fossil_redirect_home(); }
17331733
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
@@ -1752,10 +1752,11 @@
17521752
}
17531753
if( strcmp(zModAction,"approve")==0 ){
17541754
moderation_approve(rid);
17551755
}
17561756
}
1757
+ zTktTitle = db_text("???", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName);
17571758
style_header("Ticket Change Details");
17581759
style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid);
17591760
style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
17601761
style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName);
17611762
style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName);
@@ -1776,17 +1777,18 @@
17761777
modPending = moderation_pending(rid);
17771778
if( modPending ){
17781779
@ <span class="modpending">*** Awaiting Moderator Approval ***</span>
17791780
}
17801781
@ <tr><th>Ticket:</th>
1781
- @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></td></tr>
1782
+ @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a><br>%h(zTktTitle)</td></tr>
17821783
@ <tr><th>Date:</th><td>
17831784
hyperlink_to_date(zDate, "</td></tr>");
17841785
@ <tr><th>User:</th><td>
17851786
hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>");
17861787
@ </table>
17871788
free(zDate);
1789
+ free(zTktTitle);
17881790
17891791
if( g.perm.ModTkt && modPending ){
17901792
@ <div class="section">Moderation</div>
17911793
@ <blockquote>
17921794
@ <form method="POST" action="%R/tinfo/%s(zUuid)">
17931795
--- src/info.c
+++ src/info.c
@@ -1723,11 +1723,11 @@
1723 const char *zUuid;
1724 char zTktName[UUID_SIZE+1];
1725 Manifest *pTktChng;
1726 int modPending;
1727 const char *zModAction;
1728
1729 login_check_credentials();
1730 if( !g.perm.RdTkt ){ login_needed(); return; }
1731 rid = name_to_rid_www("name");
1732 if( rid==0 ){ fossil_redirect_home(); }
1733 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
@@ -1752,10 +1752,11 @@
1752 }
1753 if( strcmp(zModAction,"approve")==0 ){
1754 moderation_approve(rid);
1755 }
1756 }
 
1757 style_header("Ticket Change Details");
1758 style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid);
1759 style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
1760 style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName);
1761 style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName);
@@ -1776,17 +1777,18 @@
1776 modPending = moderation_pending(rid);
1777 if( modPending ){
1778 @ <span class="modpending">*** Awaiting Moderator Approval ***</span>
1779 }
1780 @ <tr><th>Ticket:</th>
1781 @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></td></tr>
1782 @ <tr><th>Date:</th><td>
1783 hyperlink_to_date(zDate, "</td></tr>");
1784 @ <tr><th>User:</th><td>
1785 hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>");
1786 @ </table>
1787 free(zDate);
 
1788
1789 if( g.perm.ModTkt && modPending ){
1790 @ <div class="section">Moderation</div>
1791 @ <blockquote>
1792 @ <form method="POST" action="%R/tinfo/%s(zUuid)">
1793
--- src/info.c
+++ src/info.c
@@ -1723,11 +1723,11 @@
1723 const char *zUuid;
1724 char zTktName[UUID_SIZE+1];
1725 Manifest *pTktChng;
1726 int modPending;
1727 const char *zModAction;
1728 char *zTktTitle;
1729 login_check_credentials();
1730 if( !g.perm.RdTkt ){ login_needed(); return; }
1731 rid = name_to_rid_www("name");
1732 if( rid==0 ){ fossil_redirect_home(); }
1733 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
@@ -1752,10 +1752,11 @@
1752 }
1753 if( strcmp(zModAction,"approve")==0 ){
1754 moderation_approve(rid);
1755 }
1756 }
1757 zTktTitle = db_text("???", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName);
1758 style_header("Ticket Change Details");
1759 style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid);
1760 style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
1761 style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName);
1762 style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName);
@@ -1776,17 +1777,18 @@
1777 modPending = moderation_pending(rid);
1778 if( modPending ){
1779 @ <span class="modpending">*** Awaiting Moderator Approval ***</span>
1780 }
1781 @ <tr><th>Ticket:</th>
1782 @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a><br>%h(zTktTitle)</td></tr>
1783 @ <tr><th>Date:</th><td>
1784 hyperlink_to_date(zDate, "</td></tr>");
1785 @ <tr><th>User:</th><td>
1786 hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>");
1787 @ </table>
1788 free(zDate);
1789 free(zTktTitle);
1790
1791 if( g.perm.ModTkt && modPending ){
1792 @ <div class="section">Moderation</div>
1793 @ <blockquote>
1794 @ <form method="POST" action="%R/tinfo/%s(zUuid)">
1795
+46
--- src/rss.c
+++ src/rss.c
@@ -19,20 +19,48 @@
1919
*/
2020
#include "config.h"
2121
#include <time.h>
2222
#include "rss.h"
2323
#include <assert.h>
24
+
25
+static int append_tag_filter(Blob* bSQL, const char* zName, const char* zType)
26
+{
27
+ if ( zName ){
28
+ int nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB '%s-%q*'",
29
+ zType, zName);
30
+ if ( nTagId == 0 ){
31
+ return 0;
32
+ }
33
+ blob_appendf(bSQL, " AND objid IN (SELECT rid FROM tagxref WHERE tagid=%d)", nTagId);
34
+ }
35
+ return 1;
36
+}
2437
2538
/*
2639
** WEBPAGE: timeline.rss
40
+** URL: /timeline.rss/y=TYPE&n=LIMIT&tkt=UUID&tag=TAG&name=FILENAME&wiki=NAME
41
+**
42
+** Produce an RSS feed of the timeline.
43
+**
44
+** TYPE may be: all, ci (show checkins only), t (show tickets only),
45
+** w (show wiki only). LIMIT is the number of items to show.
46
+**
47
+** tkt=UUID filters for only those events for the specified ticket. tag=TAG
48
+** filters for a tag, and name=FILENAME for a file. Some combinations may be
49
+** used.
2750
*/
51
+
2852
void page_timeline_rss(void){
2953
Stmt q;
3054
int nLine=0;
3155
char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0;
3256
Blob bSQL;
3357
const char *zType = PD("y","all"); /* Type of events. All if NULL */
58
+ const char *zTicketUuid = PD("tkt",NULL);
59
+ const char *zTag = PD("tag",NULL);
60
+ const char *zFilename = PD("name",NULL);
61
+ const char *zWiki = PD("wiki",NULL);
3462
int nLimit = atoi(PD("n","20"));
3563
const char zSQL1[] =
3664
@ SELECT
3765
@ blob.rid,
3866
@ uuid,
@@ -62,10 +90,11 @@
6290
if( !g.perm.Read ){
6391
if( g.perm.RdTkt && g.perm.RdWiki ){
6492
blob_append(&bSQL, " AND event.type!='ci'", -1);
6593
}else if( g.perm.RdTkt ){
6694
blob_append(&bSQL, " AND event.type=='t'", -1);
95
+
6796
}else{
6897
blob_append(&bSQL, " AND event.type=='w'", -1);
6998
}
7099
}else if( !g.perm.RdWiki ){
71100
if( g.perm.RdTkt ){
@@ -76,10 +105,27 @@
76105
}else if( !g.perm.RdTkt ){
77106
assert( !g.perm.RdTkt &&& g.perm.Read && g.perm.RdWiki );
78107
blob_append(&bSQL, " AND event.type!='t'", -1);
79108
}
80109
}
110
+
111
+ if( !append_tag_filter(&bSQL, zTicketUuid, "tkt") ){
112
+ return;
113
+ }
114
+ if( !append_tag_filter(&bSQL, zTag, "sym") ){
115
+ return;
116
+ }
117
+ if( !append_tag_filter(&bSQL, zWiki, "wiki") ){
118
+ return;
119
+ }
120
+
121
+ if ( zFilename ){
122
+ blob_appendf(&bSQL,
123
+ " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
124
+ zFilename, filename_collation()
125
+ );
126
+ }
81127
82128
blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );
83129
84130
cgi_set_content_type("application/rss+xml");
85131
86132
--- src/rss.c
+++ src/rss.c
@@ -19,20 +19,48 @@
19 */
20 #include "config.h"
21 #include <time.h>
22 #include "rss.h"
23 #include <assert.h>
 
 
 
 
 
 
 
 
 
 
 
 
 
24
25 /*
26 ** WEBPAGE: timeline.rss
 
 
 
 
 
 
 
 
 
 
27 */
 
28 void page_timeline_rss(void){
29 Stmt q;
30 int nLine=0;
31 char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0;
32 Blob bSQL;
33 const char *zType = PD("y","all"); /* Type of events. All if NULL */
 
 
 
 
34 int nLimit = atoi(PD("n","20"));
35 const char zSQL1[] =
36 @ SELECT
37 @ blob.rid,
38 @ uuid,
@@ -62,10 +90,11 @@
62 if( !g.perm.Read ){
63 if( g.perm.RdTkt && g.perm.RdWiki ){
64 blob_append(&bSQL, " AND event.type!='ci'", -1);
65 }else if( g.perm.RdTkt ){
66 blob_append(&bSQL, " AND event.type=='t'", -1);
 
67 }else{
68 blob_append(&bSQL, " AND event.type=='w'", -1);
69 }
70 }else if( !g.perm.RdWiki ){
71 if( g.perm.RdTkt ){
@@ -76,10 +105,27 @@
76 }else if( !g.perm.RdTkt ){
77 assert( !g.perm.RdTkt &&& g.perm.Read && g.perm.RdWiki );
78 blob_append(&bSQL, " AND event.type!='t'", -1);
79 }
80 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
82 blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );
83
84 cgi_set_content_type("application/rss+xml");
85
86
--- src/rss.c
+++ src/rss.c
@@ -19,20 +19,48 @@
19 */
20 #include "config.h"
21 #include <time.h>
22 #include "rss.h"
23 #include <assert.h>
24
25 static int append_tag_filter(Blob* bSQL, const char* zName, const char* zType)
26 {
27 if ( zName ){
28 int nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB '%s-%q*'",
29 zType, zName);
30 if ( nTagId == 0 ){
31 return 0;
32 }
33 blob_appendf(bSQL, " AND objid IN (SELECT rid FROM tagxref WHERE tagid=%d)", nTagId);
34 }
35 return 1;
36 }
37
38 /*
39 ** WEBPAGE: timeline.rss
40 ** URL: /timeline.rss/y=TYPE&n=LIMIT&tkt=UUID&tag=TAG&name=FILENAME&wiki=NAME
41 **
42 ** Produce an RSS feed of the timeline.
43 **
44 ** TYPE may be: all, ci (show checkins only), t (show tickets only),
45 ** w (show wiki only). LIMIT is the number of items to show.
46 **
47 ** tkt=UUID filters for only those events for the specified ticket. tag=TAG
48 ** filters for a tag, and name=FILENAME for a file. Some combinations may be
49 ** used.
50 */
51
52 void page_timeline_rss(void){
53 Stmt q;
54 int nLine=0;
55 char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0;
56 Blob bSQL;
57 const char *zType = PD("y","all"); /* Type of events. All if NULL */
58 const char *zTicketUuid = PD("tkt",NULL);
59 const char *zTag = PD("tag",NULL);
60 const char *zFilename = PD("name",NULL);
61 const char *zWiki = PD("wiki",NULL);
62 int nLimit = atoi(PD("n","20"));
63 const char zSQL1[] =
64 @ SELECT
65 @ blob.rid,
66 @ uuid,
@@ -62,10 +90,11 @@
90 if( !g.perm.Read ){
91 if( g.perm.RdTkt && g.perm.RdWiki ){
92 blob_append(&bSQL, " AND event.type!='ci'", -1);
93 }else if( g.perm.RdTkt ){
94 blob_append(&bSQL, " AND event.type=='t'", -1);
95
96 }else{
97 blob_append(&bSQL, " AND event.type=='w'", -1);
98 }
99 }else if( !g.perm.RdWiki ){
100 if( g.perm.RdTkt ){
@@ -76,10 +105,27 @@
105 }else if( !g.perm.RdTkt ){
106 assert( !g.perm.RdTkt &&& g.perm.Read && g.perm.RdWiki );
107 blob_append(&bSQL, " AND event.type!='t'", -1);
108 }
109 }
110
111 if( !append_tag_filter(&bSQL, zTicketUuid, "tkt") ){
112 return;
113 }
114 if( !append_tag_filter(&bSQL, zTag, "sym") ){
115 return;
116 }
117 if( !append_tag_filter(&bSQL, zWiki, "wiki") ){
118 return;
119 }
120
121 if ( zFilename ){
122 blob_appendf(&bSQL,
123 " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
124 zFilename, filename_collation()
125 );
126 }
127
128 blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );
129
130 cgi_set_content_type("application/rss+xml");
131
132

Keyboard Shortcuts

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