@@ -314,6 +314,7 @@ clientSocket and the catch block logic are updated accordingly.
314314 if (debugEnabled) log.debug(" Found a pr/ path, '{}'." , path)
315315
316316 return when (path) {
317+ " pr/bs" -> handleBsEndpoint(writer, output)
317318 " pr/db" -> handleDbEndpoint(writer, output)
318319 " pr/pr" -> handlePrEndpoint(writer, output)
319320 " pr/ex" -> handleExEndpoint(writer, output)
@@ -555,6 +556,31 @@ clientSocket and the catch block logic are updated accordingly.
555556 }
556557 }
557558
559+ private fun handleBsEndpoint (writer : PrintWriter , output : java.io.OutputStream ) {
560+ if (debugEnabled) log.debug(" Entering handleBsEndpoint()." )
561+
562+ var projectDatabase : SQLiteDatabase ? = null
563+ var outputStarted = false
564+
565+ try {
566+ projectDatabase = SQLiteDatabase .openDatabase(config.projectDatabasePath,
567+ null ,
568+ SQLiteDatabase .OPEN_READONLY )
569+
570+ outputStarted = realHandleBsEndpoint(writer, output, projectDatabase)
571+
572+ } catch (e: Exception ) {
573+ log.error(" Error handling /pr/bs endpoint: {}" , e.message)
574+ sendError(writer, output, 500 , " Internal Server Error 6" , " Error generating database table." , outputStarted)
575+
576+ } finally {
577+ projectDatabase?.close()
578+ }
579+
580+ if (debugEnabled) log.debug(" Leaving handleBsEndpoint()." )
581+ }
582+
583+
558584 private fun handleExEndpoint (writer : PrintWriter , output : java.io.OutputStream ) {
559585 val flag = if (experimentsEnabled) " {}" else " {display: none;}"
560586
@@ -618,6 +644,63 @@ second response.
618644 if (debugEnabled) log.debug(" Leaving handlePrEndpoint()." )
619645 }
620646
647+ private fun realHandleBsEndpoint (writer : PrintWriter , output : java.io.OutputStream , projectDatabase : SQLiteDatabase ) : Boolean {
648+ if (debugEnabled) log.debug(" Entering realHandleBsEndpoint()." )
649+
650+ val query = """
651+ SELECT id,
652+ name,
653+ DATETIME(create_at / 1000, 'unixepoch'),
654+ DATETIME(last_modified / 1000, 'unixepoch'),
655+ location,
656+ template_name,
657+ language
658+ FROM recent_project_table
659+ ORDER BY last_modified DESC"""
660+
661+ var html = getTableHtml(" Projects" , " Projects" ) + """
662+ <tr>
663+ <th>Id</th>
664+ <th>Name</th>
665+ <th>Created</th>
666+ <th>Modified <span style="font-family: sans-serif">V</span></th>
667+ <th>Directory</th>
668+ <th>Template</th>
669+ <th>Language</th>
670+ </tr>"""
671+
672+ val cursor = projectDatabase.rawQuery(query, arrayOf())
673+
674+ try {
675+ if (debugEnabled) log.debug(" Retrieved {} rows." , cursor.count)
676+
677+ while (cursor.moveToNext()) {
678+ html + = """ <tr>
679+ <td>${escapeHtml(cursor.getString(0 ) ? : " " )} </td>
680+ <td>${escapeHtml(cursor.getString(1 ) ? : " " )} </td>
681+ <td>${escapeHtml(cursor.getString(2 ) ? : " " )} </td>
682+ <td>${escapeHtml(cursor.getString(3 ) ? : " " )} </td>
683+ <td>${escapeHtml(cursor.getString(4 ) ? : " " )} </td>
684+ <td>${escapeHtml(cursor.getString(5 ) ? : " " )} </td>
685+ <td>${escapeHtml(cursor.getString(6 ) ? : " " )} </td>
686+ </tr>"""
687+ }
688+
689+ html + = " </table></body></html>"
690+
691+ } finally {
692+ cursor.close()
693+ }
694+
695+ if (debugEnabled) log.debug(" html is '{}'." , html) // May output a lot of stuff but better too much than too little. --DS, 23-Feb-2026
696+
697+ writeNormalToClient(writer, output, html)
698+
699+ if (debugEnabled) log.debug(" Leaving realHandlePrEndpoint()." )
700+
701+ return true
702+ }
703+
621704 private fun realHandlePrEndpoint (writer : PrintWriter , output : java.io.OutputStream , projectDatabase : SQLiteDatabase ) : Boolean {
622705 if (debugEnabled) log.debug(" Entering realHandlePrEndpoint()." )
623706
0 commit comments