From ef7317dde6575f1b407e49011b6fbbe40121eaad Mon Sep 17 00:00:00 2001
From: ze0s <43699394+zze0s@users.noreply.github.com>
Date: Sun, 16 Mar 2025 18:33:47 +0100
Subject: [PATCH] feat(filters): show current download count in list (#2001)
* feat(filters): show current and max downloads in list
* feat(filters): remove unused func param
---
internal/database/filter.go | 15 ++++++++++++++-
internal/domain/filter.go | 12 ++++++------
internal/filter/service.go | 9 +++++++++
web/src/screens/filters/List.tsx | 26 ++++++++++++++++++++++++--
web/src/types/Filter.d.ts | 10 ++++++++++
5 files changed, 63 insertions(+), 9 deletions(-)
diff --git a/internal/database/filter.go b/internal/database/filter.go
index b993290..4fdda0d 100644
--- a/internal/database/filter.go
+++ b/internal/database/filter.go
@@ -62,6 +62,8 @@ func (r *FilterRepo) find(ctx context.Context, params domain.FilterQueryParams)
"f.enabled",
"f.name",
"f.priority",
+ "f.max_downloads",
+ "f.max_downloads_unit",
"f.created_at",
"f.updated_at",
).
@@ -108,10 +110,21 @@ func (r *FilterRepo) find(ctx context.Context, params domain.FilterQueryParams)
for rows.Next() {
var f domain.Filter
- if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &f.Priority, &f.CreatedAt, &f.UpdatedAt, &f.ActionsCount, &f.ActionsEnabledCount, &f.IsAutoUpdated); err != nil {
+ var maxDownloadsUnit sql.Null[string]
+ var maxDownloads sql.Null[int32]
+
+ if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &f.Priority, &maxDownloads, &maxDownloadsUnit, &f.CreatedAt, &f.UpdatedAt, &f.ActionsCount, &f.ActionsEnabledCount, &f.IsAutoUpdated); err != nil {
return nil, errors.Wrap(err, "error scanning row")
}
+ if maxDownloads.Valid {
+ f.MaxDownloads = int(maxDownloads.V)
+ }
+
+ if maxDownloadsUnit.Valid {
+ f.MaxDownloadsUnit = domain.FilterMaxDownloadsUnit(maxDownloadsUnit.V)
+ }
+
filters = append(filters, f)
}
if err := rows.Err(); err != nil {
diff --git a/internal/domain/filter.go b/internal/domain/filter.go
index ca8f67f..6b2341e 100644
--- a/internal/domain/filter.go
+++ b/internal/domain/filter.go
@@ -45,11 +45,11 @@ type FilterRepo interface {
}
type FilterDownloads struct {
- HourCount int
- DayCount int
- WeekCount int
- MonthCount int
- TotalCount int
+ HourCount int `json:"hour_count"`
+ DayCount int `json:"day_count"`
+ WeekCount int `json:"week_count"`
+ MonthCount int `json:"month_count"`
+ TotalCount int `json:"total_count"`
}
func (f *FilterDownloads) String() string {
@@ -172,7 +172,7 @@ type Filter struct {
Indexers []Indexer `json:"indexers"`
ReleaseProfileDuplicateID int64 `json:"release_profile_duplicate_id,omitempty"`
DuplicateHandling *DuplicateReleaseProfile `json:"release_profile_duplicate"`
- Downloads *FilterDownloads `json:"-"`
+ Downloads *FilterDownloads `json:"downloads,omitempty"`
Rejections []string `json:"-"`
RejectReasons *RejectionReasons `json:"-"`
}
diff --git a/internal/filter/service.go b/internal/filter/service.go
index ac55738..b7de765 100644
--- a/internal/filter/service.go
+++ b/internal/filter/service.go
@@ -94,6 +94,15 @@ func (s *service) Find(ctx context.Context, params domain.FilterQueryParams) ([]
}
filter.Indexers = indexers
+ if filter.MaxDownloads > 0 && filter.MaxDownloadsUnit != "" {
+ counts, err := s.repo.GetDownloadsByFilterId(ctx, filter.ID)
+ if err != nil {
+ return ret, err
+ }
+
+ filter.Downloads = counts
+ }
+
ret = append(ret, filter)
}
diff --git a/web/src/screens/filters/List.tsx b/web/src/screens/filters/List.tsx
index 4156d0f..f4066ea 100644
--- a/web/src/screens/filters/List.tsx
+++ b/web/src/screens/filters/List.tsx
@@ -612,7 +612,7 @@ function FilterListItem({ filter, idx }: FilterListItemProps) {
className="flex items-center cursor-pointer hover:text-black dark:hover:text-gray-300"
>
- Actions: {filter.actions_enabled_count}/{filter.actions_count}
+ Actions: {filter.actions_enabled_count}/{filter.actions_count}
}
@@ -636,11 +636,16 @@ function FilterListItem({ filter, idx }: FilterListItemProps) {
className="flex items-center cursor-pointer hover:text-black dark:hover:text-gray-300"
>
- Actions: {filter.actions_enabled_count}/{filter.actions_count}
+ Actions: {filter.actions_enabled_count}/{filter.actions_count}
)}
+ {filter.max_downloads_unit !== "" && filter.downloads !== undefined && (
+
+ Downloads: {renderMaxDownloads(filter.max_downloads_unit, filter.downloads)}/{filter.max_downloads} per {filter.max_downloads_unit}
+
+ )}
@@ -656,6 +661,23 @@ function FilterListItem({ filter, idx }: FilterListItemProps) {
);
}
+function renderMaxDownloads(unit: string, downloads: FilterDownloads): number {
+ switch (unit) {
+ case "HOUR":
+ return downloads.hour_count
+ case "DAY":
+ return downloads.day_count
+ case "WEEK":
+ return downloads.week_count
+ case "MONTH":
+ return downloads.month_count
+ case "EVER":
+ return downloads.total_count
+ default:
+ return 0
+ }
+}
+
interface IndexerTagProps {
indexer: Indexer;
}
diff --git a/web/src/types/Filter.d.ts b/web/src/types/Filter.d.ts
index eb68348..4b3dbed 100644
--- a/web/src/types/Filter.d.ts
+++ b/web/src/types/Filter.d.ts
@@ -82,6 +82,7 @@ interface Filter {
actions: Action[];
indexers: Indexer[];
external: ExternalFilter[];
+ downloads?: FilterDownloads;
release_profile_duplicate_id?: number;
}
@@ -152,3 +153,12 @@ interface ExternalFilter {
webhook_retry_delay_seconds?: number;
filter_id?: number;
}
+
+interface FilterDownloads {
+ hour_count: number;
+ day_count: number;
+ week_count: number;
+ month_count: number;
+ year_count: number;
+ total_count: number;
+}