diff --git a/internal/actions/actions.go b/internal/actions/actions.go index 026fbfd..16b8a22 100644 --- a/internal/actions/actions.go +++ b/internal/actions/actions.go @@ -150,7 +150,12 @@ func resetHooks() { } func indexGists() { - log.Info().Msg("Indexing all Gists...") + log.Info().Msg("Rebuilding index from scratch...") + if err := index.ResetIndex(); err != nil { + log.Error().Err(err).Msg("Cannot reset index") + return + } + gists, err := db.GetAllGistsRows() if err != nil { log.Error().Err(err).Msg("Cannot get gists") diff --git a/internal/i18n/locales/de-DE.yml b/internal/i18n/locales/de-DE.yml index 5d84498..82523c9 100644 --- a/internal/i18n/locales/de-DE.yml +++ b/internal/i18n/locales/de-DE.yml @@ -192,7 +192,7 @@ admin.actions.sync-db: 'Gists von der Datenbank synchronisieren' admin.actions.git-gc: '„garbage collection“ bei allen git Repositories ausführen' admin.actions.sync-previews: 'Alle Gist Vorschauen synchronisieren' admin.actions.reset-hooks: 'Alle Git server Hooks für alle Repositories synchronisieren' -admin.actions.index-gists: 'Alle Gists Indexieren' +admin.actions.index-gists: 'Suchindex neu aufbauen' admin.id: 'ID' admin.user: 'Benutzer' admin.delete: 'Löschen' @@ -236,7 +236,7 @@ flash.admin.sync-db: 'Synchronisiere Repositories aus der Datenbank...' flash.admin.git-gc: 'Sammle Repositories...' flash.admin.sync-previews: 'Synchronisiere Gist-Vorschauen...' flash.admin.reset-hooks: 'Setze Git-Server-Hooks für alle Repositories zurück...' -flash.admin.index-gists: 'Indiziere alle Gists...' +flash.admin.index-gists: 'Suchindex wird neu aufgebaut...' flash.auth.username-exists: 'Benutzername existiert bereits' flash.auth.invalid-credentials: 'Ungültige Anmeldeinformationen' diff --git a/internal/i18n/locales/en-US.yml b/internal/i18n/locales/en-US.yml index 9c88f72..e686c5e 100644 --- a/internal/i18n/locales/en-US.yml +++ b/internal/i18n/locales/en-US.yml @@ -292,7 +292,7 @@ admin.actions.sync-db: Synchronize gists from database admin.actions.git-gc: Garbage collect all git repositories admin.actions.sync-previews: Synchronize all gists previews admin.actions.reset-hooks: Reset Git server hooks for all repositories -admin.actions.index-gists: Index all gists +admin.actions.index-gists: Rebuild search index admin.actions.sync-gist-languages: Synchronize all gists languages admin.id: ID admin.user: User @@ -338,7 +338,7 @@ flash.admin.sync-db: Syncing repositories from database... flash.admin.git-gc: Garbage collecting repositories... flash.admin.sync-previews: Syncing Gist previews... flash.admin.reset-hooks: Resetting Git server hooks for all repositories... -flash.admin.index-gists: Indexing all gists... +flash.admin.index-gists: Rebuilding search index... flash.admin.sync-gist-languages: Syncing Gist languages... flash.auth.username-exists: Username already exists diff --git a/internal/i18n/locales/es-ES.yml b/internal/i18n/locales/es-ES.yml index 2a5132a..4200e8f 100644 --- a/internal/i18n/locales/es-ES.yml +++ b/internal/i18n/locales/es-ES.yml @@ -213,7 +213,7 @@ admin.invitations: 'Invitaciones' admin.invitations.create: 'Crear invitación' admin.actions.sync-previews: 'Sincronizar todas las vistas previas de gists' admin.actions.reset-hooks: 'Resetear los hooks de Git en todos los repositorios' -admin.actions.index-gists: 'Indexar todos los gists' +admin.actions.index-gists: 'Reconstruir índice de búsqueda' admin.config-link-overriden: 'sobrescrito' admin.invitations.help: 'Las invitaciones se pueden usar para crear una cuenta aunque el registro esté deshabilitado.' admin.invitations.max_uses: 'Cantidad máxima de usos' @@ -231,7 +231,7 @@ flash.admin.sync-db: 'Sincronizando repositorios desde la base de datos...' flash.admin.git-gc: 'Recolectando basura en los repositorios...' flash.admin.sync-previews: 'Sincronizando vistas previas de gists...' flash.admin.reset-hooks: 'Reseteando hooks del servidor Git en todos los repositorios...' -flash.admin.index-gists: 'Indexando todos los gists...' +flash.admin.index-gists: 'Reconstruyendo índice de búsqueda...' flash.auth.username-exists: 'El nombre de usuario ya existe' flash.auth.invalid-credentials: 'Credenciales incorrectas' flash.auth.account-linked-oauth: 'Cuenta vinculada a %s' diff --git a/internal/i18n/locales/fr-FR.yml b/internal/i18n/locales/fr-FR.yml index 76df799..236fba6 100644 --- a/internal/i18n/locales/fr-FR.yml +++ b/internal/i18n/locales/fr-FR.yml @@ -193,7 +193,7 @@ admin.actions.reset-hooks: Réinitialiser les hooks de Git pour tous les dépôt gist.new.url: URL gist.search.no-results: Aucun gist trouvé settings.unlink-gitlab-account: Détacher le compte GitLab -admin.actions.index-gists: Indexer tous les gists +admin.actions.index-gists: Reconstruire l'index de recherche gist.new.preview: 'Aperçu' gist.new.create-a-new-gist: 'Créer un nouveau gist' gist.edit.edit-gist: 'Modifier %s' @@ -231,7 +231,7 @@ flash.admin.sync-db: 'Synchronisation des dépôts à partir de la base de donn flash.admin.git-gc: 'Nettoyage des dépôts...' flash.admin.sync-previews: 'Synchronisation des aperçus du Gist...' flash.admin.reset-hooks: 'Réinitialisation des hooks du serveur Git pour tous les dépôts...' -flash.admin.index-gists: 'Indexation de tous les gists...' +flash.admin.index-gists: 'Reconstruction de l''index de recherche...' flash.auth.username-exists: 'Nom d''utilisateur déjà utilisé' flash.auth.invalid-credentials: 'Identifiants non valides' flash.auth.account-linked-oauth: 'Compte lié à %s' diff --git a/internal/i18n/locales/hu-HU.yml b/internal/i18n/locales/hu-HU.yml index cc00d0b..61e091b 100644 --- a/internal/i18n/locales/hu-HU.yml +++ b/internal/i18n/locales/hu-HU.yml @@ -170,7 +170,7 @@ admin.actions.sync-db: Gistek szinkronizálása az adatbázissal admin.actions.git-gc: Használatlan git repository-k eltávolítása admin.actions.sync-previews: Gist előnézetek szinkronizálása admin.actions.reset-hooks: Git server hook-ok alaphelyzetbe állítása minden repository-nál -admin.actions.index-gists: Gistek indexelése +admin.actions.index-gists: Keresési index újraépítése admin.id: Azonosító admin.user: Felhasználó admin.delete: Törlés diff --git a/internal/i18n/locales/it_IT.yml b/internal/i18n/locales/it_IT.yml index 2560722..395330b 100644 --- a/internal/i18n/locales/it_IT.yml +++ b/internal/i18n/locales/it_IT.yml @@ -191,7 +191,7 @@ admin.actions.sync-db: 'Sincronizza gists dal database' admin.actions.git-gc: 'Esegui la garbage collection da tutti i repositories' admin.actions.sync-previews: 'Sincronizza tutte le anteprime dei gists' admin.actions.reset-hooks: 'Resetta tutti gli hook del server Git per tutti i repositories' -admin.actions.index-gists: 'Indicizza tutti i gists' +admin.actions.index-gists: 'Ricostruisci indice di ricerca' admin.id: 'ID' admin.user: 'Utente' admin.delete: 'Elimina' @@ -235,7 +235,7 @@ flash.admin.sync-db: 'Sincronizzando i repositories dal database...' flash.admin.git-gc: 'Eseguendo il garbage collector dei repositories...' flash.admin.sync-previews: 'Sincronizzando le anteprime dei gists...' flash.admin.reset-hooks: 'Resettando gli hook di Git per tutti i repositories...' -flash.admin.index-gists: 'Indicizzando tutti i gists...' +flash.admin.index-gists: 'Ricostruzione indice di ricerca...' flash.auth.username-exists: 'Il nome utente esiste già' flash.auth.invalid-credentials: 'Credenziali errate' diff --git a/internal/i18n/locales/pl_PL.yml b/internal/i18n/locales/pl_PL.yml index 43c43ce..99f8080 100644 --- a/internal/i18n/locales/pl_PL.yml +++ b/internal/i18n/locales/pl_PL.yml @@ -227,7 +227,7 @@ admin.actions.sync-db: 'Synchronizuj Gisty z bazy danych' admin.actions.git-gc: 'Zbierz śmieci we wszystkich repozytoriach Git' admin.actions.sync-previews: 'Synchronizuj podglądy wszystkich Gistów' admin.actions.reset-hooks: 'Zresetuj hooki serwera Git dla wszystkich repozytoriów' -admin.actions.index-gists: 'Indeksuj wszystkie Gisty' +admin.actions.index-gists: 'Przebuduj indeks wyszukiwania' admin.id: 'ID' admin.user: 'Użytkownik' admin.delete: 'Usuń' @@ -271,7 +271,7 @@ flash.admin.sync-db: 'Synchronizowanie repozytoriów z bazy danych...' flash.admin.git-gc: 'Zbieranie śmieci w repozytoriach...' flash.admin.sync-previews: 'Synchronizowanie podglądów Gistów...' flash.admin.reset-hooks: 'Resetowanie hooków serwera Git dla wszystkich repozytoriów...' -flash.admin.index-gists: 'Indeksowanie wszystkich Gistów...' +flash.admin.index-gists: 'Przebudowywanie indeksu wyszukiwania...' flash.auth.username-exists: 'Nazwa użytkownika już istnieje' flash.auth.invalid-credentials: 'Niepoprawne dane logowania' diff --git a/internal/i18n/locales/ru-RU.yml b/internal/i18n/locales/ru-RU.yml index d278aad..1dd27f5 100644 --- a/internal/i18n/locales/ru-RU.yml +++ b/internal/i18n/locales/ru-RU.yml @@ -214,7 +214,7 @@ admin.invitations: 'Инвайты' admin.invitations.create: 'Создать инвайт' admin.actions.sync-previews: 'Обновить предпросмотры всех фрагментов' admin.actions.reset-hooks: 'Сбросить хуки Git-сервера для всех репозиториев' -admin.actions.index-gists: 'Проиндексировать все фрагменты' +admin.actions.index-gists: 'Перестроить поисковый индекс' validation.should-not-be-empty: 'Поле %s не должно быть пустым' admin.invitations.help: 'Инвайты используются для создания аккаунта, даже когда регистрация запрещена.' admin.invitations.max_uses: 'Максимальное количество использований' @@ -232,7 +232,7 @@ flash.admin.sync-db: 'Выполняется синхронизация репо flash.admin.git-gc: 'Сборка мусора в репозиториях…' flash.admin.sync-previews: 'Обновление предпросмотров фрагментов…' flash.admin.reset-hooks: 'Пересоздание Git-хуков для всех репозиториев…' -flash.admin.index-gists: 'Выполняется индексация фрагментов…' +flash.admin.index-gists: 'Перестроение поискового индекса…' flash.auth.username-exists: 'Такое имя пользователя уже занято' flash.auth.invalid-credentials: 'Некорректные данные для входа' flash.auth.account-linked-oauth: 'Учётная запись связана с %s' diff --git a/internal/i18n/locales/tr-TR.yml b/internal/i18n/locales/tr-TR.yml index c78ac1a..4ded186 100644 --- a/internal/i18n/locales/tr-TR.yml +++ b/internal/i18n/locales/tr-TR.yml @@ -191,7 +191,7 @@ admin.actions.sync-db: Gistleri veri tabanından senkronize et admin.actions.git-gc: Tüm Git depolarındaki gereksiz verileri temizle admin.actions.sync-previews: Tüm gist önizlemelerini senkronize et admin.actions.reset-hooks: Tüm depolar için Git sunucu kancalarını sıfırla -admin.actions.index-gists: Tüm gistleri indeksle +admin.actions.index-gists: Arama dizinini yeniden oluştur admin.id: ID admin.user: Kullanıcı admin.delete: Sil @@ -234,7 +234,7 @@ flash.admin.sync-db: Depolar veri tabanından senkronize ediliyor... flash.admin.git-gc: Depolardan gereksiz veriler temizleniyor... flash.admin.sync-previews: Gist önizlemeleri senkronize ediliyor... flash.admin.reset-hooks: Tüm depolar için Git sunucusu kancaları sıfırlanıyor... -flash.admin.index-gists: Tüm gistler indeksleniyor... +flash.admin.index-gists: Arama dizini yeniden oluşturuluyor... flash.auth.username-exists: Kullanıcı adı zaten mevcut flash.auth.invalid-credentials: Geçersiz kimlik bilgileri diff --git a/internal/i18n/locales/uk-UK.yml b/internal/i18n/locales/uk-UK.yml index 3d0fc21..25f9156 100644 --- a/internal/i18n/locales/uk-UK.yml +++ b/internal/i18n/locales/uk-UK.yml @@ -192,7 +192,7 @@ admin.actions.sync-db: Синхронізувати gists з базою дани admin.actions.git-gc: Збір сміття з репозиторіїв Git admin.actions.sync-previews: Синхронізувати всі gists перегляди admin.actions.reset-hooks: Скинути серверні Git hooks для всіх репозиторіїв -admin.actions.index-gists: Проіндексувати всі gists +admin.actions.index-gists: Перебудувати пошуковий індекс admin.id: ID admin.user: Користувач admin.delete: Видалити @@ -236,7 +236,7 @@ flash.admin.sync-db: Синхронізація репозиторіїв за б flash.admin.git-gc: Збір сміття з репозиторіїв... flash.admin.sync-previews: Синхронізація Gist переглядів... flash.admin.reset-hooks: Скидання cерверниз Git hooks для всіх репозиторіїв... -flash.admin.index-gists: Індексація всіх gists... +flash.admin.index-gists: Перебудова пошукового індексу... flash.auth.username-exists: Це ім'я користувача вже існує flash.auth.invalid-credentials: Недійсні облікові дані diff --git a/internal/i18n/locales/zh-CN.yml b/internal/i18n/locales/zh-CN.yml index d72f022..9f21828 100644 --- a/internal/i18n/locales/zh-CN.yml +++ b/internal/i18n/locales/zh-CN.yml @@ -214,7 +214,7 @@ admin.invitations: '邀请' admin.invitations.create: '创建邀请' admin.actions.sync-previews: '同步所有 Gists 预览' admin.actions.reset-hooks: '重置所有存储库的 Git 服务 hooks' -admin.actions.index-gists: '索引所有 Gists' +admin.actions.index-gists: '重建搜索索引' admin.invitations.help: '即使在禁用注册功能的情况下,邀请功能也可用于创建帐户。' admin.invitations.max_uses: '最多使用次数' admin.invitations.expires_at: '过期时间' @@ -231,7 +231,7 @@ flash.admin.sync-db: '正在从数据库同步存储库...' flash.admin.git-gc: '正在进行存储库垃圾回收...' flash.admin.sync-previews: '正在同步 Gist 预览...' flash.admin.reset-hooks: '正在重置所有存储库的 Git 服务挂钩...' -flash.admin.index-gists: '正在索引所有 Gists...' +flash.admin.index-gists: '正在重建搜索索引...' flash.auth.username-exists: '用户名已存在' flash.auth.invalid-credentials: '无效的凭证' flash.auth.account-linked-oauth: '帐户已关联到 %s' diff --git a/internal/i18n/locales/zh-TW.yml b/internal/i18n/locales/zh-TW.yml index e2e5fe6..22234c5 100644 --- a/internal/i18n/locales/zh-TW.yml +++ b/internal/i18n/locales/zh-TW.yml @@ -190,7 +190,7 @@ gist.search.no-results: 沒有找到任何 Gists gist.search.help.title: Gists 的標題 gist.search.help.filename: Gists 的檔案名稱 gist.search.help.language: Gists 的程式語言 -admin.actions.index-gists: 索引所有的 Gists +admin.actions.index-gists: 重建搜尋索引 gist.search.help.user: 由使用者建立的 Gists gist.search.found: 已找到 Gists gist.search.help.extension: Gists 的副檔名 diff --git a/internal/index/bleve.go b/internal/index/bleve.go index 00369fe..4abef73 100644 --- a/internal/index/bleve.go +++ b/internal/index/bleve.go @@ -2,6 +2,8 @@ package index import ( "errors" + "fmt" + "os" "strconv" "github.com/blevesearch/bleve/v2" @@ -82,6 +84,15 @@ func (i *BleveIndexer) open() (bleve.Index, error) { return bleve.New(i.path, mapping) } +func (i *BleveIndexer) Reset() error { + i.Close() + if err := os.RemoveAll(i.path); err != nil { + return fmt.Errorf("failed to remove Bleve index directory: %w", err) + } + log.Info().Msg("Bleve index directory removed, re-creating index") + return i.Init() +} + func (i *BleveIndexer) Close() { if i == nil || i.index == nil { return diff --git a/internal/index/indexer.go b/internal/index/indexer.go index 445ddfd..25907a8 100644 --- a/internal/index/indexer.go +++ b/internal/index/indexer.go @@ -2,10 +2,11 @@ package index import ( "fmt" - "github.com/rs/zerolog/log" - "github.com/thomiceli/opengist/internal/config" "path/filepath" "sync/atomic" + + "github.com/rs/zerolog/log" + "github.com/thomiceli/opengist/internal/config" ) var atomicIndexer atomic.Pointer[Indexer] @@ -13,6 +14,7 @@ var atomicIndexer atomic.Pointer[Indexer] type Indexer interface { Init() error Close() + Reset() error Add(gist *Gist) error Remove(gistID uint) error Search(query string, metadata SearchGistMetadata, userId uint, page int) ([]uint, uint64, map[string]int, error) @@ -84,6 +86,19 @@ func Close() { atomicIndexer.Store(nil) } +func ResetIndex() error { + if !IndexEnabled() { + return nil + } + + idx := atomicIndexer.Load() + if idx == nil { + return fmt.Errorf("indexer is not initialized") + } + + return (*idx).Reset() +} + func AddInIndex(gist *Gist) error { if !IndexEnabled() { return nil diff --git a/internal/index/meilisearch.go b/internal/index/meilisearch.go index ba35799..9bef5b3 100644 --- a/internal/index/meilisearch.go +++ b/internal/index/meilisearch.go @@ -72,6 +72,21 @@ func (i *MeiliIndexer) open() (meilisearch.IndexManager, error) { return i.client.Index(i.indexName), nil } +func (i *MeiliIndexer) Reset() error { + if i.client != nil { + taskInfo, err := i.client.DeleteIndex(i.indexName) + if err != nil { + return fmt.Errorf("failed to delete Meilisearch index: %w", err) + } + _, err = i.client.WaitForTask(taskInfo.TaskUID, 0) + if err != nil { + return fmt.Errorf("failed to wait for Meilisearch index deletion: %w", err) + } + log.Info().Msg("Meilisearch index deleted, re-creating index") + } + return i.Init() +} + func (i *MeiliIndexer) Close() { if i.client != nil { i.client.Close()