Skip to content

Commit 5536d29

Browse files
committed
feat(download): add ginger download source as the default replacement
1 parent 7ee51b8 commit 5536d29

7 files changed

Lines changed: 235 additions & 8 deletions

File tree

frontend/src/views/settings/Settings.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ const downloadSiteOptions: Array<SelectOption> = [
243243
{
244244
label: "konmai",
245245
value: "konmai"
246+
},
247+
{
248+
label: "ginger",
249+
value: "ginger"
246250
}
247251
];
248252

frontend/wailsjs/runtime/runtime.d.ts

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,4 +246,85 @@ export function OnFileDropOff() :void
246246
export function CanResolveFilePaths(): boolean;
247247

248248
// Resolves file paths for an array of files
249-
export function ResolveFilePaths(files: File[]): void
249+
export function ResolveFilePaths(files: File[]): void
250+
251+
// Notification types
252+
export interface NotificationOptions {
253+
id: string;
254+
title: string;
255+
subtitle?: string; // macOS and Linux only
256+
body?: string;
257+
categoryId?: string;
258+
data?: { [key: string]: any };
259+
}
260+
261+
export interface NotificationAction {
262+
id?: string;
263+
title?: string;
264+
destructive?: boolean; // macOS-specific
265+
}
266+
267+
export interface NotificationCategory {
268+
id?: string;
269+
actions?: NotificationAction[];
270+
hasReplyField?: boolean;
271+
replyPlaceholder?: string;
272+
replyButtonTitle?: string;
273+
}
274+
275+
// [InitializeNotifications](https://wails.io/docs/reference/runtime/notification#initializenotifications)
276+
// Initializes the notification service for the application.
277+
// This must be called before sending any notifications.
278+
export function InitializeNotifications(): Promise<void>;
279+
280+
// [CleanupNotifications](https://wails.io/docs/reference/runtime/notification#cleanupnotifications)
281+
// Cleans up notification resources and releases any held connections.
282+
export function CleanupNotifications(): Promise<void>;
283+
284+
// [IsNotificationAvailable](https://wails.io/docs/reference/runtime/notification#isnotificationavailable)
285+
// Checks if notifications are available on the current platform.
286+
export function IsNotificationAvailable(): Promise<boolean>;
287+
288+
// [RequestNotificationAuthorization](https://wails.io/docs/reference/runtime/notification#requestnotificationauthorization)
289+
// Requests notification authorization from the user (macOS only).
290+
export function RequestNotificationAuthorization(): Promise<boolean>;
291+
292+
// [CheckNotificationAuthorization](https://wails.io/docs/reference/runtime/notification#checknotificationauthorization)
293+
// Checks the current notification authorization status (macOS only).
294+
export function CheckNotificationAuthorization(): Promise<boolean>;
295+
296+
// [SendNotification](https://wails.io/docs/reference/runtime/notification#sendnotification)
297+
// Sends a basic notification with the given options.
298+
export function SendNotification(options: NotificationOptions): Promise<void>;
299+
300+
// [SendNotificationWithActions](https://wails.io/docs/reference/runtime/notification#sendnotificationwithactions)
301+
// Sends a notification with action buttons. Requires a registered category.
302+
export function SendNotificationWithActions(options: NotificationOptions): Promise<void>;
303+
304+
// [RegisterNotificationCategory](https://wails.io/docs/reference/runtime/notification#registernotificationcategory)
305+
// Registers a notification category that can be used with SendNotificationWithActions.
306+
export function RegisterNotificationCategory(category: NotificationCategory): Promise<void>;
307+
308+
// [RemoveNotificationCategory](https://wails.io/docs/reference/runtime/notification#removenotificationcategory)
309+
// Removes a previously registered notification category.
310+
export function RemoveNotificationCategory(categoryId: string): Promise<void>;
311+
312+
// [RemoveAllPendingNotifications](https://wails.io/docs/reference/runtime/notification#removeallpendingnotifications)
313+
// Removes all pending notifications from the notification center.
314+
export function RemoveAllPendingNotifications(): Promise<void>;
315+
316+
// [RemovePendingNotification](https://wails.io/docs/reference/runtime/notification#removependingnotification)
317+
// Removes a specific pending notification by its identifier.
318+
export function RemovePendingNotification(identifier: string): Promise<void>;
319+
320+
// [RemoveAllDeliveredNotifications](https://wails.io/docs/reference/runtime/notification#removealldeliverednotifications)
321+
// Removes all delivered notifications from the notification center.
322+
export function RemoveAllDeliveredNotifications(): Promise<void>;
323+
324+
// [RemoveDeliveredNotification](https://wails.io/docs/reference/runtime/notification#removedeliverednotification)
325+
// Removes a specific delivered notification by its identifier.
326+
export function RemoveDeliveredNotification(identifier: string): Promise<void>;
327+
328+
// [RemoveNotification](https://wails.io/docs/reference/runtime/notification#removenotification)
329+
// Removes a notification by its identifier (cross-platform convenience function).
330+
export function RemoveNotification(identifier: string): Promise<void>;

