From d8ae28cacc2092cc542c217750a6846f4ffd7a2a Mon Sep 17 00:00:00 2001 From: liwei Date: Fri, 6 Oct 2023 11:11:31 +0800 Subject: [PATCH] adjust extension repository model --- pkg/download/downloader.go | 10 +++- pkg/download/extension.go | 58 +++++++++++++------ .../testdata/extensions/update/manifest.json | 6 +- ui/flutter/lib/api/model/extension.dart | 17 +++++- ui/flutter/lib/api/model/extension.g.dart | 17 +++++- .../extension/views/extension_view.dart | 5 +- 6 files changed, 85 insertions(+), 28 deletions(-) diff --git a/pkg/download/downloader.go b/pkg/download/downloader.go index a400c01be..220e7f1e3 100644 --- a/pkg/download/downloader.go +++ b/pkg/download/downloader.go @@ -29,6 +29,10 @@ const ( bucketExtension = "extension" ) +var ( + ErrTaskNotFound = errors.New("task not found") +) + type Listener func(event *Event) type Progress struct { @@ -264,7 +268,7 @@ func (d *Downloader) Create(rrId string, opts *base.Options) (taskId string, err func (d *Downloader) Pause(id string) (err error) { task := d.GetTask(id) if task == nil { - return + return ErrTaskNotFound } if err = d.doPause(task, base.DownloadStatusPause); err != nil { return err @@ -275,7 +279,7 @@ func (d *Downloader) Pause(id string) (err error) { func (d *Downloader) Continue(id string) (err error) { task := d.GetTask(id) if task == nil { - return + return ErrTaskNotFound } d.tryRunning(func(remain int) { if remain == 0 { @@ -330,7 +334,7 @@ func (d *Downloader) Delete(id string, force bool) (err error) { defer d.lock.Unlock() task := d.GetTask(id) if task == nil { - return + return ErrTaskNotFound } task.lock.Lock() defer task.lock.Unlock() diff --git a/pkg/download/extension.go b/pkg/download/extension.go index 28700deeb..99d40f956 100644 --- a/pkg/download/extension.go +++ b/pkg/download/extension.go @@ -30,9 +30,9 @@ var ( type ActivationEvent string const ( - HookEventOnResolve ActivationEvent = "onResolve" - //HookEventOnError HookEvent = "onError" - //HookEventOnDone HookEvent = "onDone" + EventOnResolve ActivationEvent = "onResolve" + //EventOnError ActivationEvent = "onError" + //EventOnDone ActivationEvent = "onDone" ) func (d *Downloader) InstallExtensionByGit(url string) (*Extension, error) { @@ -69,12 +69,13 @@ func (d *Downloader) InstallExtensionByFolder(path string) (*Extension, error) { func (d *Downloader) UpgradeCheckExtension(identity string) (newVersion string, err error) { ext, err := d.GetExtension(identity) if err != nil { - return "", err + return } - if ext.InstallUrl == "" { + installUrl := ext.buildInstallUrl() + if installUrl == "" { return } - _, err = d.fetchExtensionByGit(ext.InstallUrl, func(tempExtPath string) (*Extension, error) { + _, err = d.fetchExtensionByGit(installUrl, func(tempExtPath string) (*Extension, error) { tempExt, err := d.parseExtensionByPath(tempExtPath) if err != nil { return nil, err @@ -92,10 +93,11 @@ func (d *Downloader) UpgradeExtension(identity string) error { if err != nil { return err } - if ext.InstallUrl == "" { + installUrl := ext.buildInstallUrl() + if installUrl == "" { return nil } - if _, err := d.InstallExtensionByGit(ext.InstallUrl); err != nil { + if _, err := d.InstallExtensionByGit(installUrl); err != nil { return err } return nil @@ -227,7 +229,7 @@ func (d *Downloader) triggerOnResolve(req *base.Request) (res *base.Resource) { var err error for _, ext := range d.extensions { for _, script := range ext.Scripts { - if script.match(HookEventOnResolve, req.URL) { + if script.match(EventOnResolve, req.URL) { scriptFilePath := filepath.Join(d.extensionPath(ext), script.Entry) if _, err = os.Stat(scriptFilePath); os.IsNotExist(err) { continue @@ -259,7 +261,7 @@ func (d *Downloader) triggerOnResolve(req *base.Request) (res *base.Resource) { // TODO: log return } - if fn, ok := gopeed.Events[HookEventOnResolve]; ok { + if fn, ok := gopeed.Events[EventOnResolve]; ok { _, err = engine.CallFunction(fn, ctx) if err != nil { // TODO: log @@ -298,12 +300,10 @@ type Extension struct { Version string `json:"version"` // Homepage homepage url Homepage string `json:"homepage"` - // InstallUrl install url - InstallUrl string `json:"installUrl"` - // Repository git repository url - Repository string `json:"repository"` - Scripts []*Script `json:"scripts"` - Settings []*Setting `json:"settings"` + // Repository git repository info + Repository *Repository `json:"repository"` + Scripts []*Script `json:"scripts"` + Settings []*Setting `json:"settings"` Disabled bool `json:"disabled"` CreatedAt time.Time `json:"createdAt"` @@ -330,13 +330,30 @@ func (e *Extension) buildIdentity() string { return e.Author + "@" + e.Name } +func (e *Extension) buildInstallUrl() string { + if e.Repository == nil || e.Repository.Url == "" { + return "" + } + repoUrl := e.Repository.Url + if e.Repository.Directory != "" { + if strings.HasSuffix(repoUrl, "/") { + repoUrl = repoUrl[:len(repoUrl)-1] + } + dir := e.Repository.Directory + if strings.HasPrefix(dir, "/") { + dir = dir[1:] + } + repoUrl = repoUrl + "#" + dir + } + return repoUrl +} + func (e *Extension) update(newExt *Extension) error { e.Title = newExt.Title e.Description = newExt.Description e.Icon = newExt.Icon e.Version = newExt.Version e.Homepage = newExt.Homepage - e.InstallUrl = newExt.InstallUrl e.Repository = newExt.Repository e.Scripts = newExt.Scripts // don't override settings @@ -345,6 +362,11 @@ func (e *Extension) update(newExt *Extension) error { return nil } +type Repository struct { + Url string `json:"url"` + Directory string `json:"directory"` +} + type Script struct { // Event active event name Event string `json:"event"` @@ -410,7 +432,7 @@ func (h InstanceEvents) register(name ActivationEvent, fn goja.Callable) { } func (h InstanceEvents) OnResolve(fn goja.Callable) { - h.register(HookEventOnResolve, fn) + h.register(EventOnResolve, fn) } //func (h InstanceEvents) OnError(fn goja.Callable) { diff --git a/pkg/download/testdata/extensions/update/manifest.json b/pkg/download/testdata/extensions/update/manifest.json index 7c940ca8d..30522af35 100644 --- a/pkg/download/testdata/extensions/update/manifest.json +++ b/pkg/download/testdata/extensions/update/manifest.json @@ -5,8 +5,10 @@ "description": "Download github release assets", "version": "0.0.1", "homepage": "https://gopeed.com", - "repository": "https://github.com/GopeedLab/gopeed-extension-samples", - "installURL": "https://github.com/GopeedLab/gopeed-extension-samples#github-release-sample", + "repository": { + "url": "https://github.com/GopeedLab/gopeed-extension-samples", + "directory": "github-release-sample" + }, "scripts": [ { "event": "onResolve", diff --git a/ui/flutter/lib/api/model/extension.dart b/ui/flutter/lib/api/model/extension.dart index 95e735b0b..526458fa7 100644 --- a/ui/flutter/lib/api/model/extension.dart +++ b/ui/flutter/lib/api/model/extension.dart @@ -13,7 +13,7 @@ class Extension { String version; String homepage; String installUrl; - String repository; + Repository? repository; List? settings; bool disabled; @@ -36,6 +36,21 @@ class Extension { Map toJson() => _$ExtensionToJson(this); } +@JsonSerializable() +class Repository { + String url; + String directory; + + Repository({ + required this.url, + required this.directory, + }); + + factory Repository.fromJson(Map json) => + _$RepositoryFromJson(json); + Map toJson() => _$RepositoryToJson(this); +} + @JsonSerializable() class Setting { String name; diff --git a/ui/flutter/lib/api/model/extension.g.dart b/ui/flutter/lib/api/model/extension.g.dart index e8a584897..027083844 100644 --- a/ui/flutter/lib/api/model/extension.g.dart +++ b/ui/flutter/lib/api/model/extension.g.dart @@ -16,7 +16,9 @@ Extension _$ExtensionFromJson(Map json) => Extension( version: json['version'] as String, homepage: json['homepage'] as String, installUrl: json['installUrl'] as String, - repository: json['repository'] as String, + repository: json['repository'] == null + ? null + : Repository.fromJson(json['repository'] as Map), disabled: json['disabled'] as bool, )..settings = (json['settings'] as List?) ?.map((e) => Setting.fromJson(e as Map)) @@ -33,7 +35,6 @@ Map _$ExtensionToJson(Extension instance) { 'version': instance.version, 'homepage': instance.homepage, 'installUrl': instance.installUrl, - 'repository': instance.repository, }; void writeNotNull(String key, dynamic value) { @@ -42,11 +43,23 @@ Map _$ExtensionToJson(Extension instance) { } } + writeNotNull('repository', instance.repository?.toJson()); writeNotNull('settings', instance.settings?.map((e) => e.toJson()).toList()); val['disabled'] = instance.disabled; return val; } +Repository _$RepositoryFromJson(Map json) => Repository( + url: json['url'] as String, + directory: json['directory'], + ); + +Map _$RepositoryToJson(Repository instance) => + { + 'url': instance.url, + 'directory': instance.directory, + }; + Setting _$SettingFromJson(Map json) => Setting( name: json['name'] as String, title: json['title'] as String, diff --git a/ui/flutter/lib/app/modules/extension/views/extension_view.dart b/ui/flutter/lib/app/modules/extension/views/extension_view.dart index 5d2cd2a8a..c9d99c16d 100644 --- a/ui/flutter/lib/app/modules/extension/views/extension_view.dart +++ b/ui/flutter/lib/app/modules/extension/views/extension_view.dart @@ -130,11 +130,12 @@ class ExtensionView extends GetView { }, icon: const Icon(Icons.home)) : null, - extension.repository.isNotEmpty == true + extension.repository?.url.isNotEmpty == true ? IconButton( onPressed: () { launchUrl( - Uri.parse(extension.repository), + Uri.parse( + extension.repository!.url), mode: LaunchMode .externalApplication); },