Skip to content

Commit

Permalink
user settings
Browse files Browse the repository at this point in the history
  • Loading branch information
acharneski committed Nov 12, 2023
1 parent 083a27a commit 48123ca
Show file tree
Hide file tree
Showing 26 changed files with 180 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ package com.simiacryptus.skyenet.servers
import com.simiacryptus.openai.OpenAIClient
import com.simiacryptus.skyenet.OutputInterceptor
import com.simiacryptus.skyenet.util.AwsUtil.decryptResource
import com.simiacryptus.skyenet.webui.AuthenticatedWebsite
import com.simiacryptus.skyenet.webui.ApplicationServerBase
import com.simiacryptus.skyenet.webui.UserInfoServlet
import com.simiacryptus.skyenet.servlet.AuthenticatedWebsite
import com.simiacryptus.skyenet.webui.ApplicationBase
import com.simiacryptus.skyenet.servlet.UserInfoServlet
import com.simiacryptus.skyenet.servlet.UserSettingsServlet
import com.simiacryptus.skyenet.webui.WebSocketServer
import jakarta.servlet.DispatcherType
import jakarta.servlet.Servlet
Expand Down Expand Up @@ -44,6 +45,7 @@ abstract class AppServerBase(

val welcomeResources = Resource.newResource(javaClass.classLoader.getResource("welcome"))
val userInfoServlet = UserInfoServlet()
val userSettingsServlet = UserSettingsServlet()

protected fun _main(args: Array<String>) {
try {
Expand All @@ -62,6 +64,7 @@ abstract class AppServerBase(
port,
*(arrayOf(
newWebAppContext("/userInfo", userInfoServlet),
newWebAppContext("/userSettings", userSettingsServlet),
newWebAppContext("/proxy", ProxyHttpServlet()),
authentication.configure(
newWebAppContext(
Expand Down Expand Up @@ -100,12 +103,13 @@ abstract class AppServerBase(
val requestURI = req?.requestURI ?: "/"
resp?.contentType = when (requestURI) {
"/" -> "text/html"
else -> ApplicationServerBase.getMimeType(requestURI)
else -> ApplicationBase.getMimeType(requestURI)
}
when {
requestURI == "/" -> resp?.writer?.write(homepage().trimIndent())
requestURI == "/index.html" -> resp?.writer?.write(homepage().trimIndent())
requestURI.startsWith("/userInfo") -> userInfoServlet.doGet(req!!, resp!!)
requestURI.startsWith("/userSettings") -> userSettingsServlet.doGet(req!!, resp!!)
else -> try {
val inputStream = welcomeResources.addPath(requestURI)?.inputStream
inputStream?.copyTo(resp?.outputStream!!)
Expand All @@ -114,6 +118,14 @@ abstract class AppServerBase(
}
}
}

override fun doPost(req: HttpServletRequest?, resp: HttpServletResponse?) {
val requestURI = req?.requestURI ?: "/"
when {
requestURI.startsWith("/userSettings") -> userSettingsServlet.doPost(req!!, resp!!)
else -> resp?.sendError(404)
}
}
}

@Language("HTML")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.simiacryptus.skyenet.servers

import com.simiacryptus.skyenet.actors.CodingActor
import com.simiacryptus.skyenet.webui.MarkdownUtil.renderMarkdown
import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown
import com.simiacryptus.skyenet.webui.PersistentSessionBase
import com.simiacryptus.skyenet.webui.SessionDiv
import com.simiacryptus.skyenet.webui.MacroChat
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.simiacryptus.skyenet.servers

import com.simiacryptus.skyenet.actors.ParsedActor
import com.simiacryptus.skyenet.webui.MarkdownUtil.renderMarkdown
import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown
import com.simiacryptus.skyenet.webui.PersistentSessionBase
import com.simiacryptus.skyenet.webui.SessionDiv
import com.simiacryptus.skyenet.webui.MacroChat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ open class ReadOnlyApp(
temperature: Double = 0.3,
oauthConfig: String? = null,
val api: OpenAIClient,
) : ApplicationServerBase(
) : ApplicationBase(
applicationName = applicationName,
oauthConfig = oauthConfig,
temperature = temperature,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.simiacryptus.skyenet.servers

import com.simiacryptus.skyenet.actors.SimpleActor
import com.simiacryptus.skyenet.webui.*
import com.simiacryptus.skyenet.util.MarkdownUtil
import org.slf4j.LoggerFactory

open class SimpleActorTestApp(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.simiacryptus.skyenet.webui
package com.simiacryptus.skyenet.servlet

import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl
Expand Down Expand Up @@ -129,8 +129,9 @@ open class AuthenticatedWebsite(

companion object {
private val log = org.slf4j.LoggerFactory.getLogger(AuthenticatedWebsite::class.java)
val users = HashMap<String, Userinfo>()


val users = java.util.HashMap<String, Userinfo>()
fun getUser(req: HttpServletRequest): Userinfo? {
val sessionId = req.cookies?.find { it.name == "sessionId" }?.value
return if (null == sessionId) null else users[sessionId]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.simiacryptus.skyenet.webui
package com.simiacryptus.skyenet.servlet

import com.simiacryptus.skyenet.webui.ApplicationBase
import com.simiacryptus.skyenet.webui.SessionDataStorage
import jakarta.servlet.http.HttpServlet
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
Expand All @@ -18,7 +20,7 @@ class FileServlet(val sessionDataStorage: SessionDataStorage) : HttpServlet() {
val file = File(sessionDir, filePath)
if (file.isFile) {
val filename = file.name
resp.contentType = ApplicationServerBase.getMimeType(filename)
resp.contentType = ApplicationBase.getMimeType(filename)
resp.status = HttpServletResponse.SC_OK
file.inputStream().use { inputStream ->
resp.outputStream.use { outputStream ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.simiacryptus.skyenet.webui
package com.simiacryptus.skyenet.servlet

import com.simiacryptus.skyenet.webui.SessionDataStorage
import jakarta.servlet.http.HttpServlet
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.simiacryptus.skyenet.webui
package com.simiacryptus.skyenet.servlet

import com.simiacryptus.skyenet.webui.SessionDataStorage
import jakarta.servlet.http.HttpServlet
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.simiacryptus.skyenet.webui
package com.simiacryptus.skyenet.servlet

import com.simiacryptus.skyenet.webui.ApplicationBase
import com.simiacryptus.util.JsonUtil
import jakarta.servlet.http.HttpServlet
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse

class SettingsServlet(
val server: ApplicationServerBase,
class SessionSettingsServlet(
private val server: ApplicationBase,
) : HttpServlet() {
override fun doGet(req: HttpServletRequest, resp: HttpServletResponse) {
resp.contentType = "text/html"
Expand All @@ -18,22 +19,24 @@ class SettingsServlet(
} else {
val settings = server.getSettings<Any>(sessionId)
val json = if(settings != null) JsonUtil.toJson(settings) else ""
//language=HTML
resp.writer.write(
"""
|<html>
|<head>
|<title>Settings</title>
|</head>
|<body>
|<form action="${req.contextPath}/settings" method="post">
|<input type="hidden" name="sessionId" value="$sessionId" />
|<input type="hidden" name="action" value="save" />
|<textarea name="settings" style="width: 100%; height: 100px;">$json</textarea>
|<input type="submit" value="Save" />
|</form>
|</body>
|</html>
""".trimMargin()
|<html>
|<head>
| <title>Settings</title>
| <link rel="icon" type="image/svg+xml" href="/favicon.svg"/>
|</head>
|<body>
|<form action="${req.contextPath}/settings" method="post">
| <input type="hidden" name="sessionId" value="$sessionId"/>
| <input type="hidden" name="action" value="save"/>
| <textarea name="settings" style="width: 100%; height: 100px;">$json</textarea>
| <input type="submit" value="Save"/>
|</form>
|</body>
|</html>
""".trimMargin()
)
}
}
Expand All @@ -48,7 +51,6 @@ class SettingsServlet(
} else {
val settings = JsonUtil.fromJson<Any>(req.getParameter("settings"), server.settingsClass)
server.sessionDataStorage.updateSettings(sessionId, settings)
// Redirect back to ${req.contextPath}/#<session>
resp.sendRedirect("${req.contextPath}/#$sessionId")
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.simiacryptus.skyenet.webui
package com.simiacryptus.skyenet.servlet

import com.simiacryptus.util.JsonUtil
import jakarta.servlet.http.HttpServlet
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.simiacryptus.skyenet.servlet

import com.google.api.services.oauth2.model.Userinfo
import com.simiacryptus.util.JsonUtil
import jakarta.servlet.http.HttpServlet
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse

class UserSettingsServlet : HttpServlet() {
public override fun doGet(req: HttpServletRequest, resp: HttpServletResponse) {
resp.contentType = "text/html"
resp.status = HttpServletResponse.SC_OK
val authId = req.cookies?.firstOrNull { it.name == "sessionId" }?.value
if (null == authId) {
resp.status = HttpServletResponse.SC_BAD_REQUEST
} else {
val userinfo = AuthenticatedWebsite.users[authId]
if(null == userinfo) {
resp.status = HttpServletResponse.SC_BAD_REQUEST
} else {
val settings = getUserSettings(userinfo)
val json = if (settings != null) JsonUtil.toJson(settings) else ""
//language=HTML
resp.writer.write(
"""
|<html>
|<head>
| <title>Settings</title>
| <link rel="icon" type="image/svg+xml" href="/favicon.svg"/>
|</head>
|<body>
|<form action="/userSettings/" method="post">
| <input type="hidden" name="sessionId" value="$authId"/>
| <input type="hidden" name="action" value="save"/>
| <textarea name="settings" style="width: 100%; height: 100px;">$json</textarea>
| <input type="submit" value="Save"/>
|</form>
|</body>
|</html>
""".trimMargin()
)
}
}
}

public override fun doPost(req: HttpServletRequest, resp: HttpServletResponse) {
val userinfo = AuthenticatedWebsite.getUser(req)
if (null == userinfo) {
resp.status = HttpServletResponse.SC_BAD_REQUEST
} else {
val settings = JsonUtil.fromJson<UserSettings>(req.getParameter("settings"), UserSettings::class.java)
updateUserSettings(userinfo, settings)
resp.sendRedirect("/")
}
}

companion object {
val log = org.slf4j.LoggerFactory.getLogger(UserSettingsServlet::class.java)
private val userSettings = HashMap<String, UserSettings>()

fun getUserSettings(userinfo: Userinfo): UserSettings {
return userSettings.getOrPut(userinfo.id) {
UserSettings()
}
}

fun updateUserSettings(userinfo: Userinfo, settings: UserSettings) {
userSettings[userinfo.id] = settings
}

}
}
data class UserSettings(
val apiKey: String = "",
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.simiacryptus.skyenet.webui
package com.simiacryptus.skyenet.servlet

import com.simiacryptus.skyenet.webui.SessionDataStorage
import jakarta.servlet.http.HttpServlet
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.simiacryptus.skyenet.webui
package com.simiacryptus.skyenet.util

import org.eclipse.jetty.util.URIUtil
import org.eclipse.jetty.util.resource.Resource
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.simiacryptus.skyenet.webui
package com.simiacryptus.skyenet.util

import com.vladsch.flexmark.ext.tables.TablesExtension
import com.vladsch.flexmark.html.HtmlRenderer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.simiacryptus.skyenet.webui

import com.simiacryptus.skyenet.servlet.*
import com.simiacryptus.util.JsonUtil
import jakarta.servlet.http.HttpServlet
import jakarta.servlet.http.HttpServletRequest
Expand All @@ -10,7 +11,7 @@ import org.eclipse.jetty.webapp.WebAppContext
import org.slf4j.LoggerFactory
import java.io.File

abstract class ApplicationServerBase(
abstract class ApplicationBase(
final override val applicationName: String,
val oauthConfig: String? = null,
resourceBase: String = "simpleSession",
Expand All @@ -25,7 +26,7 @@ abstract class ApplicationServerBase(
@Suppress("UNCHECKED_CAST")
var settings: T? = sessionDataStorage.getSettings(sessionId, settingsClass as Class<T>)
if (null == settings) {
settings = initSettings<T>(sessionId)
settings = initSettings(sessionId)
if (null != settings) {
sessionDataStorage.updateSettings(sessionId, settings)
}
Expand All @@ -42,24 +43,24 @@ abstract class ApplicationServerBase(
protected open val fileZip = ServletHolder("fileZip", ZipServlet(sessionDataStorage))
protected open val fileIndex = ServletHolder("fileIndex", FileServlet(sessionDataStorage))
protected open val sessionsServlet = ServletHolder("sessionList", SessionServlet(this.sessionDataStorage))
protected open val settingsServlet = ServletHolder("settings", SettingsServlet(this))
protected open val sessionSettingsServlet = ServletHolder("settings", SessionSettingsServlet(this))

override fun configure(context: WebAppContext, prefix: String, baseURL: String) {
super.configure(context, prefix, baseURL)
override fun configure(webAppContext: WebAppContext, prefix: String, baseUrl: String) {
super.configure(webAppContext, prefix, baseUrl)

if (null != oauthConfig) (AuthenticatedWebsite(
"$baseURL/oauth2callback",
this@ApplicationServerBase.applicationName
"$baseUrl/oauth2callback",
this@ApplicationBase.applicationName
) {
FileUtils.openInputStream(File(oauthConfig))
}).configure(context)

context.addServlet(appInfo, prefix + "appInfo")
context.addServlet(userInfo, prefix + "userInfo")
context.addServlet(fileIndex, prefix + "fileIndex/*")
context.addServlet(fileZip, prefix + "fileZip")
context.addServlet(sessionsServlet, prefix + "sessions")
context.addServlet(settingsServlet, prefix + "settings")
}).configure(webAppContext)

webAppContext.addServlet(appInfo, prefix + "appInfo")
webAppContext.addServlet(userInfo, prefix + "userInfo")
webAppContext.addServlet(fileIndex, prefix + "fileIndex/*")
webAppContext.addServlet(fileZip, prefix + "fileZip")
webAppContext.addServlet(sessionsServlet, prefix + "sessions")
webAppContext.addServlet(sessionSettingsServlet, prefix + "settings")
}

inner class AppInfoServlet : HttpServlet() {
Expand All @@ -80,7 +81,7 @@ abstract class ApplicationServerBase(
protected open val userInfo = ServletHolder("userInfo", UserInfoServlet())

companion object {
val log = LoggerFactory.getLogger(ApplicationServerBase::class.java)
val log = LoggerFactory.getLogger(ApplicationBase::class.java)
val spinner =
"""<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>"""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ open class BasicChat(
oauthConfig: String? = null,
val model: OpenAIClient.Model = OpenAIClient.Models.GPT35Turbo,
val api: OpenAIClient,
) : ApplicationServerBase(
) : ApplicationBase(
applicationName = applicationName,
oauthConfig = oauthConfig,
) {
Expand Down
Loading

0 comments on commit 48123ca

Please sign in to comment.