Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web): move from react-router to @tanstack/router #1338

Merged
merged 50 commits into from Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
4da1e6d
fix(auth): invalid cookie handling and wrongful basic auth invalidation
martylukyy Jan 1, 2024
c212da8
fix(auth): fix test to reflect new HTTP status code
martylukyy Jan 1, 2024
171ea93
fix(auth/web): do not throw on error
martylukyy Jan 2, 2024
8083967
fix(http): replace http codes in middleware to prevent basic auth inv…
martylukyy Jan 2, 2024
7e9bb19
fix test
martylukyy Jan 2, 2024
17a705b
Merge branch 'develop' into fix/auth/cookie-handling-and-basic-auth
zze0s Jan 2, 2024
ed674e8
fix(web): api client handle 403
zze0s Jan 2, 2024
0c527ef
refactor(http): auth_test use testify.assert
zze0s Jan 2, 2024
cc13001
refactor(http): set session opts after valid login
zze0s Jan 2, 2024
a7fabc1
Merge branch 'develop' into fix/auth/cookie-handling-and-basic-auth
kaiserbh Jan 3, 2024
09b86e8
refactor(http): send more client headers
zze0s Jan 3, 2024
0ee395e
fix(http): test
zze0s Jan 3, 2024
47423a6
refactor(web): move router to tanstack/router
zze0s Jan 4, 2024
e671f16
refactor(web): use route loaders and suspense
zze0s Jan 5, 2024
316be1c
refactor(web): useSuspense for settings
zze0s Jan 12, 2024
75c8b49
refactor(web): invalidate cookie in middleware
zze0s Jan 12, 2024
e769764
Merge branch 'develop' into fix/auth/cookie-handling-and-basic-auth
zze0s Feb 5, 2024
b18ba9a
fix: loclfile
zze0s Feb 5, 2024
ceca826
fix: load filter/id
zze0s Feb 7, 2024
f41b543
fix(web): login, onboard, types, imports
zze0s Feb 7, 2024
e57fd4a
fix(web): filter load
zze0s Feb 7, 2024
7ed5d8a
fix(web): build errors
zze0s Feb 8, 2024
4774923
fix(web): ts-expect-error
zze0s Feb 8, 2024
f618433
fix(tests): filter_test.go
zze0s Feb 8, 2024
4ba183c
fix(filters): tests
zze0s Feb 8, 2024
6bbebf1
Merge branch 'develop' into fix/auth/cookie-handling-and-basic-auth
zze0s Feb 8, 2024
6e08c1a
refactor: remove duplicate spinner components
martylukyy Feb 10, 2024
7a745a1
fix: refactor missed SectionLoader to RingResizeSpinner
martylukyy Feb 10, 2024
cb6744d
fix: substitute divides with borders to account for unloaded elements
martylukyy Feb 10, 2024
b425e1b
fix(api): action status URL param
martylukyy Feb 10, 2024
67a055f
revert: action status URL param
martylukyy Feb 10, 2024
d3e926b
fix(routing): notfound handling and split files
zze0s Feb 11, 2024
6c03e8c
fix(filters): notfound get params
zze0s Feb 11, 2024
f1a117d
fix(queries): colon
zze0s Feb 11, 2024
d849efd
fix(queries): comments ts-ignore
zze0s Feb 11, 2024
c69ae5e
fix(queries): extract queryKeys
zze0s Feb 11, 2024
2970df4
fix(queries): remove err
zze0s Feb 11, 2024
63b985d
fix(routes): move zob schema inline
zze0s Feb 11, 2024
66042f2
fix(auth): middleware and redirect to login
zze0s Feb 11, 2024
a961835
fix(auth): failing test
zze0s Feb 11, 2024
0373323
fix(logs): invalidate correct key
zze0s Feb 11, 2024
26ae66c
fix(logs): invalidate correct key
zze0s Feb 11, 2024
815e13a
fix(logs): invalidate correct key
zze0s Feb 11, 2024
404e736
fix: JSX element stealing focus from searchbar
martylukyy Feb 11, 2024
048b500
reimplement empty release table state text
martylukyy Feb 11, 2024
83fbc72
fix(context): use deep-copy
zze0s Feb 12, 2024
889408a
fix(releases): empty state and filter input warnings
zze0s Feb 12, 2024
e39c122
fix(releases): empty states
zze0s Feb 12, 2024
30d04d9
fix(auth): onboarding
zze0s Feb 12, 2024
b8b135a
fix(cache): invalidate queries
zze0s Feb 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
493 changes: 159 additions & 334 deletions internal/database/filter.go

