Changes On Branch timeline-rss-ticket
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch timeline-rss-ticket Excluding Merge-Ins

This is equivalent to a diff from fab09a1710 to 1c46835e4c

2013-02-18
21:45
/info/TICKET_UUID now only shows the ticket title if the ticket db has a title field. Leaf check-in: 1c46835e4c user: stephan tags: timeline-rss-ticket
2013-02-12
16:57
Update src/rss.c with latest version from dg-misc branch (original at [01e85ec4]). check-in: a10282407c user: dg tags: timeline-rss-ticket
11:53
Replaced a call to realloc() with cson_realloc() (which, in turn, uses the fossil realloc). check-in: a1d2cd84b8 user: stephan tags: trunk
10:08
timeline.rss with single-ticket support, based on David Given's patch. check-in: 1bc09124bd user: stephan tags: timeline-rss-ticket
2013-02-11
19:30
Merging from trunk. I still have merge conflicts since my previous merge. check-in: bdeb633a6c user: viriketo tags: annotate_links
2013-02-08
09:37
Eliminate use of starts_with_utf16(be|le)_bom functions, starts_with_utf16_bom should be enough. External code will typically call "starts_with_utf16_bom" first, and if it returns true call "blob_to_utf8_no_bom" converting it to utf-8. There is no reason any more then for external code to know wheter the BOM was le or be. check-in: fab09a1710 user: jan.nijtmans tags: trunk
08:55
Addendum to previous commit: Allow the user to decide whether the "fossil knows nothing about" warning should abort the commit or not. check-in: c31bbd4084 user: jan.nijtmans tags: trunk

