mirror of
https://github.com/internetee/registry.git
synced 2025-08-16 06:23:57 +02:00
175 lines
5.8 KiB
Ruby
175 lines
5.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Admin
|
|
module Tools
|
|
# Controller for the admin wordcloud generator tool that creates visual representations
|
|
# of the most common words used in domain names
|
|
class WordcloudController < BaseController # rubocop:disable Metrics/ClassLength
|
|
WORDCLOUD_DIR = Rails.root.join('public', 'wordcloud')
|
|
WORDCLOUD_IMAGE_PATH = WORDCLOUD_DIR.join('wordcloud.png')
|
|
WORDCLOUD_CONFIG_PATH = WORDCLOUD_DIR.join('config.json')
|
|
TOP_WORDS_PATH = WORDCLOUD_DIR.join('top_words.txt')
|
|
|
|
before_action :authorize_admin
|
|
before_action :clear_cache, only: :create
|
|
before_action :ensure_wordcloud_dir, only: :create
|
|
|
|
def index
|
|
# Load configuration
|
|
@config = load_wordcloud_config
|
|
|
|
# Setup wordcloud data if image exists
|
|
if File.exist?(WORDCLOUD_IMAGE_PATH)
|
|
setup_wordcloud_data
|
|
else
|
|
@wordcloud_url = nil
|
|
end
|
|
end
|
|
|
|
def create
|
|
# Validate domains file
|
|
if params[:domains_file].present?
|
|
domains_file_path = process_uploaded_file(params[:domains_file])
|
|
return redirect_to admin_tools_wordcloud_path if domains_file_path.nil?
|
|
else
|
|
flash[:alert] = I18n.t('admin.tools.wordcloud_no_file')
|
|
return redirect_to admin_tools_wordcloud_path
|
|
end
|
|
|
|
# Collect and save configuration
|
|
config = build_config_from_params
|
|
File.write(WORDCLOUD_CONFIG_PATH, config.to_json)
|
|
|
|
# Start the background job
|
|
GenerateWordCloudJob.perform_later(domains_file_path.to_s, current_admin_user.id, config)
|
|
redirect_to progress_admin_tools_wordcloud_path
|
|
|
|
rescue StandardError => e
|
|
logger.error "Error starting wordcloud generation: #{e.message}"
|
|
flash[:alert] = "#{I18n.t('admin.tools.wordcloud_error')}: #{e.message}"
|
|
redirect_to admin_tools_wordcloud_path
|
|
end
|
|
|
|
# GET /admin/tools/wordcloud/progress
|
|
def progress
|
|
@progress_key = "wordcloud_progress:#{current_admin_user.id}"
|
|
@progress_data = Rails.cache.fetch(@progress_key) || { status: 'not_started', progress: 0 }
|
|
end
|
|
|
|
# GET /admin/tools/wordcloud/status
|
|
def status
|
|
progress_key = "wordcloud_progress:#{current_admin_user.id}"
|
|
progress_data = Rails.cache.fetch(progress_key) || { status: 'not_started', progress: 0 }
|
|
|
|
render json: progress_data
|
|
end
|
|
|
|
private
|
|
|
|
def ensure_wordcloud_dir
|
|
FileUtils.mkdir_p(WORDCLOUD_DIR) unless Dir.exist?(WORDCLOUD_DIR)
|
|
end
|
|
|
|
def process_uploaded_file(uploaded_file)
|
|
# Create a persistent copy of the uploaded file
|
|
persistent_file_path = Rails.root.join('tmp', "domains_#{Time.now.to_i}.csv")
|
|
|
|
# Copy the file content to a persistent location
|
|
FileUtils.cp(uploaded_file.tempfile.path, persistent_file_path)
|
|
|
|
# Validate file has content
|
|
if File.size(persistent_file_path).zero?
|
|
File.delete(persistent_file_path)
|
|
flash[:alert] = I18n.t('admin.tools.wordcloud_empty_file')
|
|
return nil
|
|
end
|
|
|
|
persistent_file_path
|
|
end
|
|
|
|
def build_config_from_params
|
|
# Base configuration
|
|
config = {
|
|
width: params[:width].presence || 800,
|
|
height: params[:height].presence || 800,
|
|
max_words: params[:max_words].presence || 500,
|
|
background_color: params[:background_color].presence || 'white',
|
|
min_word_length: params[:min_word_length].presence || 2,
|
|
include_numbers: params[:include_numbers] == '1',
|
|
batch_size: params[:batch_size].presence || 500,
|
|
additional_prompt: params[:additional_prompt].presence || nil
|
|
}
|
|
|
|
# Process additional stopwords
|
|
if params[:additional_stopwords].present?
|
|
stopwords = params[:additional_stopwords].downcase.split(/[\s,]+/).reject(&:empty?)
|
|
config[:additional_stopwords] = stopwords if stopwords.any?
|
|
end
|
|
|
|
# Process special terms
|
|
if params[:special_terms].present?
|
|
special_terms = params[:special_terms].split(/[\s,]+/).reject(&:empty?)
|
|
config[:special_terms] = special_terms if special_terms.any?
|
|
end
|
|
|
|
config
|
|
end
|
|
|
|
def load_wordcloud_config
|
|
if File.exist?(WORDCLOUD_CONFIG_PATH)
|
|
begin
|
|
JSON.parse(File.read(WORDCLOUD_CONFIG_PATH))
|
|
rescue JSON::ParserError
|
|
default_wordcloud_config
|
|
end
|
|
else
|
|
default_wordcloud_config
|
|
end
|
|
end
|
|
|
|
def setup_wordcloud_data
|
|
# Add timestamp to prevent caching
|
|
@wordcloud_url = "/wordcloud/wordcloud.png?t=#{File.mtime(WORDCLOUD_IMAGE_PATH).to_i}"
|
|
|
|
# Get the file's modification time and convert to application timezone
|
|
@wordcloud_generated_at = File.mtime(WORDCLOUD_IMAGE_PATH).in_time_zone(Time.zone)
|
|
|
|
# Load top words
|
|
load_top_words
|
|
end
|
|
|
|
def load_top_words
|
|
return unless File.exist?(TOP_WORDS_PATH)
|
|
|
|
@top_words = []
|
|
File.readlines(TOP_WORDS_PATH).each do |line|
|
|
if line =~ /^\d+\.\s+(\w+):\s+(\d+)$/
|
|
@top_words << [$1, $2.to_i]
|
|
end
|
|
end
|
|
end
|
|
|
|
def default_wordcloud_config
|
|
{
|
|
'width' => 800,
|
|
'height' => 800,
|
|
'max_words' => 500,
|
|
'background_color' => 'white',
|
|
'additional_stopwords' => [],
|
|
'include_numbers' => true,
|
|
'min_word_length' => 2,
|
|
'special_terms' => ['e-', 'i-', '2-', '3-', '4-', '.com', 'tr.ee', 'ai', 'web'],
|
|
'batch_size' => 500
|
|
}
|
|
end
|
|
|
|
def authorize_admin
|
|
authorize! :access, :tools
|
|
end
|
|
|
|
def clear_cache
|
|
Rails.cache.delete("wordcloud_progress:#{current_admin_user.id}")
|
|
end
|
|
end
|
|
end
|
|
end
|