Large diffs are not rendered by default.

12 changes: 5 additions & 7 deletions internal/database/filter_test.go
Expand Up @@ -205,11 +205,10 @@ func TestFilterRepo_Delete(t *testing.T) {
err = repo.Delete(context.Background(), createdFilters[0].ID)
assert.NoError(t, err)

// Verify that the filter is deleted
// Verify that the filter is deleted and return error ErrRecordNotFound
filter, err := repo.FindByID(context.Background(), createdFilters[0].ID)
assert.NoError(t, err)
assert.NotNil(t, filter)
assert.Equal(t, 0, filter.ID)
assert.ErrorIs(t, err, domain.ErrRecordNotFound)
assert.Nil(t, filter)
})

t.Run(fmt.Sprintf("Delete_Fails_No_Record [%s]", dbType), func(t *testing.T) {
Expand Down Expand Up @@ -451,12 +450,11 @@ func TestFilterRepo_FindByID(t *testing.T) {
_ = repo.Delete(context.Background(), createdFilters[0].ID)
})

// TODO: This should succeed, but it fails because we are not handling the error correctly. Fix this.
t.Run(fmt.Sprintf("FindByID_Fails_Invalid_ID [%s]", dbType), func(t *testing.T) {
// Test using an invalid ID
filter, err := repo.FindByID(context.Background(), -1)
assert.NoError(t, err) // should return an error
assert.NotNil(t, filter) // should be nil
assert.ErrorIs(t, err, domain.ErrRecordNotFound) // should return an error
assert.Nil(t, filter) // should be nil
})

}
Expand Down
149 changes: 69 additions & 80 deletions internal/domain/filter.go
Expand Up @@ -174,86 +174,75 @@
)

