# frozen_string_literal: true class WordsController < ApplicationController def index @stats = { total: Word.count, unseen: Review.where(status: "new").count, known: Review.where(status: "known").count, learning: Review.where(status: "learning").count, skipped: Review.where(status: "skipped").count, due: Review.due.count } @words = Word.includes(:review).by_text end def create raw = params[:word_list].to_s.strip lines = raw.split("\n").map(&:strip).reject { |l| l.blank? || l.start_with?("#") } imported = 0 skipped = 0 lines.each do |line| text, definition = parse_line(line) next if text.blank? w = Word.new(text: text.strip, definition: definition&.strip.presence) if w.save imported += 1 else skipped += 1 end end flash[:notice] = "Imported #{imported} word#{"s" unless imported == 1}." flash[:alert] = "Skipped #{skipped} (duplicates or invalid)." if skipped > 0 redirect_to words_path end def destroy Word.find(params[:id]).destroy redirect_to words_path, notice: "Removed." end private def parse_line(line) # "word - definition", "word: definition", "word | definition", "word\tdefinition" if (m = line.match(/\A(.+?)\s*(?:\t|-{1,2}|:{1,2}|\|)\s*(.+)\z/)) [ m[1], m[2] ] else [ line, nil ] end end end