Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bookmarks #1087

Merged
merged 1 commit into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions service/src/commonMain/kotlin/androidmakers/service/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import androidmakers.service.context.maxAge
import com.apollographql.apollo3.api.ExecutionContext
import com.apollographql.apollo3.execution.ExecutableSchema
import com.apollographql.apollo3.execution.ktor.respondGraphQL
import com.google.auth.oauth2.GoogleCredentials
import com.google.cloud.datastore.DatastoreOptions
import com.google.firebase.auth.FirebaseAuthException
import io.ktor.http.*
import io.ktor.server.application.*
Expand Down Expand Up @@ -42,10 +44,12 @@ fun main(@Suppress("UNUSED_PARAMETER") args: Array<String>) {
Sessionize.importAndroidMakers2024()
}
}

embeddedServer(Netty, port = System.getenv("POST")?.toIntOrNull() ?: 8080) {
install(CORS) {
anyHost()
allowNonSimpleContentTypes = true
allowHeader("Authorization")
}

routing {
Expand All @@ -64,6 +68,9 @@ fun main(@Suppress("UNUSED_PARAMETER") args: Array<String>) {
}.start(wait = true)
}

val datastore = DatastoreOptions.newBuilder()
.setCredentials(GoogleCredentials.getApplicationDefault()).build().service

private suspend fun PipelineContext<Unit, ApplicationCall>.apolloCall(executableSchema: ExecutableSchema) {
val context = call.context()
call.respondGraphQL(executableSchema, context) {
Expand All @@ -89,11 +96,12 @@ private fun ApplicationCall.firebaseUid(): String? {
request.headers.get("authorization")
?.substring("Bearer ".length)
?.firebaseUid()
} catch (e: FirebaseAuthException) {
} catch (e: Exception) {
e.printStackTrace()
throw e
}
}

private fun ApplicationCall.context(): ExecutionContext {
return AuthenticationContext(firebaseUid()) + DatastoreContext() + CacheControlContext()
return AuthenticationContext(firebaseUid()) + DatastoreContext(datastore) + CacheControlContext()
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
package androidmakers.service.context

import androidmakers.service.graphql.KIND_BOOKMARKS
import com.apollographql.apollo3.api.ExecutionContext
import com.google.auth.oauth2.GoogleCredentials
import com.google.cloud.datastore.Datastore
import com.google.cloud.datastore.DatastoreOptions
import com.google.cloud.datastore.KeyFactory

class DatastoreContext: ExecutionContext.Element {
private var datastore: Datastore? = null

@Synchronized
fun datastore(): Datastore {
if (datastore == null) {
datastore = DatastoreOptions.newBuilder()
.setCredentials(GoogleCredentials.getApplicationDefault()).build().service
}
return datastore!!
}
class DatastoreContext(val datastore: Datastore): ExecutionContext.Element {
val bookmarksKeyFactory = datastore.newKeyFactory().setKind(KIND_BOOKMARKS)

companion object Key: ExecutionContext.Key<DatastoreContext>

override val key: ExecutionContext.Key<DatastoreContext>
get() = Key
}

internal fun ExecutionContext.datastore(): Datastore = get(DatastoreContext)!!.datastore()
internal fun ExecutionContext.datastore(): Datastore = get(DatastoreContext)!!.datastore
internal fun ExecutionContext.bookmarksKeyFactory(): KeyFactory = get(DatastoreContext)!!.bookmarksKeyFactory
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@
package androidmakers.service.graphql

import androidmakers.service.Sessionize
import androidmakers.service.context.bookmarksKeyFactory
import androidmakers.service.context.datastore
import androidmakers.service.context.uid
import androidmakers.service.context.updateMaxAge
import com.apollographql.apollo3.annotations.*
import com.apollographql.apollo3.api.ExecutionContext
import com.apollographql.apollo3.ast.GQLStringValue
import com.apollographql.apollo3.ast.GQLValue
import com.apollographql.apollo3.execution.Coercing
import com.apollographql.apollo3.execution.internal.ExternalValue
import com.google.cloud.datastore.BooleanValue
import com.google.cloud.datastore.Entity
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime

const val KIND_BOOKMARKS = "Bookmarks"

@GraphQLMutationRoot
class RootMutation {
Expand All @@ -27,10 +23,13 @@ class RootMutation {
"bookmarks require authentication"
}

if (Sessionize.data.get().sessions.none { it.id == sessionId }) {
throw Error("Cannot add bookmark for inexisting session '$sessionId'")
}

val datastore = executionContext.datastore()
val keyFactory = datastore.newKeyFactory()

val key = keyFactory.newKey(uid)
val key = executionContext.bookmarksKeyFactory().newKey(uid)
val entity = datastore.get(key)
val entityBuilder = if (entity == null) {
Entity.newBuilder(key)!!
Expand Down Expand Up @@ -60,9 +59,8 @@ class RootMutation {
}

val datastore = executionContext.datastore()
val keyFactory = datastore.newKeyFactory()

val key = keyFactory.newKey(uid)
val key = executionContext.bookmarksKeyFactory().newKey(uid)
val entity = datastore.get(key)
if (entity == null) {
return BookmarkConnection(emptyList())
Expand Down Expand Up @@ -90,9 +88,8 @@ class RootMutation {
}

val datastore = executionContext.datastore()
val keyFactory = datastore.newKeyFactory()

val key = keyFactory.newKey(uid)
val key = executionContext.bookmarksKeyFactory().newKey(uid)
datastore.delete(key)

return true
Expand Down Expand Up @@ -158,7 +155,7 @@ class RootQuery {
}

@Deprecated("Use speakersPage instead")
fun speakers(dfe: ExecutionContext): List<Speaker> {
fun speakers(): List<Speaker> {
return Sessionize.data.get().speakers
}

Expand Down Expand Up @@ -202,9 +199,8 @@ class RootQuery {
}

val datastore = executionContext.datastore()
val keyFactory = datastore.newKeyFactory()

val key = keyFactory.newKey(uid)
val key = executionContext.bookmarksKeyFactory().newKey(uid)
val entity = datastore.get(key)
if (entity == null) {
return BookmarkConnection(emptyList())
Expand Down Expand Up @@ -318,11 +314,11 @@ data class Session(
val type: String,
val links: List<Link>
): Node {
fun speakers(dfe: ExecutionContext): List<Speaker> {
fun speakers(): List<Speaker> {
return Sessionize.data.get().speakers.filter { speakerIds.contains(it.id) }
}

fun room(dfe: ExecutionContext): Room? {
fun room(): Room? {
val roomId = roomIds.firstOrNull()
if (roomId == null) {
return null
Expand All @@ -332,7 +328,7 @@ data class Session(
}
}

fun rooms(dfe: ExecutionContext): List<Room> {
fun rooms(): List<Room> {
return Sessionize.data.get().rooms.filter {
roomIds.contains(it.id)
}
Expand All @@ -357,9 +353,7 @@ data class Speaker(
val photoUrlThumbnail: String?,
private val sessionIds: List<String>,
): Node {
fun sessions(
dfe: ExecutionContext,
): List<Session> {
fun sessions(): List<Session> {
return Sessionize.data.get().sessions.filter {
sessionIds.contains(it.id)
}
Expand Down
Loading