diff --git a/internal/database/feed.go b/internal/database/feed.go index 826c9a6..b0b6789 100644 --- a/internal/database/feed.go +++ b/internal/database/feed.go @@ -27,22 +27,23 @@ type FeedRepo struct { func (r *FeedRepo) FindByID(ctx context.Context, id int) (*domain.Feed, error) { queryBuilder := r.db.squirrel. Select( - "id", - "indexer", - "name", - "type", - "enabled", - "url", - "interval", - "timeout", - "max_age", - "api_key", - "cookie", - "created_at", - "updated_at", + "f.id", + "i.identifier", + "f.name", + "f.type", + "f.enabled", + "f.url", + "f.interval", + "f.timeout", + "f.max_age", + "f.api_key", + "f.cookie", + "f.created_at", + "f.updated_at", ). - From("feed"). - Where("id = ?", id) + From("feed f"). + Join("indexer i ON f.indexer_id = i.id"). + Where("f.id = ?", id) query, args, err := queryBuilder.ToSql() if err != nil { @@ -72,22 +73,23 @@ func (r *FeedRepo) FindByID(ctx context.Context, id int) (*domain.Feed, error) { func (r *FeedRepo) FindByIndexerIdentifier(ctx context.Context, indexer string) (*domain.Feed, error) { queryBuilder := r.db.squirrel. Select( - "id", - "indexer", - "name", - "type", - "enabled", - "url", - "interval", - "timeout", - "max_age", - "api_key", - "cookie", - "created_at", - "updated_at", + "f.id", + "i.identifier", + "f.name", + "f.type", + "f.enabled", + "f.url", + "f.interval", + "f.timeout", + "f.max_age", + "f.api_key", + "f.cookie", + "f.created_at", + "f.updated_at", ). - From("feed"). - Where("indexer = ?", indexer) + From("feed f"). + Join("indexer i ON f.indexer_id = i.id"). + Where("i.name = ?", indexer) query, args, err := queryBuilder.ToSql() if err != nil { @@ -105,7 +107,6 @@ func (r *FeedRepo) FindByIndexerIdentifier(ctx context.Context, indexer string) if err := row.Scan(&f.ID, &f.Indexer, &f.Name, &f.Type, &f.Enabled, &f.URL, &f.Interval, &f.Timeout, &f.MaxAge, &apiKey, &cookie, &f.CreatedAt, &f.UpdatedAt); err != nil { return nil, errors.Wrap(err, "error scanning row") - } f.ApiKey = apiKey.String @@ -117,24 +118,25 @@ func (r *FeedRepo) FindByIndexerIdentifier(ctx context.Context, indexer string) func (r *FeedRepo) Find(ctx context.Context) ([]domain.Feed, error) { queryBuilder := r.db.squirrel. Select( - "id", - "indexer", - "name", - "type", - "enabled", - "url", - "interval", - "timeout", - "max_age", - "api_key", - "cookie", - "last_run", - "last_run_data", - "created_at", - "updated_at", + "f.id", + "i.identifier", + "f.name", + "f.type", + "f.enabled", + "f.url", + "f.interval", + "f.timeout", + "f.max_age", + "f.api_key", + "f.cookie", + "f.last_run", + "f.last_run_data", + "f.created_at", + "f.updated_at", ). - From("feed"). - OrderBy("name ASC") + From("feed f"). + Join("indexer i ON f.indexer_id = i.id"). + OrderBy("f.name ASC") query, args, err := queryBuilder.ToSql() if err != nil { @@ -175,7 +177,6 @@ func (r *FeedRepo) Store(ctx context.Context, feed *domain.Feed) error { Insert("feed"). Columns( "name", - "indexer", "type", "enabled", "url", @@ -186,7 +187,6 @@ func (r *FeedRepo) Store(ctx context.Context, feed *domain.Feed) error { ). Values( feed.Name, - feed.Indexer, feed.Type, feed.Enabled, feed.URL, @@ -212,7 +212,6 @@ func (r *FeedRepo) Update(ctx context.Context, feed *domain.Feed) error { queryBuilder := r.db.squirrel. Update("feed"). Set("name", feed.Name). - Set("indexer", feed.Indexer). Set("type", feed.Type). Set("enabled", feed.Enabled). Set("url", feed.URL). diff --git a/internal/indexer/service.go b/internal/indexer/service.go index 7d9e2a9..45c7f61 100644 --- a/internal/indexer/service.go +++ b/internal/indexer/service.go @@ -69,22 +69,17 @@ func NewService(log logger.Logger, config *domain.Config, repo domain.IndexerRep } func (s *service) Store(ctx context.Context, indexer domain.Indexer) (*domain.Indexer, error) { - identifier := indexer.Identifier + // if indexer is rss or torznab do additional cleanup for identifier switch indexer.Implementation { - case "torznab": - // if the name already contains torznab remove it - cleanName := strings.ReplaceAll(strings.ToLower(indexer.Name), "torznab", "") - identifier = slug.Make(fmt.Sprintf("%v-%v", indexer.Implementation, cleanName)) // torznab-name + case "torznab", "rss": + // make lowercase + cleanName := strings.ToLower(indexer.Name) - case "rss": - // if the name already contains rss remove it - cleanName := strings.ReplaceAll(strings.ToLower(indexer.Name), "rss", "") - identifier = slug.Make(fmt.Sprintf("%v-%v", indexer.Implementation, cleanName)) // rss-name + // torznab-name OR rss-name + indexer.Identifier = slug.Make(fmt.Sprintf("%v-%v", indexer.Implementation, cleanName)) } - indexer.Identifier = identifier - i, err := s.repo.Store(ctx, indexer) if err != nil { s.log.Error().Stack().Err(err).Msgf("failed to store indexer: %v", indexer.Name) @@ -92,8 +87,7 @@ func (s *service) Store(ctx context.Context, indexer domain.Indexer) (*domain.In } // add to indexerInstances - err = s.addIndexer(*i) - if err != nil { + if err = s.addIndexer(*i); err != nil { s.log.Error().Stack().Err(err).Msgf("failed to add indexer: %v", indexer.Name) return nil, err } diff --git a/web/src/forms/settings/IndexerForms.tsx b/web/src/forms/settings/IndexerForms.tsx index 0de6473..4f5ae0d 100644 --- a/web/src/forms/settings/IndexerForms.tsx +++ b/web/src/forms/settings/IndexerForms.tsx @@ -2,13 +2,13 @@ import { Fragment, useState } from "react"; import { toast } from "react-hot-toast"; import { useMutation, useQuery } from "react-query"; import Select, { components, ControlProps, InputProps, MenuProps, OptionProps } from "react-select"; -import type { FieldProps, FormikErrors } from "formik"; +import type { FieldProps } from "formik"; import { Field, Form, Formik, FormikValues } from "formik"; import { XMarkIcon } from "@heroicons/react/24/solid"; import { Dialog, Transition } from "@headlessui/react"; -import { sleep, slugify } from "../../utils"; +import { sleep } from "../../utils"; import { queryClient } from "../../App"; import DEBUG from "../../components/debug"; import { APIClient } from "../../api/APIClient"; @@ -183,15 +183,6 @@ const SettingFields = (ind: IndexerDefinition, indexer: string) => { } }; -function slugIdentifier(name: string, prefix?: string) { - const l = name.toLowerCase(); - if (prefix && prefix !== "") { - const r = l.replaceAll(prefix, ""); - return slugify(`${prefix}-${r}`); - } - return slugify(l); -} - type SelectValue = { label: string; value: string; @@ -236,15 +227,11 @@ export function IndexerAddForm({ isOpen, toggle }: AddProps) { ); const onSubmit = (formData: FormikValues) => { - console.log("form: ", formData); const ind = data && data.find(i => i.identifier === formData.identifier); if (!ind) return; if (formData.implementation === "torznab") { - // create slug for indexer identifier as "torznab-indexer_name" - const name = slugIdentifier(formData.name, "torznab"); - const createFeed: FeedCreate = { name: formData.name, enabled: false, @@ -253,7 +240,6 @@ export function IndexerAddForm({ isOpen, toggle }: AddProps) { api_key: formData.feed.api_key, interval: 30, timeout: 60, - indexer: name, indexer_id: 0 }; @@ -266,12 +252,8 @@ export function IndexerAddForm({ isOpen, toggle }: AddProps) { } }); return; - } - - if (formData.implementation === "rss") { - // create slug for indexer identifier as "torznab-indexer_name" - const name = slugIdentifier(formData.name, "rss"); + } else if (formData.implementation === "rss") { const createFeed: FeedCreate = { name: formData.name, enabled: false, @@ -279,7 +261,6 @@ export function IndexerAddForm({ isOpen, toggle }: AddProps) { url: formData.feed.url, interval: 30, timeout: 60, - indexer: name, indexer_id: 0 }; @@ -292,10 +273,8 @@ export function IndexerAddForm({ isOpen, toggle }: AddProps) { } }); return; - } - - if (formData.implementation === "irc") { + } else if (formData.implementation === "irc") { const channels: IrcChannel[] = []; if (ind.irc?.channels.length) { ind.irc.channels.forEach(element => { diff --git a/web/src/types/Feed.d.ts b/web/src/types/Feed.d.ts index 86b4292..0388158 100644 --- a/web/src/types/Feed.d.ts +++ b/web/src/types/Feed.d.ts @@ -19,7 +19,6 @@ interface Feed { type FeedType = "TORZNAB" | "RSS"; interface FeedCreate { - indexer: string; name: string; type: FeedType; enabled: boolean;