Fossil SCM

Use the display name rather than the login for forum posts.

drh 2020-03-27 14:30 trunk
Commit 2e71dc25d94c3f9a8b652d73057dd737dc3053f602621d87cb0daa71f4eab430
3 files changed +30 -2 +2 +37 -3
+30 -2
--- src/alerts.c
+++ src/alerts.c
@@ -671,10 +671,38 @@
671671
char *zOut = alert_find_emailaddr(zIn);
672672
if( zOut ){
673673
sqlite3_result_text(context, zOut, -1, fossil_free);
674674
}
675675
}
676
+
677
+/*
678
+** SQL function: display_name(X)
679
+**
680
+** If X is a string, search for a user name at the beginning of that
681
+** string. The user name must be followed by an email address. If
682
+** found, return the user name. If not found, return NULL.
683
+**
684
+** This routine is used to extract the display name from the USER.INFO
685
+** field.
686
+*/
687
+void alert_display_name_func(
688
+ sqlite3_context *context,
689
+ int argc,
690
+ sqlite3_value **argv
691
+){
692
+ const char *zIn = (const char*)sqlite3_value_text(argv[0]);
693
+ int i;
694
+ if( zIn==0 ) return;
695
+ while( fossil_isspace(zIn[0]) ) zIn++;
696
+ for(i=0; zIn[i] && zIn[i]!='<' && zIn[i]!='\n'; i++){}
697
+ if( zIn[i]=='<' ){
698
+ while( i>0 && fossil_isspace(zIn[i-1]) ){ i--; }
699
+ if( i>0 ){
700
+ sqlite3_result_text(context, zIn, i, SQLITE_TRANSIENT);
701
+ }
702
+ }
703
+}
676704
677705
/*
678706
** Return the hostname portion of an email address - the part following
679707
** the @
680708
*/
@@ -2142,12 +2170,12 @@
21422170
" (SELECT uuid FROM blob WHERE rid=forumpost.fpid)," /* 1 */
21432171
" datetime(event.mtime)," /* 2 */
21442172
" substr(comment,instr(comment,':')+2)," /* 3 */
21452173
" (SELECT uuid FROM blob WHERE rid=forumpost.firt)," /* 4 */
21462174
" wantalert.needMod," /* 5 */
2147
- " coalesce(trim(substr(info,1,instr(info,'<')-1)),euser,user)," /* 6 */
2148
- " forumpost.fprev IS NULL" /* 7 */
2175
+ " coalesce(display_name(info),euser,user)," /* 6 */
2176
+ " forumpost.fprev IS NULL" /* 7 */
21492177
" FROM temp.wantalert, event, forumpost"
21502178
" LEFT JOIN user ON (login=coalesce(euser,user))"
21512179
" WHERE event.objid=substr(wantalert.eventId,2)+0"
21522180
" AND eventId GLOB 'f*'"
21532181
" AND forumpost.fpid=event.objid"
21542182
--- src/alerts.c
+++ src/alerts.c
@@ -671,10 +671,38 @@
671 char *zOut = alert_find_emailaddr(zIn);
672 if( zOut ){
673 sqlite3_result_text(context, zOut, -1, fossil_free);
674 }
675 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
676
677 /*
678 ** Return the hostname portion of an email address - the part following
679 ** the @
680 */
@@ -2142,12 +2170,12 @@
2142 " (SELECT uuid FROM blob WHERE rid=forumpost.fpid)," /* 1 */
2143 " datetime(event.mtime)," /* 2 */
2144 " substr(comment,instr(comment,':')+2)," /* 3 */
2145 " (SELECT uuid FROM blob WHERE rid=forumpost.firt)," /* 4 */
2146 " wantalert.needMod," /* 5 */
2147 " coalesce(trim(substr(info,1,instr(info,'<')-1)),euser,user)," /* 6 */
2148 " forumpost.fprev IS NULL" /* 7 */
2149 " FROM temp.wantalert, event, forumpost"
2150 " LEFT JOIN user ON (login=coalesce(euser,user))"
2151 " WHERE event.objid=substr(wantalert.eventId,2)+0"
2152 " AND eventId GLOB 'f*'"
2153 " AND forumpost.fpid=event.objid"
2154
--- src/alerts.c
+++ src/alerts.c
@@ -671,10 +671,38 @@
671 char *zOut = alert_find_emailaddr(zIn);
672 if( zOut ){
673 sqlite3_result_text(context, zOut, -1, fossil_free);
674 }
675 }
676
677 /*
678 ** SQL function: display_name(X)
679 **
680 ** If X is a string, search for a user name at the beginning of that
681 ** string. The user name must be followed by an email address. If
682 ** found, return the user name. If not found, return NULL.
683 **
684 ** This routine is used to extract the display name from the USER.INFO
685 ** field.
686 */
687 void alert_display_name_func(
688 sqlite3_context *context,
689 int argc,
690 sqlite3_value **argv
691 ){
692 const char *zIn = (const char*)sqlite3_value_text(argv[0]);
693 int i;
694 if( zIn==0 ) return;
695 while( fossil_isspace(zIn[0]) ) zIn++;
696 for(i=0; zIn[i] && zIn[i]!='<' && zIn[i]!='\n'; i++){}
697 if( zIn[i]=='<' ){
698 while( i>0 && fossil_isspace(zIn[i-1]) ){ i--; }
699 if( i>0 ){
700 sqlite3_result_text(context, zIn, i, SQLITE_TRANSIENT);
701 }
702 }
703 }
704
705 /*
706 ** Return the hostname portion of an email address - the part following
707 ** the @
708 */
@@ -2142,12 +2170,12 @@
2170 " (SELECT uuid FROM blob WHERE rid=forumpost.fpid)," /* 1 */
2171 " datetime(event.mtime)," /* 2 */
2172 " substr(comment,instr(comment,':')+2)," /* 3 */
2173 " (SELECT uuid FROM blob WHERE rid=forumpost.firt)," /* 4 */
2174 " wantalert.needMod," /* 5 */
2175 " coalesce(display_name(info),euser,user)," /* 6 */
2176 " forumpost.fprev IS NULL" /* 7 */
2177 " FROM temp.wantalert, event, forumpost"
2178 " LEFT JOIN user ON (login=coalesce(euser,user))"
2179 " WHERE event.objid=substr(wantalert.eventId,2)+0"
2180 " AND eventId GLOB 'f*'"
2181 " AND forumpost.fpid=event.objid"
2182
+2
--- src/db.c
+++ src/db.c
@@ -1041,10 +1041,12 @@
10411041
0, capability_union_step, capability_union_finalize);
10421042
sqlite3_create_function(db, "fullcap", 1, SQLITE_UTF8, 0,
10431043
capability_fullcap, 0, 0);
10441044
sqlite3_create_function(db, "find_emailaddr", 1, SQLITE_UTF8, 0,
10451045
alert_find_emailaddr_func, 0, 0);
1046
+ sqlite3_create_function(db, "display_name", 1, SQLITE_UTF8, 0,
1047
+ alert_display_name_func, 0, 0);
10461048
}
10471049
10481050
#if USE_SEE
10491051
/*
10501052
** This is a pointer to the saved database encryption key string.
10511053
--- src/db.c
+++ src/db.c
@@ -1041,10 +1041,12 @@
1041 0, capability_union_step, capability_union_finalize);
1042 sqlite3_create_function(db, "fullcap", 1, SQLITE_UTF8, 0,
1043 capability_fullcap, 0, 0);
1044 sqlite3_create_function(db, "find_emailaddr", 1, SQLITE_UTF8, 0,
1045 alert_find_emailaddr_func, 0, 0);
 
 
1046 }
1047
1048 #if USE_SEE
1049 /*
1050 ** This is a pointer to the saved database encryption key string.
1051
--- src/db.c
+++ src/db.c
@@ -1041,10 +1041,12 @@
1041 0, capability_union_step, capability_union_finalize);
1042 sqlite3_create_function(db, "fullcap", 1, SQLITE_UTF8, 0,
1043 capability_fullcap, 0, 0);
1044 sqlite3_create_function(db, "find_emailaddr", 1, SQLITE_UTF8, 0,
1045 alert_find_emailaddr_func, 0, 0);
1046 sqlite3_create_function(db, "display_name", 1, SQLITE_UTF8, 0,
1047 alert_display_name_func, 0, 0);
1048 }
1049
1050 #if USE_SEE
1051 /*
1052 ** This is a pointer to the saved database encryption key string.
1053
+37 -3
--- src/forum.c
+++ src/forum.c
@@ -352,10 +352,35 @@
352352
@ Trust user "%h(pPost->zUser)"
353353
@ so that future posts by "%h(pPost->zUser)" do not require moderation.
354354
@ </label>
355355
@ <input type="hidden" name="trustuser" value="%h(pPost->zUser)">
356356
}
357
+
358
+/*
359
+** Compute a display name from a login name.
360
+**
361
+** If the input login is found in the USER table, then check the USER.INFO
362
+** field to see if it has display-name followed by an email address.
363
+** If it does, that becomes the new display name. If not, let the display
364
+** name just be the login.
365
+**
366
+** Space to hold the returned name is obtained form fossil_strdup()
367
+** and should be freed by the caller.
368
+*/
369
+char *display_name_from_login(const char *zLogin){
370
+ static Stmt q;
371
+ char *zResult;
372
+ db_static_prepare(&q,
373
+ "SELECT coalesce(display_name(info),$login) FROM user WHERE login=$login"
374
+ );
375
+ db_bind_text(&q, "$login", zLogin);
376
+ db_step(&q);
377
+ zResult = fossil_strdup(db_column_text(&q,0));
378
+ db_reset(&q);
379
+ return zResult;
380
+}
381
+
357382
358383
/*
359384
** Display all posts in a forum thread in chronological order
360385
*/
361386
static void forum_display_chronological(int froot, int target, int bRawMode){
@@ -367,10 +392,11 @@
367392
char *zDate;
368393
Manifest *pPost;
369394
int isPrivate; /* True for posts awaiting moderation */
370395
int sameUser; /* True if author is also the reader */
371396
const char *zUuid;
397
+ char *zDisplayName; /* The display name */
372398
373399
pPost = manifest_get(p->fpid, CFTYPE_FORUM, 0);
374400
if( pPost==0 ) continue;
375401
if( p->fpid==target ){
376402
@ <div id="forum%d(p->fpid)" class="forumTime forumSel">
@@ -381,11 +407,13 @@
381407
}
382408
if( pPost->zThreadTitle ){
383409
@ <h1>%h(pPost->zThreadTitle)</h1>
384410
}
385411
zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate);
386
- @ <h3 class='forumPostHdr'>(%d(p->sid)) By %h(pPost->zUser) on %h(zDate)
412
+ zDisplayName = display_name_from_login(pPost->zUser);
413
+ @ <h3 class='forumPostHdr'>(%d(p->sid)) By %h(zDisplayName) on %h(zDate)
414
+ fossil_free(zDisplayName);
387415
fossil_free(zDate);
388416
if( p->pEdit ){
389417
@ edit of %z(href("%R/forumpost/%S?t=%c",p->pEdit->zUuid,cMode))\
390418
@ %d(p->pEdit->sid)</a>
391419
}
@@ -479,10 +507,11 @@
479507
iIndentScale--;
480508
}
481509
for(p=pThread->pDisplay; p; p=p->pDisplay){
482510
int isPrivate; /* True for posts awaiting moderation */
483511
int sameUser; /* True if reader is also the poster */
512
+ char *zDisplayName; /* User name to be displayed */
484513
pOPost = manifest_get(p->fpid, CFTYPE_FORUM, 0);
485514
if( p->pLeaf ){
486515
fpid = p->pLeaf->fpid;
487516
zUuid = p->pLeaf->zUuid;
488517
pPost = manifest_get(fpid, CFTYPE_FORUM, 0);
@@ -502,12 +531,14 @@
502531
if( pPost==0 ) continue;
503532
if( pPost->zThreadTitle ){
504533
@ <h1>%h(pPost->zThreadTitle)</h1>
505534
}
506535
zDate = db_text(0, "SELECT datetime(%.17g)", pOPost->rDate);
536
+ zDisplayName = display_name_from_login(pOPost->zUser);
507537
@ <h3 class='forumPostHdr'>\
508
- @ (%d(p->pLeaf?p->pLeaf->sid:p->sid)) By %h(pOPost->zUser) on %h(zDate)
538
+ @ (%d(p->pLeaf?p->pLeaf->sid:p->sid)) By %h(zDisplayName) on %h(zDate)
539
+ fossil_free(zDisplayName);
509540
fossil_free(zDate);
510541
if( g.perm.Debug ){
511542
@ <span class="debug">\
512543
@ <a href="%R/artifact/%h(p->zUuid)">(artifact)</a></span>
513544
}
@@ -1065,19 +1096,22 @@
10651096
@ <input type="hidden" name="edit" value="1">
10661097
forum_from_line();
10671098
forum_entry_widget(zTitle, zMimetype, zContent);
10681099
}else{
10691100
/* Reply */
1101
+ char *zDisplayName;
10701102
zMimetype = PD("mimetype",DEFAULT_FORUM_MIMETYPE);
10711103
zContent = PDT("content","");
10721104
style_header("Reply");
10731105
if( pRootPost->zThreadTitle ){
10741106
@ <h1>Thread: %h(pRootPost->zThreadTitle)</h1>
10751107
}
10761108
@ <h2>Replying To:</h2>
10771109
zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate);
1078
- @ <h3 class='forumPostHdr'>By %h(pPost->zUser) on %h(zDate)</h3>
1110
+ zDisplayName = display_name_from_login(pPost->zUser);
1111
+ @ <h3 class='forumPostHdr'>By %h(zDisplayName) on %h(zDate)</h3>
1112
+ fossil_free(zDisplayName);
10791113
fossil_free(zDate);
10801114
forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit");
10811115
if( P("preview") ){
10821116
@ <h2>Preview:</h2>
10831117
forum_render(0, zMimetype,zContent, "forumEdit");
10841118
--- src/forum.c
+++ src/forum.c
@@ -352,10 +352,35 @@
352 @ Trust user "%h(pPost->zUser)"
353 @ so that future posts by "%h(pPost->zUser)" do not require moderation.
354 @ </label>
355 @ <input type="hidden" name="trustuser" value="%h(pPost->zUser)">
356 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
358 /*
359 ** Display all posts in a forum thread in chronological order
360 */
361 static void forum_display_chronological(int froot, int target, int bRawMode){
@@ -367,10 +392,11 @@
367 char *zDate;
368 Manifest *pPost;
369 int isPrivate; /* True for posts awaiting moderation */
370 int sameUser; /* True if author is also the reader */
371 const char *zUuid;
 
372
373 pPost = manifest_get(p->fpid, CFTYPE_FORUM, 0);
374 if( pPost==0 ) continue;
375 if( p->fpid==target ){
376 @ <div id="forum%d(p->fpid)" class="forumTime forumSel">
@@ -381,11 +407,13 @@
381 }
382 if( pPost->zThreadTitle ){
383 @ <h1>%h(pPost->zThreadTitle)</h1>
384 }
385 zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate);
386 @ <h3 class='forumPostHdr'>(%d(p->sid)) By %h(pPost->zUser) on %h(zDate)
 
 
387 fossil_free(zDate);
388 if( p->pEdit ){
389 @ edit of %z(href("%R/forumpost/%S?t=%c",p->pEdit->zUuid,cMode))\
390 @ %d(p->pEdit->sid)</a>
391 }
@@ -479,10 +507,11 @@
479 iIndentScale--;
480 }
481 for(p=pThread->pDisplay; p; p=p->pDisplay){
482 int isPrivate; /* True for posts awaiting moderation */
483 int sameUser; /* True if reader is also the poster */
 
484 pOPost = manifest_get(p->fpid, CFTYPE_FORUM, 0);
485 if( p->pLeaf ){
486 fpid = p->pLeaf->fpid;
487 zUuid = p->pLeaf->zUuid;
488 pPost = manifest_get(fpid, CFTYPE_FORUM, 0);
@@ -502,12 +531,14 @@
502 if( pPost==0 ) continue;
503 if( pPost->zThreadTitle ){
504 @ <h1>%h(pPost->zThreadTitle)</h1>
505 }
506 zDate = db_text(0, "SELECT datetime(%.17g)", pOPost->rDate);
 
507 @ <h3 class='forumPostHdr'>\
508 @ (%d(p->pLeaf?p->pLeaf->sid:p->sid)) By %h(pOPost->zUser) on %h(zDate)
 
509 fossil_free(zDate);
510 if( g.perm.Debug ){
511 @ <span class="debug">\
512 @ <a href="%R/artifact/%h(p->zUuid)">(artifact)</a></span>
513 }
@@ -1065,19 +1096,22 @@
1065 @ <input type="hidden" name="edit" value="1">
1066 forum_from_line();
1067 forum_entry_widget(zTitle, zMimetype, zContent);
1068 }else{
1069 /* Reply */
 
1070 zMimetype = PD("mimetype",DEFAULT_FORUM_MIMETYPE);
1071 zContent = PDT("content","");
1072 style_header("Reply");
1073 if( pRootPost->zThreadTitle ){
1074 @ <h1>Thread: %h(pRootPost->zThreadTitle)</h1>
1075 }
1076 @ <h2>Replying To:</h2>
1077 zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate);
1078 @ <h3 class='forumPostHdr'>By %h(pPost->zUser) on %h(zDate)</h3>
 
 
1079 fossil_free(zDate);
1080 forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit");
1081 if( P("preview") ){
1082 @ <h2>Preview:</h2>
1083 forum_render(0, zMimetype,zContent, "forumEdit");
1084
--- src/forum.c
+++ src/forum.c
@@ -352,10 +352,35 @@
352 @ Trust user "%h(pPost->zUser)"
353 @ so that future posts by "%h(pPost->zUser)" do not require moderation.
354 @ </label>
355 @ <input type="hidden" name="trustuser" value="%h(pPost->zUser)">
356 }
357
358 /*
359 ** Compute a display name from a login name.
360 **
361 ** If the input login is found in the USER table, then check the USER.INFO
362 ** field to see if it has display-name followed by an email address.
363 ** If it does, that becomes the new display name. If not, let the display
364 ** name just be the login.
365 **
366 ** Space to hold the returned name is obtained form fossil_strdup()
367 ** and should be freed by the caller.
368 */
369 char *display_name_from_login(const char *zLogin){
370 static Stmt q;
371 char *zResult;
372 db_static_prepare(&q,
373 "SELECT coalesce(display_name(info),$login) FROM user WHERE login=$login"
374 );
375 db_bind_text(&q, "$login", zLogin);
376 db_step(&q);
377 zResult = fossil_strdup(db_column_text(&q,0));
378 db_reset(&q);
379 return zResult;
380 }
381
382
383 /*
384 ** Display all posts in a forum thread in chronological order
385 */
386 static void forum_display_chronological(int froot, int target, int bRawMode){
@@ -367,10 +392,11 @@
392 char *zDate;
393 Manifest *pPost;
394 int isPrivate; /* True for posts awaiting moderation */
395 int sameUser; /* True if author is also the reader */
396 const char *zUuid;
397 char *zDisplayName; /* The display name */
398
399 pPost = manifest_get(p->fpid, CFTYPE_FORUM, 0);
400 if( pPost==0 ) continue;
401 if( p->fpid==target ){
402 @ <div id="forum%d(p->fpid)" class="forumTime forumSel">
@@ -381,11 +407,13 @@
407 }
408 if( pPost->zThreadTitle ){
409 @ <h1>%h(pPost->zThreadTitle)</h1>
410 }
411 zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate);
412 zDisplayName = display_name_from_login(pPost->zUser);
413 @ <h3 class='forumPostHdr'>(%d(p->sid)) By %h(zDisplayName) on %h(zDate)
414 fossil_free(zDisplayName);
415 fossil_free(zDate);
416 if( p->pEdit ){
417 @ edit of %z(href("%R/forumpost/%S?t=%c",p->pEdit->zUuid,cMode))\
418 @ %d(p->pEdit->sid)</a>
419 }
@@ -479,10 +507,11 @@
507 iIndentScale--;
508 }
509 for(p=pThread->pDisplay; p; p=p->pDisplay){
510 int isPrivate; /* True for posts awaiting moderation */
511 int sameUser; /* True if reader is also the poster */
512 char *zDisplayName; /* User name to be displayed */
513 pOPost = manifest_get(p->fpid, CFTYPE_FORUM, 0);
514 if( p->pLeaf ){
515 fpid = p->pLeaf->fpid;
516 zUuid = p->pLeaf->zUuid;
517 pPost = manifest_get(fpid, CFTYPE_FORUM, 0);
@@ -502,12 +531,14 @@
531 if( pPost==0 ) continue;
532 if( pPost->zThreadTitle ){
533 @ <h1>%h(pPost->zThreadTitle)</h1>
534 }
535 zDate = db_text(0, "SELECT datetime(%.17g)", pOPost->rDate);
536 zDisplayName = display_name_from_login(pOPost->zUser);
537 @ <h3 class='forumPostHdr'>\
538 @ (%d(p->pLeaf?p->pLeaf->sid:p->sid)) By %h(zDisplayName) on %h(zDate)
539 fossil_free(zDisplayName);
540 fossil_free(zDate);
541 if( g.perm.Debug ){
542 @ <span class="debug">\
543 @ <a href="%R/artifact/%h(p->zUuid)">(artifact)</a></span>
544 }
@@ -1065,19 +1096,22 @@
1096 @ <input type="hidden" name="edit" value="1">
1097 forum_from_line();
1098 forum_entry_widget(zTitle, zMimetype, zContent);
1099 }else{
1100 /* Reply */
1101 char *zDisplayName;
1102 zMimetype = PD("mimetype",DEFAULT_FORUM_MIMETYPE);
1103 zContent = PDT("content","");
1104 style_header("Reply");
1105 if( pRootPost->zThreadTitle ){
1106 @ <h1>Thread: %h(pRootPost->zThreadTitle)</h1>
1107 }
1108 @ <h2>Replying To:</h2>
1109 zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate);
1110 zDisplayName = display_name_from_login(pPost->zUser);
1111 @ <h3 class='forumPostHdr'>By %h(zDisplayName) on %h(zDate)</h3>
1112 fossil_free(zDisplayName);
1113 fossil_free(zDate);
1114 forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit");
1115 if( P("preview") ){
1116 @ <h2>Preview:</h2>
1117 forum_render(0, zMimetype,zContent, "forumEdit");
1118

Keyboard Shortcuts

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