lexivo/app/controllers/words_controller.rb
viktorvsk 3992ba64be
Some checks failed
CI / Lint & Test (push) Has been cancelled
Deploy Status Page / Build & Deploy (push) Has been cancelled
feat: handle word_file upload in create action
2026-04-23 04:51:47 +00:00

62 lines
1.5 KiB
Ruby

# 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
if params[:word_file].present?
file_content = params[:word_file].read.force_encoding("UTF-8")
raw = "#{raw}\n#{file_content}".strip
end
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