Fossil SCM

When to a repolist, if any of the repositories have a non-zero repolist-skin setting, use that repository as the skin for the listing. If the repolist-skin setting is 2, then omit that repository from the list for directory-scan lists, but always show all repos for a "fossil all ui" list. This *almost* works, but still has some small issues. This is an incremental check-in.

drh 2019-07-29 14:06 trunk
Commit 958e0bdc4ab87bdba6c71c3c081a63e9932574171b5dff062dde09a9d8bc9e47
+7
--- src/db.c
+++ src/db.c
@@ -3422,10 +3422,17 @@
34223422
** SETTING: repo-cksum boolean default=on
34233423
** Compute checksums over all files in each checkout as a double-check
34243424
** of correctness. Disable this on large repositories for a performance
34253425
** improvement.
34263426
*/
3427
+/*
3428
+** SETTING: repolist-skin width=2 default=0
3429
+** If non-zero then this repository desires to be used as the skin for
3430
+** repository lists. If 2, then use then omit this repository from the
3431
+** list for directory-scan lists. The repository is always displayed
3432
+** in lists for "fossil all ui" or "fossil all server".
3433
+*/
34273434
/*
34283435
** SETTING: self-register boolean default=off
34293436
** Allow users to register themselves through the HTTP UI.
34303437
** This is useful if you want to see other names than
34313438
** "Anonymous" in e.g. ticketing system. On the other hand
34323439
--- src/db.c
+++ src/db.c
@@ -3422,10 +3422,17 @@
3422 ** SETTING: repo-cksum boolean default=on
3423 ** Compute checksums over all files in each checkout as a double-check
3424 ** of correctness. Disable this on large repositories for a performance
3425 ** improvement.
3426 */
 
 
 
 
 
 
 
