From d7ee5ea76fb3b21e648d272c6ddaa4aed3762582 Mon Sep 17 00:00:00 2001 From: Andrew Charneski Date: Mon, 9 Sep 2024 08:21:45 -0400 Subject: [PATCH] 1.6.1 (#183) * 1.6.1 * Update PDFExtractorAction.kt * wip * wip --- build.gradle.kts | 4 +- .../MarkdownImplementActionGroup.review.md | 15 +--- gradle.properties | 2 +- .../generic/DocumentDataExtractorAction.kt | 80 +++++++++++++++++++ .../DocumentDataExtractorConfigDialog.kt | 67 ++++++++++++++++ .../simiacryptus/aicoder/util/UITools.kt | 7 ++ .../jopenai/exceptions/CustomException.kt | 3 - src/main/resources/META-INF/plugin.xml | 6 ++ 8 files changed, 167 insertions(+), 17 deletions(-) create mode 100644 src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentDataExtractorAction.kt create mode 100644 src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentDataExtractorConfigDialog.kt delete mode 100644 src/main/kotlin/com/simiacryptus/jopenai/exceptions/CustomException.kt diff --git a/build.gradle.kts b/build.gradle.kts index de2c0eaa..39395120 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,7 +25,7 @@ version = properties("pluginVersion") val kotlin_version = "2.0.0-Beta5" // This line can be removed if not used elsewhere val jetty_version = "11.0.18" val slf4j_version = "2.0.9" -val skyenet_version = "1.2.0" +val skyenet_version = "1.2.1" val remoterobot_version = "0.11.21" val jackson_version = "2.17.0" @@ -40,7 +40,7 @@ dependencies { exclude(group = "org.jetbrains.kotlin", module = "") } - implementation(group = "com.simiacryptus", name = "jo-penai", version = "1.1.0") + implementation(group = "com.simiacryptus", name = "jo-penai", version = "1.1.1") { exclude(group = "org.jetbrains.kotlin", module = "") } diff --git a/docs/src/main/kotlin/com/github/simiacryptus/aicoder/actions/markdown/MarkdownImplementActionGroup.review.md b/docs/src/main/kotlin/com/github/simiacryptus/aicoder/actions/markdown/MarkdownImplementActionGroup.review.md index 1e1807f6..8c204561 100644 --- a/docs/src/main/kotlin/com/github/simiacryptus/aicoder/actions/markdown/MarkdownImplementActionGroup.review.md +++ b/docs/src/main/kotlin/com/github/simiacryptus/aicoder/actions/markdown/MarkdownImplementActionGroup.review.md @@ -12,35 +12,28 @@ This code defines a Kotlin class `MarkdownImplementActionGroup` which extends `A ## Specific Issues and Recommendations -1. Unused Import - - Severity: ๐Ÿ˜Š Minor - - Type: ๐Ÿงน Cleanup - - Description: The import `com.simiacryptus.jopenai.exceptions.CustomException` is not used in the code. - - Recommendation: Remove the unused import to keep the code clean. - - File: MarkdownImplementActionGroup.kt, line 1-25 (import section) - -2. Hardcoded Language List +1. Hardcoded Language List - Severity: ๐Ÿ˜ Moderate - Type: ๐Ÿ’ก Idea - Description: The list of supported languages is hardcoded in the `markdownLanguages` property. - Recommendation: Consider moving this list to a configuration file or a separate object to make it more maintainable and easily extensible. - File: MarkdownImplementActionGroup.kt, lines 27-31 -3. Commented Out Code +2. Commented Out Code - Severity: ๐Ÿ˜Š Minor - Type: ๐Ÿงน Cleanup - Description: There is commented out code in the `processSelection` method. - Recommendation: Remove the commented out code (`/*escapeHtml4*/` and `/*.indent(" ")*/`) if it's no longer needed. - File: MarkdownImplementActionGroup.kt, line 93 -4. Error Handling +3. Error Handling - Severity: ๐Ÿ˜ Moderate - Type: ๐Ÿ› Bug - Description: There's no explicit error handling for the API call in the `processSelection` method. - Recommendation: Add try-catch blocks to handle potential exceptions from the API call and provide appropriate error messages to the user. - File: MarkdownImplementActionGroup.kt, line 89 -5. Magic Numbers +4. Magic Numbers - Severity: ๐Ÿ˜Š Minor - Type: ๐Ÿงน Cleanup - Description: The `deserializerRetries` parameter in the `getProxy` method is set to a magic number (5). diff --git a/gradle.properties b/gradle.properties index d711b0df..82db46b2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ pluginName=intellij-aicoder pluginRepositoryUrl=https://github.com/SimiaCryptus/intellij-aicoder -pluginVersion=1.6.0 +pluginVersion=1.6.1 jvmArgs=-Xmx8g org.gradle.jvmargs=-Xmx8g diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentDataExtractorAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentDataExtractorAction.kt new file mode 100644 index 00000000..fdce3818 --- /dev/null +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentDataExtractorAction.kt @@ -0,0 +1,80 @@ +package com.github.simiacryptus.aicoder.actions.generic + +import com.github.simiacryptus.aicoder.AppServer +import com.github.simiacryptus.aicoder.actions.BaseAction +import com.github.simiacryptus.aicoder.util.UITools +import com.intellij.openapi.actionSystem.ActionUpdateThread +import com.intellij.openapi.actionSystem.AnActionEvent +import com.simiacryptus.skyenet.apps.general.DocumentParserApp +import com.simiacryptus.skyenet.core.platform.StorageInterface +import com.simiacryptus.skyenet.core.platform.file.DataStorage +import org.slf4j.LoggerFactory +import java.awt.Desktop +import com.intellij.openapi.ui.DialogWrapper +import com.simiacryptus.skyenet.core.platform.Session +import java.io.File + +class DocumentDataExtractorAction : BaseAction() { + val path = "/pdfExtractor" + private var settings = DocumentParserApp.Settings() + + override fun getActionUpdateThread() = ActionUpdateThread.BGT + + override fun isEnabled(event: AnActionEvent): Boolean { + if(!super.isEnabled(event)) return false + val selectedFile = UITools.getSelectedFile(event) + return selectedFile != null && ( + selectedFile.name.endsWith(".pdf", ignoreCase = true) || + selectedFile.name.endsWith(".txt", ignoreCase = true) || + selectedFile.name.endsWith(".md", ignoreCase = true) || + selectedFile.name.endsWith(".html", ignoreCase = true) + ) + } + + override fun handle(e: AnActionEvent) { + val selectedFile = UITools.getSelectedFile(e) + if (selectedFile == null || (!selectedFile.name.endsWith( + ".pdf", + ignoreCase = true + ) && !selectedFile.name.endsWith(".txt", ignoreCase = true)) + ) { + UITools.showErrorDialog(e.project, "Please select a PDF or text file.", "Invalid Selection") + return + } + val configDialog = DocumentDataExtractorConfigDialog(e.project, settings) + if (!configDialog.showAndGet()) return + settings = configDialog.settings + + + val session = StorageInterface.newGlobalID() + val pdfFile = selectedFile.toFile + DataStorage.sessionPaths[session] = pdfFile.parentFile + + val documentParserApp = object : DocumentParserApp( + applicationName = "Document Extractor", + path = path, + api = api, + fileInput = pdfFile.toPath(), + ) { + override fun initSettings(session: Session): T = settings as T + override val root: File get() = selectedFile.parent.toFile + } + + SessionProxyServer.chats[session] = documentParserApp + val server = AppServer.getServer(e.project) + Thread { + Thread.sleep(500) + try { + val uri = server.server.uri.resolve("/#$session") + BaseAction.log.info("Opening browser to $uri") + Desktop.getDesktop().browse(uri) + } catch (e: Throwable) { + BaseAction.log.warn("Error opening browser", e) + } + }.start() + } + + companion object { + private val log = LoggerFactory.getLogger(DocumentDataExtractorAction::class.java) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentDataExtractorConfigDialog.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentDataExtractorConfigDialog.kt new file mode 100644 index 00000000..c6a1bbfd --- /dev/null +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentDataExtractorConfigDialog.kt @@ -0,0 +1,67 @@ +package com.github.simiacryptus.aicoder.actions.generic + +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.DialogWrapper +import com.intellij.ui.components.JBCheckBox +import com.intellij.ui.components.JBTextField +import com.simiacryptus.skyenet.apps.general.DocumentParserApp +import javax.swing.* + +class DocumentDataExtractorConfigDialog( + project: Project?, + var settings: DocumentParserApp.Settings +) : DialogWrapper(project) { + + private val dpiField = JBTextField(settings.dpi.toString()) + private val maxPagesField = JBTextField(settings.maxPages.toString()) + private val outputFormatField = JBTextField(settings.outputFormat) + private val pagesPerBatchField = JBTextField(settings.pagesPerBatch.toString()) + private val showImagesCheckbox = JBCheckBox("Show Images", settings.showImages) + private val saveImageFilesCheckbox = JBCheckBox("Save Image Files", settings.saveImageFiles) + private val saveTextFilesCheckbox = JBCheckBox("Save Text Files", settings.saveTextFiles) + private val saveFinalJsonCheckbox = JBCheckBox("Save Final JSON", settings.saveFinalJson) + + init { + init() + title = "Configure Document Data Extractor" + } + + override fun createCenterPanel(): JComponent { + val panel = JPanel() + panel.layout = BoxLayout(panel, BoxLayout.Y_AXIS) + + panel.add(createLabeledField("DPI:", dpiField)) + panel.add(createLabeledField("Max Pages:", maxPagesField)) + panel.add(createLabeledField("Output Format:", outputFormatField)) + panel.add(createLabeledField("Pages Per Batch:", pagesPerBatchField)) + panel.add(showImagesCheckbox) + panel.add(saveImageFilesCheckbox) + panel.add(saveTextFilesCheckbox) + panel.add(saveFinalJsonCheckbox) + + return panel + } + + private fun createLabeledField(label: String, field: JComponent): JPanel { + val panel = JPanel() + panel.layout = BoxLayout(panel, BoxLayout.X_AXIS) + panel.add(JLabel(label)) + panel.add(Box.createHorizontalStrut(10)) + panel.add(field) + return panel + } + + override fun doOKAction() { + settings = DocumentParserApp.Settings( + dpi = dpiField.text.toFloatOrNull() ?: settings.dpi, + maxPages = maxPagesField.text.toIntOrNull() ?: settings.maxPages, + outputFormat = outputFormatField.text, + pagesPerBatch = pagesPerBatchField.text.toIntOrNull() ?: settings.pagesPerBatch, + showImages = showImagesCheckbox.isSelected, + saveImageFiles = saveImageFilesCheckbox.isSelected, + saveTextFiles = saveTextFilesCheckbox.isSelected, + saveFinalJson = saveFinalJsonCheckbox.isSelected + ) + super.doOKAction() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/util/UITools.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/util/UITools.kt index 1e925bdb..a2999f28 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/util/UITools.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/util/UITools.kt @@ -979,5 +979,12 @@ object UITools { return if (value == JOptionPane.UNINITIALIZED_VALUE) null else value } + fun showErrorDialog(project: Project?, errorMessage: String, subMessage: String) { + val formBuilder = FormBuilder.createFormBuilder() + formBuilder.addLabeledComponent("Error", JLabel(errorMessage)) + formBuilder.addLabeledComponent("Details", JLabel(subMessage)) + showOptionDialog(formBuilder.panel, "Dismiss", title = "Error", modal = true) + } + } diff --git a/src/main/kotlin/com/simiacryptus/jopenai/exceptions/CustomException.kt b/src/main/kotlin/com/simiacryptus/jopenai/exceptions/CustomException.kt deleted file mode 100644 index e77a3191..00000000 --- a/src/main/kotlin/com/simiacryptus/jopenai/exceptions/CustomException.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.simiacryptus.jopenai.exceptions - -class CustomException(message: String) : Exception(message) \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 717def1f..5853797d 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -112,6 +112,12 @@ + + +