type FilterUpdate struct {
ID int `json:"id"`
Name *string `json:"name,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
MinSize *string `json:"min_size,omitempty"`
MaxSize *string `json:"max_size,omitempty"`
Delay *int `json:"delay,omitempty"`
Priority *int32 `json:"priority,omitempty"`
MaxDownloads *int `json:"max_downloads,omitempty"`
MaxDownloadsUnit *FilterMaxDownloadsUnit `json:"max_downloads_unit,omitempty"`
MatchReleases *string `json:"match_releases,omitempty"`
ExceptReleases *string `json:"except_releases,omitempty"`
UseRegex *bool `json:"use_regex,omitempty"`
MatchReleaseGroups *string `json:"match_release_groups,omitempty"`
ExceptReleaseGroups *string `json:"except_release_groups,omitempty"`
MatchReleaseTags *string `json:"match_release_tags,omitempty"`
ExceptReleaseTags *string `json:"except_release_tags,omitempty"`
UseRegexReleaseTags *bool `json:"use_regex_release_tags,omitempty"`
MatchDescription *string `json:"match_description,omitempty"`
ExceptDescription *string `json:"except_description,omitempty"`
UseRegexDescription *bool `json:"use_regex_description,omitempty"`
Scene *bool `json:"scene,omitempty"`
Origins *[]string `json:"origins,omitempty"`
ExceptOrigins *[]string `json:"except_origins,omitempty"`
Bonus *[]string `json:"bonus,omitempty"`
Freeleech *bool `json:"freeleech,omitempty"`
FreeleechPercent *string `json:"freeleech_percent,omitempty"`
SmartEpisode *bool `json:"smart_episode,omitempty"`
Shows *string `json:"shows,omitempty"`
Seasons *string `json:"seasons,omitempty"`
Episodes *string `json:"episodes,omitempty"`
Resolutions *[]string `json:"resolutions,omitempty"` // SD, 480i, 480p, 576p, 720p, 810p, 1080i, 1080p.
Codecs *[]string `json:"codecs,omitempty"` // XviD, DivX, x264, h.264 (or h264), mpeg2 (or mpeg-2), VC-1 (or VC1), WMV, Remux, h.264 Remux (or h264 Remux), VC-1 Remux (or VC1 Remux).
Sources *[]string `json:"sources,omitempty"` // DSR, PDTV, HDTV, HR.PDTV, HR.HDTV, DVDRip, DVDScr, BDr, BD5, BD9, BDRip, BRRip, DVDR, MDVDR, HDDVD, HDDVDRip, BluRay, WEB-DL, TVRip, CAM, R5, TELESYNC, TS, TELECINE, TC. TELESYNC and TS are synonyms (you don't need both). Same for TELECINE and TC
Containers *[]string `json:"containers,omitempty"`
MatchHDR *[]string `json:"match_hdr,omitempty"`
ExceptHDR *[]string `json:"except_hdr,omitempty"`
MatchOther *[]string `json:"match_other,omitempty"`
ExceptOther *[]string `json:"except_other,omitempty"`
Years *string `json:"years,omitempty"`
Artists *string `json:"artists,omitempty"`
Albums *string `json:"albums,omitempty"`
MatchReleaseTypes *[]string `json:"match_release_types,omitempty"` // Album,Single,EP
ExceptReleaseTypes *string `json:"except_release_types,omitempty"`
Formats *[]string `json:"formats,omitempty"` // MP3, FLAC, Ogg, AAC, AC3, DTS
Quality *[]string `json:"quality,omitempty"` // 192, 320, APS (VBR), V2 (VBR), V1 (VBR), APX (VBR), V0 (VBR), q8.x (VBR), Lossless, 24bit Lossless, Other
Media *[]string `json:"media,omitempty"` // CD, DVD, Vinyl, Soundboard, SACD, DAT, Cassette, WEB, Other
PerfectFlac *bool `json:"perfect_flac,omitempty"`
Cue *bool `json:"cue,omitempty"`
Log *bool `json:"log,omitempty"`
LogScore *int `json:"log_score,omitempty"`
MatchCategories *string `json:"match_categories,omitempty"`
ExceptCategories *string `json:"except_categories,omitempty"`
MatchUploaders *string `json:"match_uploaders,omitempty"`
ExceptUploaders *string `json:"except_uploaders,omitempty"`
MatchLanguage *[]string `json:"match_language,omitempty"`
ExceptLanguage *[]string `json:"except_language,omitempty"`
Tags *string `json:"tags,omitempty"`
ExceptTags *string `json:"except_tags,omitempty"`
TagsAny *string `json:"tags_any,omitempty"`
ExceptTagsAny *string `json:"except_tags_any,omitempty"`
TagsMatchLogic *string `json:"tags_match_logic,omitempty"`
ExceptTagsMatchLogic *string `json:"except_tags_match_logic,omitempty"`
MinSeeders *int `json:"min_seeders,omitempty"`
MaxSeeders *int `json:"max_seeders,omitempty"`
MinLeechers *int `json:"min_leechers,omitempty"`
MaxLeechers *int `json:"max_leechers,omitempty"`
ExternalScriptEnabled *bool `json:"external_script_enabled,omitempty"`
ExternalScriptCmd *string `json:"external_script_cmd,omitempty"`
ExternalScriptArgs *string `json:"external_script_args,omitempty"`
ExternalScriptExpectStatus *int `json:"external_script_expect_status,omitempty"`
ExternalWebhookEnabled *bool `json:"external_webhook_enabled,omitempty"`
ExternalWebhookHost *string `json:"external_webhook_host,omitempty"`
ExternalWebhookData *string `json:"external_webhook_data,omitempty"`
ExternalWebhookExpectStatus *int `json:"external_webhook_expect_status,omitempty"`
ExternalWebhookRetryStatus *string `json:"external_webhook_retry_status,omitempty"`
ExternalWebhookRetryAttempts *int `json:"external_webhook_retry_attempts,omitempty"`
ExternalWebhookRetryDelaySeconds *int `json:"external_webhook_retry_delay_seconds,omitempty"`
Actions []*Action `json:"actions,omitempty"`
External []FilterExternal `json:"external,omitempty"`
Indexers []Indexer `json:"indexers,omitempty"`
ID int `json:"id"`
Name *string `json:"name,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
MinSize *string `json:"min_size,omitempty"`
MaxSize *string `json:"max_size,omitempty"`
Delay *int `json:"delay,omitempty"`
Priority *int32 `json:"priority,omitempty"`
MaxDownloads *int `json:"max_downloads,omitempty"`
MaxDownloadsUnit *FilterMaxDownloadsUnit `json:"max_downloads_unit,omitempty"`
MatchReleases *string `json:"match_releases,omitempty"`
ExceptReleases *string `json:"except_releases,omitempty"`
UseRegex *bool `json:"use_regex,omitempty"`
MatchReleaseGroups *string `json:"match_release_groups,omitempty"`
ExceptReleaseGroups *string `json:"except_release_groups,omitempty"`
MatchReleaseTags *string `json:"match_release_tags,omitempty"`
ExceptReleaseTags *string `json:"except_release_tags,omitempty"`
UseRegexReleaseTags *bool `json:"use_regex_release_tags,omitempty"`
MatchDescription *string `json:"match_description,omitempty"`
ExceptDescription *string `json:"except_description,omitempty"`
UseRegexDescription *bool `json:"use_regex_description,omitempty"`
Scene *bool `json:"scene,omitempty"`
Origins *[]string `json:"origins,omitempty"`
ExceptOrigins *[]string `json:"except_origins,omitempty"`
Bonus *[]string `json:"bonus,omitempty"`
Freeleech *bool `json:"freeleech,omitempty"`
FreeleechPercent *string `json:"freeleech_percent,omitempty"`
SmartEpisode *bool `json:"smart_episode,omitempty"`
Shows *string `json:"shows,omitempty"`
Seasons *string `json:"seasons,omitempty"`
Episodes *string `json:"episodes,omitempty"`
Resolutions *[]string `json:"resolutions,omitempty"` // SD, 480i, 480p, 576p, 720p, 810p, 1080i, 1080p.
Codecs *[]string `json:"codecs,omitempty"` // XviD, DivX, x264, h.264 (or h264), mpeg2 (or mpeg-2), VC-1 (or VC1), WMV, Remux, h.264 Remux (or h264 Remux), VC-1 Remux (or VC1 Remux).
Sources *[]string `json:"sources,omitempty"` // DSR, PDTV, HDTV, HR.PDTV, HR.HDTV, DVDRip, DVDScr, BDr, BD5, BD9, BDRip, BRRip, DVDR, MDVDR, HDDVD, HDDVDRip, BluRay, WEB-DL, TVRip, CAM, R5, TELESYNC, TS, TELECINE, TC. TELESYNC and TS are synonyms (you don't need both). Same for TELECINE and TC
Containers *[]string `json:"containers,omitempty"`
MatchHDR *[]string `json:"match_hdr,omitempty"`
ExceptHDR *[]string `json:"except_hdr,omitempty"`
MatchOther *[]string `json:"match_other,omitempty"`
ExceptOther *[]string `json:"except_other,omitempty"`
Years *string `json:"years,omitempty"`
Artists *string `json:"artists,omitempty"`
Albums *string `json:"albums,omitempty"`
MatchReleaseTypes *[]string `json:"match_release_types,omitempty"` // Album,Single,EP
ExceptReleaseTypes *string `json:"except_release_types,omitempty"`
Formats *[]string `json:"formats,omitempty"` // MP3, FLAC, Ogg, AAC, AC3, DTS
Quality *[]string `json:"quality,omitempty"` // 192, 320, APS (VBR), V2 (VBR), V1 (VBR), APX (VBR), V0 (VBR), q8.x (VBR), Lossless, 24bit Lossless, Other
Media *[]string `json:"media,omitempty"` // CD, DVD, Vinyl, Soundboard, SACD, DAT, Cassette, WEB, Other
PerfectFlac *bool `json:"perfect_flac,omitempty"`
Cue *bool `json:"cue,omitempty"`
Log *bool `json:"log,omitempty"`
LogScore *int `json:"log_score,omitempty"`
MatchCategories *string `json:"match_categories,omitempty"`
ExceptCategories *string `json:"except_categories,omitempty"`
MatchUploaders *string `json:"match_uploaders,omitempty"`
ExceptUploaders *string `json:"except_uploaders,omitempty"`
MatchLanguage *[]string `json:"match_language,omitempty"`
ExceptLanguage *[]string `json:"except_language,omitempty"`
Tags *string `json:"tags,omitempty"`
ExceptTags *string `json:"except_tags,omitempty"`
TagsAny *string `json:"tags_any,omitempty"`
ExceptTagsAny *string `json:"except_tags_any,omitempty"`
TagsMatchLogic *string `json:"tags_match_logic,omitempty"`
ExceptTagsMatchLogic *string `json:"except_tags_match_logic,omitempty"`
MinSeeders *int `json:"min_seeders,omitempty"`
MaxSeeders *int `json:"max_seeders,omitempty"`
MinLeechers *int `json:"min_leechers,omitempty"`
MaxLeechers *int `json:"max_leechers,omitempty"`
Actions []*Action `json:"actions,omitempty"`
External []FilterExternal `json:"external,omitempty"`
Indexers []Indexer `json:"indexers,omitempty"`
}

