Fossil

Check-in [070e63db33]
Login

Check-in [070e63db33]

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

Overview
Comment:Merge old tagview branch into this branch
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | eric-tagview-rework | trunk
Files: files | file ages | folders
SHA1: 070e63db3362346be6782a270135c950434e7518
User & Date: eric 2008-08-17 20:53:20.000
Context
2008-08-21
20:59
Include non-sym- tags in tagview web page. Also merge mainline into tagview branch. ... (check-in: 5fb14b9a0f user: eric tags: eric-tagview-rework, trunk)
2008-08-17
20:53
Merge old tagview branch into this branch ... (check-in: 070e63db33 user: eric tags: eric-tagview-rework, trunk)
2008-08-04
20:46
Make the info web page handle symbolic tags as well as UUIDs. Start trying to make the currently-disabled tagview page more useful. ... (check-in: 3984b1b2c1 user: eric tags: eric-tagview-rework, trunk)
2008-02-20
17:13
made hyperlinks in the footer div less ugly. ... (check-in: 89a2d5e899 user: stephan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/cgi.c.
198
199
200
201
202
203
204

205
206
207

208
209
210
211
212
213
214
  const char *zValue,   /* Value of the cookie.  Automatically escaped */
  const char *zPath,    /* Path cookie applies to.  NULL means "/" */
  int lifetime          /* Expiration of the cookie in seconds from now */
){
  if( zPath==0 ) zPath = g.zTop;
  if( lifetime>0 ){
    lifetime += (int)time(0);

    blob_appendf(&extraHeader,
       "Set-Cookie: %s=%t; Path=%s; expires=%s; Version=1\r\n",
        zName, zValue, zPath, cgi_rfc822_datestamp(lifetime));

  }else{
    blob_appendf(&extraHeader,
       "Set-Cookie: %s=%t; Path=%s; Version=1\r\n",
       zName, zValue, zPath);
  }
}








>

|
|
>







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  const char *zValue,   /* Value of the cookie.  Automatically escaped */
  const char *zPath,    /* Path cookie applies to.  NULL means "/" */
  int lifetime          /* Expiration of the cookie in seconds from now */
){
  if( zPath==0 ) zPath = g.zTop;
  if( lifetime>0 ){
    lifetime += (int)time(0);
    char * zDate = cgi_rfc822_datestamp(lifetime);
    blob_appendf(&extraHeader,
       "Set-Cookie: %s=%t; Path=%s; expires=%z; Version=1\r\n",
        zName, zValue, zPath, zDate);
    if( zDate[0] ) free( zDate );
  }else{
    blob_appendf(&extraHeader,
       "Set-Cookie: %s=%t; Path=%s; Version=1\r\n",
       zName, zValue, zPath);
  }
}

284
285
286
287
288
289
290

291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

312

313
314
315
316
317
318
319
    iReplyStatus = 304;
    zReplyStatus = "Not Modified";
  }
#endif

  if( g.fullHttpReply ){
    fprintf(g.httpOut, "HTTP/1.0 %d %s\r\n", iReplyStatus, zReplyStatus);

    fprintf(g.httpOut, "Date: %s\r\n", cgi_rfc822_datestamp(time(0)));

    fprintf(g.httpOut, "Connection: close\r\n");
  }else{
    fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
  }

  if( blob_size(&extraHeader)>0 ){
    fprintf(g.httpOut, "%s", blob_buffer(&extraHeader));
  }

  if( g.isConst ){
    /* constant means that the input URL will _never_ generate anything
    ** else. In the case of attachments, the contents won't change because
    ** an attempt to change them generates a new attachment number. In the
    ** case of most /getfile calls for specific versions, the only way the
    ** content changes is if someone breaks the SCM. And if that happens, a
    ** stale cache is the least of the problem. So we provide an Expires
    ** header set to a reasonable period (default: one week).
    */
    /*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
    time_t expires = time(0) + 604800;

    fprintf(g.httpOut, "Expires: %s\r\n", cgi_rfc822_datestamp(expires));

  }

  /* Content intended for logged in users should only be cached in
  ** the browser, not some shared location.
  */
  fprintf(g.httpOut, "Cache-control: private\r\n");








>
|
>




















>
|
>







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
    iReplyStatus = 304;
    zReplyStatus = "Not Modified";
  }