3427 /*
3428 ** SETTING: self-register boolean default=off
3429 ** Allow users to register themselves through the HTTP UI.
3430 ** This is useful if you want to see other names than
3431 ** "Anonymous" in e.g. ticketing system. On the other hand
3432
--- src/db.c
+++ src/db.c
@@ -3422,10 +3422,17 @@
3422 ** SETTING: repo-cksum boolean default=on
3423 ** Compute checksums over all files in each checkout as a double-check
3424 ** of correctness. Disable this on large repositories for a performance
3425 ** improvement.
3426 */
3427 /*
3428 ** SETTING: repolist-skin width=2 default=0
3429 ** If non-zero then this repository desires to be used as the skin for
3430 ** repository lists. If 2, then use then omit this repository from the
3431 ** list for directory-scan lists. The repository is always displayed
3432 ** in lists for "fossil all ui" or "fossil all server".
3433 */
3434 /*
3435 ** SETTING: self-register boolean default=off
3436 ** Allow users to register themselves through the HTTP UI.
3437 ** This is useful if you want to see other names than
3438 ** "Anonymous" in e.g. ticketing system. On the other hand
3439
+1 -1
--- src/main.c
+++ src/main.c
@@ -2421,11 +2421,11 @@
24212421
g.fSshClient |= CGI_SSH_CLIENT;
24222422
ssh_request_loop(zIpAddr, 0);
24232423
}else{
24242424
cgi_set_parameter("REMOTE_ADDR", "127.0.0.1");
24252425
cgi_handle_http_request(0);
2426
- process_one_web_page(0, 0, 0);
2426
+ process_one_web_page(0, 0, 1);
24272427
}
24282428
}
24292429
24302430
#if !defined(_WIN32)
24312431
#if !defined(__DARWIN__) && !defined(__APPLE__) && !defined(__HAIKU__)
24322432
--- src/main.c
+++ src/main.c
@@ -2421,11 +2421,11 @@
2421 g.fSshClient |= CGI_SSH_CLIENT;
2422 ssh_request_loop(zIpAddr, 0);
2423 }else{
2424 cgi_set_parameter("REMOTE_ADDR", "127.0.0.1");
2425 cgi_handle_http_request(0);
2426 process_one_web_page(0, 0, 0);
2427 }
2428 }
2429
2430 #if !defined(_WIN32)
2431 #if !defined(__DARWIN__) && !defined(__APPLE__) && !defined(__HAIKU__)
2432
--- src/main.c
+++ src/main.c
@@ -2421,11 +2421,11 @@
2421 g.fSshClient |= CGI_SSH_CLIENT;
2422 ssh_request_loop(zIpAddr, 0);
2423 }else{
2424 cgi_set_parameter("REMOTE_ADDR", "127.0.0.1");
2425 cgi_handle_http_request(0);
2426 process_one_web_page(0, 0, 1);
2427 }
2428 }
2429
2430 #if !defined(_WIN32)
2431 #if !defined(__DARWIN__) && !defined(__APPLE__) && !defined(__HAIKU__)
2432
+92 -37
--- src/repolist.c
+++ src/repolist.c
@@ -27,30 +27,49 @@
2727
** input. All other fields are outputs.
2828
*/
2929
struct RepoInfo {
3030
char *zRepoName; /* Name of the repository file */
3131
int isValid; /* True if zRepoName is a valid Fossil repository */
32
+ int isRepolistSkin; /* 1 or 2 if this repository wants to be the skin
33
+ ** for the repository list. 2 means do use this
34
+ ** repository but do not display it in the list. */
3235
char *zProjName; /* Project Name. Memory from fossil_malloc() */
3336
double rMTime; /* Last update. Julian day number */
3437
};
3538
#endif
3639
3740
/*
3841
** Discover information about the repository given by
39
-** pRepo->zRepoName.
42
+** pRepo->zRepoName. The discovered information is stored in
43
+**
44
+**
45
+**
46
+**
47
+** This is an expensive routine in that it has to open and close an
48
+** SQLite database file.
4049
*/
41
-void remote_repo_info(RepoInfo *pRepo){
50
+static void remote_repo_info(RepoInfo *pRepo){
4251
sqlite3 *db;
4352
sqlite3_stmt *pStmt;
4453
int rc;
4554
55
+ pRepo->isRepolistSkin = 0;
4656
pRepo->isValid = 0;
4757
pRepo->zProjName = 0;
4858
pRepo->rMTime = 0.0;
4959
5060
g.dbIgnoreErrors++;
5161
rc = sqlite3_open_v2(pRepo->zRepoName, &db, SQLITE_OPEN_READWRITE, 0);
62
+ if( rc ) goto finish_repo_list;
63
+ rc = sqlite3_prepare_v2(db, "SELECT value FROM config"
64
+ " WHERE name='repolist-skin'",
65
+ -1, &pStmt, 0);
66
+ if( rc ) goto finish_repo_list;
67
+ if( sqlite3_step(pStmt)==SQLITE_ROW ){
68
+ pRepo->isRepolistSkin = sqlite3_column_int(pStmt,0);
69
+ }
70
+ sqlite3_finalize(pStmt);
5271
if( rc ) goto finish_repo_list;
5372
rc = sqlite3_prepare_v2(db, "SELECT value FROM config"
5473
" WHERE name='project-name'",
5574
-1, &pStmt, 0);
5675
if( rc ) goto finish_repo_list;
@@ -65,10 +84,13 @@
6584
pRepo->isValid = 1;
6685
sqlite3_finalize(pStmt);
6786
finish_repo_list:
6887
g.dbIgnoreErrors--;
6988
sqlite3_close(db);
89
+ if( pRepo->isRepolistSkin && !g.repositoryOpen ){
90
+ db_open_repository(pRepo->zRepoName);
91
+ }
7092
}
7193
7294
/*
7395
** Generate a web-page that lists all repositories located under the
7496
** g.zRepositoryName directory and return non-zero.
@@ -85,15 +107,18 @@
85107
**
86108
** Or, if no repositories can be located beneath g.zRepositoryName,
87109
** return 0.
88110
*/
89111
int repo_list_page(void){
90
- Blob base;
91
- int n = 0;
92
- int allRepo;
112
+ Blob base; /* document root for all repositories */
113
+ int n = 0; /* Number of repositories found */
114
+ int allRepo; /* True if running "fossil ui all".
115
+ ** False if a directory scan of base for repos */
116
+ Blob html; /* Html for the body of the repository list */
93117
94118
assert( g.db==0 );
119
+ blob_init(&html, 0, 0);
95120
if( fossil_strcmp(g.zRepositoryName,"/")==0 && !g.fJail ){
96121
/* For the special case of the "repository directory" being "/",
97122
** show all of the repositories named in the ~/.fossil database.
98123
**
99124
** On unix systems, then entries are of the form "repo:/home/..."
@@ -118,28 +143,21 @@
118143
db_multi_exec("CREATE TABLE vfile(pathname);");
119144
vfile_scan(&base, blob_size(&base), 0, 0, 0);
120145
db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'");
121146
allRepo = 0;
122147
}
123
- @ <html>
124
- @ <head>
125
- @ <base href="%s(g.zBaseURL)/" />
126
- @ <meta name="viewport" content="width=device-width, initial-scale=1.0">
127
- @ <title>Repository List</title>
128
- @ </head>
129
- @ <body>
130148
n = db_int(0, "SELECT count(*) FROM sfile");
131149
if( n>0 ){
132150
Stmt q;
133151
double rNow;
134
- @ <h1 align="center">Fossil Repositories</h1>
135
- @ <table border="0" class="sortable" data-init-sort="1" \
136
- @ data-column-types="tntnk"><thead>
137
- @ <tr><th>Filename<th width="20">\
138
- @ <th>Project Name<th width="20">\
139
- @ <th>Last Modified</tr>
140
- @ </thead><tbody>
152
+ blob_append_sql(&html,
153
+ "<table border='0' class='sortable' data-init-sort='1'"
154
+ " data-column-types='txtxk'><thead>\n"
155
+ "<tr><th>Filename<th width='20'>"
156
+ "<th>Project Name<th width='20'>"
157
+ "<th>Last Modified</tr>\n"
158
+ "</thead><tbody>\n");
141159
db_prepare(&q, "SELECT pathname"
142160
" FROM sfile ORDER BY pathname COLLATE nocase;");
143161
rNow = db_double(0, "SELECT julianday('now')");
144162
while( db_step(&q)==SQLITE_ROW ){
145163
const char *zName = db_column_text(&q, 0);
@@ -165,48 +183,85 @@
165183
x.zRepoName = zFull;
166184
remote_repo_info(&x);
167185
fossil_free(zFull);
168186
if( !x.isValid ){
169187
continue;
188
+ }
189
+ if( x.isRepolistSkin==2 && !allRepo ){
190
+ /* Repositories with repolist-skin==2 are omitted from directory
191
+ ** scan lists, but included in "fossil all ui" lists */
192
+ continue;
170193
}
171194
iAge = (rNow - x.rMTime)*86400;
172195
if( iAge<0 ) x.rMTime = rNow;
173196
zAge = human_readable_age(rNow - x.rMTime);
174
- @ <tr><td valign="top">\
197
+ blob_append_sql(&html, "<tr><td valign='top'>");
175198
if( sqlite3_strglob("*.fossil", zName)!=0 ){
176199
/* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
177200
** do not work for repositories whose names do not end in ".fossil".
178201
** So do not hyperlink those cases. */
179
- @ %h(zName)
202
+ blob_append_sql(&html,"%h",zName);
180203
} else if( sqlite3_strglob("*/.*", zName)==0 ){
181
- /* Do not show hidden repos */
182
- @ %h(zName) (hidden)
204
+ /* Do not show hyperlinks for hidden repos */
205
+ blob_append_sql(&html, "%h (hidden)", zName);
183206
} else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){
184
- @ <a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a>
207
+ blob_append_sql(&html,
208
+ "<a href='%R/%T/home' target='_blank'>/%h</a>\n",
209
+ zUrl, zName);
185210
}else{
186
- @ <a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a>
211
+ blob_append_sql(&html,
212
+ "<a href='%R/%T/home' target='_blank'>%h</a>\n",
213
+ zUrl, zName);
187214
}
188215
if( x.zProjName ){
189
- @ <td></td><td>%h(x.zProjName)</td>
216
+ blob_append_sql(&html, "<td></td><td>%h</td>\n", x.zProjName);
190217
fossil_free(x.zProjName);
191218
}else{
192
- @ <td></td><td></td>
219
+ blob_append_sql(&html, "<td></td><td></td>\n");
193220
}
194
- @ <td></td><td data-sortkey='%08x(iAge)'>%h(zAge)</tr>
221
+ blob_append_sql(&html,
222
+ "<td></td><td data-sortkey='%08x'>%h</tr>\n",
223
+ iAge, zAge);
195224
fossil_free(zAge);
196225
sqlite3_free(zUrl);
197226
}
198
- @ </tbody></table>
227
+ db_finalize(&q);
228
+ blob_append_sql(&html,"</tbody></table>\n");
229
+ }else{
230
+ blob_append_sql(&html,"<h1>No Repositories Found</h1>\n");
231
+ }
232
+ if( g.repositoryOpen ){
233
+ /* This case runs if remote_repository_info() found a repository
234
+ ** that has the "repolist_skin" property set to non-zero and left
235
+ ** that repository open in g.db. Use the skin of that repository
236
+ ** for display. */
237
+ login_check_credentials();
238
+ style_header("Repository List");
239
+ @ <style>
240
+ style_render_stylesheet();
241
+ @ </style>
242
+ @ %s(blob_str(&html))
243
+ style_table_sorter();
244
+ style_footer();
199245
}else{
200
- @ <h1>No Repositories Found</h1>
201
- }
202
- @ <script>%s(builtin_text("sorttable.js"))</script>
203
- @ </body>
204
- @ </html>
205
- cgi_reply();
206
- sqlite3_close(g.db);
207
- g.db = 0;
246
+ /* If no repositories were found that had the "repolist_skin"
247
+ ** property set, then use a default skin */
248
+ @ <html>
249
+ @ <head>
250
+ @ <base href="%s(g.zBaseURL)/" />
251
+ @ <meta name="viewport" content="width=device-width, initial-scale=1.0">
252
+ @ <title>Repository List</title>
253
+ @ </head>
254
+ @ <body>
255
+ @ <h1 align="center">Fossil Repositories</h1>
256
+ @ %s(blob_str(&html))
257
+ @ <script>%s(builtin_text("sorttable.js"))</script>
258
+ @ </body>
259
+ @ </html>
260
+ }
261
+ blob_reset(&html);
262
+ cgi_reply();
208263
return n;
209264
}
210265
211266
/*
212267
** COMMAND: test-list-page
213268
--- src/repolist.c
+++ src/repolist.c
@@ -27,30 +27,49 @@
27 ** input. All other fields are outputs.
28 */
29 struct RepoInfo {
30 char *zRepoName; /* Name of the repository file */
31 int isValid; /* True if zRepoName is a valid Fossil repository */
 
 
 
32 char *zProjName; /* Project Name. Memory from fossil_malloc() */
33 double rMTime; /* Last update. Julian day number */
34 };
35 #endif
36
37 /*
38 ** Discover information about the repository given by
39 ** pRepo->zRepoName.
 
 
 
 
 
 
40 */
41 void remote_repo_info(RepoInfo *pRepo){
42 sqlite3 *db;
43 sqlite3_stmt *pStmt;
44 int rc;
45
 
46 pRepo->isValid = 0;
47 pRepo->zProjName = 0;
48 pRepo->rMTime = 0.0;
49
50 g.dbIgnoreErrors++;
51 rc = sqlite3_open_v2(pRepo->zRepoName, &db, SQLITE_OPEN_READWRITE, 0);
 
 
 
 
 
 
 
 
 
52 if( rc ) goto finish_repo_list;
53 rc = sqlite3_prepare_v2(db, "SELECT value FROM config"
54 " WHERE name='project-name'",
55 -1, &pStmt, 0);
56 if( rc ) goto finish_repo_list;
@@ -65,10 +84,13 @@
65 pRepo->isValid = 1;
66 sqlite3_finalize(pStmt);
67 finish_repo_list:
68 g.dbIgnoreErrors--;
69 sqlite3_close(db);
 
 
 
70 }
71
72 /*
73 ** Generate a web-page that lists all repositories located under the
74 ** g.zRepositoryName directory and return non-zero.
@@ -85,15 +107,18 @@
85 **
86 ** Or, if no repositories can be located beneath g.zRepositoryName,
87 ** return 0.
88 */
89 int repo_list_page(void){
90 Blob base;
91 int n = 0;
92 int allRepo;
 
 
93
94 assert( g.db==0 );
 
95 if( fossil_strcmp(g.zRepositoryName,"/")==0 && !g.fJail ){
96 /* For the special case of the "repository directory" being "/",
97 ** show all of the repositories named in the ~/.fossil database.
98 **
99 ** On unix systems, then entries are of the form "repo:/home/..."
@@ -118,28 +143,21 @@
118 db_multi_exec("CREATE TABLE vfile(pathname);");
119 vfile_scan(&base, blob_size(&base), 0, 0, 0);
120 db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'");
121 allRepo = 0;
122 }
123 @ <html>
124 @ <head>
125 @ <base href="%s(g.zBaseURL)/" />
126 @ <meta name="viewport" content="width=device-width, initial-scale=1.0">
127 @ <title>Repository List</title>
128 @ </head>
129 @ <body>
130 n = db_int(0, "SELECT count(*) FROM sfile");
131 if( n>0 ){
132 Stmt q;
133 double rNow;
134 @ <h1 align="center">Fossil Repositories</h1>
135 @ <table border="0" class="sortable" data-init-sort="1" \
136 @ data-column-types="tntnk"><thead>
137 @ <tr><th>Filename<th width="20">\
138 @ <th>Project Name<th width="20">\
139 @ <th>Last Modified</tr>
140 @ </thead><tbody>
141 db_prepare(&q, "SELECT pathname"
142 " FROM sfile ORDER BY pathname COLLATE nocase;");
143 rNow = db_double(0, "SELECT julianday('now')");
144 while( db_step(&q)==SQLITE_ROW ){
145 const char *zName = db_column_text(&q, 0);
@@ -165,48 +183,85 @@
165 x.zRepoName = zFull;
166 remote_repo_info(&x);
167 fossil_free(zFull);
168 if( !x.isValid ){
169 continue;
 
 
 
 
 
170 }
171 iAge = (rNow - x.rMTime)*86400;
172 if( iAge<0 ) x.rMTime = rNow;
173 zAge = human_readable_age(rNow - x.rMTime);
174 @ <tr><td valign="top">\
175 if( sqlite3_strglob("*.fossil", zName)!=0 ){
176 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
177 ** do not work for repositories whose names do not end in ".fossil".
178 ** So do not hyperlink those cases. */
179 @ %h(zName)
180 } else if( sqlite3_strglob("*/.*", zName)==0 ){
181 /* Do not show hidden repos */
182 @ %h(zName) (hidden)
183 } else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){
184 @ <a href="%R/%T(zUrl)/home" target="_blank">/%h(zName)</a>
 
 
185 }else{
186 @ <a href="%R/%T(zUrl)/home" target="_blank">%h(zName)</a>
 
 
187 }
188 if( x.zProjName ){
189 @ <td></td><td>%h(x.zProjName)</td>
190 fossil_free(x.zProjName);
191 }else{
192 @ <td></td><td></td>
193 }
194 @ <td></td><td data-sortkey='%08x(iAge)'>%h(zAge)</tr>
 
 
195 fossil_free(zAge);
196 sqlite3_free(zUrl);
197 }
198 @ </tbody></table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199 }else{
200 @ <h1>No Repositories Found</h1>
201 }
202 @ <script>%s(builtin_text("sorttable.js"))</script>
203 @ </body>
204 @ </html>
205 cgi_reply();
206 sqlite3_close(g.db);
207 g.db = 0;
 
 
 
 
 
 
 
 
 