func (f *Filter) Validate() error {
Expand Down Expand Up @@ -726,7 +715,7 @@
return false
}

max, err := strconv.ParseInt(minMax[1], 10, 32)

Check failure on line 718 in internal/domain/filter.go

View workflow job for this annotation

GitHub Actions / Nilaway Linter

error: Potential nil panic detected. Observed nil flow from source to dereference point:
if err != nil {
return false
}
Expand Down
24 changes: 23 additions & 1 deletion internal/filter/service.go
Expand Up @@ -124,6 +124,12 @@ func (s *service) FindByID(ctx context.Context, filterID int) (*domain.Filter, e
return nil, err
}

externalFilters, err := s.repo.FindExternalFiltersByID(ctx, filter.ID)
if err != nil {
s.log.Error().Err(err).Msgf("could not find external filters for filter id: %v", filter.ID)
}
filter.External = externalFilters

actions, err := s.actionRepo.FindByFilterID(ctx, filter.ID, nil)
if err != nil {
s.log.Error().Err(err).Msgf("could not find filter actions for filter id: %v", filter.ID)
Expand All @@ -142,9 +148,25 @@ func (s *service) FindByID(ctx context.Context, filterID int) (*domain.Filter, e

func (s *service) FindByIndexerIdentifier(ctx context.Context, indexer string) ([]*domain.Filter, error) {
// get filters for indexer
filters, err := s.repo.FindByIndexerIdentifier(ctx, indexer)
if err != nil {
return nil, err
}

// we do not load actions here since we do not need it at this stage
// only load those after filter has matched
return s.repo.FindByIndexerIdentifier(ctx, indexer)
for _, filter := range filters {
filter := filter

externalFilters, err := s.repo.FindExternalFiltersByID(ctx, filter.ID)
if err != nil {
s.log.Error().Err(err).Msgf("could not find external filters for filter id: %v", filter.ID)
}
filter.External = externalFilters

}

return filters, nil
}

func (s *service) GetDownloadsByFilterId(ctx context.Context, filterID int) (*domain.FilterDownloads, error) {
Expand Down