Fossil SCM

Tickets are now held for moderator approval.

drh 2012-11-01 15:08 UTC moderation
Commit aa4dd798351eeced19d8e13aa2bd28be6c8264fd
3 files changed +53 -22 +1 +26 -16
+53 -22
--- src/info.c
+++ src/info.c
@@ -1664,10 +1664,12 @@
16641664
int rid;
16651665
char *zDate;
16661666
const char *zUuid;
16671667
char zTktName[UUID_SIZE+1];
16681668
Manifest *pTktChng;
1669
+ int modPending;
1670
+ const char *zModAction;
16691671
16701672
login_check_credentials();
16711673
if( !g.perm.RdTkt ){ login_needed(); return; }
16721674
rid = name_to_rid_www("name");
16731675
if( rid==0 ){ fossil_redirect_home(); }
@@ -1680,39 +1682,68 @@
16801682
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
16811683
g.zTop, zUuid);
16821684
}
16831685
}
16841686
pTktChng = manifest_get(rid, CFTYPE_TICKET);
1687
+ zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
1688
+ memcpy(zTktName, pTktChng->zTicketUuid, UUID_SIZE+1);
16851689
if( pTktChng==0 ){
16861690
fossil_redirect_home();
1691
+ }
1692
+ if( g.perm.ModTkt && (zModAction = P("modaction"))!=0 ){
1693
+ if( strcmp(zModAction,"delete")==0 ){
1694
+ moderation_disapprove(rid);
1695
+ cgi_redirectf("%R/tktview/%s", zTktName);
1696
+ /*NOTREACHED*/
1697
+ }
1698
+ if( strcmp(zModAction,"approve")==0 ){
1699
+ moderation_approve(rid);
1700
+ }
16871701
}
16881702
style_header("Ticket Change Details");
1689
- zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
1690
- memcpy(zTktName, pTktChng->zTicketUuid, UUID_SIZE);
1691
- zTktName[UUID_SIZE] = 0;
1692
- if( g.perm.Hyperlink ){
1693
- @ <h2>Changes to ticket
1694
- @ %z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></h2>
1695
- @
1696
- @ <p>By %h(pTktChng->zUser) on %s(zDate).
1697
- style_submenu_element("Raw", "Raw", "%R/artifact/%T", zUuid);
1698
- style_submenu_element("History", "History",
1699
- "%R/tkthistory/%s", pTktChng->zTicketUuid);
1700
- }else{
1701
- @ <h2>Changes to ticket %s(zTktName)</h2>
1702
- @
1703
- @ <p>By %h(pTktChng->zUser) on %s(zDate).
1704
- @ </p>
1705
- }
1703
+ style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid);
1704
+ style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
1705
+ style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName);
1706
+ style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName);
1707
+
1708
+ @ <div class="section">Overview</div>
1709
+ @ <p><table class="label-value">
1710
+ @ <tr><th>Artifact&nbsp;ID:</th>
1711
+ @ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a>
1712
+ if( g.perm.Setup ){
1713
+ @ (%d(rid))
1714
+ }
1715
+ modPending = moderation_pending(rid);
1716
+ if( modPending ){
1717
+ @ <span class="modpending">*** Moderation Pending ***</span>
1718
+ }
1719
+ @ <tr><th>Ticket:</th>
1720
+ @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></td></tr>
1721
+ @ <tr><th>Date:</th><td>
1722
+ hyperlink_to_date(zDate, "</td></tr>");
17061723
free(zDate);
1724
+ @ <tr><th>User:</th><td>
1725
+ hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>");
1726
+ @ </table>
1727
+
1728
+ if( g.perm.ModTkt && modPending ){
1729
+ @ <div class="section">Moderation</div>
1730
+ @ <blockquote>
1731
+ @ <form method="POST" action="%R/tinfo/%s(zUuid)">
1732
+ @ <label><input type="radio" name="modaction" value="delete">
1733
+ @ Delete this change</label><br />
1734
+ @ <label><input type="radio" name="modaction" value="approve">
1735
+ @ Approve this change</label><br />
1736
+ @ <input type="submit" value="Submit">
1737
+ @ </form>
1738
+ @ </blockquote>
1739
+ }
1740
+
1741
+ @ <div class="section">Changes</div>
1742
+ @ <p>
17071743
ticket_output_change_artifact(pTktChng);
17081744
manifest_destroy(pTktChng);
1709
- if( g.perm.Setup ){
1710
- @
1711
- @ <p>These changes are implemented by artifact
1712
- @ %z(href("%R/artifact/%s",zUuid))%s(zUuid)</a> (%d(rid)).</p>
1713
- }
17141745
style_footer();
17151746
}
17161747
17171748
17181749
/*
17191750
--- src/info.c
+++ src/info.c
@@ -1664,10 +1664,12 @@
1664 int rid;
1665 char *zDate;
1666 const char *zUuid;
1667 char zTktName[UUID_SIZE+1];
1668 Manifest *pTktChng;
 
 
1669
1670 login_check_credentials();
1671 if( !g.perm.RdTkt ){ login_needed(); return; }
1672 rid = name_to_rid_www("name");
1673 if( rid==0 ){ fossil_redirect_home(); }
@@ -1680,39 +1682,68 @@
1680 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1681 g.zTop, zUuid);
1682 }
1683 }
1684 pTktChng = manifest_get(rid, CFTYPE_TICKET);
 
 
1685 if( pTktChng==0 ){
1686 fossil_redirect_home();
 
 
 
 
 
 
 
 
 
 
1687 }
1688 style_header("Ticket Change Details");
1689 zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
1690 memcpy(zTktName, pTktChng->zTicketUuid, UUID_SIZE);
1691 zTktName[UUID_SIZE] = 0;
1692 if( g.perm.Hyperlink ){
1693 @ <h2>Changes to ticket
1694 @ %z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></h2>
1695 @
1696 @ <p>By %h(pTktChng->zUser) on %s(zDate).
1697 style_submenu_element("Raw", "Raw", "%R/artifact/%T", zUuid);
1698 style_submenu_element("History", "History",
1699 "%R/tkthistory/%s", pTktChng->zTicketUuid);
1700 }else{
1701 @ <h2>Changes to ticket %s(zTktName)</h2>
1702 @
1703 @ <p>By %h(pTktChng->zUser) on %s(zDate).
1704 @ </p>
1705 }
 
 
 
1706 free(zDate);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1707 ticket_output_change_artifact(pTktChng);
1708 manifest_destroy(pTktChng);
1709 if( g.perm.Setup ){
1710 @
1711 @ <p>These changes are implemented by artifact
1712 @ %z(href("%R/artifact/%s",zUuid))%s(zUuid)</a> (%d(rid)).</p>
1713 }
1714 style_footer();
1715 }
1716
1717
1718 /*
1719
--- src/info.c
+++ src/info.c
@@ -1664,10 +1664,12 @@
1664 int rid;
1665 char *zDate;
1666 const char *zUuid;
1667 char zTktName[UUID_SIZE+1];
1668 Manifest *pTktChng;
1669 int modPending;
1670 const char *zModAction;
1671
1672 login_check_credentials();
1673 if( !g.perm.RdTkt ){ login_needed(); return; }
1674 rid = name_to_rid_www("name");
1675 if( rid==0 ){ fossil_redirect_home(); }
@@ -1680,39 +1682,68 @@
1682 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1683 g.zTop, zUuid);
1684 }
1685 }
1686 pTktChng = manifest_get(rid, CFTYPE_TICKET);
1687 zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
1688 memcpy(zTktName, pTktChng->zTicketUuid, UUID_SIZE+1);
1689 if( pTktChng==0 ){
1690 fossil_redirect_home();
1691 }
1692 if( g.perm.ModTkt && (zModAction = P("modaction"))!=0 ){
1693 if( strcmp(zModAction,"delete")==0 ){
1694 moderation_disapprove(rid);
1695 cgi_redirectf("%R/tktview/%s", zTktName);
1696 /*NOTREACHED*/
1697 }
1698 if( strcmp(zModAction,"approve")==0 ){
1699 moderation_approve(rid);
1700 }
1701 }
1702 style_header("Ticket Change Details");
1703 style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid);
1704 style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
1705 style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName);
1706 style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName);
1707
1708 @ <div class="section">Overview</div>
1709 @ <p><table class="label-value">
1710 @ <tr><th>Artifact&nbsp;ID:</th>
1711 @ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a>
1712 if( g.perm.Setup ){
1713 @ (%d(rid))
1714 }
1715 modPending = moderation_pending(rid);
1716 if( modPending ){
1717 @ <span class="modpending">*** Moderation Pending ***</span>
1718 }
1719 @ <tr><th>Ticket:</th>
1720 @ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></td></tr>
1721 @ <tr><th>Date:</th><td>
1722 hyperlink_to_date(zDate, "</td></tr>");
1723 free(zDate);
1724 @ <tr><th>User:</th><td>
1725 hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>");
1726 @ </table>
1727
1728 if( g.perm.ModTkt && modPending ){
1729 @ <div class="section">Moderation</div>
1730 @ <blockquote>
1731 @ <form method="POST" action="%R/tinfo/%s(zUuid)">
1732 @ <label><input type="radio" name="modaction" value="delete">
1733 @ Delete this change</label><br />
1734 @ <label><input type="radio" name="modaction" value="approve">
1735 @ Approve this change</label><br />
1736 @ <input type="submit" value="Submit">
1737 @ </form>
1738 @ </blockquote>
1739 }
1740
1741 @ <div class="section">Changes</div>
1742 @ <p>
1743 ticket_output_change_artifact(pTktChng);
1744 manifest_destroy(pTktChng);
 
 
 
 
 
