| | @@ -1362,10 +1362,11 @@ |
| 1362 | 1362 | ** * Comment & user |
| 1363 | 1363 | */ |
| 1364 | 1364 | int object_description( |
| 1365 | 1365 | int rid, /* The artifact ID */ |
| 1366 | 1366 | u32 objdescFlags, /* Flags to control display */ |
| 1367 | + const char *zFileName, /* Explicit file name or 0 */ |
| 1367 | 1368 | Blob *pDownloadName /* Fill with an appropriate download name */ |
| 1368 | 1369 | ){ |
| 1369 | 1370 | Stmt q; |
| 1370 | 1371 | int cnt = 0; |
| 1371 | 1372 | int nWiki = 0; |
| | @@ -1401,10 +1402,11 @@ |
| 1401 | 1402 | const char *zVers = db_column_text(&q, 4); |
| 1402 | 1403 | int mPerm = db_column_int(&q, 5); |
| 1403 | 1404 | const char *zBr = db_column_text(&q, 6); |
| 1404 | 1405 | int szFile = db_column_int(&q,7); |
| 1405 | 1406 | int sameFilename = prevName!=0 && fossil_strcmp(zName,prevName)==0; |
| 1407 | + if( zFileName && fossil_strcmp(zName,zFileName)!=0 ) continue; |
| 1406 | 1408 | if( sameFilename && !showDetail ){ |
| 1407 | 1409 | if( cnt==1 ){ |
| 1408 | 1410 | @ %z(href("%R/whatis/%!S",zUuid))[more...]</a> |
| 1409 | 1411 | } |
| 1410 | 1412 | cnt++; |
| | @@ -1747,13 +1749,13 @@ |
| 1747 | 1749 | @ %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a> To |
| 1748 | 1750 | @ %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>.</h2> |
| 1749 | 1751 | }else{ |
| 1750 | 1752 | @ <h2>Differences From |
| 1751 | 1753 | @ Artifact %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a>:</h2> |
| 1752 | | - object_description(v1, objdescFlags, 0); |
| 1754 | + object_description(v1, objdescFlags,0, 0); |
| 1753 | 1755 | @ <h2>To Artifact %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>:</h2> |
| 1754 | | - object_description(v2, objdescFlags, 0); |
| 1756 | + object_description(v2, objdescFlags,0, 0); |
| 1755 | 1757 | } |
| 1756 | 1758 | if( pRe ){ |
| 1757 | 1759 | @ <b>Only differences that match regular expression "%h(zRe)" |
| 1758 | 1760 | @ are shown.</b> |
| 1759 | 1761 | } |
| | @@ -1937,11 +1939,11 @@ |
| 1937 | 1939 | }else{ |
| 1938 | 1940 | @ :</h2> |
| 1939 | 1941 | } |
| 1940 | 1942 | blob_zero(&downloadName); |
| 1941 | 1943 | if( P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL; |
| 1942 | | - object_description(rid, objdescFlags, &downloadName); |
| 1944 | + object_description(rid, objdescFlags, 0, &downloadName); |
| 1943 | 1945 | style_submenu_element("Download", "%s/raw/%T?name=%s", |
| 1944 | 1946 | g.zTop, blob_str(&downloadName), zUuid); |
| 1945 | 1947 | @ <hr /> |
| 1946 | 1948 | content_get(rid, &content); |
| 1947 | 1949 | @ <blockquote><pre> |
| | @@ -2127,20 +2129,34 @@ |
| 2127 | 2129 | Blob downloadName; |
| 2128 | 2130 | int renderAsWiki = 0; |
| 2129 | 2131 | int renderAsHtml = 0; |
| 2130 | 2132 | int objType; |
| 2131 | 2133 | int asText; |
| 2132 | | - const char *zUuid; |
| 2134 | + const char *zUuid = 0; |
| 2133 | 2135 | u32 objdescFlags = OBJDESC_BASE; |
| 2134 | 2136 | int descOnly = fossil_strcmp(g.zPath,"whatis")==0; |
| 2135 | 2137 | int isFile = fossil_strcmp(g.zPath,"file")==0; |
| 2136 | 2138 | const char *zLn = P("ln"); |
| 2137 | 2139 | const char *zName = P("name"); |
| 2140 | + const char *zCI = P("ci"); |
| 2138 | 2141 | HQuery url; |
| 2142 | + Blob dirname; |
| 2143 | + |
| 2144 | + if( zCI ){ |
| 2145 | + login_check_credentials(); |
| 2146 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 2139 | 2147 | |
| 2148 | + blob_zero(&dirname); |
| 2149 | + hyperlinked_path(zName, &dirname, zCI, "dir", ""); |
| 2150 | + blob_reset(&dirname); |
| 2151 | + } |
| 2140 | 2152 | url_initialize(&url, g.zPath); |
| 2141 | | - rid = artifact_from_ci_and_filename(&url, 0); |
| 2153 | + if( isFile&&zName ) { |
| 2154 | + rid = artifact_from_ci_and_filename(0, "name"); |
| 2155 | + }else{ |
| 2156 | + rid = artifact_from_ci_and_filename(&url, 0); |
| 2157 | + } |
| 2142 | 2158 | if( rid==0 ){ |
| 2143 | 2159 | url_add_parameter(&url, "name", zName); |
| 2144 | 2160 | if( isFile ){ |
| 2145 | 2161 | /* Do a top-level directory listing in /file mode if no argument |
| 2146 | 2162 | ** specified */ |
| | @@ -2196,12 +2212,24 @@ |
| 2196 | 2212 | if( descOnly || P("verbose")!=0 ){ |
| 2197 | 2213 | url_add_parameter(&url, "verbose", "1"); |
| 2198 | 2214 | objdescFlags |= OBJDESC_DETAIL; |
| 2199 | 2215 | } |
| 2200 | 2216 | zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 2217 | + |
| 2201 | 2218 | if( isFile ){ |
| 2202 | | - @ <h2>Latest version of file '%h(zName)':</h2> |
| 2219 | + if( zCI ){ |
| 2220 | + const char *zPath; |
| 2221 | + Blob path; |
| 2222 | + blob_zero(&path); |
| 2223 | + hyperlinked_path(zName, &path, zCI, "dir", ""); |
| 2224 | + zPath = blob_str(&path); |
| 2225 | + @ <h2>File %s(zPath) of check-in [%z(href("/info/%!S",zCI))%S(zCI)</a>] |
| 2226 | + @ </h2> |
| 2227 | + blob_reset(&path); |
| 2228 | + }else{ |
| 2229 | + @ <h2>Latest version of file '%h(zName)':</h2> |
| 2230 | + } |
| 2203 | 2231 | style_submenu_element("Artifact", "%R/artifact/%S", zUuid); |
| 2204 | 2232 | }else{ |
| 2205 | 2233 | @ <h2>Artifact |
| 2206 | 2234 | style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid); |
| 2207 | 2235 | if( g.perm.Setup ){ |
| | @@ -2211,11 +2239,11 @@ |
| 2211 | 2239 | } |
| 2212 | 2240 | } |
| 2213 | 2241 | blob_zero(&downloadName); |
| 2214 | 2242 | asText = P("txt")!=0; |
| 2215 | 2243 | if( asText ) objdescFlags &= ~OBJDESC_BASE; |
| 2216 | | - objType = object_description(rid, objdescFlags, &downloadName); |
| 2244 | + objType = object_description(rid, objdescFlags, (isFile ? zName : 0),&downloadName); |
| 2217 | 2245 | if( !descOnly && P("download")!=0 ){ |
| 2218 | 2246 | cgi_redirectf("%R/raw/%T?name=%s", blob_str(&downloadName), |
| 2219 | 2247 | db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid)); |
| 2220 | 2248 | /*NOTREACHED*/ |
| 2221 | 2249 | } |
| 2222 | 2250 | |