Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| SHA1 Hash: | dd2d3177b1b8333ee909d14edfd5f3287b689498 |
|---|---|
| Date: | 2010-03-17 23:15:04 |
| User: | drh |
| Comment: | Basic functionality of attachments is now in place. |
Tags And Properties
- bgcolor=#c0ffc0 inherited from [c3d7df650b]
- branch=experimental inherited from [c3d7df650b] branch timeline
- sym-experimental inherited from [c3d7df650b]
Changes
[hide diffs]Changes to src/attach.c
@@ -30,10 +30,11 @@
/*
** WEBPAGE: attachlist
**
** tkt=TICKETUUID
** page=WIKIPAGE
+** all
**
** List attachments.
*/
void attachlist_page(void){
const char *zPage = P("page");
@@ -79,22 +80,104 @@
}
}
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename);
}else{
- zUrlTail = mprintf("page=%s&file=%t", zTarget, zFilename);
+ zUrlTail = mprintf("page=%t&file=%t", zTarget, zFilename);
}
+ @
@ <p><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a>
- @ [<a href="/attachdownload?%s(zUrlTail)">download</a>]<br>
+ @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br>
@ %w(zComment)<br>
- @ Added by %h(zUser) on %s(zDate)</p>
- @
+ if( zPage==0 && zTkt==0 ){
+ if( strlen(zTarget)==UUID_SIZE && validate16(zTarget, UUID_SIZE) ){
+ char zShort[20];
+ memcpy(zShort, zTarget, 10);
+ zShort[10] = 0;
+ @ Added to ticket <a href="%s(g.zTop)/tktview?name=%s(zTarget)">
+ @ %s(zShort)</a>
+ }else{
+ @ Added to wiki page <a href="%s(g.zTop)/wiki?name=%t(zTarget)">
+ @ %h(zTarget)</a>
+ }
+ }else{
+ @ Add
+ }
+ @ by %h(zUser) on
+ hyperlink_to_date(zDate, ".");
free(zUrlTail);
}
db_finalize(&q);
style_footer();
return;
+}
+
+/*
+** WEBPAGE: attachdownload
+** WEBPAGE: attachimage
+** WEBPAGE: attachview
+**
+** tkt=TICKETUUID
+** page=WIKIPAGE
+** file=FILENAME
+** attachid=ID
+**
+** List attachments.
+*/
+void attachview_page(void){
+ const char *zPage = P("page");
+ const char *zTkt = P("tkt");
+ const char *zFile = P("file");
+ const char *zTarget;
+ int attachid = atoi(PD("attachid","0"));
+ char *zUUID;
+
+ if( zPage && zTkt ) zTkt = 0;
+ if( zFile==0 ) fossil_redirect_home();
+ login_check_credentials();
+ if( zPage ){
+ if( g.okRdWiki==0 ) login_needed();
+ zTarget = zPage;
+ }else if( zTkt ){
+ if( g.okRdTkt==0 ) login_needed();
+ zTarget = zTkt;
+ }else{
+ fossil_redirect_home();
+ }
+ if( attachid>0 ){
+ zUUID = db_text(0,
+ "SELECT coalesce(src,'x') FROM attachment"
+ " WHERE target=%Q AND attachid=%d",
+ zTarget, attachid
+ );
+ }else{
+ zUUID = db_text(0,
+ "SELECT coalesce(src,'x') FROM attachment"
+ " WHERE target=%Q AND filename=%Q"
+ " ORDER BY mtime DESC LIMIT 1",
+ zTarget, zFile
+ );
+ }
+ if( zUUID==0 ){
+ style_header("No Such Attachment");
+ @ No such attachment....
+ style_footer();
+ return;
+ }else if( zUUID[0]=='x' ){
+ style_header("Missing");
+ @ Attachment has been deleted
+ style_footer();
+ return;
+ }
+ g.okRead = 1;
+ cgi_replace_parameter("name",zUUID);
+ if( strcmp(g.zPath,"attachview")==0 ){
+ artifact_page();
+ }else{
+ cgi_replace_parameter("m", mimetype_from_name(zFile));
+ rawartifact_page();
+ }
}
/*
** WEBPAGE: attachadd
**
@@ -173,11 +256,11 @@
manifest_crosslink(rid, &manifest);
db_end_transaction(0);
cgi_redirect(zFrom);
}
style_header("Add Attachment");
- @ <h1>Add Attachment To %s(zTargetType)</h1>
+ @ <h2>Add Attachment To %s(zTargetType)</h2>
@ <form action="%s(g.zBaseURL)/attachadd" method="POST"
@ enctype="multipart/form-data">
@ File to Attach:
@ <input type="file" name="f" size="60"><br>
@ Description:<br>
Changes to src/info.c
@@ -732,10 +732,52 @@
}
cnt++;
}
db_finalize(&q);
}
+ db_prepare(&q,
+ "SELECT target, filename, datetime(mtime), user, src"
+ " FROM attachment"
+ " WHERE src=(SELECT uuid FROM blob WHERE rid=%d)"
+ " ORDER BY mtime DESC",
+ rid
+ );
+ while( db_step(&q)==SQLITE_ROW ){
+ const char *zTarget = db_column_text(&q, 0);
+ const char *zFilename = db_column_text(&q, 1);
+ const char *zDate = db_column_text(&q, 2);
+ const char *zUser = db_column_text(&q, 3);
+ const char *zSrc = db_column_text(&q, 4);
+ if( cnt>0 ){
+ @ Also attachment "%h(zFilename)" to
+ }else{
+ @ Attachment "%h(zFilename)" to
+ }
+ if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
+ char zShort[20];
+ memcpy(zShort, zTarget, 10);
+ if( g.okHistory && g.okRdTkt ){
+ @ ticket [<a href="%s(g.zTop)/tktview?name=%s(zShort)">%s(zShort)</a>]
+ }else{
+ @ ticket [%s(zShort)]
+ }
+ }else{
+ if( g.okHistory && g.okRdWiki ){
+ @ wiki page [<a href="%s(g.zTop)/wiki?name=%t(zTarget)">%h(zTarget)</a>]
+ }else{
+ @ wiki page [%h(zTarget)]
+ }
+ }
+ @ added by
+ hyperlink_to_user(zUser,zDate," on");
+ hyperlink_to_date(zDate,".");
+ cnt++;
+ if( pDownloadName && blob_size(pDownloadName)==0 ){
+ blob_append(pDownloadName, zSrc, -1);
+ }
+ }
+ db_finalize(&q);
if( cnt==0 ){
char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
@ Control artifact.
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_append(pDownloadName, zUuid, -1);
Changes to src/tkt.c
@@ -296,18 +296,20 @@
**
** View a ticket.
*/
void tktview_page(void){
const char *zScript;
+ char *zFullName;
+ const char *zUuid = PD("name","");
+
login_check_credentials();
if( !g.okRdTkt ){ login_needed(); return; }
if( g.okWrTkt || g.okApndTkt ){
style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T",
g.zTop, PD("name",""));
}
if( g.okHistory ){
- const char *zUuid = PD("name","");
style_submenu_element("History", "History Of This Ticket",
"%s/tkthistory/%T", g.zTop, zUuid);
style_submenu_element("Timeline", "Timeline Of This Ticket",
"%s/tkttimeline/%T", g.zTop, zUuid);
style_submenu_element("Check-ins", "Check-ins Of This Ticket",
@@ -315,18 +317,54 @@
}
if( g.okNewTkt ){
style_submenu_element("New Ticket", "Create a new ticket",
"%s/tktnew", g.zTop);
}
+ if( g.okApndTkt && g.okAttach ){
+ style_submenu_element("Attach", "Add An Attachment",
+ "%s/attachadd?tkt=%T", g.zTop, zUuid);
+ }
style_header("View Ticket");
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
ticket_init();
initializeVariablesFromDb();
zScript = ticket_viewpage_code();
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br />\n", -1);
Th_Render(zScript);
if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
+
+ zFullName = db_text(0,
+ "SELECT tkt_uuid FROM ticket"
+ " WHERE tkt_uuid GLOB '%q*'", zUuid);
+ if( zFullName ){
+ int cnt = 0;
+ Stmt q;
+ db_prepare(&q,
+ "SELECT datetime(mtime,'localtime'), filename, user"
+ " FROM attachment"
+ " WHERE isLatest AND src NOT NULL AND target=%Q"
+ " ORDER BY mtime DESC",
+ zFullName);
+ while( db_step(&q)==SQLITE_ROW ){
+ const char *zDate = db_column_text(&q, 0);
+ const char *zFile = db_column_text(&q, 1);
+ const char *zUser = db_column_text(&q, 2);
+ if( cnt==0 ){
+ @ <hr><h2>Attachments:</h2>
+ @ <ul>
+ }
+ cnt++;
+ @ <li><a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&file=%t(zFile)">
+ @ %h(zFile)</a> add by %h(zUser) on
+ hyperlink_to_date(zDate, ".</li>");
+ }
+ if( cnt ){
+ @ </ul>
+ }
+ db_finalize(&q);
+ }
+
style_footer();
}
/*
** TH command: append_field FIELD STRING
Changes to src/wiki.c
@@ -127,10 +127,12 @@
int isSandbox;
Blob wiki;
Manifest m;
const char *zPageName;
char *zBody = mprintf("%s","<i>Empty Page</i>");
+ Stmt q;
+ int cnt = 0;
login_check_credentials();
if( !g.okRdWiki ){ login_needed(); return; }
zPageName = P("name");
if( zPageName==0 ){
@@ -152,11 +154,12 @@
@ <li> Create a <a href="%s(g.zBaseURL)/wikinew">new wiki page</a>.</li>
}
@ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a>
@ available on this server.</li>
@ <li> <form method="GET" action="%s(g.zBaseURL)/wfind">
- @ Search wiki titles: <input type="text" name="title"/> <input type="submit" />
+ @ Search wiki titles: <input type="text" name="title"/>
+ @ <input type="submit" />
@ </li>
@ </ul>
style_footer();
return;
}
@@ -186,10 +189,14 @@
if( !g.isHome ){
if( (rid && g.okWrWiki) || (!rid && g.okNewWiki) ){
style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T",
g.zTop, zPageName);
}
+ if( rid && g.okWrWiki && g.okAttach ){
+ style_submenu_element("Attach", "Add An Attachment",
+ "%s/attachadd?page=%T", g.zTop, zPageName);
+ }
if( rid && g.okApndWiki ){
style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T",
g.zTop, zPageName);
}
if( g.okHistory ){
@@ -199,10 +206,35 @@
}
style_header(zPageName);
blob_init(&wiki, zBody, -1);
wiki_convert(&wiki, 0, 0);
blob_reset(&wiki);
+
+ db_prepare(&q,
+ "SELECT datetime(mtime,'localtime'), filename, user"
+ " FROM attachment"
+ " WHERE isLatest AND src NOT NULL AND target=%Q"
+ " ORDER BY mtime DESC",
+ zPageName);
+ while( db_step(&q)==SQLITE_ROW ){
+ const char *zDate = db_column_text(&q, 0);
+ const char *zFile = db_column_text(&q, 1);
+ const char *zUser = db_column_text(&q, 2);
+ if( cnt==0 ){
+ @ <hr><h2>Attachments:</h2>
+ @ <ul>
+ }
+ cnt++;
+ @ <li><a href="%s(g.zTop)/attachview?page=%s(zPageName)&file=%t(zFile)">
+ @ %h(zFile)</a> add by %h(zUser) on
+ hyperlink_to_date(zDate, ".</li>");
+ }
+ if( cnt ){
+ @ </ul>
+ }
+ db_finalize(&q);
+
if( !isSandbox ){
manifest_clear(&m);
}
style_footer();
}