#endif

  if( g.fullHttpReply ){
    fprintf(g.httpOut, "HTTP/1.0 %d %s\r\n", iReplyStatus, zReplyStatus);
    char * zDate = cgi_rfc822_datestamp(time(0));
    fprintf(g.httpOut, "Date: %s\r\n", zDate );
    if( zDate[0] ) free( zDate );
    fprintf(g.httpOut, "Connection: close\r\n");
  }else{
    fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
  }

  if( blob_size(&extraHeader)>0 ){
    fprintf(g.httpOut, "%s", blob_buffer(&extraHeader));
  }

  if( g.isConst ){
    /* constant means that the input URL will _never_ generate anything
    ** else. In the case of attachments, the contents won't change because
    ** an attempt to change them generates a new attachment number. In the
    ** case of most /getfile calls for specific versions, the only way the
    ** content changes is if someone breaks the SCM. And if that happens, a
    ** stale cache is the least of the problem. So we provide an Expires
    ** header set to a reasonable period (default: one week).
    */
    /*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
    time_t expires = time(0) + 604800;
    char * zDate = cgi_rfc822_datestamp(expires);
    fprintf(g.httpOut, "Expires: %s\r\n", zDate );
    if( zDate[0] ) free( zDate );
  }

  /* Content intended for logged in users should only be cached in
  ** the browser, not some shared location.
  */
  fprintf(g.httpOut, "Cache-control: private\r\n");

1265
1266
1267
1268
1269
1270
1271


1272
1273
1274
1275
1276
1277
1278
     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 0};


/*
** Returns an RFC822-formatted time string suitable for HTTP headers, among
** other things.
** Returned timezone is always GMT as required by HTTP/1.1 specification.


**
** See http://www.faqs.org/rfcs/rfc822.html, section 5
** and http://www.faqs.org/rfcs/rfc2616.html, section 3.3.
*/
char *cgi_rfc822_datestamp(time_t now){
  struct tm *pTm;
  pTm = gmtime(&now);







>
>







1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 0};


