CVSTrac Legacy Code

Check-in [afb2fee9b7]
Login

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

Overview
Comment:(#791) first stab at a generic report RSS feed. Item titles need some fine tuning and there's no way to determine dates, but otherwise it seems sane.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:afb2fee9b7a4513e7723d8cf714993f2ce978cff
User & Date: cpb 2009-03-10 03:06:12
Context
2009-03-13
02:00
(#783) when we append to a ticket we get bounced back to the ticket view. Might as well get bounced back to the anchor we just added. check-in: fb194a19a2 user: cpb tags: trunk
2009-03-10
03:06
(#791) first stab at a generic report RSS feed. Item titles need some fine tuning and there's no way to determine dates, but otherwise it seems sane. check-in: afb2fee9b7 user: cpb tags: trunk
01:19
the dashed-forms of the git commands are now not reliably avaiable. check-in: ec1de0af03 user: cpb tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to rss.c.

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <assert.h>
#include "config.h"
#include "rss.h"

/*
** Generate a common RSS header
*/
static void common_rss_header(char *zTitle, char *zDescription, int nBuildDate){
  int nTTL = atoi(db_config("rss_ttl", "60"));
  cgi_set_content_type("text/xml");
  g.zLinkURL = g.zBaseURL;  /* formatting for output links... */
#if CVSTRAC_I18N
  @ <?xml version="1.0" encoding="%h(nl_langinfo(CODESET))"?>
#else
  @ <?xml version="1.0" encoding="ISO-8859-1"?>







|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <assert.h>
#include "config.h"
#include "rss.h"

/*
** Generate a common RSS header
*/
void common_rss_header(char *zTitle, char *zDescription, int nBuildDate){
  int nTTL = atoi(db_config("rss_ttl", "60"));
  cgi_set_content_type("text/xml");
  g.zLinkURL = g.zBaseURL;  /* formatting for output links... */
#if CVSTRAC_I18N
  @ <?xml version="1.0" encoding="%h(nl_langinfo(CODESET))"?>
#else
  @ <?xml version="1.0" encoding="ISO-8859-1"?>

Changes to view.c.

917
918
919
920
921
922
923





















































































924
925
926
927
928
929
930
....
1178
1179
1180
1181
1182
1183
1184




1185
1186
1187
1188
1189
1190
1191
....
1211
1212
1213
1214
1215
1216
1217


































































  }
  if( tn>0 && g.okWrite ){
    @ <td valign="top"><a href="tktedit?tn=%d(tn),%d(rn)">edit</a></td>
  }
  @ </tr>
  return 0;
}






















































































/*
** Output the text given in the argument.  Convert tabs and newlines into
** spaces.
*/
static void output_no_tabs(const char *z){
  while( z && z[0] ){
................................................................................

    db_execute("PRAGMA empty_result_callbacks=ON");
    common_standard_menu("rptview", 0);
    common_add_help_item("CvstracReport");
    common_add_action_item(
      mprintf("rptview?tablist=1&%s", getenv("QUERY_STRING")),
      "Raw Data"




    );
    if( g.okAdmin || (g.okQuery && strcmp(g.zUser,zOwner)==0) ){
      common_add_action_item( mprintf("rptedit?rn=%d",rn), "Edit");
    }
    common_add_action_item( mprintf("rptsql?rn=%d",rn), "SQL");
    add_rpt_tools(NULL,rn);
    common_header("%s", zTitle);
................................................................................
    db_restrict_access(0);
    cgi_set_content_type("text/plain");
  }
  if( !tabs ){
    common_footer();
  }
}









































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
....
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
....
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
  }
  if( tn>0 && g.okWrite ){
    @ <td valign="top"><a href="tktedit?tn=%d(tn),%d(rn)">edit</a></td>
  }
  @ </tr>
  return 0;
}

/*
** Another callback function for db_query
*/
static int generate_rss(
  void* pUser,     /* Pointer to output state */
  int nArg,        /* Number of columns in this result row */
  char **azArg,    /* Text of data in all columns */
  char **azName    /* Names of the columns */
){
  struct GenerateHTML* pState = (struct GenerateHTML*)pUser;
  int i;
  int rn;            /* Report number */
  int iBg = -1;      /* Index of column that determines background color */
  char *zTitle = NULL;
  char *zDesc = NULL;

  /* Get the report number
  */
  rn = pState->rn;

  /* Figure out the column that determines background color */
  for(i=0; i<nArg; i++){
    if( azName[i][0]=='b' && strcmp(azName[i],"bgcolor")==0 ){
      iBg = i;
    }
  }

  if( azArg==0 ){
    return 0;
  }

  ++pState->nCount;

  /* Output the data for this entry from the database
  */
  {
    /* we'll need to restore this later */
    int n=0, n2=0;
    char *zContent = cgi_extract_content(&n);

    for(i=0; i<nArg; i++){
      char *zData = azArg[i];
      if( zData == NULL ) continue;
      if( i==iBg ) continue;

      if( azName[i][0] == '_' ) {
        if( zData[0] ){
          output_formatted("\n----\n", NULL);
          output_formatted(zData, 0);
        }
      }else if( azName[i][0]=='#' ){
        output_ticket(atoi(zData),rn);
      }else{
        if( zTitle==NULL ){
          @ %h(zData)
        }else{
          @ %h(azName[i]): \
          output_report_field(zData,rn);
        }
      }
      if( zTitle==NULL ){
        /* first "good" column will be the title. The content of the
        ** title won't be found in the body.
        */
        zTitle = cgi_extract_content(&n2);
      }else {
        @ <br />
      }
    }

    zDesc = cgi_extract_content(&n2);

    /* restore the original buffer */
    cgi_append_content(zContent,n);
    if( zContent ) free(zContent);
  }

  @ <item>
  @ <title>%h(zTitle)</title>
  @ <description>%h(zDesc)</description>
  @ </item>

  return 0;
}

/*
** Output the text given in the argument.  Convert tabs and newlines into
** spaces.
*/
static void output_no_tabs(const char *z){
  while( z && z[0] ){
................................................................................

    db_execute("PRAGMA empty_result_callbacks=ON");
    common_standard_menu("rptview", 0);
    common_add_help_item("CvstracReport");
    common_add_action_item(
      mprintf("rptview?tablist=1&%s", getenv("QUERY_STRING")),
      "Raw Data"
    );
    common_add_action_item(
      mprintf( "rptview.rss?%s", getenv("QUERY_STRING")),
      "RSS"
    );
    if( g.okAdmin || (g.okQuery && strcmp(g.zUser,zOwner)==0) ){
      common_add_action_item( mprintf("rptedit?rn=%d",rn), "Edit");
    }
    common_add_action_item( mprintf("rptsql?rn=%d",rn), "SQL");
    add_rpt_tools(NULL,rn);
    common_header("%s", zTitle);
................................................................................
    db_restrict_access(0);
    cgi_set_content_type("text/plain");
  }
  if( !tabs ){
    common_footer();
  }
}

/*
** WEBPAGE: /rptview.rss
**
** Generate a report.  The rn query parameter is the report number
** corresponding to REPORTFMT.RN.  If the tablist query parameter exists,
** then the output consists of lines of tab-separated fields instead of
** an HTML table.
*/
void rss_view(void){
  int rn;
  char **az;
  char *zSql;
  char *zTitle;
  char *zDesc;
  struct GenerateHTML sState;

  login_check_credentials();
  if( !g.okRead ){ login_needed(); return; }
  throttle(1,0);
  rn = atoi(PD("rn","0"));
  if( rn==0 ){
    cgi_redirect("reportlist");
    return;
  }
  db_add_functions();
  view_add_functions(0);
  az = db_query(
    "SELECT title, sqlcode, owner, cols, description "
    "FROM reportfmt WHERE rn=%d", rn);
  if( az[0]==0 ){
    cgi_redirect("reportlist");
    return;
  }
  zTitle = az[0];
  zSql = az[1];
  zDesc = az[4];

  if( P("order_by") ){
    /*
    ** If the user wants to do a column sort, wrap the query into a sub
    ** query and then sort the results. This is a whole lot easier than
    ** trying to insert an ORDER BY into the query itself, especially
    ** if the query is already ordered.
    */
    int nField = atoi(P("order_by"));
    if( nField > 0 ){
      const char* zDir = PD("order_dir","");
      zDir = !strcmp("ASC",zDir) ? "ASC" : "DESC";
      zSql = mprintf("SELECT * FROM (%s) ORDER BY %d %s", zSql, nField, zDir);
    }
  }

  common_rss_header(zTitle,
    zDesc ? format_formatted(zDesc,NULL) : "",
    time(0));

  db_execute("PRAGMA empty_result_callbacks=ON");
  db_restrict_access(1);
  sState.rn = rn;
  sState.nCount = 0;
  db_callback_query(generate_rss, &sState, "%s", zSql);
  db_restrict_access(0);

  common_rss_footer();
}