208 return n;
209 }
210
211 /*
212 ** COMMAND: test-list-page
213
--- src/repolist.c
+++ src/repolist.c
@@ -27,30 +27,49 @@
27 ** input. All other fields are outputs.
28 */
29 struct RepoInfo {
30 char *zRepoName; /* Name of the repository file */
31 int isValid; /* True if zRepoName is a valid Fossil repository */
32 int isRepolistSkin; /* 1 or 2 if this repository wants to be the skin
33 ** for the repository list. 2 means do use this
34 ** repository but do not display it in the list. */
35 char *zProjName; /* Project Name. Memory from fossil_malloc() */
36 double rMTime; /* Last update. Julian day number */
37 };
38 #endif
39
40 /*
41 ** Discover information about the repository given by
42 ** pRepo->zRepoName. The discovered information is stored in
43 **
44 **
45 **
46 **
47 ** This is an expensive routine in that it has to open and close an
48 ** SQLite database file.
49 */
50 static void remote_repo_info(RepoInfo *pRepo){
51 sqlite3 *db;
52 sqlite3_stmt *pStmt;
53 int rc;
54
55 pRepo->isRepolistSkin = 0;
56 pRepo->isValid = 0;
57 pRepo->zProjName = 0;
58 pRepo->rMTime = 0.0;
59
60 g.dbIgnoreErrors++;
61 rc = sqlite3_open_v2(pRepo->zRepoName, &db, SQLITE_OPEN_READWRITE, 0);
62 if( rc ) goto finish_repo_list;
63 rc = sqlite3_prepare_v2(db, "SELECT value FROM config"
64 " WHERE name='repolist-skin'",
65 -1, &pStmt, 0);
66 if( rc ) goto finish_repo_list;
67 if( sqlite3_step(pStmt)==SQLITE_ROW ){
68 pRepo->isRepolistSkin = sqlite3_column_int(pStmt,0);
69 }
70 sqlite3_finalize(pStmt);
71 if( rc ) goto finish_repo_list;
72 rc = sqlite3_prepare_v2(db, "SELECT value FROM config"
73 " WHERE name='project-name'",
74 -1, &pStmt, 0);
75 if( rc ) goto finish_repo_list;
@@ -65,10 +84,13 @@
84 pRepo->isValid = 1;
85 sqlite3_finalize(pStmt);
86 finish_repo_list:
87 g.dbIgnoreErrors--;
88 sqlite3_close(db);
89 if( pRepo->isRepolistSkin && !g.repositoryOpen ){
90 db_open_repository(pRepo->zRepoName);
91 }
92 }
93
94 /*
95 ** Generate a web-page that lists all repositories located under the
96 ** g.zRepositoryName directory and return non-zero.
@@ -85,15 +107,18 @@
107 **
108 ** Or, if no repositories can be located beneath g.zRepositoryName,
109 ** return 0.
110 */
111 int repo_list_page(void){
112 Blob base; /* document root for all repositories */
113 int n = 0; /* Number of repositories found */
114 int allRepo; /* True if running "fossil ui all".
115 ** False if a directory scan of base for repos */
116 Blob html; /* Html for the body of the repository list */
117
118 assert( g.db==0 );
119 blob_init(&html, 0, 0);
120 if( fossil_strcmp(g.zRepositoryName,"/")==0 && !g.fJail ){
121 /* For the special case of the "repository directory" being "/",
122 ** show all of the repositories named in the ~/.fossil database.
123 **
124 ** On unix systems, then entries are of the form "repo:/home/..."
@@ -118,28 +143,21 @@
143 db_multi_exec("CREATE TABLE vfile(pathname);");
144 vfile_scan(&base, blob_size(&base), 0, 0, 0);
145 db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'");
146 allRepo = 0;
147 }
 
 
 
 
 
 
 
148 n = db_int(0, "SELECT count(*) FROM sfile");
149 if( n>0 ){
150 Stmt q;
151 double rNow;
152 blob_append_sql(&html,
153 "<table border='0' class='sortable' data-init-sort='1'"
154 " data-column-types='txtxk'><thead>\n"
155 "<tr><th>Filename<th width='20'>"
156 "<th>Project Name<th width='20'>"
157 "<th>Last Modified</tr>\n"
158 "</thead><tbody>\n");
159 db_prepare(&q, "SELECT pathname"
160 " FROM sfile ORDER BY pathname COLLATE nocase;");
161 rNow = db_double(0, "SELECT julianday('now')");
162 while( db_step(&q)==SQLITE_ROW ){
163 const char *zName = db_column_text(&q, 0);
@@ -165,48 +183,85 @@
183 x.zRepoName = zFull;
184 remote_repo_info(&x);
185 fossil_free(zFull);
186 if( !x.isValid ){
187 continue;
188 }
189 if( x.isRepolistSkin==2 && !allRepo ){
190 /* Repositories with repolist-skin==2 are omitted from directory
191 ** scan lists, but included in "fossil all ui" lists */
192 continue;
193 }
194 iAge = (rNow - x.rMTime)*86400;
195 if( iAge<0 ) x.rMTime = rNow;
196 zAge = human_readable_age(rNow - x.rMTime);
197 blob_append_sql(&html, "<tr><td valign='top'>");
198 if( sqlite3_strglob("*.fossil", zName)!=0 ){
199 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
200 ** do not work for repositories whose names do not end in ".fossil".
201 ** So do not hyperlink those cases. */
202 blob_append_sql(&html,"%h",zName);
203 } else if( sqlite3_strglob("*/.*", zName)==0 ){
204 /* Do not show hyperlinks for hidden repos */
205 blob_append_sql(&html, "%h (hidden)", zName);
206 } else if( allRepo && sqlite3_strglob("[a-zA-Z]:/?*", zName)!=0 ){
207 blob_append_sql(&html,
208 "<a href='%R/%T/home' target='_blank'>/%h</a>\n",
209 zUrl, zName);
210 }else{
211 blob_append_sql(&html,
212 "<a href='%R/%T/home' target='_blank'>%h</a>\n",
213 zUrl, zName);
214 }
215 if( x.zProjName ){
216 blob_append_sql(&html, "<td></td><td>%h</td>\n", x.zProjName);
217 fossil_free(x.zProjName);
218 }else{
219 blob_append_sql(&html, "<td></td><td></td>\n");
220 }
221 blob_append_sql(&html,
222 "<td></td><td data-sortkey='%08x'>%h</tr>\n",
223 iAge, zAge);
224 fossil_free(zAge);
225 sqlite3_free(zUrl);
226 }
227 db_finalize(&q);
228 blob_append_sql(&html,"</tbody></table>\n");
229 }else{
230 blob_append_sql(&html,"<h1>No Repositories Found</h1>\n");
231 }
232 if( g.repositoryOpen ){
233 /* This case runs if remote_repository_info() found a repository
234 ** that has the "repolist_skin" property set to non-zero and left
235 ** that repository open in g.db. Use the skin of that repository
236 ** for display. */
237 login_check_credentials();
238 style_header("Repository List");
239 @ <style>
240 style_render_stylesheet();
241 @ </style>
242 @ %s(blob_str(&html))
243 style_table_sorter();
244 style_footer();
245 }else{
246 /* If no repositories were found that had the "repolist_skin"
247 ** property set, then use a default skin */
248 @ <html>
249 @ <head>
250 @ <base href="%s(g.zBaseURL)/" />
251 @ <meta name="viewport" content="width=device-width, initial-scale=1.0">
252 @ <title>Repository List</title>
253 @ </head>
254 @ <body>
255 @ <h1 align="center">Fossil Repositories</h1>
256 @ %s(blob_str(&html))
257 @ <script>%s(builtin_text("sorttable.js"))</script>
258 @ </body>
259 @ </html>
260 }
261 blob_reset(&html);
262 cgi_reply();
263 return n;
264 }
265
266 /*
267 ** COMMAND: test-list-page
268
+11 -5
--- src/style.c
+++ src/style.c
@@ -983,20 +983,17 @@
983983
Th_Render(zScript?zScript:"");
984984
}
985985
986986
987987
/*
988
-** WEBPAGE: style.css
989
-**
990
-** Return the style sheet.
988
+** Render the text of the stylesheet.
991989
*/
992
-void page_style_css(void){
990
+void style_render_stylesheet(void){
993991
Blob css;
994992
int i;
995993
int isInit = 0;
996994
997
- cgi_set_content_type("text/css");
998995
blob_init(&css,skin_get("css"),-1);
999996
1000997
/* add special missing definitions */
1001998
for(i=1; cssDefaultList[i].elementClass; i++){
1002999
char *z = blob_str(&css);
@@ -1025,11 +1022,20 @@
10251022
Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL);
10261023
Th_Store("home", g.zTop);
10271024
image_url_var("logo");
10281025
image_url_var("background");
10291026
Th_Render(blob_str(&css));
1027
+}
10301028
1029
+/*
1030
+** WEBPAGE: style.css
1031
+**
1032
+** Return the style sheet.
1033
+*/
1034
+void page_style_css(void){
1035
+ cgi_set_content_type("text/css");
1036
+ style_render_stylesheet();
10311037
/* Tell CGI that the content returned by this page is considered cacheable */
10321038
g.isConst = 1;
10331039
}
10341040
10351041
/*
10361042
--- src/style.c
+++ src/style.c
@@ -983,20 +983,17 @@
983 Th_Render(zScript?zScript:"");
984 }
985
986
987 /*
988 ** WEBPAGE: style.css
989 **
990 ** Return the style sheet.
991 */
992 void page_style_css(void){
993 Blob css;
994 int i;
995 int isInit = 0;
996
997 cgi_set_content_type("text/css");
998 blob_init(&css,skin_get("css"),-1);
999
1000 /* add special missing definitions */
1001 for(i=1; cssDefaultList[i].elementClass; i++){
1002 char *z = blob_str(&css);
@@ -1025,11 +1022,20 @@
1025 Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL);
1026 Th_Store("home", g.zTop);
1027 image_url_var("logo");
1028 image_url_var("background");
1029 Th_Render(blob_str(&css));
 
1030
 
 
 
 
 
 
 
 
1031 /* Tell CGI that the content returned by this page is considered cacheable */
1032 g.isConst = 1;
1033 }
1034
1035 /*
1036
--- src/style.c
+++ src/style.c
@@ -983,20 +983,17 @@
983 Th_Render(zScript?zScript:"");
984 }
985
986
987 /*
988 ** Render the text of the stylesheet.
 
 
989 */
990 void style_render_stylesheet(void){
991 Blob css;
992 int i;
993 int isInit = 0;
994
 
995 blob_init(&css,skin_get("css"),-1);
996
997 /* add special missing definitions */
998 for(i=1; cssDefaultList[i].elementClass; i++){
999 char *z = blob_str(&css);
@@ -1025,11 +1022,20 @@
1022 Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL);
1023 Th_Store("home", g.zTop);
1024 image_url_var("logo");
1025 image_url_var("background");
1026 Th_Render(blob_str(&css));
1027 }
1028
1029 /*
1030 ** WEBPAGE: style.css
1031 **
1032 ** Return the style sheet.
1033 */
1034 void page_style_css(void){
1035 cgi_set_content_type("text/css");
1036 style_render_stylesheet();
1037 /* Tell CGI that the content returned by this page is considered cacheable */
1038 g.isConst = 1;
1039 }
1040
1041 /*
1042

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button