From 47eb0d4836f36dcae632ebe2ff6f74d701cbff17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=B1=B6=E6=B3=BD?= Date: Fri, 10 Sep 2021 14:33:57 +0800 Subject: [PATCH] Update version:: 1.3-SNAPSHOT
  • Add aliyun OSS support
  • Minimum supported version 2019.3
  • Upload dialog style adjustment
  • --- build.gradle.kts | 5 +- .../design/MISConfigurationInterfaceForm.form | 213 +++++++++++++++--- .../design/MISConfigurationInterfaceForm.java | 22 +- .../design/MISPreUploadImageConfirmForm.form | 45 +++- .../design/MISPreUploadImageConfirmForm.java | 1 + .../action/MISDeleteImageIntentionAction.kt | 14 +- .../action/MISPreUploadImageConfirmDialog.kt | 53 +++-- .../jetbrains/plugin/mis/config/MISConfig.kt | 37 +++ .../plugin/mis/config/MISConfigView.kt | 103 ++++++++- .../mis/filestore/MISAliyunOSSFileStore.kt | 43 ---- .../mis/filestore/MISFileStoreFactory.kt | 6 +- .../mis/filestore/MISTencentOSSFileStore.kt | 42 ---- .../filestore/impl/MISAbstractOSSFileStore.kt | 43 ++++ .../filestore/impl/MISAliyunOSSFileStore.kt | 73 ++++++ .../filestore/{ => impl}/MISLocalFileStore.kt | 20 +- .../filestore/{ => impl}/MISQiniuFileStore.kt | 73 ++---- .../jetbrains/plugin/mis/toolkit/Consts.kt | 2 - src/main/resources/META-INF/plugin.xml | 17 +- .../description.html | 38 ---- 19 files changed, 576 insertions(+), 274 deletions(-) delete mode 100644 src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISAliyunOSSFileStore.kt delete mode 100644 src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISTencentOSSFileStore.kt create mode 100644 src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISAbstractOSSFileStore.kt create mode 100644 src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISAliyunOSSFileStore.kt rename src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/{ => impl}/MISLocalFileStore.kt (83%) rename src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/{ => impl}/MISQiniuFileStore.kt (63%) delete mode 100644 src/main/resources/intentionDescriptions/MISDeleteImageIntentionAction/description.html diff --git a/build.gradle.kts b/build.gradle.kts index 6d99a0e..1e216cc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,7 +29,7 @@ plugins { } group = "com.github.wenzewoo.jetbrains.plugin" -version = "1.2-SNAPSHOT" +version = "1.3-SNAPSHOT" repositories { mavenCentral() @@ -39,11 +39,12 @@ dependencies { implementation(kotlin("stdlib-jdk8")) compile("net.coobird", "thumbnailator", "0.4.8") compile("com.qiniu", "qiniu-java-sdk", "7.2.28") + compile("com.aliyun.oss", "aliyun-sdk-oss", "3.13.0") } // See https://github.com/JetBrains/gradle-intellij-plugin/ intellij { - version = "IC-2018.3" + version = "IC-2019.3" updateSinceUntilBuild = false } configure { diff --git a/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISConfigurationInterfaceForm.form b/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISConfigurationInterfaceForm.form index 5bc53e8..2dd347c 100644 --- a/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISConfigurationInterfaceForm.form +++ b/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISConfigurationInterfaceForm.form @@ -58,6 +58,7 @@ + @@ -250,7 +251,9 @@ - + + + @@ -258,7 +261,9 @@ - + + + @@ -274,8 +279,8 @@ - + @@ -414,58 +419,198 @@ - + - + - + - + - + - - - - - - - - - - - + - + - + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISConfigurationInterfaceForm.java b/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISConfigurationInterfaceForm.java index 887d75c..362e533 100644 --- a/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISConfigurationInterfaceForm.java +++ b/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISConfigurationInterfaceForm.java @@ -51,10 +51,22 @@ public class MISConfigurationInterfaceForm { protected JTextField textQiniuStyleSuffix; protected JButton buttonTestQiniu; protected final JRadioButton[] radioQiniuBucketZones = { // - this.radioQiniuBucketZoneEastChina, // - this.radioQiniuBucketZoneNorthChina, // - this.radioQiniuBucketZoneSouthChina, // - this.radioQiniuBucketZoneNorthAmerica, // - this.radioQiniuBucketZoneSoutheastAsia// + this.radioQiniuBucketZoneEastChina, // + this.radioQiniuBucketZoneNorthChina, // + this.radioQiniuBucketZoneSouthChina, // + this.radioQiniuBucketZoneNorthAmerica, // + this.radioQiniuBucketZoneSoutheastAsia// }; + + + // aliyun oss config + protected JCheckBox checkAliyunEnable; + protected JTextField textAliyunBucket; + protected JTextField textAliyunAccessKey; + protected JTextField textAliyunSecretKey; + protected JTextField textAliyunEndpoint; + protected JComboBox comboAliyunNewFilenameTemplate; + protected JTextField textAliyunNewFilenameCustomText; + protected JTextField textAliyunStyleSuffix; + protected JButton buttonTestAliyun; } diff --git a/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISPreUploadImageConfirmForm.form b/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISPreUploadImageConfirmForm.form index 0d49a2a..2a2586e 100644 --- a/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISPreUploadImageConfirmForm.form +++ b/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISPreUploadImageConfirmForm.form @@ -1,16 +1,16 @@
    - + - + - + @@ -18,7 +18,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -36,7 +36,7 @@ - + @@ -46,7 +46,7 @@ - + @@ -76,7 +76,7 @@ - + @@ -84,7 +84,7 @@ - + @@ -93,7 +93,7 @@ - + @@ -101,7 +101,7 @@ - + @@ -111,6 +111,29 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISPreUploadImageConfirmForm.java b/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISPreUploadImageConfirmForm.java index 44c76e5..70768ba 100644 --- a/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISPreUploadImageConfirmForm.java +++ b/src/main/java/com/github/wenzewoo/jetbrains/plugin/mis/design/MISPreUploadImageConfirmForm.java @@ -31,4 +31,5 @@ public class MISPreUploadImageConfirmForm extends JDialog { protected JTextField textMarkdownTitle; protected JButton buttonOk; protected JButton buttonCancel; + protected JLabel labelTitle; } diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/action/MISDeleteImageIntentionAction.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/action/MISDeleteImageIntentionAction.kt index 884a220..9765d7e 100644 --- a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/action/MISDeleteImageIntentionAction.kt +++ b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/action/MISDeleteImageIntentionAction.kt @@ -40,6 +40,7 @@ import com.intellij.psi.PsiElement import java.io.File import javax.swing.SwingWorker +@Suppress("IntentionDescriptionNotFoundInspection") class MISDeleteImageIntentionAction : PsiElementBaseIntentionAction() { override fun getFamilyName(): String { return this.text @@ -50,9 +51,9 @@ class MISDeleteImageIntentionAction : PsiElementBaseIntentionAction() { } override fun isAvailable(project: Project, editor: Editor?, element: PsiElement): Boolean { - return Toolkits.isMarkdownImageMark( + return Toolkits.isMarkdownFile(editor) && Toolkits.isMarkdownImageMark( Toolkits.getCurrentLineStringWithEditor(editor) - ) && Toolkits.isMarkdownFile(editor) + ) } override fun invoke(project: Project, editor: Editor?, element: PsiElement) { @@ -72,8 +73,7 @@ class DeleteImageSwingWorker( ) : SwingWorker() { override fun doInBackground(): Boolean { val state = MISConfigService.getInstance().state!! - - // local delete + // local return if (!markdownUrl.startsWith("http", true)) { val fromFile = (editor as EditorEx).virtualFile MISFileStoreFactory.of(Consts.FileStoreLocal).delete( @@ -81,9 +81,13 @@ class DeleteImageSwingWorker( markdownUrl ) } - // qiniu delete + // qiniu else if (state.qiniuEnabled && markdownUrl.contains(state.qiniuDomain)) { MISFileStoreFactory.of(Consts.FileStoreQiniu).delete(null, markdownUrl) + } + // aliyun oss + else if (state.aliyunEnabled && markdownUrl.contains(state.aliyunEndpoint)) { + MISFileStoreFactory.of(Consts.FileStoreAliyunOSS).delete(null, markdownUrl) } else { false } diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/action/MISPreUploadImageConfirmDialog.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/action/MISPreUploadImageConfirmDialog.kt index b02825d..06ffe97 100644 --- a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/action/MISPreUploadImageConfirmDialog.kt +++ b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/action/MISPreUploadImageConfirmDialog.kt @@ -48,6 +48,7 @@ class MISPreUploadImageConfirmDialog( init { this.isModal = true + this.isUndecorated = true this.contentPane = this.dialogPanel this.rootPane.defaultButton = this.buttonOk this.defaultCloseOperation = WindowConstants.DO_NOTHING_ON_CLOSE @@ -77,6 +78,9 @@ class MISPreUploadImageConfirmDialog( if (it.qiniuEnabled) { this.comboUploadTo.addItem(Consts.FileStoreQiniu) } + if (it.aliyunEnabled) { + this.comboUploadTo.addItem(Consts.FileStoreAliyunOSS) + } this.comboUploadTo.selectedItem = it.currentUploadTo } @@ -98,7 +102,7 @@ class MISPreUploadImageConfirmDialog( this.textMarkdownTitle.text = this.imageFile?.name ?: "" this.isResizable = false - this.title = "Upload Image: ${this.imageFile?.name ?: "with Clipboard"}" + this.labelTitle.text = this.imageFile?.name ?: "with Clipboard" this.pack() this.setLocationRelativeTo(null) this.isVisible = true @@ -106,29 +110,38 @@ class MISPreUploadImageConfirmDialog( private fun setSaveAsValueWithUploadToAndImageType() { MISConfigService.getInstance().state?.let { - val uploadTo = this.comboUploadTo.selectedItem?.toString()!! // init local - if (uploadTo == Consts.FileStoreLocal) { - val path = if (it.localFileSavePathTemplate != Consts.CustomFlag) { - this.replaceVariable(it.localFileSavePathTemplate) - } else { - this.replaceVariable(it.localFileSavePathCustomText) - } + when (this.comboUploadTo.selectedItem?.toString()!!) { + Consts.FileStoreLocal -> { + val path = if (it.localFileSavePathTemplate != Consts.CustomFlag) { + this.replaceVariable(it.localFileSavePathTemplate) + } else { + this.replaceVariable(it.localFileSavePathCustomText) + } - val filename = if (it.localFileNewFilenameTemplate != Consts.CustomFlag) { - this.replaceVariable(it.localFileNewFilenameTemplate) - } else { - this.replaceVariable(it.localFileNewFilenameCustomText) + val filename = if (it.localFileNewFilenameTemplate != Consts.CustomFlag) { + this.replaceVariable(it.localFileNewFilenameTemplate) + } else { + this.replaceVariable(it.localFileNewFilenameCustomText) + } + this.textSaveAs.text = "${path}${filename}" } - this.textSaveAs.text = "${path}${filename}" - } - // init qiniu - else if (uploadTo == Consts.FileStoreQiniu) { - this.textSaveAs.text = if (it.qiniuNewFilenameTemplate != Consts.CustomFlag) { - this.replaceVariable(it.qiniuNewFilenameTemplate) - } else { - this.replaceVariable(it.qiniuNewFilenameCustomText) + // init qiniu + Consts.FileStoreQiniu -> { + this.textSaveAs.text = if (it.qiniuNewFilenameTemplate != Consts.CustomFlag) { + this.replaceVariable(it.qiniuNewFilenameTemplate) + } else { + this.replaceVariable(it.qiniuNewFilenameCustomText) + } + } + // init aliyun oss + Consts.FileStoreAliyunOSS -> { + this.textSaveAs.text = if (it.aliyunNewFilenameTemplate != Consts.CustomFlag) { + this.replaceVariable(it.aliyunNewFilenameTemplate) + } else { + this.replaceVariable(it.aliyunNewFilenameCustomText) + } } } } diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/config/MISConfig.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/config/MISConfig.kt index 5dd21dc..904be58 100644 --- a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/config/MISConfig.kt +++ b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/config/MISConfig.kt @@ -49,6 +49,17 @@ class MISConfig { var qiniuNewFilenameCustomText: String = "" + // aliyun oss + var aliyunEnabled: Boolean = false + var aliyunBucket: String = "" + var aliyunAccessKey: String = "" + var aliyunSecretKey: String = "" + var aliyunEndpoint: String = "" + var aliyunStyleSuffix: String? = "" + var aliyunNewFilenameTemplate: String = "" + var aliyunNewFilenameCustomText: String = "" + + var currentUploadTo = Consts.FileStoreLocal @@ -95,6 +106,32 @@ class MISConfig { } } } + + // valid aliyun oss + if (this.aliyunEnabled) { + if (this.aliyunBucket.isEmpty()) { + this.aliyunEnabled = false + return "Please set aliyun oss bucket" + } + if (this.aliyunAccessKey.isEmpty()) { + this.aliyunEnabled = false + return "Please set aliyun oss accessKey" + } + if (this.aliyunSecretKey.isEmpty()) { + this.aliyunEnabled = false + return "Please set aliyun oss secretKey" + } + if (this.aliyunEndpoint.isEmpty()) { + this.aliyunEnabled = false + return "Please set aliyun oss endpoint" + } + if (this.aliyunNewFilenameTemplate == Consts.CustomFlag) { + if (this.aliyunNewFilenameCustomText.isEmpty()) { + this.aliyunEnabled = false + return "Please set aliyun oss new filename" + } + } + } return null } } diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/config/MISConfigView.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/config/MISConfigView.kt index 9d55623..b0df1dc 100644 --- a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/config/MISConfigView.kt +++ b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/config/MISConfigView.kt @@ -22,6 +22,8 @@ * SOFTWARE. */ +@file:Suppress("DuplicatedCode") + package com.github.wenzewoo.jetbrains.plugin.mis.config import com.github.wenzewoo.jetbrains.plugin.mis.design.MISConfigurationInterfaceForm @@ -46,6 +48,7 @@ class MISConfigView : MISConfigurationInterfaceForm(), SearchableConfigurable, C this.initializationComponentsListener() } + @Suppress("DuplicatedCode") private fun initializationComponentsValue() { MISConfigService.getInstance().state?.let { // local @@ -66,12 +69,24 @@ class MISConfigView : MISConfigurationInterfaceForm(), SearchableConfigurable, C this.textQiniuNewFilenameCustomText.text = it.qiniuNewFilenameCustomText this.textQiniuStyleSuffix.text = it.qiniuStyleSuffix this.selectRadioWithQiniuBucketZone(it.qiniuBucketZone) + + + // aliyun oss + this.checkAliyunEnable.isSelected = it.aliyunEnabled + this.textAliyunBucket.text = it.aliyunBucket + this.textAliyunAccessKey.text = it.aliyunAccessKey + this.textAliyunSecretKey.text = it.aliyunSecretKey + this.textAliyunEndpoint.text = it.aliyunEndpoint + this.comboAliyunNewFilenameTemplate.selectedItem = it.aliyunNewFilenameTemplate + this.textAliyunNewFilenameCustomText.text = it.aliyunNewFilenameCustomText + this.textAliyunStyleSuffix.text = it.aliyunStyleSuffix } } private fun initializationComponentsListener() { this.initializationComponentsListenerWithLocal() this.initializationComponentsListenerWithQiniu() + this.initializationComponentsListenerWithAliyun() } private fun initializationComponentsListenerWithQiniu() { @@ -129,6 +144,50 @@ class MISConfigView : MISConfigurationInterfaceForm(), SearchableConfigurable, C } } + private fun initializationComponentsListenerWithAliyun() { + // newFileName 联动效果 + this.textAliyunNewFilenameCustomText.isVisible = + this.comboAliyunNewFilenameTemplate.selectedItem?.toString() == Consts.CustomFlag + this.comboAliyunNewFilenameTemplate.addItemListener { + this.textAliyunNewFilenameCustomText.isVisible = it.item.toString() == Consts.CustomFlag + if (this.textAliyunNewFilenameCustomText.isVisible) { + this.textAliyunNewFilenameCustomText.requestFocus() + } + } + + // checkAliyunEnable & components 联动效果 + val components: Array = arrayOf( + this.textAliyunBucket, + this.textAliyunAccessKey, + this.textAliyunSecretKey, + this.textAliyunEndpoint, + this.comboAliyunNewFilenameTemplate, + this.textAliyunNewFilenameCustomText, + this.textAliyunStyleSuffix, + this.buttonTestAliyun + ) + this.batchSetComponentEnabled(this.checkAliyunEnable.isSelected, *components) + this.checkAliyunEnable.addActionListener { + MISConfigService.getInstance().state?.let { state -> + state.aliyunEnabled = this.checkAliyunEnable.isSelected + } + this.batchSetComponentEnabled(this.checkAliyunEnable.isSelected, *components) + } + + this.buttonTestAliyun.addActionListener { + // save config + this.apply() + + // test connection + val message = if (MISFileStoreFactory.of(Consts.FileStoreAliyunOSS).test()) { + "Successful." + } else { + "Upload fail, Please check the configuration." + } + Messages.showInfoMessage(message, "Test Result") + } + } + private fun selectRadioWithQiniuBucketZone(index: Int) { if (index in 0..4) { MISConfigService.getInstance().state?.let { @@ -196,9 +255,10 @@ class MISConfigView : MISConfigurationInterfaceForm(), SearchableConfigurable, C override fun isModified(): Boolean { val state = MISConfigService.getInstance().state!! - return this.isModifiedWithLocal(state) || this.isModifiedWithQiniu(state) + return this.isModifiedWithLocal(state) || this.isModifiedWithQiniu(state) || this.isModifiedWithAliyun(state) } + @Suppress("DuplicatedCode") private fun isModifiedWithQiniu(state: MISConfig): Boolean { return this.batchNotEqualsWithAny( arrayOf( @@ -224,6 +284,32 @@ class MISConfigView : MISConfigurationInterfaceForm(), SearchableConfigurable, C ) } + @Suppress("DuplicatedCode") + private fun isModifiedWithAliyun(state: MISConfig): Boolean { + return this.batchNotEqualsWithAny( + arrayOf( + state.aliyunEnabled, + state.aliyunBucket, + state.aliyunAccessKey, + state.aliyunSecretKey, + state.aliyunEndpoint, + state.aliyunNewFilenameTemplate, + state.aliyunNewFilenameCustomText, + state.aliyunStyleSuffix + ), + arrayOf( + this.checkAliyunEnable.isSelected, + this.textAliyunBucket.text, + this.textAliyunAccessKey.text, + this.textAliyunSecretKey.text, + this.textAliyunEndpoint.text, + this.comboAliyunNewFilenameTemplate.selectedItem, + this.textAliyunNewFilenameCustomText.text, + this.textAliyunStyleSuffix.text + ) + ) + } + private fun isModifiedWithLocal(state: MISConfig): Boolean { return this.batchNotEqualsWithAny( arrayOf( @@ -262,7 +348,7 @@ class MISConfigView : MISConfigurationInterfaceForm(), SearchableConfigurable, C MISConfigService.getInstance().state?.let { // save local - it.localFileEnabled = this.checkLocalFileEnable.isEnabled + it.localFileEnabled = this.checkLocalFileEnable.isSelected it.localFileSavePathTemplate = this.comboLocalFileSavePathTemplate.selectedItem?.toString()!! it.localFileSavePathCustomText = this.textLocalFileSavePathCustomText.text it.localFileNewFilenameTemplate = this.comboLocalFileNewFilenameTemplate.selectedItem?.toString()!! @@ -271,7 +357,7 @@ class MISConfigView : MISConfigurationInterfaceForm(), SearchableConfigurable, C // save qiniu - it.qiniuEnabled = this.checkQiniuEnable.isEnabled + it.qiniuEnabled = this.checkQiniuEnable.isSelected it.qiniuBucket = this.textQiniuBucket.text it.qiniuAccessKey = this.textQiniuAccessKey.text it.qiniuSecretKey = this.textQiniuSecretKey.text @@ -280,6 +366,17 @@ class MISConfigView : MISConfigurationInterfaceForm(), SearchableConfigurable, C it.qiniuNewFilenameCustomText = this.textQiniuNewFilenameCustomText.text it.qiniuStyleSuffix = this.textQiniuStyleSuffix.text + + // save aliyun oss + it.aliyunEnabled = this.checkAliyunEnable.isSelected + it.aliyunBucket = this.textAliyunBucket.text + it.aliyunAccessKey = this.textAliyunAccessKey.text + it.aliyunSecretKey = this.textAliyunSecretKey.text + it.aliyunEndpoint = this.textAliyunEndpoint.text + it.aliyunNewFilenameTemplate = this.comboAliyunNewFilenameTemplate.selectedItem?.toString()!! + it.aliyunNewFilenameCustomText = this.textAliyunNewFilenameCustomText.text + it.aliyunStyleSuffix = this.textAliyunStyleSuffix.text + it.validMessage()?.let { message -> Messages.showErrorDialog(message, "Save Error"); } diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISAliyunOSSFileStore.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISAliyunOSSFileStore.kt deleted file mode 100644 index 7129183..0000000 --- a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISAliyunOSSFileStore.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 吴汶泽 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.github.wenzewoo.jetbrains.plugin.mis.filestore - -import com.github.wenzewoo.jetbrains.plugin.mis.entity.ImageWrapper -import java.io.File - -class MISAliyunOSSFileStore : MISFileStore { - override fun test(): Boolean { - TODO("Not yet implemented") - } - - override fun write(imageWrapper: ImageWrapper, saveAs: String): String { - TODO("Not yet implemented") - } - - override fun delete(localFile: File?, markdownUrl: String): Boolean { - TODO("Not yet implemented") - } - -} diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISFileStoreFactory.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISFileStoreFactory.kt index f80aa76..09bb215 100644 --- a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISFileStoreFactory.kt +++ b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISFileStoreFactory.kt @@ -24,6 +24,9 @@ package com.github.wenzewoo.jetbrains.plugin.mis.filestore +import com.github.wenzewoo.jetbrains.plugin.mis.filestore.impl.MISAliyunOSSFileStore +import com.github.wenzewoo.jetbrains.plugin.mis.filestore.impl.MISLocalFileStore +import com.github.wenzewoo.jetbrains.plugin.mis.filestore.impl.MISQiniuFileStore import com.github.wenzewoo.jetbrains.plugin.mis.toolkit.Consts @@ -39,9 +42,6 @@ object MISFileStoreFactory { Consts.FileStoreAliyunOSS -> { MISAliyunOSSFileStore() } - Consts.FileStoreTencentOSS -> { - MISTencentOSSFileStore() - } else -> MISLocalFileStore() } } diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISTencentOSSFileStore.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISTencentOSSFileStore.kt deleted file mode 100644 index d93e243..0000000 --- a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISTencentOSSFileStore.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 吴汶泽 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.github.wenzewoo.jetbrains.plugin.mis.filestore - -import com.github.wenzewoo.jetbrains.plugin.mis.entity.ImageWrapper -import java.io.File - -class MISTencentOSSFileStore : MISFileStore { - override fun test(): Boolean { - TODO("Not yet implemented") - } - - override fun write(imageWrapper: ImageWrapper, saveAs: String): String { - TODO("Not yet implemented") - } - - override fun delete(localFile: File?, markdownUrl: String): Boolean { - TODO("Not yet implemented") - } -} diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISAbstractOSSFileStore.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISAbstractOSSFileStore.kt new file mode 100644 index 0000000..7074c58 --- /dev/null +++ b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISAbstractOSSFileStore.kt @@ -0,0 +1,43 @@ +package com.github.wenzewoo.jetbrains.plugin.mis.filestore.impl + +import com.github.wenzewoo.jetbrains.plugin.mis.entity.ImageWrapper +import java.io.ByteArrayOutputStream +import java.io.FileInputStream +import java.nio.charset.Charset +import javax.imageio.ImageIO + +abstract class MISAbstractOSSFileStore : MISLocalFileStore() { + + override fun test(): Boolean { + val fileKey = "MarkdownImageSupportValid${System.currentTimeMillis()}.txt" + val fileContent = "Test upload with ${System.currentTimeMillis()}".toByteArray(Charset.defaultCharset()) + return if (this.upload(fileContent, fileKey, true)) { + this.delete(null, this.previewUrl(fileKey)) + } else false + } + + override fun write(imageWrapper: ImageWrapper, saveAs: String): String { + return try { + val saveAsSuffix = saveAs.substring(saveAs.lastIndexOf(".") + 1) + val byteArray: ByteArray = if (null != imageWrapper.imageFile) { + // Read pictures bytes + FileInputStream(imageWrapper.imageFile!!).readBytes() + } else { + // Generate pictures + val out = ByteArrayOutputStream() + ImageIO.write(imageWrapper.image, saveAsSuffix, out) + out.toByteArray() + } + if (this.upload(byteArray, saveAs, false)) { + return this.previewUrl(saveAs, true) + } + "Upload to oss error" + } catch (e: Throwable) { + "Upload to oss error:${e.message}" + } + } + + abstract fun upload(byteArray: ByteArray, fileKey: String, check: Boolean): Boolean + + abstract fun previewUrl(fileKey: String, styleSuffix: Boolean = true): String +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISAliyunOSSFileStore.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISAliyunOSSFileStore.kt new file mode 100644 index 0000000..2f9a7c8 --- /dev/null +++ b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISAliyunOSSFileStore.kt @@ -0,0 +1,73 @@ +/* + * MIT License + * + * Copyright (c) 2020 吴汶泽 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.github.wenzewoo.jetbrains.plugin.mis.filestore.impl + +import com.aliyun.oss.OSSClientBuilder +import com.github.wenzewoo.jetbrains.plugin.mis.config.MISConfigService +import java.io.File +import java.net.HttpURLConnection +import java.net.URL + +class MISAliyunOSSFileStore : MISAbstractOSSFileStore() { + private val state = MISConfigService.getInstance().state!! + private val ossClient = OSSClientBuilder().build(state.aliyunEndpoint, state.aliyunAccessKey, state.aliyunSecretKey) + + + @Suppress("HttpUrlsUsage") + override fun delete(localFile: File?, markdownUrl: String): Boolean { + var fileKey = markdownUrl.replace("https://${state.aliyunBucket}.${state.aliyunEndpoint}", "") + .replace("http://${state.aliyunBucket}.${state.aliyunEndpoint}", "") + .replace(state.aliyunStyleSuffix ?: "", "") + if (fileKey.startsWith("/")) { + fileKey = fileKey.substring(1) + } + + return try { + ossClient.deleteObject(state.aliyunBucket, fileKey) + true + } catch (e: Throwable) { + false + } + } + + override fun upload(byteArray: ByteArray, fileKey: String, check: Boolean): Boolean { + return try { + ossClient.putObject(state.aliyunBucket, fileKey, byteArray.inputStream()) + if (check) { + val url = URL(this.previewUrl(fileKey, false)) + val conn = url.openConnection() as HttpURLConnection + return conn.responseCode == 200 || conn.responseCode == 304 + } + true + } catch (e: Throwable) { + false + } + } + + override fun previewUrl(fileKey: String, styleSuffix: Boolean): String { + return "https://${state.aliyunBucket}.${state.aliyunEndpoint}/${fileKey}${if (styleSuffix) state.aliyunStyleSuffix else ""}" + } + +} diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISLocalFileStore.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISLocalFileStore.kt similarity index 83% rename from src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISLocalFileStore.kt rename to src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISLocalFileStore.kt index 2e27f4a..d9ca95e 100644 --- a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISLocalFileStore.kt +++ b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISLocalFileStore.kt @@ -22,24 +22,30 @@ * SOFTWARE. */ -package com.github.wenzewoo.jetbrains.plugin.mis.filestore +package com.github.wenzewoo.jetbrains.plugin.mis.filestore.impl import com.github.wenzewoo.jetbrains.plugin.mis.config.MISConfigService import com.github.wenzewoo.jetbrains.plugin.mis.entity.ImageWrapper +import com.github.wenzewoo.jetbrains.plugin.mis.filestore.MISFileStore import com.github.wenzewoo.jetbrains.plugin.mis.toolkit.Toolkits import com.intellij.openapi.util.io.FileUtil import java.io.File import java.io.FileOutputStream import javax.imageio.ImageIO -class MISLocalFileStore : MISFileStore { +open class MISLocalFileStore : MISFileStore { override fun test(): Boolean { return true } override fun write(imageWrapper: ImageWrapper, saveAs: String): String { // create new empty file - val saveAsFile = File(saveAs.replaceFirst(".", imageWrapper.fromFile.parent.toString().replace("file://", ""))) + val saveAsFile = File( + saveAs.replaceFirst( + ".", + imageWrapper.fromFile.parent.toString().replace("file://", "") + ) + ) FileUtil.createIfDoesntExist(saveAsFile) val saveAsSuffix = Toolkits.getFileSuffix(saveAsFile); @@ -52,10 +58,10 @@ class MISLocalFileStore : MISFileStore { FileUtil.copy(imageWrapper.imageFile!!, saveAsFile) } else { // Generate pictures - val out = FileOutputStream(saveAsFile) - ImageIO.write(imageWrapper.image, saveAsSuffix, out) - out.flush() - out.close() + FileOutputStream(saveAsFile).use { + ImageIO.write(imageWrapper.image, saveAsSuffix, it) + it.flush() + } } } return saveAs diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISQiniuFileStore.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISQiniuFileStore.kt similarity index 63% rename from src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISQiniuFileStore.kt rename to src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISQiniuFileStore.kt index 6641e89..0831a4b 100644 --- a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/MISQiniuFileStore.kt +++ b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/filestore/impl/MISQiniuFileStore.kt @@ -22,65 +22,39 @@ * SOFTWARE. */ -package com.github.wenzewoo.jetbrains.plugin.mis.filestore +package com.github.wenzewoo.jetbrains.plugin.mis.filestore.impl import com.github.wenzewoo.jetbrains.plugin.mis.config.MISConfigService -import com.github.wenzewoo.jetbrains.plugin.mis.entity.ImageWrapper import com.qiniu.common.Zone import com.qiniu.storage.BucketManager import com.qiniu.storage.Configuration import com.qiniu.storage.UploadManager import com.qiniu.util.Auth -import com.qiniu.util.IOUtils -import java.io.ByteArrayOutputStream import java.io.File -import java.io.FileInputStream -import java.io.InputStream import java.net.HttpURLConnection import java.net.URL -import javax.imageio.ImageIO -class MISQiniuFileStore : MISFileStore { - private val testFileName = "favicon.png" +class MISQiniuFileStore : MISAbstractOSSFileStore() { private val state = MISConfigService.getInstance().state!! - override fun test(): Boolean { - val inputStream: InputStream = this.javaClass.getResourceAsStream("/${testFileName}") - val testFileKey = "MarkdownImageSupportTest-${System.currentTimeMillis()}-${testFileName}" - return this.upload(IOUtils.toByteArray(inputStream), testFileKey, true) - } - - override fun write(imageWrapper: ImageWrapper, saveAs: String): String { - return try { - val saveAsSuffix = saveAs.substring(saveAs.lastIndexOf(".") + 1) - val byteArray: ByteArray = if (null != imageWrapper.imageFile) { - // Read pictures bytes - FileInputStream(imageWrapper.imageFile!!).readBytes() - } else { - // Generate pictures - val out = ByteArrayOutputStream() - ImageIO.write(imageWrapper.image, saveAsSuffix, out) - out.toByteArray() - } - if (this.upload(byteArray, saveAs, false)) { - return this.buildPreviewUrl(saveAs) - } - "Upload to qiniu error" - } catch (e: Throwable) { - "Upload to qiniu error:${e.message}" - } - } - override fun delete(localFile: File?, markdownUrl: String): Boolean { var fileKey = markdownUrl.replace(state.qiniuDomain, "").replace(state.qiniuStyleSuffix ?: "", "") if (fileKey.startsWith("/")) { fileKey = fileKey.substring(1) } - return this.delete(fileKey) + return try { + val cfg = Configuration(getZone()) + val auth = Auth.create(state.qiniuAccessKey, state.qiniuSecretKey) + val bucketManager = BucketManager(auth, cfg) + val response = bucketManager.delete(state.qiniuBucket, fileKey) + return response.isOK + } catch (e: Throwable) { + false + } } - private fun upload(byteArray: ByteArray, fileKey: String, check: Boolean): Boolean { + override fun upload(byteArray: ByteArray, fileKey: String, check: Boolean): Boolean { return try { val cfg = Configuration(getZone()) val uploadManager = UploadManager(cfg) @@ -91,7 +65,7 @@ class MISQiniuFileStore : MISFileStore { ) if (response.isOK && null != response.jsonToMap()["key"]) { if (check) { - val url = URL(this.buildPreviewUrl(fileKey)) + val url = URL(this.previewUrl(fileKey, false)) val conn = url.openConnection() as HttpURLConnection return conn.responseCode == 200 || conn.responseCode == 304 } @@ -103,25 +77,8 @@ class MISQiniuFileStore : MISFileStore { } } - private fun delete(fileKey: String): Boolean { - return try { - val cfg = Configuration(getZone()) - val auth = Auth.create(state.qiniuAccessKey, state.qiniuSecretKey) - val bucketManager = BucketManager(auth, cfg) - val response = bucketManager.delete(state.qiniuBucket, fileKey) - return response.isOK - } catch (e: Throwable) { - false - } - } - - private fun buildPreviewUrl(fileKey: String): String { - return "${state.qiniuDomain}${ - if (!state.qiniuDomain.endsWith("/")) { - "/" - } else { - "" - }}${fileKey}${state.qiniuStyleSuffix}" + override fun previewUrl(fileKey: String, styleSuffix: Boolean): String { + return "${state.qiniuDomain}${if (!state.qiniuDomain.endsWith("/")) "/" else ""}${fileKey}${if (styleSuffix) state.qiniuStyleSuffix else ""}" } private fun getZone(): Zone { diff --git a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/toolkit/Consts.kt b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/toolkit/Consts.kt index bc9d0c2..fa4a58e 100644 --- a/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/toolkit/Consts.kt +++ b/src/main/kotlin/com/github/wenzewoo/jetbrains/plugin/mis/toolkit/Consts.kt @@ -29,6 +29,4 @@ object Consts { const val FileStoreLocal = "Local" const val FileStoreQiniu = "Qiniu" const val FileStoreAliyunOSS = "AliyunOSS" - const val FileStoreTencentOSS = "TencentOSS" - val FileStoreList = arrayOf(FileStoreLocal, FileStoreQiniu, FileStoreAliyunOSS, FileStoreTencentOSS) } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 98a5d0d..a43ca3e 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -66,6 +66,21 @@ ]]> 1.3-SNAPSHOT:2021/09/10

    +
      +
    • Fix issues#1
    • +
    • Add aliyun OSS support
    • +
    • Minimum supported version 2019.3
    • +
    • Upload dialog style adjustment
    • +
    +
      +
    • Fix issues#1
    • +
    • 增加阿里云OSS支持
    • +
    • 最低支持版本2019.3
    • +
    • 上传Dialog样式调整
    • +
    +
    +

    1.2-SNAPSHOT:2020/04/14

    • Fix null pointer exception
    • @@ -93,7 +108,7 @@
    ]]>
    - + com.intellij.modules.lang diff --git a/src/main/resources/intentionDescriptions/MISDeleteImageIntentionAction/description.html b/src/main/resources/intentionDescriptions/MISDeleteImageIntentionAction/description.html deleted file mode 100644 index 923b8d6..0000000 --- a/src/main/resources/intentionDescriptions/MISDeleteImageIntentionAction/description.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - -

    Write your description here. - Start the description with a verb in 3rd person singular, like reports, detects, highlights. - In the first sentence, briefly explain what exactly the inspection helps you detect. - Make sure the sentence is not very long and complicated. - The first sentence must be in a dedicated paragraph separated from the rest of the text. This will make the - description easier to read. - Make sure the description doesn’t just repeat the inspection title. -

    - -

    Text after this comment will only be shown in the settings of the inspection.

    - -