Fossil SCM
Add the "Last Login" column to the setup_ulist page.
Commit
5832d2fc6090572cd84c18021ea36f420de2f46b40a67a4566e3cb2f3901b76d
Parent
38f37679d39d020…
1 file changed
+22
-4
+22
-4
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -142,10 +142,11 @@ | ||
| 142 | 142 | ** Show a list of users. Clicking on any user jumps to the edit |
| 143 | 143 | ** screen for that user. Requires Admin privileges. |
| 144 | 144 | */ |
| 145 | 145 | void setup_ulist(void){ |
| 146 | 146 | Stmt s; |
| 147 | + double rNow; | |
| 147 | 148 | |
| 148 | 149 | login_check_credentials(); |
| 149 | 150 | if( !g.perm.Admin ){ |
| 150 | 151 | login_needed(0); |
| 151 | 152 | return; |
| @@ -198,41 +199,58 @@ | ||
| 198 | 199 | db_finalize(&s); |
| 199 | 200 | @ </tbody></table> |
| 200 | 201 | @ <div class='section'>Users</div> |
| 201 | 202 | @ <table border=1 cellpadding=2 cellspacing=0 class='userTable' id='userlist'> |
| 202 | 203 | @ <thead><tr> |
| 203 | - @ <th>ID<th>Login<th>Caps<th>Info<th>Date<th>Expire</tr></thead> | |
| 204 | + @ <th>ID<th>Login Name<th>Caps<th>Info<th>Date<th>Expire<th>Last Login</tr></thead> | |
| 204 | 205 | @ <tbody> |
| 206 | + db_multi_exec( | |
| 207 | + "CREATE TEMP TABLE lastAccess(uname TEXT PRIMARY KEY, atime REAL) WITHOUT ROWID;" | |
| 208 | + ); | |
| 209 | + if( db_table_exists("repository","accesslog") ){ | |
| 210 | + db_multi_exec( | |
| 211 | + "INSERT INTO lastAccess(uname, atime)" | |
| 212 | + " SELECT uname, max(mtime) FROM accesslog WHERE success GROUP BY uname;" | |
| 213 | + ); | |
| 214 | + } | |
| 205 | 215 | db_prepare(&s, |
| 206 | 216 | "SELECT uid, login, cap, info, date(mtime,'unixepoch'), lower(login) AS sortkey, " |
| 207 | 217 | " CASE WHEN info LIKE '%%expires 20%%'" |
| 208 | 218 | " THEN substr(info,instr(lower(info),'expires')+8,10)" |
| 209 | - " END AS exp" | |
| 210 | - " FROM user" | |
| 219 | + " END AS exp," | |
| 220 | + "atime" | |
| 221 | + " FROM user LEFT JOIN lastAccess ON login=uname" | |
| 211 | 222 | " WHERE login NOT IN ('anonymous','nobody','developer','reader')" |
| 212 | 223 | " ORDER BY sortkey" |
| 213 | 224 | ); |
| 225 | + rNow = db_double(0.0, "SELECT julianday('now');"); | |
| 214 | 226 | while( db_step(&s)==SQLITE_ROW ){ |
| 215 | 227 | int uid = db_column_int(&s, 0); |
| 216 | 228 | const char *zLogin = db_column_text(&s, 1); |
| 217 | 229 | const char *zCap = db_column_text(&s, 2); |
| 218 | 230 | const char *zInfo = db_column_text(&s, 3); |
| 219 | 231 | const char *zDate = db_column_text(&s, 4); |
| 220 | 232 | const char *zSortKey = db_column_text(&s,5); |
| 221 | 233 | const char *zExp = db_column_text(&s,6); |
| 234 | + double rATime = db_column_double(&s,7); | |
| 235 | + char *zAge = 0; | |
| 236 | + if( rATime>0.0 ){ | |
| 237 | + zAge = human_readable_age(rNow - rATime); | |
| 238 | + } | |
| 222 | 239 | @ <tr> |
| 223 | 240 | @ <td><a href='setup_uedit?id=%d(uid)'>%d(uid)</a> |
| 224 | 241 | @ <td data-sortkey='%h(zSortKey)'><a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a> |
| 225 | 242 | @ <td>%h(zCap) |
| 226 | 243 | @ <td>%h(zInfo) |
| 227 | 244 | @ <td>%h(zDate?zDate:"") |
| 228 | 245 | @ <td>%h(zExp?zExp:"") |
| 246 | + @ <td data-sortkey='%f(rATime)'>%s(zAge?zAge:"") | |
| 229 | 247 | @ </tr> |
| 230 | 248 | } |
| 231 | 249 | @ </tbody></table> |
| 232 | 250 | db_finalize(&s); |
| 233 | - output_table_sorting_javascript("userlist","nktxTT",2); | |
| 251 | + output_table_sorting_javascript("userlist","nktxTTK",2); | |
| 234 | 252 | style_footer(); |
| 235 | 253 | } |
| 236 | 254 | |
| 237 | 255 | /* |
| 238 | 256 | ** Render the user-capability table |
| 239 | 257 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -142,10 +142,11 @@ | |
| 142 | ** Show a list of users. Clicking on any user jumps to the edit |
| 143 | ** screen for that user. Requires Admin privileges. |
| 144 | */ |
| 145 | void setup_ulist(void){ |
| 146 | Stmt s; |
| 147 | |
| 148 | login_check_credentials(); |
| 149 | if( !g.perm.Admin ){ |
| 150 | login_needed(0); |
| 151 | return; |
| @@ -198,41 +199,58 @@ | |
| 198 | db_finalize(&s); |
| 199 | @ </tbody></table> |
| 200 | @ <div class='section'>Users</div> |
| 201 | @ <table border=1 cellpadding=2 cellspacing=0 class='userTable' id='userlist'> |
| 202 | @ <thead><tr> |
| 203 | @ <th>ID<th>Login<th>Caps<th>Info<th>Date<th>Expire</tr></thead> |
| 204 | @ <tbody> |
| 205 | db_prepare(&s, |
| 206 | "SELECT uid, login, cap, info, date(mtime,'unixepoch'), lower(login) AS sortkey, " |
| 207 | " CASE WHEN info LIKE '%%expires 20%%'" |
| 208 | " THEN substr(info,instr(lower(info),'expires')+8,10)" |
| 209 | " END AS exp" |
| 210 | " FROM user" |
| 211 | " WHERE login NOT IN ('anonymous','nobody','developer','reader')" |
| 212 | " ORDER BY sortkey" |
| 213 | ); |
| 214 | while( db_step(&s)==SQLITE_ROW ){ |
| 215 | int uid = db_column_int(&s, 0); |
| 216 | const char *zLogin = db_column_text(&s, 1); |
| 217 | const char *zCap = db_column_text(&s, 2); |
| 218 | const char *zInfo = db_column_text(&s, 3); |
| 219 | const char *zDate = db_column_text(&s, 4); |
| 220 | const char *zSortKey = db_column_text(&s,5); |
| 221 | const char *zExp = db_column_text(&s,6); |
| 222 | @ <tr> |
| 223 | @ <td><a href='setup_uedit?id=%d(uid)'>%d(uid)</a> |
| 224 | @ <td data-sortkey='%h(zSortKey)'><a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a> |
| 225 | @ <td>%h(zCap) |
| 226 | @ <td>%h(zInfo) |
| 227 | @ <td>%h(zDate?zDate:"") |
| 228 | @ <td>%h(zExp?zExp:"") |
| 229 | @ </tr> |
| 230 | } |
| 231 | @ </tbody></table> |
| 232 | db_finalize(&s); |
| 233 | output_table_sorting_javascript("userlist","nktxTT",2); |
| 234 | style_footer(); |
| 235 | } |
| 236 | |
| 237 | /* |
| 238 | ** Render the user-capability table |
| 239 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -142,10 +142,11 @@ | |
| 142 | ** Show a list of users. Clicking on any user jumps to the edit |
| 143 | ** screen for that user. Requires Admin privileges. |
| 144 | */ |
| 145 | void setup_ulist(void){ |
| 146 | Stmt s; |
| 147 | double rNow; |
| 148 | |
| 149 | login_check_credentials(); |
| 150 | if( !g.perm.Admin ){ |
| 151 | login_needed(0); |
| 152 | return; |
| @@ -198,41 +199,58 @@ | |
| 199 | db_finalize(&s); |
| 200 | @ </tbody></table> |
| 201 | @ <div class='section'>Users</div> |
| 202 | @ <table border=1 cellpadding=2 cellspacing=0 class='userTable' id='userlist'> |
| 203 | @ <thead><tr> |
| 204 | @ <th>ID<th>Login Name<th>Caps<th>Info<th>Date<th>Expire<th>Last Login</tr></thead> |
| 205 | @ <tbody> |
| 206 | db_multi_exec( |
| 207 | "CREATE TEMP TABLE lastAccess(uname TEXT PRIMARY KEY, atime REAL) WITHOUT ROWID;" |
| 208 | ); |
| 209 | if( db_table_exists("repository","accesslog") ){ |
| 210 | db_multi_exec( |
| 211 | "INSERT INTO lastAccess(uname, atime)" |
| 212 | " SELECT uname, max(mtime) FROM accesslog WHERE success GROUP BY uname;" |
| 213 | ); |
| 214 | } |
| 215 | db_prepare(&s, |
| 216 | "SELECT uid, login, cap, info, date(mtime,'unixepoch'), lower(login) AS sortkey, " |
| 217 | " CASE WHEN info LIKE '%%expires 20%%'" |
| 218 | " THEN substr(info,instr(lower(info),'expires')+8,10)" |
| 219 | " END AS exp," |
| 220 | "atime" |
| 221 | " FROM user LEFT JOIN lastAccess ON login=uname" |
| 222 | " WHERE login NOT IN ('anonymous','nobody','developer','reader')" |
| 223 | " ORDER BY sortkey" |
| 224 | ); |
| 225 | rNow = db_double(0.0, "SELECT julianday('now');"); |
| 226 | while( db_step(&s)==SQLITE_ROW ){ |
| 227 | int uid = db_column_int(&s, 0); |
| 228 | const char *zLogin = db_column_text(&s, 1); |
| 229 | const char *zCap = db_column_text(&s, 2); |
| 230 | const char *zInfo = db_column_text(&s, 3); |
| 231 | const char *zDate = db_column_text(&s, 4); |
| 232 | const char *zSortKey = db_column_text(&s,5); |
| 233 | const char *zExp = db_column_text(&s,6); |
| 234 | double rATime = db_column_double(&s,7); |
| 235 | char *zAge = 0; |
| 236 | if( rATime>0.0 ){ |
| 237 | zAge = human_readable_age(rNow - rATime); |
| 238 | } |
| 239 | @ <tr> |
| 240 | @ <td><a href='setup_uedit?id=%d(uid)'>%d(uid)</a> |
| 241 | @ <td data-sortkey='%h(zSortKey)'><a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a> |
| 242 | @ <td>%h(zCap) |
| 243 | @ <td>%h(zInfo) |
| 244 | @ <td>%h(zDate?zDate:"") |
| 245 | @ <td>%h(zExp?zExp:"") |
| 246 | @ <td data-sortkey='%f(rATime)'>%s(zAge?zAge:"") |
| 247 | @ </tr> |
| 248 | } |
| 249 | @ </tbody></table> |
| 250 | db_finalize(&s); |
| 251 | output_table_sorting_javascript("userlist","nktxTTK",2); |
| 252 | style_footer(); |
| 253 | } |
| 254 | |
| 255 | /* |
| 256 | ** Render the user-capability table |
| 257 |