Changes to src/db.c.

  1870   1870   }
  1871   1871   int db_lget_int(const char *zName, int dflt){
  1872   1872     return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
  1873   1873   }
  1874   1874   void db_lset_int(const char *zName, int value){
  1875   1875     db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
  1876   1876   }
         1877  +
         1878  +/*
         1879  +** Returns non-0 if the database (which must be open) table identified
         1880  +** by zTableName has a column named zColName (case-sensitive), else
         1881  +** returns 0.
         1882  +*/
         1883  +int db_table_has_column( char const *zTableName, char const *zColName ){
         1884  +  Stmt q = empty_Stmt;
         1885  +  int rc = 0;
         1886  +  db_prepare( &q, "PRAGMA table_info(%Q)", zTableName );
         1887  +  while(SQLITE_ROW == db_step(&q)){
         1888  +    /* Columns: (cid, name, type, notnull, dflt_value, pk) */
         1889  +    char const * zCol = db_column_text(&q, 1);
         1890  +    if(0==fossil_strcmp(zColName, zCol)){
         1891  +      rc = 1;
         1892  +      break;
         1893  +    }
         1894  +  }
         1895  +  db_finalize(&q);
         1896  +  return rc;
         1897  +}
  1877   1898   
  1878   1899   /*
  1879   1900   ** Record the name of a local repository in the global_config() database.
  1880   1901   ** The repository filename %s is recorded as an entry with a "name" field
  1881   1902   ** of the following form:
  1882   1903   **
  1883   1904   **       repo:%s

Changes to src/info.c.

  1721   1721     int rid;
  1722   1722     char *zDate;
  1723   1723     const char *zUuid;
  1724   1724     char zTktName[UUID_SIZE+1];
  1725   1725     Manifest *pTktChng;
  1726   1726     int modPending;
  1727   1727     const char *zModAction;
  1728         -
         1728  +  char *zTktTitle;
  1729   1729     login_check_credentials();
  1730   1730     if( !g.perm.RdTkt ){ login_needed(); return; }
  1731   1731     rid = name_to_rid_www("name");
  1732   1732     if( rid==0 ){ fossil_redirect_home(); }
  1733   1733     zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
  1734   1734     if( g.perm.Admin ){
  1735   1735       if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
................................................................................
  1750   1750         cgi_redirectf("%R/tktview/%s", zTktName);
  1751   1751         /*NOTREACHED*/
  1752   1752       }
  1753   1753       if( strcmp(zModAction,"approve")==0 ){
  1754   1754         moderation_approve(rid);
  1755   1755       }
  1756   1756     }
         1757  +  zTktTitle = db_table_has_column( "ticket", "title" )
         1758  +      ? db_text("(No title)", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName)
         1759  +      : 0;
  1757   1760     style_header("Ticket Change Details");
  1758   1761     style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid);
  1759   1762     style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
  1760   1763     style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName);
  1761   1764     style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName);
  1762   1765     if( P("plaintext") ){
  1763   1766       style_submenu_element("Formatted", "Formatted", "%R/info/%S", zUuid);
................................................................................
  1774   1777       @ (%d(rid))
  1775   1778     }
  1776   1779     modPending = moderation_pending(rid);
  1777   1780     if( modPending ){
  1778   1781       @ <span class="modpending">*** Awaiting Moderator Approval ***</span>
  1779   1782     }
  1780   1783     @ <tr><th>Ticket:</th>
  1781         -  @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></td></tr>
         1784  +  @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a>
         1785  +  if(zTktTitle){
         1786  +        @<br>%h(zTktTitle)
         1787  +  }
         1788  +  @</td></tr>
  1782   1789     @ <tr><th>Date:</th><td>
  1783   1790     hyperlink_to_date(zDate, "</td></tr>");
  1784   1791     @ <tr><th>User:</th><td>
  1785   1792     hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>");
  1786   1793     @ </table>
  1787   1794     free(zDate);
         1795  +  free(zTktTitle);
  1788   1796     
  1789   1797     if( g.perm.ModTkt && modPending ){
  1790   1798       @ <div class="section">Moderation</div>
  1791   1799       @ <blockquote>
  1792   1800       @ <form method="POST" action="%R/tinfo/%s(zUuid)">
  1793   1801       @ <label><input type="radio" name="modaction" value="delete">
  1794   1802       @ Delete this change</label><br />

Changes to src/rss.c.

    20     20   #include "config.h"
    21     21   #include <time.h>
    22     22   #include "rss.h"
    23     23   #include <assert.h>
    24     24   
    25     25   /*
    26     26   ** WEBPAGE: timeline.rss
           27  +** URL:  /timeline.rss/y=TYPE&n=LIMIT&tkt=UUID&tag=TAG&wiki=NAME&name=FILENAME
           28  +**
           29  +** Produce an RSS feed of the timeline.
           30  +**
           31  +** TYPE may be: all, ci (show checkins only), t (show tickets only),
           32  +** w (show wiki only). LIMIT is the number of items to show.
           33  +**
           34  +** tkt=UUID filters for only those events for the specified ticket. tag=TAG
           35  +** filters for a tag, and wiki=NAME for a wiki page. Only one may be used.
           36  +**
           37  +** In addition, name=FILENAME filters for a specific file. This may be
           38  +** combined with one of the other filters (useful for looking at a specific
           39  +** branch).
    27     40   */
           41  +
    28     42   void page_timeline_rss(void){
    29     43     Stmt q;
    30     44     int nLine=0;
    31     45     char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0;
    32     46     Blob bSQL;
    33     47     const char *zType = PD("y","all"); /* Type of events.  All if NULL */
           48  +  const char *zTicketUuid = PD("tkt",NULL);
           49  +  const char *zTag = PD("tag",NULL);
           50  +  const char *zFilename = PD("name",NULL);
           51  +  const char *zWiki = PD("wiki",NULL);
    34     52     int nLimit = atoi(PD("n","20"));
           53  +  int nTagId;
    35     54     const char zSQL1[] =
    36     55       @ SELECT
    37     56       @   blob.rid,
    38     57       @   uuid,
    39     58       @   event.mtime,
    40     59       @   coalesce(ecomment,comment),
    41     60       @   coalesce(euser,user),
................................................................................
    60     79       blob_appendf(&bSQL, " AND event.type=%Q", zType);
    61     80     }else{
    62     81       if( !g.perm.Read ){
    63     82         if( g.perm.RdTkt && g.perm.RdWiki ){
    64     83           blob_append(&bSQL, " AND event.type!='ci'", -1);
    65     84         }else if( g.perm.RdTkt ){
    66     85           blob_append(&bSQL, " AND event.type=='t'", -1);
           86  +        
    67     87         }else{
    68     88           blob_append(&bSQL, " AND event.type=='w'", -1);
    69     89         }
    70     90       }else if( !g.perm.RdWiki ){
    71     91         if( g.perm.RdTkt ){
    72     92           blob_append(&bSQL, " AND event.type!='w'", -1);
    73     93         }else{
................................................................................
    74     94           blob_append(&bSQL, " AND event.type=='ci'", -1);
    75     95         }
    76     96       }else if( !g.perm.RdTkt ){
    77     97         assert( !g.perm.RdTkt &&& g.perm.Read && g.perm.RdWiki );
    78     98         blob_append(&bSQL, " AND event.type!='t'", -1);
    79     99       }
    80    100     }
          101  +
          102  +  if( zTicketUuid ){
          103  +    nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
          104  +      zTicketUuid);
          105  +    if ( nTagId==0 ){
          106  +      nTagId = -1;
          107  +    }
          108  +  }else if( zTag ){
          109  +    nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'sym-%q*'",
          110  +      zTag);
          111  +    if ( nTagId==0 ){
          112  +      nTagId = -1;
          113  +    }
          114  +  }else if( zWiki ){
          115  +    nTagId = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'wiki-%q*'",
          116  +      zWiki);
          117  +    if ( nTagId==0 ){
          118  +      nTagId = -1;
          119  +    }
          120  +  }else{
          121  +    nTagId = 0;
          122  +  }
          123  +
          124  +  if( nTagId==-1 ){
          125  +    blob_appendf(&bSQL, " AND 0");
          126  +  }else if( nTagId!=0 ){
          127  +    blob_appendf(&bSQL, " AND (EXISTS(SELECT 1 FROM tagxref"
          128  +      " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid))", nTagId);
          129  +  }
          130  +
          131  +  if( zFilename ){
          132  +    blob_appendf(&bSQL,
          133  +      " AND (SELECT mlink.fnid FROM mlink WHERE event.objid=mlink.mid) IN (SELECT fnid FROM filename WHERE name=%Q %s)",
          134  +        zFilename, filename_collation()
          135  +    );
          136  +  }
    81    137   
    82    138     blob_append( &bSQL, " ORDER BY event.mtime DESC", -1 );
    83    139   
    84    140     cgi_set_content_type("application/rss+xml");
    85    141   
    86    142     zProjectName = db_get("project-name", 0);
    87    143     if( zProjectName==0 ){