Skip to content

Commit

Permalink
refactor(backend): better implementation to generate verbatim.
Browse files Browse the repository at this point in the history
  • Loading branch information
GerardPaligot committed Apr 15, 2024
1 parent 563968f commit 61b6f69
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import com.google.api.services.drive.Drive

interface DriveDataSource {
fun findDriveByName(name: String): String?
fun findFolderByName(driveId: String, parentId: String?, name: String): String?
fun findFileByName(driveId: String, parentId: String?, name: String): String?
fun createFolder(driveId: String, parentId: String?, name: String): String
fun copyFile(driveId: String, fileId: String, name: String): String
fun moveFile(driveId: String, fileId: String, folderId: String): List<String>
fun grantPermission(fileId: String, email: String)
fun findFolderByName(name: String, parentId: String? = null, driveId: String? = null): String?
fun findFileByName(name: String, parentId: String? = null, driveId: String? = null): String?
fun createFolder(name: String, parentId: String? = null, driveId: String? = null): String
fun copyFile(name: String, fileId: String, driveId: String? = null): String
fun moveFile(fileId: String, folderId: String): List<String>
fun grantPermission(fileId: String, email: String): String?

object Factory {
fun create(service: Drive): DriveDataSource = GoogleDriveDataSource(service)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,59 +15,67 @@ class GoogleDriveDataSource(private val service: Drive) : DriveDataSource {
return drives.drives.find { it.name == name }?.id
}

override fun findFolderByName(driveId: String, parentId: String?, name: String): String? {
override fun findFolderByName(name: String, parentId: String?, driveId: String?): String? {
return service.files().list().apply {
this.driveId = driveId
includeItemsFromAllDrives = true
supportsAllDrives = true
corpora = "drive"
if (driveId != null) {
this.driveId = driveId
includeItemsFromAllDrives = true
supportsAllDrives = true
corpora = "drive"
}
pageSize = PageSize
fields = "nextPageToken, files(id)"
this.q = "name='$name'${parentId?.let { " and parents='$parentId'" } ?: run { "" }}"
}.execute().files.firstOrNull()?.id
}

override fun findFileByName(driveId: String, parentId: String?, name: String): String? {
override fun findFileByName(name: String, parentId: String?, driveId: String?): String? {
return service.files().list().apply {
this.driveId = driveId
includeItemsFromAllDrives = true
supportsAllDrives = true
corpora = "drive"
if (driveId != null) {
this.driveId = driveId
includeItemsFromAllDrives = true
supportsAllDrives = true
corpora = "drive"
}
pageSize = PageSize
fields = "nextPageToken, files(id)"
this.q = "name='$name'${parentId?.let { " and parents='$parentId'" } ?: run { "" }}"
}.execute().files.firstOrNull()?.id
}

override fun createFolder(driveId: String, parentId: String?, name: String): String {
override fun createFolder(name: String, parentId: String?, driveId: String?): String {
val fileMetadata = File().apply {
this.name = name
mimeType = "application/vnd.google-apps.folder"
parents = listOf(driveId)
if (driveId != null) {
parents = listOf(driveId)
}
}
val folderId = service.files().create(fileMetadata).apply {
supportsAllDrives = true
fields = "id"
}.execute().id
if (parentId != null) {
moveFile(driveId, folderId, parentId)
moveFile(folderId, parentId)
}
return folderId
}

override fun copyFile(driveId: String, fileId: String, name: String): String {
override fun copyFile(name: String, fileId: String, driveId: String?): String {
val file = File().apply {
this.name = name
this.mimeType = "application/vnd.google-apps.spreadsheet"
parents = listOf(driveId)
if (driveId != null) {
parents = listOf(driveId)
}
}
return service.files().copy(fileId, file).apply {
supportsAllDrives = true
fields = "id"
}.execute().id
}

override fun moveFile(driveId: String, fileId: String, folderId: String): List<String> {
override fun moveFile(fileId: String, folderId: String): List<String> {
val file = service.files()[fileId].apply {
supportsAllDrives = true
fields = "parents"
Expand All @@ -80,11 +88,15 @@ class GoogleDriveDataSource(private val service: Drive) : DriveDataSource {
}.execute().parents
}

override fun grantPermission(fileId: String, email: String) {
val userPermission: Permission = Permission()
.setType("user")
.setRole("writer")
userPermission.setEmailAddress(email)
service.permissions().create(fileId, userPermission).setFields("id").execute()
override fun grantPermission(fileId: String, email: String): String? {
val userPermission: Permission = Permission().apply {
type = "user"
role = "writer"
emailAddress = email
}
return service.permissions().create(fileId, userPermission).apply {
supportsAllDrives = true
fields = "id"
}.execute().id
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.gdglille.devfest.backend.events.EventDao
import org.gdglille.devfest.backend.formats.FormatDao
import org.gdglille.devfest.backend.internals.helpers.drive.GoogleDriveDataSource
import org.gdglille.devfest.backend.speakers.SpeakerDao
import org.gdglille.devfest.backend.speakers.SpeakerDb
import org.gdglille.devfest.models.inputs.TalkInput
import org.gdglille.devfest.models.inputs.TalkVerbatimInput

Expand Down Expand Up @@ -71,15 +72,25 @@ class TalkRepository(
suspend fun verbatim(eventId: String, verbatim: TalkVerbatimInput) = coroutineScope {
val driveId = driveDataSource.findDriveByName(verbatim.driveName)
?: throw NotFoundException("Drive ${verbatim.driveName} doesn't exist")
val eventFolderId = driveDataSource.findFolderByName(driveId, null, verbatim.eventFolder)
val eventFolderId = driveDataSource.findFolderByName(verbatim.eventFolder, null, driveId)
?: throw NotFoundException("Folder ${verbatim.eventFolder} doesn't exist")
val targetFolderId = driveDataSource.findFolderByName(driveId, eventFolderId, verbatim.targetFolder)
val targetFolderId = driveDataSource.findFolderByName(verbatim.targetFolder, eventFolderId, driveId)
?: throw NotFoundException("Folder ${verbatim.targetFolder} doesn't exist")
val templateId = driveDataSource.findFileByName(driveId, null, verbatim.templateName)
val templateId = driveDataSource.findFileByName(verbatim.templateName, null, driveId)
?: throw NotFoundException("File ${verbatim.templateName} doesn't exist")
val talks = talkDao.getAll(eventId)
val speakers = speakerDao.getAll(eventId)
val asyncVerbatims = talks.map { talkDb ->
async { verbatimByTalk(eventId, talkDb.id, driveId, targetFolderId, templateId) }
async {
verbatimByTalk(
targetFolderId = targetFolderId,
talkId = talkDb.id,
talkTitle = talkDb.title,
speakers = speakers.filter { talkDb.speakerIds.contains(it.id) },
driveId = driveId,
templateId = templateId
)
}
}
return@coroutineScope asyncVerbatims.awaitAll()
}
Expand All @@ -91,37 +102,34 @@ class TalkRepository(
) = coroutineScope {
val driveId = driveDataSource.findDriveByName(verbatim.driveName)
?: throw NotFoundException("Drive ${verbatim.driveName} doesn't exist")
val eventFolderId = driveDataSource.findFolderByName(driveId, null, verbatim.eventFolder)
val eventFolderId = driveDataSource.findFolderByName(verbatim.eventFolder, null, driveId)
?: throw NotFoundException("Folder ${verbatim.eventFolder} doesn't exist")
val targetFolderId = driveDataSource.findFolderByName(driveId, eventFolderId, verbatim.targetFolder)
val targetFolderId = driveDataSource.findFolderByName(verbatim.targetFolder, eventFolderId, driveId)
?: throw NotFoundException("Folder ${verbatim.targetFolder} doesn't exist")
val templateId = driveDataSource.findFileByName(driveId, null, verbatim.templateName)
val templateId = driveDataSource.findFileByName(verbatim.templateName, null, driveId)
?: throw NotFoundException("File ${verbatim.templateName} doesn't exist")
return@coroutineScope verbatimByTalk(eventId, talkId, driveId, targetFolderId, templateId)
val talkDb = talkDao.get(eventId, talkId)
?: throw NotFoundException("Talk $talkId doesn't exist")
val speakers = speakerDao.getByIds(eventId, talkDb.speakerIds)
return@coroutineScope verbatimByTalk(targetFolderId, talkId, talkDb.title, speakers, driveId, templateId)
}

@Suppress("LongParameterList")
private suspend fun verbatimByTalk(
eventId: String,
targetFolderId: String,
talkId: String,
talkTitle: String,
speakers: List<SpeakerDb>,
driveId: String,
targetFolderId: String,
templateId: String
) = coroutineScope {
val talkDb = talkDao.get(eventId, talkId)
?: throw NotFoundException("Talk $talkId doesn't exist")
val emailSpeakers = speakerDao.getByIds(eventId, talkDb.speakerIds)
.filter { it.email != null }
.map { it.email!! }
val emailSpeakers = speakers.filter { it.email != null }.map { it.email!! }
if (emailSpeakers.isEmpty()) {
throw NotFoundException("No speakers in talk $talkId")
}
val talkFolderId = driveDataSource.findFolderByName(driveId, targetFolderId, talkDb.title)
if (talkFolderId != null) {
return@coroutineScope talkFolderId
}
val fileId = driveDataSource.copyFile(driveId, templateId, "Verbatims")
val folderId = driveDataSource.createFolder(driveId, targetFolderId, talkDb.title)
driveDataSource.moveFile(driveId, fileId, folderId)
val folderId = driveDataSource.createFolder(talkTitle, targetFolderId, driveId)
val fileId = driveDataSource.copyFile("Verbatims", templateId, driveId)
driveDataSource.moveFile(fileId, folderId)
emailSpeakers.forEach { driveDataSource.grantPermission(fileId = folderId, email = it) }
return@coroutineScope folderId
}
Expand Down

0 comments on commit 61b6f69

Please sign in to comment.