Check-in [1fcfa000b4]
Not logged in

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

Overview
SHA1 Hash:1fcfa000b4a1f014d4f9ec05096f1895b15c65ab
Date: 2010-03-17 19:57:01
User: drh
Comment:Added screens for adding and listing attachments.
Tags And Properties
Changes

Changes to src/attach.c

    41   Blob sql;                                                                            41   Blob sql;
    42   Stmt q;                                                                              42   Stmt q;
    43                                                                                        43 
    44   if( zPage && zTkt ) zTkt = 0;                                                        44   if( zPage && zTkt ) zTkt = 0;
    45   login_check_credentials();                                                           45   login_check_credentials();
    46   blob_zero(&sql);                                                                     46   blob_zero(&sql);
    47   blob_append(&sql,                                                                    47   blob_append(&sql,
    48      "SELECT datetime(mtime,'localtime'), src, filename, comment, user"          |     48      "SELECT datetime(mtime,'localtime'), src, target, filename, comment, user"
    49      "  FROM attachment",                                                              49      "  FROM attachment",
    50      -1                                                                                50      -1
    51   );                                                                                   51   );
    52   if( zPage ){                                                                         52   if( zPage ){
    53     if( g.okRdWiki==0 ) login_needed();                                                53     if( g.okRdWiki==0 ) login_needed();
    54     style_header("Attachments To %h", zPage);                                          54     style_header("Attachments To %h", zPage);
    55     blob_appendf(&sql, " WHERE target=%Q", zPage);                                     55     blob_appendf(&sql, " WHERE target=%Q", zPage);
................................................................................................................................................................................
    61     if( g.okRdTkt==0 && g.okRdWiki==0 ) login_needed();                                61     if( g.okRdTkt==0 && g.okRdWiki==0 ) login_needed();
    62     style_header("All Attachments");                                                   62     style_header("All Attachments");
    63   }                                                                                    63   }
    64   blob_appendf(&sql, " ORDER BY mtime DESC");                                          64   blob_appendf(&sql, " ORDER BY mtime DESC");
    65   db_prepare(&q, "%s", blob_str(&sql));                                                65   db_prepare(&q, "%s", blob_str(&sql));
    66   while( db_step(&q)==SQLITE_ROW ){                                                    66   while( db_step(&q)==SQLITE_ROW ){
    67     const char *zDate = db_column_text(&q, 0);                                         67     const char *zDate = db_column_text(&q, 0);
    68     const char *zSrc = db_column_text(&q, 1);                                    |     68     /* const char *zSrc = db_column_text(&q, 1); */
    69     const char *zFilename = db_column_text(&q, 2);                               |     69     const char *zTarget = db_column_text(&q, 2);
    70     const char *zComment = db_column_text(&q, 3);                                |     70     const char *zFilename = db_column_text(&q, 3);
    71     const char *zUser = db_column_text(&q, 4);                                   |     71     const char *zComment = db_column_text(&q, 4);
                                                                                        >     72     const char *zUser = db_column_text(&q, 5);
    72     int i;                                                                             73     int i;
                                                                                        >     74     char *zUrlTail;
    73     for(i=0; zFilename[i]; i++){                                                       75     for(i=0; zFilename[i]; i++){
    74       if( zFilename[i]=='/' && zFilename[i+1]!=0 ){                                    76       if( zFilename[i]=='/' && zFilename[i+1]!=0 ){
    75         zFilename = &zFilename[i+1];                                                   77         zFilename = &zFilename[i+1];
    76         i = -1;                                                                        78         i = -1;
    77       }                                                                                79       }
    78     }                                                                                  80     }
    79     @ <p><b>%h(zFilename)</b>                                                    |     81     if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
                                                                                        >     82       zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename);
                                                                                        >     83     }else{
                                                                                        >     84       zUrlTail = mprintf("page=%s&file=%t", zTarget, zFilename);
                                                                                        >     85     }
                                                                                        >     86     @ <p><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a>
                                                                                        >     87     @ [<a href="/attachdownload?%s(zUrlTail)">download</a>]<br>
    80     @ %w(zComment)<br>                                                                 88     @ %w(zComment)<br>
    81     @ Added by %h(zUser) on %s(zDate)</p>                                              89     @ Added by %h(zUser) on %s(zDate)</p>
    82     @                                                                                  90     @
                                                                                        >     91     free(zUrlTail);
    83   }                                                                                    92   }
    84   db_finalize(&q);                                                                     93   db_finalize(&q);
    85   style_footer();                                                                      94   style_footer();
    86                                                                                  <
    87   return;                                                                              95   return;
                                                                                        >     96 }
                                                                                        >     97 
                                                                                        >     98 /*
                                                                                        >     99 ** WEBPAGE: attachadd
                                                                                        >    100 **
                                                                                        >    101 **    tkt=TICKETUUID
                                                                                        >    102 **    page=WIKIPAGE
                                                                                        >    103 **    from=URL
                                                                                        >    104 **
                                                                                        >    105 ** Add a new attachment.
                                                                                        >    106 */
                                                                                        >    107 void attachadd_page(void){
                                                                                        >    108   const char *zPage = P("page");
                                                                                        >    109   const char *zTkt = P("tkt");
                                                                                        >    110   const char *zFrom = PD("from", "/home");
                                                                                        >    111   const char *aContent = P("f");
                                                                                        >    112   const char *zName = PD("f:filename","unknown");
                                                                                        >    113   const char *zTarget;
                                                                                        >    114   const char *zTargetType;
                                                                                        >    115   int szContent = atoi(PD("f:bytes","0"));
                                                                                        >    116 
                                                                                        >    117   if( P("cancel") ) cgi_redirect(zFrom);
                                                                                        >    118   if( zPage && zTkt ) fossil_redirect_home();
                                                                                        >    119   if( zPage==0 && zTkt==0 ) fossil_redirect_home();
                                                                                        >    120   login_check_credentials();
                                                                                        >    121   if( zPage ){
                                                                                        >    122     if( g.okApndWiki==0 || g.okAttach==0 ) login_needed();
                                                                                        >    123     if( !db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'", zPage) ){
                                                                                        >    124       fossil_redirect_home();
                                                                                        >    125     }
                                                                                        >    126     zTarget = zPage;
                                                                                        >    127     zTargetType = mprintf("Wiki Page <a href=\"%s/wiki?name=%h\">%h</a>",
                                                                                        >    128                            g.zTop, zPage, zPage);
                                                                                        >    129   }else{
                                                                                        >    130     if( g.okApndTkt==0 || g.okAttach==0 ) login_needed();
                                                                                        >    131     if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTkt) ){
                                                                                        >    132       fossil_redirect_home();
                                                                                        >    133     }
                                                                                        >    134     zTarget = zTkt;
                                                                                        >    135     zTargetType = mprintf("Ticket <a href=\"%s/tktview?name=%.10s\">%.10s</a>",
                                                                                        >    136                           g.zTop, zTkt, zTkt);
                                                                                        >    137   }
                                                                                        >    138   if( P("ok") && szContent>0 ){
                                                                                        >    139     Blob content;
                                                                                        >    140     Blob manifest;
                                                                                        >    141     Blob cksum;
                                                                                        >    142     char *zUUID;
                                                                                        >    143     const char *zComment;
                                                                                        >    144     char *zDate;
                                                                                        >    145     int rid;
                                                                                        >    146     int i, n;
                                                                                        >    147 
                                                                                        >    148     db_begin_transaction();
                                                                                        >    149     blob_init(&content, aContent, szContent);
                                                                                        >    150     rid = content_put(&content, 0, 0);
                                                                                        >    151     zUUID = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
                                                                                        >    152     blob_zero(&manifest);
                                                                                        >    153     for(i=n=0; zName[i]; i++){
                                                                                        >    154       if( zName[i]=='/' || zName[i]=='\\' ) n = i;
                                                                                        >    155     }
                                                                                        >    156     zName += n;
                                                                                        >    157     if( zName[0]==0 ) zName = "unknown";
                                                                                        >    158     blob_appendf(&manifest, "A %F %F %s\n", zName, zTarget, zUUID);
                                                                                        >    159     zComment = PD("comment", "");
                                                                                        >    160     while( isspace(zComment[0]) ) zComment++;
                                                                                        >    161     n = strlen(zComment);
                                                                                        >    162     while( n>0 && isspace(zComment[n-1]) ){ n--; }
                                                                                        >    163     if( n>0 ){
                                                                                        >    164       blob_appendf(&manifest, "C %F\n", zComment);
                                                                                        >    165     }
                                                                                        >    166     zDate = db_text(0, "SELECT datetime('now')");
                                                                                        >    167     zDate[10] = 'T';
                                                                                        >    168     blob_appendf(&manifest, "D %s\n", zDate);
                                                                                        >    169     blob_appendf(&manifest, "U %F\n", g.zLogin ? g.zLogin : "nobody");
                                                                                        >    170     md5sum_blob(&manifest, &cksum);
                                                                                        >    171     blob_appendf(&manifest, "Z %b\n", &cksum);
                                                                                        >    172     rid = content_put(&manifest, 0, 0);
                                                                                        >    173     manifest_crosslink(rid, &manifest);
                                                                                        >    174     db_end_transaction(0);
                                                                                        >    175     cgi_redirect(zFrom);
                                                                                        >    176   }
                                                                                        >    177   style_header("Add Attachment");
                                                                                        >    178   @ <h1>Add Attachment To %s(zTargetType)</h1>
                                                                                        >    179   @ <form action="%s(g.zBaseURL)/attachadd" method="POST"
                                                                                        >    180   @  enctype="multipart/form-data">
                                                                                        >    181   @ File to Attach:
                                                                                        >    182   @ <input type="file" name="f" size="60"><br>
                                                                                        >    183   @ Description:<br>
                                                                                        >    184   @ <textarea name="comment" cols=80 rows=5 wrap="virtual"></textarea><br>
                                                                                        >    185   if( zTkt ){
                                                                                        >    186     @ <input type="hidden" name="tkt" value="%h(zTkt)">
                                                                                        >    187   }else{
                                                                                        >    188     @ <input type="hidden" name="page" value="%h(zPage)">
                                                                                        >    189   }
                                                                                        >    190   @ <input type="hidden" name="from" value="%h(zFrom)">
                                                                                        >    191   @ <input type="submit" name="ok" value="Add Attachment">
                                                                                        >    192   @ <input type="submit" name="can" value="Cancel">
                                                                                        >    193   @ </form>
                                                                                        >    194   style_footer();
    88 }                                                                                     195 }

