Fossil SCM
Update the suggested-downloads setting so that it is processed in groups of four: COUNT, TAG, MAX_AGE, and COMMENT.
Commit
081a79af9ef9159d351c09577c3bc265524ec29a5a8648b48f94562d52066846
Parent
df28ba6539589a0…
2 files changed
+11
-12
+87
-21
+11
-12
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -1428,28 +1428,27 @@ | ||
| 1428 | 1428 | @ <p> |
| 1429 | 1429 | textarea_attribute("Custom Sitemap Entries", 8, 80, |
| 1430 | 1430 | "sitemap-extra", "smextra", "", 0); |
| 1431 | 1431 | @ <hr> |
| 1432 | 1432 | @ <p>Configuration for the <a href="%R/download">/download</a> page. |
| 1433 | - @ The value is a TCL list divided into pairs. | |
| 1433 | + @ The value is a TCL list divided into groups of four: | |
| 1434 | 1434 | @ <ol> |
| 1435 | - @ <li> The first term of each pair is an integer (N). | |
| 1436 | - @ <li> The second term of each pair is a glob pattern (PATTERN). | |
| 1435 | + @ <li> Maximum number of matches (COUNT). | |
| 1436 | + @ <li> Tag to match using glob (TAG). | |
| 1437 | + @ <li> Maximum age of check-ins to match (MAX_AGE). | |
| 1438 | + @ <li> Comment to apply to matches (COMMENT). | |
| 1437 | 1439 | @ </ol> |
| 1438 | - @ For each pair, the most recent N check-ins that have a tag that | |
| 1439 | - @ matches PATTERN are included in on the /download page. The special | |
| 1440 | - @ pattern of "OPEN-LEAF" matches all open leaf check-ins. Example: | |
| 1441 | - @ <blockquote><tt>1 trunk 3 release 5 OPEN-LEAF</tt></blockquote> | |
| 1442 | - @ The example pattern above shows the union of the most recent trunk | |
| 1443 | - @ check-in, the 5 most recent open leaf check-ins, and the 3 most | |
| 1444 | - @ recent check-ins tagged with "release". | |
| 1440 | + @ The /download display is the union of all groups of four. | |
| 1441 | + @ See the <a href="%R/help/suggested-downloads">suggested-downloads</a> | |
| 1442 | + @ setting documentation for further detail. | |
| 1445 | 1443 | @ <p> |
| 1446 | 1444 | @ The /download page is omitted from the <a href="%R/sitemap">/sitemap</a> |
| 1447 | - @ if the first token is "0" or "off" or "no". The default value is "off". | |
| 1445 | + @ if the first token is "0" or "off" or "no". The default value | |
| 1446 | + @ for this setting is "off". | |
| 1448 | 1447 | @ (Property: <a href="%R/help/suggested-downloads">suggested-downloads</a>) |
| 1449 | 1448 | @ <p> |
| 1450 | - textarea_attribute("Suggested Downloads", 2, 80, | |
| 1449 | + textarea_attribute("Suggested Downloads", 4, 80, | |
| 1451 | 1450 | "suggested-downloads", "sgtrlst", "off", 0); |
| 1452 | 1451 | @ <hr> |
| 1453 | 1452 | @ <p><input type="submit" name="submit" value="Apply Changes"></p> |
| 1454 | 1453 | @ </div></form> |
| 1455 | 1454 | db_end_transaction(0); |
| 1456 | 1455 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -1428,28 +1428,27 @@ | |
| 1428 | @ <p> |
| 1429 | textarea_attribute("Custom Sitemap Entries", 8, 80, |
| 1430 | "sitemap-extra", "smextra", "", 0); |
| 1431 | @ <hr> |
| 1432 | @ <p>Configuration for the <a href="%R/download">/download</a> page. |
| 1433 | @ The value is a TCL list divided into pairs. |
| 1434 | @ <ol> |
| 1435 | @ <li> The first term of each pair is an integer (N). |
| 1436 | @ <li> The second term of each pair is a glob pattern (PATTERN). |
| 1437 | @ </ol> |
| 1438 | @ For each pair, the most recent N check-ins that have a tag that |
| 1439 | @ matches PATTERN are included in on the /download page. The special |
| 1440 | @ pattern of "OPEN-LEAF" matches all open leaf check-ins. Example: |
| 1441 | @ <blockquote><tt>1 trunk 3 release 5 OPEN-LEAF</tt></blockquote> |
| 1442 | @ The example pattern above shows the union of the most recent trunk |
| 1443 | @ check-in, the 5 most recent open leaf check-ins, and the 3 most |
| 1444 | @ recent check-ins tagged with "release". |
| 1445 | @ <p> |
| 1446 | @ The /download page is omitted from the <a href="%R/sitemap">/sitemap</a> |
| 1447 | @ if the first token is "0" or "off" or "no". The default value is "off". |
| 1448 | @ (Property: <a href="%R/help/suggested-downloads">suggested-downloads</a>) |
| 1449 | @ <p> |
| 1450 | textarea_attribute("Suggested Downloads", 2, 80, |
| 1451 | "suggested-downloads", "sgtrlst", "off", 0); |
| 1452 | @ <hr> |
| 1453 | @ <p><input type="submit" name="submit" value="Apply Changes"></p> |
| 1454 | @ </div></form> |
| 1455 | db_end_transaction(0); |
| 1456 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -1428,28 +1428,27 @@ | |
| 1428 | @ <p> |
| 1429 | textarea_attribute("Custom Sitemap Entries", 8, 80, |
| 1430 | "sitemap-extra", "smextra", "", 0); |
| 1431 | @ <hr> |
| 1432 | @ <p>Configuration for the <a href="%R/download">/download</a> page. |
| 1433 | @ The value is a TCL list divided into groups of four: |
| 1434 | @ <ol> |
| 1435 | @ <li> Maximum number of matches (COUNT). |
| 1436 | @ <li> Tag to match using glob (TAG). |
| 1437 | @ <li> Maximum age of check-ins to match (MAX_AGE). |
| 1438 | @ <li> Comment to apply to matches (COMMENT). |
| 1439 | @ </ol> |
| 1440 | @ The /download display is the union of all groups of four. |
| 1441 | @ See the <a href="%R/help/suggested-downloads">suggested-downloads</a> |
| 1442 | @ setting documentation for further detail. |
| 1443 | @ <p> |
| 1444 | @ The /download page is omitted from the <a href="%R/sitemap">/sitemap</a> |
| 1445 | @ if the first token is "0" or "off" or "no". The default value |
| 1446 | @ for this setting is "off". |
| 1447 | @ (Property: <a href="%R/help/suggested-downloads">suggested-downloads</a>) |
| 1448 | @ <p> |
| 1449 | textarea_attribute("Suggested Downloads", 4, 80, |
| 1450 | "suggested-downloads", "sgtrlst", "off", 0); |
| 1451 | @ <hr> |
| 1452 | @ <p><input type="submit" name="submit" value="Apply Changes"></p> |
| 1453 | @ </div></form> |
| 1454 | db_end_transaction(0); |
| 1455 |
+87
-21
| --- src/tar.c | ||
| +++ src/tar.c | ||
| @@ -1074,25 +1074,45 @@ | ||
| 1074 | 1074 | |
| 1075 | 1075 | /* |
| 1076 | 1076 | ** SETTING: suggested-downloads width=70 block-text |
| 1077 | 1077 | ** |
| 1078 | 1078 | ** This setting controls the suggested tarball/ZIP downloads on the |
| 1079 | -** [[/download]] page. The value is a TCL list. Each pair of items | |
| 1079 | +** [[/download]] page. The value is a TCL list. Each set of four items | |
| 1080 | 1080 | ** defines a set of check-ins to be added to the suggestion list. |
| 1081 | -** The first item of each pair is an integer count (N) and second | |
| 1082 | -** item is a tag GLOB pattern (PATTERN). For each pair, the most | |
| 1083 | -** recent N check-ins that have a tag matching PATTERN are added | |
| 1084 | -** to the list. The special pattern "OPEN-LEAF" matches any open | |
| 1085 | -** leaf check-in. | |
| 1081 | +** The items are: | |
| 1082 | +** | |
| 1083 | +** COUNT TAG MAX_AGE COMMENT | |
| 1084 | +** | |
| 1085 | +** COUNT is the number of check-ins to match, starting with the most | |
| 1086 | +** recent and working bacwards in time. Check-ins match if they contain | |
| 1087 | +** the tag TAG. If MAX_AGE is not an empty string, then it specifies | |
| 1088 | +** the maximum age of any matching check-in. COMMENT is an optional | |
| 1089 | +** comment for each match. | |
| 1090 | +** | |
| 1091 | +** The special value of "OPEN-LEAF" for TAG matches any check-in that | |
| 1092 | +** is an open leaf. | |
| 1093 | +** | |
| 1094 | +** MAX_AGE is of the form "{AMT UNITS}" where AMT is a floating point | |
| 1095 | +** value and UNITS is one of "seconds", "hours", "days", "weeks", "months", | |
| 1096 | +** or "years". If MAX_AGE is an empty string then there is no age limit. | |
| 1097 | +** | |
| 1098 | +** If COMMENT is not an empty string, the it is an additional comment | |
| 1099 | +** added to the output description of suggested download. The idea of | |
| 1100 | +** COMMENT is to explain to the reader why a check-in is a suggested | |
| 1101 | +** download. | |
| 1086 | 1102 | ** |
| 1087 | 1103 | ** Example: |
| 1088 | 1104 | ** |
| 1089 | -** 3 OPEN-LEAF 3 release 1 trunk | |
| 1105 | +** 1 trunk {} {Lastest Trunk Check-in} | |
| 1106 | +** 5 OPEN-LEAF {3 months} {Open Leaf} | |
| 1107 | +** 999 release {1 year} {} | |
| 1090 | 1108 | ** |
| 1091 | -** The value causes the /download page to show the union of the 3 | |
| 1092 | -** most recent open leaves, the three most recent check-ins marked | |
| 1093 | -** "release", and the single most recent trunk check-in. | |
| 1109 | +** The value causes the /download page to show the union of the most | |
| 1110 | +** recent trunk check-in of any age, the three most recent | |
| 1111 | +** open leaves within the the past three months, and essentually | |
| 1112 | +** all releases within the past year. If the same check-in matches more | |
| 1113 | +** than one rule, the COMMENT of the first match is used. | |
| 1094 | 1114 | */ |
| 1095 | 1115 | |
| 1096 | 1116 | /* |
| 1097 | 1117 | ** WEBPAGE: /download |
| 1098 | 1118 | ** |
| @@ -1106,70 +1126,116 @@ | ||
| 1106 | 1126 | int *anItem; /* Bytes in each term of azItem[] */ |
| 1107 | 1127 | int nItem; /* Number of terms in azItem[] */ |
| 1108 | 1128 | int i; /* Loop counter */ |
| 1109 | 1129 | int tmFlags; /* Timeline display flags */ |
| 1110 | 1130 | int n; /* Number of suggested downloads */ |
| 1131 | + double rNow; /* Current time. Julian day number */ | |
| 1111 | 1132 | |
| 1112 | 1133 | login_check_credentials(); |
| 1113 | 1134 | if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; } |
| 1114 | 1135 | |
| 1115 | 1136 | style_set_current_feature("timeline"); |
| 1116 | 1137 | style_header("Suggested Downloads"); |
| 1117 | 1138 | |
| 1118 | 1139 | zTarlistCfg = db_get("suggested-downloads","off"); |
| 1119 | 1140 | db_multi_exec( |
| 1120 | - "CREATE TEMP TABLE tarlist(rid INTEGER PRIMARY KEY);" | |
| 1141 | + "CREATE TEMP TABLE tarlist(rid INTEGER PRIMARY KEY, com TEXT);" | |
| 1121 | 1142 | ); |
| 1143 | + rNow = db_double(0.0,"SELECT julianday()"); | |
| 1122 | 1144 | if( !g.interp ) Th_FossilInit(0); |
| 1123 | 1145 | Th_SplitList(g.interp, zTarlistCfg, (int)strlen(zTarlistCfg), |
| 1124 | 1146 | &azItem, &anItem, &nItem); |
| 1125 | - for(i=0; i<nItem-1; i+=2){ | |
| 1126 | - int cnt; | |
| 1127 | - char *zLabel; | |
| 1147 | + for(i=0; i<nItem-3; i+=4){ | |
| 1148 | + int cnt; /* The number of instances of zLabel to use */ | |
| 1149 | + char *zLabel; /* The label to match */ | |
| 1150 | + double rStart; /* Starting time, julian day number */ | |
| 1151 | + char *zComment = 0; /* Comment to apply */ | |
| 1128 | 1152 | if( anItem[i]==1 && azItem[i][0]=='*' ){ |
| 1129 | 1153 | cnt = -1; |
| 1130 | 1154 | }else if( anItem[i]<1 ){ |
| 1131 | 1155 | cnt = 0; |
| 1132 | 1156 | }else{ |
| 1133 | 1157 | cnt = atoi(azItem[i]); |
| 1134 | 1158 | } |
| 1135 | 1159 | if( cnt==0 ) continue; |
| 1136 | 1160 | zLabel = fossil_strndup(azItem[i+1],anItem[i+1]); |
| 1161 | + if( anItem[i+2]==0 ){ | |
| 1162 | + rStart = 0.0; | |
| 1163 | + }else{ | |
| 1164 | + char *zMax = fossil_strndup(azItem[i+2], anItem[i+2]); | |
| 1165 | + double r = atof(zMax); | |
| 1166 | + if( strstr(zMax,"sec") ){ | |
| 1167 | + rStart = rNow - r/86400.0; | |
| 1168 | + }else | |
| 1169 | + if( strstr(zMax,"hou") ){ | |
| 1170 | + rStart = rNow - r/24.0; | |
| 1171 | + }else | |
| 1172 | + if( strstr(zMax,"da") ){ | |
| 1173 | + rStart = rNow - r; | |
| 1174 | + }else | |
| 1175 | + if( strstr(zMax,"wee") ){ | |
| 1176 | + rStart = rNow - r*7.0; | |
| 1177 | + }else | |
| 1178 | + if( strstr(zMax,"mon") ){ | |
| 1179 | + rStart = rNow - r*30.44; | |
| 1180 | + }else | |
| 1181 | + if( strstr(zMax,"yea") ){ | |
| 1182 | + rStart = rNow - r*365.24; | |
| 1183 | + }else | |
| 1184 | + { /* Default to seconds */ | |
| 1185 | + rStart = rNow - r/86400.0; | |
| 1186 | + } | |
| 1187 | + } | |
| 1188 | + if( anItem[i+3]==0 ){ | |
| 1189 | + zComment = fossil_strdup(""); | |
| 1190 | + }else{ | |
| 1191 | + zComment = fossil_strndup(azItem[i+3],anItem[i+3]); | |
| 1192 | + } | |
| 1137 | 1193 | if( fossil_strcmp("OPEN-LEAF",zLabel)==0 ){ |
| 1138 | 1194 | db_multi_exec( |
| 1139 | - "INSERT OR IGNORE INTO tarlist(rid)" | |
| 1140 | - " SELECT leaf.rid FROM leaf, event" | |
| 1195 | + "INSERT OR IGNORE INTO tarlist(rid,com)" | |
| 1196 | + " SELECT leaf.rid, %Q FROM leaf, event" | |
| 1141 | 1197 | " WHERE event.objid=leaf.rid" |
| 1198 | + " AND event.mtime>=%.6f" | |
| 1142 | 1199 | " AND NOT EXISTS(SELECT 1 FROM tagxref" |
| 1143 | 1200 | " WHERE tagxref.rid=leaf.rid" |
| 1144 | 1201 | " AND tagid=%d AND tagtype>0)" |
| 1145 | - " ORDER BY event.mtime DESC LIMIT %d", TAG_CLOSED, cnt | |
| 1202 | + " ORDER BY event.mtime DESC LIMIT %d", | |
| 1203 | + zComment, rStart, TAG_CLOSED, cnt | |
| 1146 | 1204 | ); |
| 1147 | 1205 | }else{ |
| 1148 | 1206 | db_multi_exec( |
| 1149 | 1207 | "WITH taglist(tid) AS" |
| 1150 | 1208 | " (SELECT tagid FROM tag WHERE tagname GLOB 'sym-%q')" |
| 1151 | - "INSERT OR IGNORE INTO tarlist(rid)" | |
| 1152 | - " SELECT event.objid FROM event CROSS JOIN tagxref" | |
| 1209 | + "INSERT OR IGNORE INTO tarlist(rid,com)" | |
| 1210 | + " SELECT event.objid, %Q FROM event CROSS JOIN tagxref" | |
| 1153 | 1211 | " WHERE event.type='ci'" |
| 1212 | + " AND event.mtime>=%.6f" | |
| 1154 | 1213 | " AND tagxref.tagid IN taglist" |
| 1155 | 1214 | " AND tagtype>0" |
| 1156 | 1215 | " AND tagxref.rid=event.objid" |
| 1157 | - " ORDER BY event.mtime DESC LIMIT %d", zLabel, cnt | |
| 1216 | + " ORDER BY event.mtime DESC LIMIT %d", | |
| 1217 | + zLabel, zComment, rStart, cnt | |
| 1158 | 1218 | ); |
| 1159 | 1219 | } |
| 1160 | 1220 | fossil_free(zLabel); |
| 1221 | + fossil_free(zComment); | |
| 1161 | 1222 | } |
| 1162 | 1223 | Th_Free(g.interp, azItem); |
| 1163 | 1224 | |
| 1164 | 1225 | n = db_int(0, "SELECT count(*) FROM tarlist"); |
| 1165 | 1226 | if( n==0 ){ |
| 1166 | 1227 | @ <h2>No tarball/ZIP suggestions are available at this time</h2> |
| 1167 | 1228 | }else{ |
| 1168 | 1229 | @ <h2>%d(n) Tarball/ZIP Download Suggestion%s(n>1?"s":""):</h2> |
| 1169 | 1230 | db_prepare(&q, |
| 1170 | - "%s AND blob.rid IN tarlist ORDER BY event.mtime DESC", | |
| 1231 | + "WITH matches AS (%s AND blob.rid IN (SELECT rid FROM tarlist))\n" | |
| 1232 | + "SELECT blobRid, uuid, timestamp," | |
| 1233 | + " if(length(com)>0,'<b>'||com||'</b><p>','')||comment," | |
| 1234 | + " user, leaf, bgColor, eventType, tags, tagid, brief, mtime" | |
| 1235 | + " FROM matches JOIN tarlist ON tarlist.rid=blobRid" | |
| 1236 | + " ORDER BY matches.mtime DESC", | |
| 1171 | 1237 | timeline_query_for_www() |
| 1172 | 1238 | ); |
| 1173 | 1239 | |
| 1174 | 1240 | tmFlags = TIMELINE_DISJOINT | TIMELINE_NOSCROLL | TIMELINE_COLUMNAR |
| 1175 | 1241 | | TIMELINE_BRCOLOR; |
| 1176 | 1242 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -1074,25 +1074,45 @@ | |
| 1074 | |
| 1075 | /* |
| 1076 | ** SETTING: suggested-downloads width=70 block-text |
| 1077 | ** |
| 1078 | ** This setting controls the suggested tarball/ZIP downloads on the |
| 1079 | ** [[/download]] page. The value is a TCL list. Each pair of items |
| 1080 | ** defines a set of check-ins to be added to the suggestion list. |
| 1081 | ** The first item of each pair is an integer count (N) and second |
| 1082 | ** item is a tag GLOB pattern (PATTERN). For each pair, the most |
| 1083 | ** recent N check-ins that have a tag matching PATTERN are added |
| 1084 | ** to the list. The special pattern "OPEN-LEAF" matches any open |
| 1085 | ** leaf check-in. |
| 1086 | ** |
| 1087 | ** Example: |
| 1088 | ** |
| 1089 | ** 3 OPEN-LEAF 3 release 1 trunk |
| 1090 | ** |
| 1091 | ** The value causes the /download page to show the union of the 3 |
| 1092 | ** most recent open leaves, the three most recent check-ins marked |
| 1093 | ** "release", and the single most recent trunk check-in. |
| 1094 | */ |
| 1095 | |
| 1096 | /* |
| 1097 | ** WEBPAGE: /download |
| 1098 | ** |
| @@ -1106,70 +1126,116 @@ | |
| 1106 | int *anItem; /* Bytes in each term of azItem[] */ |
| 1107 | int nItem; /* Number of terms in azItem[] */ |
| 1108 | int i; /* Loop counter */ |
| 1109 | int tmFlags; /* Timeline display flags */ |
| 1110 | int n; /* Number of suggested downloads */ |
| 1111 | |
| 1112 | login_check_credentials(); |
| 1113 | if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; } |
| 1114 | |
| 1115 | style_set_current_feature("timeline"); |
| 1116 | style_header("Suggested Downloads"); |
| 1117 | |
| 1118 | zTarlistCfg = db_get("suggested-downloads","off"); |
| 1119 | db_multi_exec( |
| 1120 | "CREATE TEMP TABLE tarlist(rid INTEGER PRIMARY KEY);" |
| 1121 | ); |
| 1122 | if( !g.interp ) Th_FossilInit(0); |
| 1123 | Th_SplitList(g.interp, zTarlistCfg, (int)strlen(zTarlistCfg), |
| 1124 | &azItem, &anItem, &nItem); |
| 1125 | for(i=0; i<nItem-1; i+=2){ |
| 1126 | int cnt; |
| 1127 | char *zLabel; |
| 1128 | if( anItem[i]==1 && azItem[i][0]=='*' ){ |
| 1129 | cnt = -1; |
| 1130 | }else if( anItem[i]<1 ){ |
| 1131 | cnt = 0; |
| 1132 | }else{ |
| 1133 | cnt = atoi(azItem[i]); |
| 1134 | } |
| 1135 | if( cnt==0 ) continue; |
| 1136 | zLabel = fossil_strndup(azItem[i+1],anItem[i+1]); |
| 1137 | if( fossil_strcmp("OPEN-LEAF",zLabel)==0 ){ |
| 1138 | db_multi_exec( |
| 1139 | "INSERT OR IGNORE INTO tarlist(rid)" |
| 1140 | " SELECT leaf.rid FROM leaf, event" |
| 1141 | " WHERE event.objid=leaf.rid" |
| 1142 | " AND NOT EXISTS(SELECT 1 FROM tagxref" |
| 1143 | " WHERE tagxref.rid=leaf.rid" |
| 1144 | " AND tagid=%d AND tagtype>0)" |
| 1145 | " ORDER BY event.mtime DESC LIMIT %d", TAG_CLOSED, cnt |
| 1146 | ); |
| 1147 | }else{ |
| 1148 | db_multi_exec( |
| 1149 | "WITH taglist(tid) AS" |
| 1150 | " (SELECT tagid FROM tag WHERE tagname GLOB 'sym-%q')" |
| 1151 | "INSERT OR IGNORE INTO tarlist(rid)" |
| 1152 | " SELECT event.objid FROM event CROSS JOIN tagxref" |
| 1153 | " WHERE event.type='ci'" |
| 1154 | " AND tagxref.tagid IN taglist" |
| 1155 | " AND tagtype>0" |
| 1156 | " AND tagxref.rid=event.objid" |
| 1157 | " ORDER BY event.mtime DESC LIMIT %d", zLabel, cnt |
| 1158 | ); |
| 1159 | } |
| 1160 | fossil_free(zLabel); |
| 1161 | } |
| 1162 | Th_Free(g.interp, azItem); |
| 1163 | |
| 1164 | n = db_int(0, "SELECT count(*) FROM tarlist"); |
| 1165 | if( n==0 ){ |
| 1166 | @ <h2>No tarball/ZIP suggestions are available at this time</h2> |
| 1167 | }else{ |
| 1168 | @ <h2>%d(n) Tarball/ZIP Download Suggestion%s(n>1?"s":""):</h2> |
| 1169 | db_prepare(&q, |
| 1170 | "%s AND blob.rid IN tarlist ORDER BY event.mtime DESC", |
| 1171 | timeline_query_for_www() |
| 1172 | ); |
| 1173 | |
| 1174 | tmFlags = TIMELINE_DISJOINT | TIMELINE_NOSCROLL | TIMELINE_COLUMNAR |
| 1175 | | TIMELINE_BRCOLOR; |
| 1176 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -1074,25 +1074,45 @@ | |
| 1074 | |
| 1075 | /* |
| 1076 | ** SETTING: suggested-downloads width=70 block-text |
| 1077 | ** |
| 1078 | ** This setting controls the suggested tarball/ZIP downloads on the |
| 1079 | ** [[/download]] page. The value is a TCL list. Each set of four items |
| 1080 | ** defines a set of check-ins to be added to the suggestion list. |
| 1081 | ** The items are: |
| 1082 | ** |
| 1083 | ** COUNT TAG MAX_AGE COMMENT |
| 1084 | ** |
| 1085 | ** COUNT is the number of check-ins to match, starting with the most |
| 1086 | ** recent and working bacwards in time. Check-ins match if they contain |
| 1087 | ** the tag TAG. If MAX_AGE is not an empty string, then it specifies |
| 1088 | ** the maximum age of any matching check-in. COMMENT is an optional |
| 1089 | ** comment for each match. |
| 1090 | ** |
| 1091 | ** The special value of "OPEN-LEAF" for TAG matches any check-in that |
| 1092 | ** is an open leaf. |
| 1093 | ** |
| 1094 | ** MAX_AGE is of the form "{AMT UNITS}" where AMT is a floating point |
| 1095 | ** value and UNITS is one of "seconds", "hours", "days", "weeks", "months", |
| 1096 | ** or "years". If MAX_AGE is an empty string then there is no age limit. |
| 1097 | ** |
| 1098 | ** If COMMENT is not an empty string, the it is an additional comment |
| 1099 | ** added to the output description of suggested download. The idea of |
| 1100 | ** COMMENT is to explain to the reader why a check-in is a suggested |
| 1101 | ** download. |
| 1102 | ** |
| 1103 | ** Example: |
| 1104 | ** |
| 1105 | ** 1 trunk {} {Lastest Trunk Check-in} |
| 1106 | ** 5 OPEN-LEAF {3 months} {Open Leaf} |
| 1107 | ** 999 release {1 year} {} |
| 1108 | ** |
| 1109 | ** The value causes the /download page to show the union of the most |
| 1110 | ** recent trunk check-in of any age, the three most recent |
| 1111 | ** open leaves within the the past three months, and essentually |
| 1112 | ** all releases within the past year. If the same check-in matches more |
| 1113 | ** than one rule, the COMMENT of the first match is used. |
| 1114 | */ |
| 1115 | |
| 1116 | /* |
| 1117 | ** WEBPAGE: /download |
| 1118 | ** |
| @@ -1106,70 +1126,116 @@ | |
| 1126 | int *anItem; /* Bytes in each term of azItem[] */ |
| 1127 | int nItem; /* Number of terms in azItem[] */ |
| 1128 | int i; /* Loop counter */ |
| 1129 | int tmFlags; /* Timeline display flags */ |
| 1130 | int n; /* Number of suggested downloads */ |
| 1131 | double rNow; /* Current time. Julian day number */ |
| 1132 | |
| 1133 | login_check_credentials(); |
| 1134 | if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; } |
| 1135 | |
| 1136 | style_set_current_feature("timeline"); |
| 1137 | style_header("Suggested Downloads"); |
| 1138 | |
| 1139 | zTarlistCfg = db_get("suggested-downloads","off"); |
| 1140 | db_multi_exec( |
| 1141 | "CREATE TEMP TABLE tarlist(rid INTEGER PRIMARY KEY, com TEXT);" |
| 1142 | ); |
| 1143 | rNow = db_double(0.0,"SELECT julianday()"); |
| 1144 | if( !g.interp ) Th_FossilInit(0); |
| 1145 | Th_SplitList(g.interp, zTarlistCfg, (int)strlen(zTarlistCfg), |
| 1146 | &azItem, &anItem, &nItem); |
| 1147 | for(i=0; i<nItem-3; i+=4){ |
| 1148 | int cnt; /* The number of instances of zLabel to use */ |
| 1149 | char *zLabel; /* The label to match */ |
| 1150 | double rStart; /* Starting time, julian day number */ |
| 1151 | char *zComment = 0; /* Comment to apply */ |
| 1152 | if( anItem[i]==1 && azItem[i][0]=='*' ){ |
| 1153 | cnt = -1; |
| 1154 | }else if( anItem[i]<1 ){ |
| 1155 | cnt = 0; |
| 1156 | }else{ |
| 1157 | cnt = atoi(azItem[i]); |
| 1158 | } |
| 1159 | if( cnt==0 ) continue; |
| 1160 | zLabel = fossil_strndup(azItem[i+1],anItem[i+1]); |
| 1161 | if( anItem[i+2]==0 ){ |
| 1162 | rStart = 0.0; |
| 1163 | }else{ |
| 1164 | char *zMax = fossil_strndup(azItem[i+2], anItem[i+2]); |
| 1165 | double r = atof(zMax); |
| 1166 | if( strstr(zMax,"sec") ){ |
| 1167 | rStart = rNow - r/86400.0; |
| 1168 | }else |
| 1169 | if( strstr(zMax,"hou") ){ |
| 1170 | rStart = rNow - r/24.0; |
| 1171 | }else |
| 1172 | if( strstr(zMax,"da") ){ |
| 1173 | rStart = rNow - r; |
| 1174 | }else |
| 1175 | if( strstr(zMax,"wee") ){ |
| 1176 | rStart = rNow - r*7.0; |
| 1177 | }else |
| 1178 | if( strstr(zMax,"mon") ){ |
| 1179 | rStart = rNow - r*30.44; |
| 1180 | }else |
| 1181 | if( strstr(zMax,"yea") ){ |
| 1182 | rStart = rNow - r*365.24; |
| 1183 | }else |
| 1184 | { /* Default to seconds */ |
| 1185 | rStart = rNow - r/86400.0; |
| 1186 | } |
| 1187 | } |
| 1188 | if( anItem[i+3]==0 ){ |
| 1189 | zComment = fossil_strdup(""); |
| 1190 | }else{ |
| 1191 | zComment = fossil_strndup(azItem[i+3],anItem[i+3]); |
| 1192 | } |
| 1193 | if( fossil_strcmp("OPEN-LEAF",zLabel)==0 ){ |
| 1194 | db_multi_exec( |
| 1195 | "INSERT OR IGNORE INTO tarlist(rid,com)" |
| 1196 | " SELECT leaf.rid, %Q FROM leaf, event" |
| 1197 | " WHERE event.objid=leaf.rid" |
| 1198 | " AND event.mtime>=%.6f" |
| 1199 | " AND NOT EXISTS(SELECT 1 FROM tagxref" |
| 1200 | " WHERE tagxref.rid=leaf.rid" |
| 1201 | " AND tagid=%d AND tagtype>0)" |
| 1202 | " ORDER BY event.mtime DESC LIMIT %d", |
| 1203 | zComment, rStart, TAG_CLOSED, cnt |
| 1204 | ); |
| 1205 | }else{ |
| 1206 | db_multi_exec( |
| 1207 | "WITH taglist(tid) AS" |
| 1208 | " (SELECT tagid FROM tag WHERE tagname GLOB 'sym-%q')" |
| 1209 | "INSERT OR IGNORE INTO tarlist(rid,com)" |
| 1210 | " SELECT event.objid, %Q FROM event CROSS JOIN tagxref" |
| 1211 | " WHERE event.type='ci'" |
| 1212 | " AND event.mtime>=%.6f" |
| 1213 | " AND tagxref.tagid IN taglist" |
| 1214 | " AND tagtype>0" |
| 1215 | " AND tagxref.rid=event.objid" |
| 1216 | " ORDER BY event.mtime DESC LIMIT %d", |
| 1217 | zLabel, zComment, rStart, cnt |
| 1218 | ); |
| 1219 | } |
| 1220 | fossil_free(zLabel); |
| 1221 | fossil_free(zComment); |
| 1222 | } |
| 1223 | Th_Free(g.interp, azItem); |
| 1224 | |
| 1225 | n = db_int(0, "SELECT count(*) FROM tarlist"); |
| 1226 | if( n==0 ){ |
| 1227 | @ <h2>No tarball/ZIP suggestions are available at this time</h2> |
| 1228 | }else{ |
| 1229 | @ <h2>%d(n) Tarball/ZIP Download Suggestion%s(n>1?"s":""):</h2> |
| 1230 | db_prepare(&q, |
| 1231 | "WITH matches AS (%s AND blob.rid IN (SELECT rid FROM tarlist))\n" |
| 1232 | "SELECT blobRid, uuid, timestamp," |
| 1233 | " if(length(com)>0,'<b>'||com||'</b><p>','')||comment," |
| 1234 | " user, leaf, bgColor, eventType, tags, tagid, brief, mtime" |
| 1235 | " FROM matches JOIN tarlist ON tarlist.rid=blobRid" |
| 1236 | " ORDER BY matches.mtime DESC", |
| 1237 | timeline_query_for_www() |
| 1238 | ); |
| 1239 | |
| 1240 | tmFlags = TIMELINE_DISJOINT | TIMELINE_NOSCROLL | TIMELINE_COLUMNAR |
| 1241 | | TIMELINE_BRCOLOR; |
| 1242 |