1745 style_footer();
1746 }
1747
1748
1749 /*
1750
--- src/moderate.c
+++ src/moderate.c
@@ -140,10 +140,11 @@
140140
Stmt q;
141141
142142
login_check_credentials();
143143
if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
144144
style_header("Pending Moderation Requests");
145
+ @ <h2>All Pending Moderation Requests</h2>
145146
blob_init(&sql, timeline_query_for_www(), -1);
146147
blob_appendf(&sql,
147148
" AND event.objid IN (SELECT objid FROM modreq)"
148149
" ORDER BY event.mtime DESC"
149150
);
150151
--- src/moderate.c
+++ src/moderate.c
@@ -140,10 +140,11 @@
140 Stmt q;
141
142 login_check_credentials();
143 if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
144 style_header("Pending Moderation Requests");
 
145 blob_init(&sql, timeline_query_for_www(), -1);
146 blob_appendf(&sql,
147 " AND event.objid IN (SELECT objid FROM modreq)"
148 " ORDER BY event.mtime DESC"
149 );
150
--- src/moderate.c
+++ src/moderate.c
@@ -140,10 +140,11 @@
140 Stmt q;
141
142 login_check_credentials();
143 if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
144 style_header("Pending Moderation Requests");
145 @ <h2>All Pending Moderation Requests</h2>
146 blob_init(&sql, timeline_query_for_www(), -1);
147 blob_appendf(&sql,
148 " AND event.objid IN (SELECT objid FROM modreq)"
149 " ORDER BY event.mtime DESC"
150 );
151
+26 -16
--- src/tkt.c
+++ src/tkt.c
@@ -415,10 +415,34 @@
415415
return TH_ERROR;
416416
}
417417
azAppend[idx] = mprintf("%.*s", argl[2], argv[2]);
418418
return TH_OK;
419419
}
420
+
421
+/*
422
+** Write a ticket into the repository.
423
+*/
424
+static void ticket_put(Blob *pTicket, const char *zTktId, int needMod){
425
+ int rid = content_put_ex(pTicket, 0, 0, 0, needMod);
426
+ if( rid==0 ){
427
+ fossil_panic("trouble committing ticket: %s", g.zErrMsg);
428
+ }
429
+ if( needMod ){
430
+ moderation_table_create();
431
+ db_multi_exec(
432
+ "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
433
+ rid, zTktId
434
+ );
435
+ }else{
436
+ db_multi_exec("INSERT INTO unsent VALUES(%d);", rid);
437
+ db_multi_exec("INSERT INTO unclustered VALUES(%d);", rid);
438
+ }
439
+ manifest_crosslink_begin();
440
+ manifest_crosslink(rid, pTicket);
441
+ assert( blob_is_reset(pTicket) );
442
+ manifest_crosslink_end();
443
+}
420444
421445
/*
422446
** Subscript command: submit_ticket
423447
**
424448
** Construct and submit a new ticket artifact. The fields of the artifact
@@ -498,18 +522,11 @@
498522
}else if( g.thTrace ){
499523
Th_Trace("submit_ticket {\n<blockquote><pre>\n%h\n</pre></blockquote>\n"
500524
"}<br />\n",
501525
blob_str(&tktchng));
502526
}else{
503
- rid = content_put(&tktchng);
504
- if( rid==0 ){
505
- fossil_panic("trouble committing ticket: %s", g.zErrMsg);
506
- }
507
- manifest_crosslink_begin();
508
- manifest_crosslink(rid, &tktchng);
509
- assert( blob_is_reset(&tktchng) );
510
- manifest_crosslink_end();
527
+ ticket_put(&tktchng, zUuid, g.perm.ModTkt==0);
511528
}
512529
return ticket_change();
513530
}
514531
515532
@@ -1187,18 +1204,11 @@
11871204
}
11881205
blob_appendf(&tktchng, "K %s\n", zTktUuid);
11891206
blob_appendf(&tktchng, "U %F\n", zUser);
11901207
md5sum_blob(&tktchng, &cksum);
11911208
blob_appendf(&tktchng, "Z %b\n", &cksum);
1192
- rid = content_put(&tktchng);
1193
- if( rid==0 ){
1194
- fossil_panic("trouble committing ticket: %s", g.zErrMsg);
1195
- }
1196
- manifest_crosslink_begin();
1197
- manifest_crosslink(rid, &tktchng);
1198
- manifest_crosslink_end();
1199
- assert( blob_is_reset(&tktchng) );
1209
+ ticket_put(&tktchng, zTktUuid, 0);
12001210
printf("ticket %s succeeded for %s\n",
12011211
(eCmd==set?"set":"add"),zTktUuid);
12021212
}
12031213
}
12041214
}
12051215
--- src/tkt.c
+++ src/tkt.c
@@ -415,10 +415,34 @@
415 return TH_ERROR;
416 }
417 azAppend[idx] = mprintf("%.*s", argl[2], argv[2]);
418 return TH_OK;
419 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
421 /*
422 ** Subscript command: submit_ticket
423 **
424 ** Construct and submit a new ticket artifact. The fields of the artifact
@@ -498,18 +522,11 @@
498 }else if( g.thTrace ){
499 Th_Trace("submit_ticket {\n<blockquote><pre>\n%h\n</pre></blockquote>\n"
500 "}<br />\n",
501 blob_str(&tktchng));
502 }else{
503 rid = content_put(&tktchng);
504 if( rid==0 ){
505 fossil_panic("trouble committing ticket: %s", g.zErrMsg);
506 }
507 manifest_crosslink_begin();
508 manifest_crosslink(rid, &tktchng);
509 assert( blob_is_reset(&tktchng) );
510 manifest_crosslink_end();
511 }
512 return ticket_change();
513 }
514
515
@@ -1187,18 +1204,11 @@
1187 }
1188 blob_appendf(&tktchng, "K %s\n", zTktUuid);
1189 blob_appendf(&tktchng, "U %F\n", zUser);
1190 md5sum_blob(&tktchng, &cksum);
1191 blob_appendf(&tktchng, "Z %b\n", &cksum);
1192 rid = content_put(&tktchng);
1193 if( rid==0 ){
1194 fossil_panic("trouble committing ticket: %s", g.zErrMsg);
1195 }
1196 manifest_crosslink_begin();
1197 manifest_crosslink(rid, &tktchng);
1198 manifest_crosslink_end();
1199 assert( blob_is_reset(&tktchng) );
1200 printf("ticket %s succeeded for %s\n",
1201 (eCmd==set?"set":"add"),zTktUuid);
1202 }
1203 }
1204 }
1205
--- src/tkt.c
+++ src/tkt.c
@@ -415,10 +415,34 @@
415 return TH_ERROR;
416 }
417 azAppend[idx] = mprintf("%.*s", argl[2], argv[2]);
418 return TH_OK;
419 }
420
421 /*
422 ** Write a ticket into the repository.
423 */
424 static void ticket_put(Blob *pTicket, const char *zTktId, int needMod){
425 int rid = content_put_ex(pTicket, 0, 0, 0, needMod);
426 if( rid==0 ){
427 fossil_panic("trouble committing ticket: %s", g.zErrMsg);
428 }
429 if( needMod ){
430 moderation_table_create();
431 db_multi_exec(
432 "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
433 rid, zTktId
434 );
435 }else{
436 db_multi_exec("INSERT INTO unsent VALUES(%d);", rid);
437 db_multi_exec("INSERT INTO unclustered VALUES(%d);", rid);
438 }
439 manifest_crosslink_begin();
440 manifest_crosslink(rid, pTicket);
441 assert( blob_is_reset(pTicket) );
442 manifest_crosslink_end();
443 }
444
445 /*
446 ** Subscript command: submit_ticket
447 **
448 ** Construct and submit a new ticket artifact. The fields of the artifact
@@ -498,18 +522,11 @@
522 }else if( g.thTrace ){
523 Th_Trace("submit_ticket {\n<blockquote><pre>\n%h\n</pre></blockquote>\n"
524 "}<br />\n",
525 blob_str(&tktchng));
526 }else{
527 ticket_put(&tktchng, zUuid, g.perm.ModTkt==0);
 
 
 
 
 
 
 
528 }
529 return ticket_change();
530 }
531
532
@@ -1187,18 +1204,11 @@
1204 }
1205 blob_appendf(&tktchng, "K %s\n", zTktUuid);
1206 blob_appendf(&tktchng, "U %F\n", zUser);
1207 md5sum_blob(&tktchng, &cksum);
1208 blob_appendf(&tktchng, "Z %b\n", &cksum);
1209 ticket_put(&tktchng, zTktUuid, 0);
 
 
 
 
 
 
 
1210 printf("ticket %s succeeded for %s\n",
1211 (eCmd==set?"set":"add"),zTktUuid);
1212 }
1213 }
1214 }
1215

Keyboard Shortcuts

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