frontend/wailsjs/runtime/runtime.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ export function EventsOff(eventName, ...additionalEventNames) {
4848
return window.runtime.EventsOff(eventName, ...additionalEventNames);
4949
}
5050

51+
export function EventsOffAll() {
52+
return window.runtime.EventsOffAll();
53+
}
54+
5155
export function EventsOnce(eventName, callback) {
5256
return EventsOnMultiple(eventName, callback, 1);
5357
}
@@ -235,4 +239,60 @@ export function CanResolveFilePaths() {
235239

236240
export function ResolveFilePaths(files) {
237241
return window.runtime.ResolveFilePaths(files);
242+
}
243+
244+
export function InitializeNotifications() {
245+
return window.runtime.InitializeNotifications();
246+
}
247+
248+
export function CleanupNotifications() {
249+
return window.runtime.CleanupNotifications();
250+
}
251+
252+
export function IsNotificationAvailable() {
253+
return window.runtime.IsNotificationAvailable();
254+
}
255+
256+
export function RequestNotificationAuthorization() {
257+
return window.runtime.RequestNotificationAuthorization();
258+
}
259+
260+
export function CheckNotificationAuthorization() {
261+
return window.runtime.CheckNotificationAuthorization();
262+
}
263+
264+
export function SendNotification(options) {
265+
return window.runtime.SendNotification(options);
266+
}
267+
268+
export function SendNotificationWithActions(options) {
269+
return window.runtime.SendNotificationWithActions(options);
270+
}
271+
272+
export function RegisterNotificationCategory(category) {
273+
return window.runtime.RegisterNotificationCategory(category);
274+
}
275+
276+
export function RemoveNotificationCategory(categoryId) {
277+
return window.runtime.RemoveNotificationCategory(categoryId);
278+
}
279+
280+
export function RemoveAllPendingNotifications() {
281+
return window.runtime.RemoveAllPendingNotifications();
282+
}
283+
284+
export function RemovePendingNotification(identifier) {
285+
return window.runtime.RemovePendingNotification(identifier);
286+
}
287+
288+
export function RemoveAllDeliveredNotifications() {
289+
return window.runtime.RemoveAllDeliveredNotifications();
290+
}
291+
292+
export function RemoveDeliveredNotification(identifier) {
293+
return window.runtime.RemoveDeliveredNotification(identifier);
294+
}
295+
296+
export function RemoveNotification(identifier) {
297+
return window.runtime.RemoveNotification(identifier);
238298
}

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ require (
1111
github.com/samber/lo v1.50.0
1212
github.com/spf13/viper v1.19.0
1313
github.com/stretchr/testify v1.10.0
14-
github.com/wailsapp/wails/v2 v2.10.2
14+
github.com/wailsapp/wails/v2 v2.12.0
1515
golang.design/x/clipboard v0.7.1
1616
gorm.io/gorm v1.25.12
1717
)
1818

1919
require (
20+
git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 // indirect
2021
github.com/andybalholm/brotli v1.1.1 // indirect
2122
github.com/cloudflare/circl v1.6.1 // indirect
2223
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
@@ -87,7 +88,7 @@ require (
8788
github.com/tkrajina/go-reflector v0.5.8 // indirect
8889
github.com/valyala/bytebufferpool v1.0.0 // indirect
8990
github.com/valyala/fasttemplate v1.2.2 // indirect
90-
github.com/wailsapp/go-webview2 v1.0.19 // indirect
91+
github.com/wailsapp/go-webview2 v1.0.22 // indirect
9192
github.com/wailsapp/mimetype v1.4.1 // indirect
9293
go.uber.org/atomic v1.9.0 // indirect
9394
go.uber.org/multierr v1.9.0 // indirect

go.sum

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 h1:N3IGoHHp9pb6mj1cbXbuaSXV/UMKwmbKLf53nQmtqMA=
2+
git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3/go.mod h1:QtOLZGz8olr4qH2vWK0QH0w0O4T9fEIjMuWpKUsH7nc=
13
github.com/Catizard/bmscanner v0.1.0 h1:pZbF56y16anjH+3G3pAVX1PSW6oah25BrEXEcBDtsRM=
24
github.com/Catizard/bmscanner v0.1.0/go.mod h1:Ry+KW6oj25W2OZuLf1ra2JbiLJkJtZF5Wp2k2ozBf8Q=
35
github.com/Catizard/bmstable v1.0.4 h1:+CdHu6K5zydbQQ09E86PHT/RniM8z3nwRNLTtxpfAdE=
@@ -171,12 +173,12 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
171173
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
172174
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
173175
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
174-
github.com/wailsapp/go-webview2 v1.0.19 h1:7U3QcDj1PrBPaxJNCui2k1SkWml+Q5kvFUFyTImA6NU=
175-
github.com/wailsapp/go-webview2 v1.0.19/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
176+
github.com/wailsapp/go-webview2 v1.0.22 h1:YT61F5lj+GGaat5OB96Aa3b4QA+mybD0Ggq6NZijQ58=
177+
github.com/wailsapp/go-webview2 v1.0.22/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
176178
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
177179
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
178-
github.com/wailsapp/wails/v2 v2.10.2 h1:29U+c5PI4K4hbx8yFbFvwpCuvqK9VgNv8WGobIlKlXk=
179-
github.com/wailsapp/wails/v2 v2.10.2/go.mod h1:XuN4IUOPpzBrHUkEd7sCU5ln4T/p1wQedfxP7fKik+4=
180+
github.com/wailsapp/wails/v2 v2.12.0 h1:BHO/kLNWFHYjCzucxbzAYZWUjub1Tvb4cSguQozHn5c=
181+
github.com/wailsapp/wails/v2 v2.12.0/go.mod h1:mo1bzK1DEJrobt7YrBjgxvb5Sihb1mhAY09hppbibQg=
180182
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
181183
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
182184
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=

internal/config/download/download.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package download
22

33
var (
4-
DefaultDownloadSource DownloadSource = &WriggleDownloadSource
4+
DefaultDownloadSource DownloadSource = &GingerDownloadSource
55
downloadSources map[string]DownloadSource = map[string]DownloadSource{
66
"wriggle": &WriggleDownloadSource,
77
"konmai": &KonmaiDownloadSource,
8+
"ginger": &GingerDownloadSource,
89
}
910
)
1011

internal/config/download/ginger.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package download
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
"strings"
9+
10+
"github.com/rotisserie/eris"
11+
)
12+
13+
var _ DownloadSource = (*gingerDownloadSource)(nil)
14+
15+
var GingerDownloadSource gingerDownloadSource = gingerDownloadSource{
16+
Meta: DownloadSourceMeta{
17+
Name: "ginger",
18+
MetaQueryURL: "https://gingerrush.com/api/v1/files/package/%s",
19+
},
20+
}
21+
22+
type gingerDownloadSource struct {
23+
Meta DownloadSourceMeta
24+
}
25+
26+
func (d *gingerDownloadSource) GetMeta() DownloadSourceMeta {
27+
return d.Meta
28+
}
29+
30+
func (d *gingerDownloadSource) GetDownloadURLFromMD5(md5 string) (downloadInfo DownloadInfo, err error) {
31+
metaQueryURL := fmt.Sprintf(d.Meta.MetaQueryURL, md5)
32+
resp, err := d.queryPackage(metaQueryURL)
33+
if err != nil {
34+
return DownloadInfo{}, err
35+
}
36+
return DownloadInfo{
37+
DownloadURL: resp.DownloadURL,
38+
UniqueSymbol: resp.DownloadURL,
39+
FileName: resp.FileName,
40+
}, nil
41+
}
42+
43+
func (d *gingerDownloadSource) queryPackage(metaQueryURL string) (*gResp, error) {
44+
resp, err := http.Get(metaQueryURL)
45+
if err != nil {
46+
return nil, eris.Wrap(err, "get meta")
47+
}
48+
defer resp.Body.Close()
49+
if resp.StatusCode != 200 {
50+
return nil, eris.Errorf("error code: %d", resp.StatusCode)
51+
}
52+
b, err := io.ReadAll(resp.Body)
53+
if err != nil {
54+
return nil, eris.Wrap(err, "http read")
55+
}
56+
if strings.HasPrefix(string(b), "404") {
57+
return nil, eris.Errorf("404 NOT FOUND")
58+
}
59+
var result gResp
60+
if err = json.Unmarshal(b, &result); err != nil {
61+
return nil, eris.Wrapf(err, "failed to unmarshal result: %s", string(b))
62+
}
63+
return &result, nil
64+
}
65+
66+
func (d *gingerDownloadSource) AllowBatchDownload() bool {
67+
return true
68+
}
69+
70+
// Ginger server models
71+
type gResp struct {
72+
ShardMD5 string `json:"shardMD5"`
73+
FileName string `json:"fileName"`
74+
FileSize int64 `json:"fileSize"`
75+
DirectoryID string `json:"directoryID"`
76+
MD5s string `json:"md5s"`
77+
DownloadURL string `json:"downloadURL"`
78+
}

0 commit comments

Comments
 (0)