/*
** Returns an RFC822-formatted time string suitable for HTTP headers, among
** other things.
** Returned timezone is always GMT as required by HTTP/1.1 specification.
** The returned string is allocated with malloc() and must be freed
** with free().
**
** See http://www.faqs.org/rfcs/rfc822.html, section 5
** and http://www.faqs.org/rfcs/rfc2616.html, section 3.3.
*/
char *cgi_rfc822_datestamp(time_t now){
  struct tm *pTm;
  pTm = gmtime(&now);
Changes to src/style.c.
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
** Draw the header.
*/
void style_header(const char *zTitleFormat, ...){
  va_list ap;
  char *zTitle;
  const char *zHeader = db_get("header", (char*)zDefaultHeader);  
  login_check_credentials();

  va_start(ap, zTitleFormat);
  zTitle = vmprintf(zTitleFormat, ap);
  va_end(ap);
  
  cgi_destination(CGI_HEADER);

  /* Generate the header up through the main menu */







|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
** Draw the header.
*/
void style_header(const char *zTitleFormat, ...){
  va_list ap;
  char *zTitle;
  const char *zHeader = db_get("header", (char*)zDefaultHeader);  
  login_check_credentials();
  
  va_start(ap, zTitleFormat);
  zTitle = vmprintf(zTitleFormat, ap);
  va_end(ap);
  
  cgi_destination(CGI_HEADER);

  /* Generate the header up through the main menu */
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
}

/*
** Draw the footer at the bottom of the page.
*/
void style_footer(void){
  const char *zFooter;

  if( !headerHasBeenGenerated ) return;
  
  /* Go back and put the submenu at the top of the page.  We delay the
  ** creation of the submenu until the end so that we can add elements
  ** to the submenu while generating page text.
  */
  cgi_destination(CGI_HEADER);
  if( nSubmenu>0 ){
    int i;







|

|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
}

/*
** Draw the footer at the bottom of the page.
*/
void style_footer(void){
  const char *zFooter;
  
  if( !headerHasBeenGenerated ) return;

  /* Go back and put the submenu at the top of the page.  We delay the
  ** creation of the submenu until the end so that we can add elements
  ** to the submenu while generating page text.
  */
  cgi_destination(CGI_HEADER);
  if( nSubmenu>0 ){
    int i;
324
325
326
327
328
329
330






331
332
333
334
335
336
337
@   font-size: 0.8em;
@   margin-top: 12px;
@   padding: 5px 10px 5px 10px;
@   text-align: right;
@   background-color: #558195;
@   color: white;
@ }






@ 
@ /* <verbatim> blocks */
@ pre.verbatim {
@    background-color: #f5f5f5;
@    padding: 0.5em;
@}
@







>
>
>
>
>
>







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
@   font-size: 0.8em;
@   margin-top: 12px;
@   padding: 5px 10px 5px 10px;
@   text-align: right;
@   background-color: #558195;
@   color: white;
@ }
@
@ /* Make the links in the footer less ugly... */
@ div.footer a { color: white; }
@ div.footer a:link { color: white; }
@ div.footer a:visited { color: white; }
@ div.footer a:hover { background-color: white; color: #558195; }
@ 
@ /* <verbatim> blocks */
@ pre.verbatim {
@    background-color: #f5f5f5;
@    padding: 0.5em;
@}
@
Changes to src/tagview.c.
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  zSql = mprintf( 
    "SELECT "
    "   linktagid(t.tagid) AS 'Tag ID',"
    "   linktagname(t.tagname) AS 'Name',"
    "   DATETIME(tx.mtime) AS 'Timestamp',"
    "   linkuuid(b.uuid) AS 'Version'"
    "  FROM tag t, tagxref tx, blob b "
    " WHERE t.tagid=tx.tagid AND tx.srcid=b.rid"
    "   AND tx.tagtype!=0 %s "
    TAGVIEW_DEFAULT_FILTER
    " ORDER BY tx.mtime DESC %s",
    zLikeClause, zLimit
  );
  db_generic_query_view(zSql, 1);
  free(zSql);







|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  zSql = mprintf( 
    "SELECT "
    "   linktagid(t.tagid) AS 'Tag ID',"
    "   linktagname(t.tagname) AS 'Name',"
    "   DATETIME(tx.mtime) AS 'Timestamp',"
    "   linkuuid(b.uuid) AS 'Version'"
    "  FROM tag t, tagxref tx, blob b "
    " WHERE t.tagid=tx.tagid AND tx.rid=b.rid"
    "   AND tx.tagtype!=0 %s "
    TAGVIEW_DEFAULT_FILTER
    " ORDER BY tx.mtime DESC %s",
    zLikeClause, zLimit
  );
  db_generic_query_view(zSql, 1);
  free(zSql);
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
  @ <h2>Tag #%d(tagid):</h2>
  zSql = mprintf( 
    "SELECT DISTINCT"
    "       linktagname(t.tagname) AS 'Tag Name',"
    "       DATETIME(tx.mtime) AS 'Timestamp',"
    "       linkuuid(b.uuid) AS 'Version'"
    "  FROM tag t, tagxref tx, blob b"
    " WHERE t.tagid=%d AND t.tagid=tx.tagid AND tx.srcid=b.rid "
    TAGVIEW_DEFAULT_FILTER
    " ORDER BY tx.mtime DESC",
    tagid
  );
  db_generic_query_view(zSql, 1);
  free(zSql);
}

/*
** Lists all tags matching the given tag name.
*/
static void tagview_page_tag_by_name( char const * tagname ){
  char *zSql;
  @ <h2>Tag '%s(tagname)':</h2>
  zSql = mprintf( 
    "SELECT DISTINCT"
    "       linktagid(t.tagid) AS 'Tag ID',"
    "       DATETIME(tx.mtime) AS 'Timestamp',"
    "       linkuuid(b.uuid) AS 'Version'"
    "  FROM tag t, tagxref tx, blob b "
    " WHERE t.tagname='%q' AND t.tagid=tx.tagid AND tx.srcid=b.rid "
    TAGVIEW_DEFAULT_FILTER
    " ORDER BY tx.mtime DESC",
    tagname);
  db_generic_query_view(zSql, 1);
  free(zSql);
}








|




















|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
  @ <h2>Tag #%d(tagid):</h2>
  zSql = mprintf( 
    "SELECT DISTINCT"
    "       linktagname(t.tagname) AS 'Tag Name',"
    "       DATETIME(tx.mtime) AS 'Timestamp',"
    "       linkuuid(b.uuid) AS 'Version'"
    "  FROM tag t, tagxref tx, blob b"
    " WHERE t.tagid=%d AND t.tagid=tx.tagid AND tx.rid=b.rid "
    TAGVIEW_DEFAULT_FILTER
    " ORDER BY tx.mtime DESC",
    tagid
  );
  db_generic_query_view(zSql, 1);
  free(zSql);
}

/*
** Lists all tags matching the given tag name.
*/
static void tagview_page_tag_by_name( char const * tagname ){
  char *zSql;
  @ <h2>Tag '%s(tagname)':</h2>
  zSql = mprintf( 
    "SELECT DISTINCT"
    "       linktagid(t.tagid) AS 'Tag ID',"
    "       DATETIME(tx.mtime) AS 'Timestamp',"
    "       linkuuid(b.uuid) AS 'Version'"
    "  FROM tag t, tagxref tx, blob b "
    " WHERE t.tagname='%q' AND t.tagid=tx.tagid AND tx.rid=b.rid "
    TAGVIEW_DEFAULT_FILTER
    " ORDER BY tx.mtime DESC",
    tagname);
  db_generic_query_view(zSql, 1);
  free(zSql);
}