Changes to src/manifest.c

   194            && !wiki_name_is_wellformed((const unsigned char *)zTarget) ){             194            && !wiki_name_is_wellformed((const unsigned char *)zTarget) ){
   195           goto manifest_syntax_error;                                                 195           goto manifest_syntax_error;
   196         }                                                                             196         }
   197         if( blob_size(&a3)>0                                                          197         if( blob_size(&a3)>0
   198          && (blob_size(&a3)!=UUID_SIZE || !validate16(zSrc, UUID_SIZE)) ){            198          && (blob_size(&a3)!=UUID_SIZE || !validate16(zSrc, UUID_SIZE)) ){
   199           goto manifest_syntax_error;                                                 199           goto manifest_syntax_error;
   200         }                                                                             200         }
   201         p->zAttachName = zName;                                                  |    201         p->zAttachName = file_tail(zName);
   202         p->zAttachSrc = zSrc;                                                         202         p->zAttachSrc = zSrc;
   203         p->zAttachTarget = zTarget;                                                   203         p->zAttachTarget = zTarget;
   204         break;                                                                        204         break;
   205       }                                                                               205       }
   206                                                                                       206 
   207       /*                                                                              207       /*
   208       **     C <comment>                                                              208       **     C <comment>
................................................................................................................................................................................
  1117     tag_insert(zTag, 1, 0, rid, m.rDate, rid);                                       1117     tag_insert(zTag, 1, 0, rid, m.rDate, rid);
  1118     free(zTag);                                                                      1118     free(zTag);
  1119     db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)",                    1119     db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)",
  1120                   m.zTicketUuid);                                                    1120                   m.zTicketUuid);
  1121   }                                                                                  1121   }
  1122   if( m.type==CFTYPE_ATTACHMENT ){                                                   1122   if( m.type==CFTYPE_ATTACHMENT ){
  1123     db_multi_exec(                                                                   1123     db_multi_exec(
  1124        "INSERT OR IGNORE INTO attachment(mtime, target, filename)"               |   1124        "INSERT INTO attachment(attachid, mtime, src, target,"
  1125        "VALUES(0.0,%Q,%Q)",                                                      |   1125                                         "filename, comment, user)"
  1126        m.zAttachTarget, m.zAttachName                                            |   1126        "VALUES(%d,%.17g,%Q,%Q,%Q,%Q,%Q);",
                                                                                        >   1127        rid, m.rDate, m.zAttachSrc, m.zAttachTarget, m.zAttachName,
                                                                                        >   1128        (m.zComment ? m.zComment : ""), m.zUser
  1127     );                                                                               1129     );
  1128     db_multi_exec(                                                                   1130     db_multi_exec(
  1129        "UPDATE attachment SET mtime=%.17g, src=%Q, comment=%Q, user=%Q"          |   1131        "UPDATE attachment SET isLatest = (mtime=="
  1130        " WHERE mtime<%.17g AND target=%Q AND filename=%Q",                       |   1132           "(SELECT max(mtime) FROM attachment"
  1131        m.rDate, m.zAttachSrc, m.zComment, m.zUser,                               |   1133           "  WHERE target=%Q AND filename=%Q))"
  1132        m.rDate, m.zAttachTarget, m.zAttachName                                   |   1134        " WHERE target=%Q AND filename=%Q",
                                                                                        >   1135        m.zAttachTarget, m.zAttachName,
                                                                                        >   1136        m.zAttachTarget, m.zAttachName
  1133     );                                                                               1137     );
  1134   }                                                                                  1138   }
  1135   db_end_transaction(0);                                                             1139   db_end_transaction(0);
  1136   manifest_clear(&m);                                                                1140   manifest_clear(&m);
  1137   return 1;                                                                          1141   return 1;
  1138 }                                                                                    1142 }

Changes to src/schema.c

   325 @ );                                                                                  325 @ );
   326 @ CREATE INDEX backlink_src ON backlink(srcid, srctype);                              326 @ CREATE INDEX backlink_src ON backlink(srcid, srctype);
   327 @                                                                                     327 @
   328 @ -- Each attachment is an entry in the following table.  Only                        328 @ -- Each attachment is an entry in the following table.  Only
   329 @ -- the most recent attachment (identified by the D card) is saved.                  329 @ -- the most recent attachment (identified by the D card) is saved.
   330 @ --                                                                                  330 @ --
   331 @ CREATE TABLE attachment(                                                            331 @ CREATE TABLE attachment(
                                                                                        >    332 @   attachid INTEGER PRIMARY KEY,   -- Local id for this attachment
                                                                                        >    333 @   isLatest BOOLEAN DEFAULT 0,     -- True if this is the one to use
   332 @   mtime TIMESTAMP,                -- Time when attachment last changed              334 @   mtime TIMESTAMP,                -- Time when attachment last changed
   333 @   src TEXT,                       -- UUID of the attachment.  NULL to delete        335 @   src TEXT,                       -- UUID of the attachment.  NULL to delete
   334 @   target TEXT,                    -- Object attached to                        |    336 @   target TEXT,                    -- Object attached to. Wikiname or Tkt UUID
   335 @   filename TEXT,                  -- Filename for the attachment                    337 @   filename TEXT,                  -- Filename for the attachment
   336 @   comment TEXT,                   -- Comment associated with this attachment        338 @   comment TEXT,                   -- Comment associated with this attachment
   337 @   user TEXT,                      -- Name of user adding attachment            |    339 @   user TEXT                       -- Name of user adding attachment
   338 @   PRIMARY KEY(target, filename)                                                <
   339 @ );                                                                                  340 @ );
                                                                                        >    341 @ CREATE INDEX attachment_idx1 ON attachment(target, filename, mtime);
                                                                                        >    342 @ CREATE INDEX attachment_idx2 ON attachment(src);
   340 @                                                                                     343 @
   341 @ -- Template for the TICKET table                                                    344 @ -- Template for the TICKET table
   342 @ --                                                                                  345 @ --
   343 @ -- NB: when changing the schema of the TICKET table here, also make the             346 @ -- NB: when changing the schema of the TICKET table here, also make the
   344 @ -- same change in tktsetup.c.                                                       347 @ -- same change in tktsetup.c.
   345 @ --                                                                                  348 @ --
   346 @ CREATE TABLE ticket(                                                                349 @ CREATE TABLE ticket(