Skip to content

Commit

Permalink
feat: init downloader for marketplace #86
Browse files Browse the repository at this point in the history
  • Loading branch information
phodal committed Sep 14, 2024
1 parent 4269591 commit 9aaa430
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import com.intellij.util.ui.ColumnInfo
import com.intellij.util.ui.ListTableModel
import com.phodal.shire.ShireIdeaIcons
import com.phodal.shire.ShireMainBundle
import com.phodal.shirecore.ShirelangNotifications
import java.awt.BorderLayout
import java.awt.Component
import javax.swing.JPanel
Expand Down Expand Up @@ -86,7 +85,7 @@ class ShirePackageTableComponent(val project: Project) {
return object : IconButtonTableCellEditor(item, ShireIdeaIcons.Download, "Download") {
init {
myButton.addActionListener {
ShirelangNotifications.info(project, "Downloading ${item.name}")
ShireDownloader.downloadAndUnzip(project, item)
fireEditingStopped()
}
}
Expand Down Expand Up @@ -121,9 +120,13 @@ class ShirePackageTableComponent(val project: Project) {

// Create a list to store the row data
val dataList = listOf(
ShirePackage("Plugin 1", "A useful plugin", "1.0", "Author A", "https://shire.run/"),
ShirePackage("Plugin 2", "Another great plugin", "2.1", "B", "https://shire.run/"),
ShirePackage("Plugin 3", "Yet another plugin", "3.0", "B", "https://shire.run/")
ShirePackage(
"基础 AI 辅助编程",
"基础 AI 编码能力包:自动化单测、提交信息生成、代码重构、AI 终端命令生成、Java 注释生成。",
"TODO",
"Phodal Huang",
"https://static.shire.run/package/basic-assistant.zip"
),
)

init {
Expand Down
76 changes: 76 additions & 0 deletions src/main/kotlin/com/phodal/shire/marketplace/ShireDownloader.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.phodal.shire.marketplace

import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectBundle
import com.intellij.openapi.project.guessProjectDir
import com.intellij.openapi.projectRoots.impl.jdkDownloader.JdkInstaller
import com.intellij.openapi.util.NlsContexts
import com.intellij.openapi.vfs.VirtualFileManager
import com.phodal.shire.ShireMainBundle
import com.phodal.shirecore.ShirelangNotifications
import java.io.BufferedInputStream
import java.io.FileOutputStream
import java.net.URL
import java.nio.file.Files
import java.nio.file.Paths
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream

object ShireDownloader {
fun downloadAndUnzip(project: Project, item: ShirePackage) {
ShirelangNotifications.info(project, "Downloading ${item.name}")
computeInBackground(project, ShireMainBundle.message("downloading.item", item.name)) {
val dir = project.guessProjectDir()!!
val targetPath = Paths.get(dir.path, ".")

val zipFile = Files.createTempFile("temp_download", ".zip")
downloadFile(item.url, zipFile.toString())

unzipFile(zipFile.toString(), targetPath.toString())

WriteCommandAction.runWriteCommandAction(null) {
VirtualFileManager.getInstance().syncRefresh()
}
}

ShirelangNotifications.info(project, "Downloaded ${item.name}")
}

private fun downloadFile(downloadUrl: String, outputFilePath: String) {
URL(downloadUrl).openStream().use { inputStream ->
Files.newOutputStream(Paths.get(outputFilePath)).use { outputStream ->
inputStream.copyTo(outputStream)
}
}
}

private fun unzipFile(zipFilePath: String, targetDirPath: String) {
ZipInputStream(BufferedInputStream(Files.newInputStream(Paths.get(zipFilePath)))).use { zis ->
var entry: ZipEntry?
while (zis.nextEntry.also { entry = it } != null) {
val filePath = Paths.get(targetDirPath, entry!!.name)
if (entry!!.isDirectory) {
Files.createDirectories(filePath)
} else {
Files.createDirectories(filePath.parent)
FileOutputStream(filePath.toFile()).use { outputStream ->
zis.copyTo(outputStream)
}
}
}
}
}

private inline fun <T : Any?> computeInBackground(
project: Project?,
@NlsContexts.DialogTitle title: String,
crossinline action: (ProgressIndicator) -> T,
): T =
ProgressManager.getInstance().run(object : Task.WithResult<T, Exception>(project, title, true) {
override fun compute(indicator: ProgressIndicator) = action(indicator)
})
}
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/shire-main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<projectService serviceImplementation="com.phodal.shire.marketplace.MarketPlaceView" client="all"/>
<toolWindow id="Shire MarketPlace"
anchor="left" icon="com.phodal.shire.ShireIdeaIcons.Default"
factoryClass="com.phodal.shire.marketplace.MarketplaceToolWindowFactory" canCloseContents="true"/>
factoryClass="com.phodal.shire.marketplace.MarketplaceToolWindowFactory"/>
</extensions>

<extensions defaultExtensionNs="com.phodal">
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/messages/ShireMainBundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ marketplace.action.installing=Installing
marketplace.dialog.installAction=Install Action
marketplace.column.author=Author
marketplace.column.action=Action
marketplace.action.install=Install
marketplace.action.install=Install
downloading.item=Downloading

0 comments on commit 9aaa430

Please sign in to comment.