Skip to content

Commit

Permalink
Add install plugin/theme api
Browse files Browse the repository at this point in the history
  • Loading branch information
qianlifeng committed Nov 27, 2023
1 parent f3cf58a commit f0cd7b2
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 29 deletions.
40 changes: 23 additions & 17 deletions Wox/plugin/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type storeManifest struct {
Url string
}

type storePluginManifest struct {
type StorePluginManifest struct {
Id string
Name string
Author string
Expand All @@ -38,7 +38,7 @@ var storeInstance *Store
var storeOnce sync.Once

type Store struct {
pluginManifests []storePluginManifest
pluginManifests []StorePluginManifest
}

func GetStoreManager() *Store {
Expand Down Expand Up @@ -71,8 +71,8 @@ func (s *Store) Start(ctx context.Context) {
})
}

func (s *Store) GetStorePluginManifests(ctx context.Context) []storePluginManifest {
var storePluginManifests []storePluginManifest
func (s *Store) GetStorePluginManifests(ctx context.Context) []StorePluginManifest {
var storePluginManifests []StorePluginManifest

for _, store := range s.getStoreManifests(ctx) {
pluginManifest, manifestErr := s.GetStorePluginManifest(ctx, store)
Expand All @@ -82,7 +82,7 @@ func (s *Store) GetStorePluginManifests(ctx context.Context) []storePluginManife
}

for _, manifest := range pluginManifest {
existingManifest, found := lo.Find(storePluginManifests, func(manifest storePluginManifest) bool {
existingManifest, found := lo.Find(storePluginManifests, func(manifest StorePluginManifest) bool {
return manifest.Id == manifest.Id
})
if found {
Expand All @@ -104,15 +104,15 @@ func (s *Store) GetStorePluginManifests(ctx context.Context) []storePluginManife
return storePluginManifests
}

func (s *Store) GetStorePluginManifest(ctx context.Context, store storeManifest) ([]storePluginManifest, error) {
func (s *Store) GetStorePluginManifest(ctx context.Context, store storeManifest) ([]StorePluginManifest, error) {
logger.Info(ctx, fmt.Sprintf("start to get plugin manifest from %s(%s)", store.Name, store.Url))

response, getErr := util.HttpGet(ctx, store.Url)
if getErr != nil {
return nil, getErr
}

var storePluginManifests []storePluginManifest
var storePluginManifests []StorePluginManifest
unmarshalErr := json.Unmarshal(response, &storePluginManifests)
if unmarshalErr != nil {
return nil, unmarshalErr
Expand All @@ -121,13 +121,13 @@ func (s *Store) GetStorePluginManifest(ctx context.Context, store storeManifest)
return storePluginManifests, nil
}

func (s *Store) Search(ctx context.Context, keyword string) []storePluginManifest {
return lo.Filter(s.pluginManifests, func(manifest storePluginManifest, _ int) bool {
func (s *Store) Search(ctx context.Context, keyword string) []StorePluginManifest {
return lo.Filter(s.pluginManifests, func(manifest StorePluginManifest, _ int) bool {
return util.IsStringMatch(manifest.Name, keyword, false)
})
}

func (s *Store) Install(ctx context.Context, manifest storePluginManifest) {
func (s *Store) Install(ctx context.Context, manifest StorePluginManifest) error {
logger.Info(ctx, fmt.Sprintf("start to install plugin %s(%s)", manifest.Name, manifest.Version))

// check if installed newer version
Expand All @@ -141,14 +141,14 @@ func (s *Store) Install(ctx context.Context, manifest storePluginManifest) {
if installedErr == nil && currentErr == nil {
if installedVersion.GreaterThan(currentVersion) {
logger.Info(ctx, fmt.Sprintf("skip %s(%s) from %s store, because it's already installed(%s)", manifest.Name, manifest.Version, manifest.Name, installedPlugin.Metadata.Version))
return
return fmt.Errorf("skip %s(%s) from %s store, because it's already installed(%s)", manifest.Name, manifest.Version, manifest.Name, installedPlugin.Metadata.Version)
}
}

uninstallErr := s.Uninstall(ctx, installedPlugin)
if uninstallErr != nil {
logger.Error(ctx, fmt.Sprintf("failed to uninstall plugin %s(%s): %s", installedPlugin.Metadata.Name, installedPlugin.Metadata.Version, uninstallErr.Error()))
return
return fmt.Errorf("failed to uninstall plugin %s(%s): %s", installedPlugin.Metadata.Name, installedPlugin.Metadata.Version, uninstallErr.Error())
}
}

Expand All @@ -158,33 +158,39 @@ func (s *Store) Install(ctx context.Context, manifest storePluginManifest) {
directoryErr := util.GetLocation().EnsureDirectoryExist(pluginDirectory)
if directoryErr != nil {
logger.Error(ctx, fmt.Sprintf("failed to create plugin directory %s: %s", pluginDirectory, directoryErr.Error()))
return
return fmt.Errorf("failed to create plugin directory %s: %s", pluginDirectory, directoryErr.Error())
}
pluginZipPath := path.Join(pluginDirectory, "plugin.zip")
downloadErr := util.HttpDownload(ctx, manifest.DownloadUrl, pluginZipPath)
if downloadErr != nil {
logger.Error(ctx, fmt.Sprintf("failed to download plugin %s(%s): %s", manifest.Name, manifest.Version, downloadErr.Error()))
return
return fmt.Errorf("failed to download plugin %s(%s): %s", manifest.Name, manifest.Version, downloadErr.Error())
}

//unzip plugin
logger.Info(ctx, fmt.Sprintf("start to unzip plugin %s(%s)", manifest.Name, manifest.Version))
util.Unzip(pluginZipPath, pluginDirectory)
unzipErr := util.Unzip(pluginZipPath, pluginDirectory)
if unzipErr != nil {
logger.Error(ctx, fmt.Sprintf("failed to unzip plugin %s(%s): %s", manifest.Name, manifest.Version, unzipErr.Error()))
return fmt.Errorf("failed to unzip plugin %s(%s): %s", manifest.Name, manifest.Version, unzipErr.Error())
}

//load plugin
logger.Info(ctx, fmt.Sprintf("start to load plugin %s(%s)", manifest.Name, manifest.Version))
loadErr := GetPluginManager().LoadPlugin(ctx, pluginDirectory)
if loadErr != nil {
logger.Error(ctx, fmt.Sprintf("failed to load plugin %s(%s): %s", manifest.Name, manifest.Version, loadErr.Error()))
return
return fmt.Errorf("failed to load plugin %s(%s): %s", manifest.Name, manifest.Version, loadErr.Error())
}

//remove plugin zip
removeErr := os.Remove(pluginZipPath)
if removeErr != nil {
logger.Error(ctx, fmt.Sprintf("failed to remove plugin zip %s: %s", pluginZipPath, removeErr.Error()))
return
return fmt.Errorf("failed to remove plugin zip %s: %s", pluginZipPath, removeErr.Error())
}

return nil
}

func (s *Store) Uninstall(ctx context.Context, plugin *Instance) error {
Expand Down
15 changes: 9 additions & 6 deletions Wox/ui/dto/theme_dto.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package dto

type Theme struct {
ThemeId string
ThemeName string
ThemeAuthor string
ThemeUrl string
IsSystemTheme bool
ThemeId string
ThemeName string
ThemeAuthor string
ThemeUrl string
Version string
IsInstalled bool
IsSystem bool
IsUpgradable bool

AppBackgroundColor string
AppPaddingLeft int
AppPaddingTop int
Expand Down Expand Up @@ -46,5 +50,4 @@ type Theme struct {
PreviewSplitLineColor string
PreviewPropertyTitleColor string
PreviewPropertyContentColor string
IsInstalled bool
}
120 changes: 120 additions & 0 deletions Wox/ui/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,66 @@ func serveAndWait(ctx context.Context, port int) {
writeSuccessResponse(w, plugins)
})

http.HandleFunc("/plugin/install", func(w http.ResponseWriter, r *http.Request) {
enableCors(w)

pluginId := r.URL.Query().Get("id")
if pluginId == "" {
writeErrorResponse(w, "plugin id is empty")
return
}

plugins := plugin.GetStoreManager().GetStorePluginManifests(ctx)
findPlugin, exist := lo.Find(plugins, func(item plugin.StorePluginManifest) bool {
if item.Id == pluginId {
return true
}
return false
})
if !exist {
writeErrorResponse(w, "can't find plugin in the store")
return
}

installErr := plugin.GetStoreManager().Install(ctx, findPlugin)
if installErr != nil {
writeErrorResponse(w, "can't install plugin: "+installErr.Error())
return
}

writeSuccessResponse(w, "")
})

http.HandleFunc("/plugin/uninstall", func(w http.ResponseWriter, r *http.Request) {
enableCors(w)

pluginId := r.URL.Query().Get("id")
if pluginId == "" {
writeErrorResponse(w, "plugin id is empty")
return
}

plugins := plugin.GetPluginManager().GetPluginInstances()
findPlugin, exist := lo.Find(plugins, func(item *plugin.Instance) bool {
if item.Metadata.Id == pluginId {
return true
}
return false
})
if !exist {
writeErrorResponse(w, "can't find plugin")
return
}

uninstallErr := plugin.GetStoreManager().Uninstall(ctx, findPlugin)
if uninstallErr != nil {
writeErrorResponse(w, "can't uninstall plugin: "+uninstallErr.Error())
return
}

writeSuccessResponse(w, "")
})

http.HandleFunc("/theme/store", func(w http.ResponseWriter, r *http.Request) {
enableCors(w)
storeThemes := GetStoreManager().GetThemes()
Expand Down Expand Up @@ -240,6 +300,66 @@ func serveAndWait(ctx context.Context, port int) {
writeSuccessResponse(w, themes)
})

http.HandleFunc("/theme/install", func(w http.ResponseWriter, r *http.Request) {
enableCors(w)

themeId := r.URL.Query().Get("id")
if themeId == "" {
writeErrorResponse(w, "theme id is empty")
return
}

storeThemes := GetStoreManager().GetThemes()
findTheme, exist := lo.Find(storeThemes, func(item Theme) bool {
if item.ThemeId == themeId {
return true
}
return false
})
if !exist {
writeErrorResponse(w, "can't find theme in theme store")
return
}

installErr := GetStoreManager().Install(ctx, findTheme)
if installErr != nil {
writeErrorResponse(w, "can't install theme: "+installErr.Error())
return
}

writeSuccessResponse(w, "")
})

http.HandleFunc("/theme/uninstall", func(w http.ResponseWriter, r *http.Request) {
enableCors(w)

themeId := r.URL.Query().Get("id")
if themeId == "" {
writeErrorResponse(w, "theme id is empty")
return
}

storeThemes := GetUIManager().GetAllThemes(ctx)
findTheme, exist := lo.Find(storeThemes, func(item Theme) bool {
if item.ThemeId == themeId {
return true
}
return false
})
if !exist {
writeErrorResponse(w, "can't find theme")
return
}

uninstallErr := GetStoreManager().Uninstall(ctx, findTheme)
if uninstallErr != nil {
writeErrorResponse(w, "can't uninstall theme: "+uninstallErr.Error())
return
}

writeSuccessResponse(w, "")
})

http.HandleFunc("/setting/wox", func(w http.ResponseWriter, r *http.Request) {
enableCors(w)

Expand Down
7 changes: 7 additions & 0 deletions Wox/ui/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/google/uuid"
"github.com/samber/lo"
"os"
"path"
"sync"
Expand All @@ -29,6 +30,7 @@ type Manager struct {
serverPort int
uiProcess *os.Process
themes *util.HashMap[string, Theme]
systemThemeIds []string
}

func GetUIManager() *Manager {
Expand All @@ -53,6 +55,7 @@ func (m *Manager) Start(ctx context.Context) error {
continue
}
m.themes.Store(theme.ThemeId, theme)
m.systemThemeIds = append(m.systemThemeIds, theme.ThemeId)
}

//load user themes
Expand Down Expand Up @@ -328,3 +331,7 @@ func (m *Manager) PostAppStart(ctx context.Context) {
m.ui.ShowApp(ctx, share.ShowContext{SelectAll: false})
}
}

func (m *Manager) IsSystemTheme(id string) bool {
return lo.Contains(m.systemThemeIds, id)
}
2 changes: 1 addition & 1 deletion Wox/ui/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (s *Store) Install(ctx context.Context, theme Theme) error {
}

func (s *Store) Uninstall(ctx context.Context, theme Theme) error {
if theme.IsSystemTheme {
if GetUIManager().IsSystemTheme(theme.ThemeId) {
return fmt.Errorf("can't uninstall system theme")
}

Expand Down
11 changes: 6 additions & 5 deletions Wox/ui/theme.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package ui

type Theme struct {
ThemeId string
ThemeName string
ThemeAuthor string
ThemeUrl string
IsSystemTheme bool
ThemeId string
ThemeName string
ThemeAuthor string
ThemeUrl string
Version string

AppBackgroundColor string
AppPaddingLeft int
AppPaddingTop int
Expand Down
1 change: 1 addition & 0 deletions theme-store.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"ThemeName": "Dark Theme QLF",
"ThemeAuthor": "Wox launcher",
"ThemeUrl": "http://www.github.com/wox-launcher/wox",
"Version": "1.0.0",
"AppBackgroundColor": "rgba(0,0,0, 0.65)",
"AppPaddingLeft": 10,
"AppPaddingTop": 10,
Expand Down

0 comments on commit f0cd7b2

Please sign in to comment.