219 lines
5.3 KiB
Ruby
219 lines
5.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'sinatra'
|
|
require 'json'
|
|
require 'yaml'
|
|
|
|
# Configure Sinatra
|
|
set :port, ENV['PORT'] || 4567
|
|
set :bind, '0.0.0.0'
|
|
set :public_folder, 'public'
|
|
set :views, 'views'
|
|
|
|
# Load responses from YAML file
|
|
RESPONSES = YAML.load_file('responses.yml')
|
|
DEFAULT_LANGUAGE = 'en'
|
|
|
|
# Helper method to get a random "no" response
|
|
def get_no_response(lang = DEFAULT_LANGUAGE)
|
|
language = RESPONSES[lang] || RESPONSES[DEFAULT_LANGUAGE]
|
|
language['responses'].sample
|
|
end
|
|
|
|
# Helper method to get language name
|
|
def get_language_name(lang)
|
|
language = RESPONSES[lang] || RESPONSES[DEFAULT_LANGUAGE]
|
|
language['name']
|
|
end
|
|
|
|
# Helper method to get available languages
|
|
def get_available_languages
|
|
RESPONSES.map { |code, data| { code: code, name: data['name'] } }
|
|
end
|
|
|
|
# Helper method to determine language from request
|
|
def determine_language(params, headers)
|
|
# Priority: URL parameter > Accept-Language header > default
|
|
return params[:lang] if params[:lang] && RESPONSES[params[:lang]]
|
|
|
|
# Parse Accept-Language header
|
|
if headers['HTTP_ACCEPT_LANGUAGE']
|
|
accepted_langs = headers['HTTP_ACCEPT_LANGUAGE']
|
|
.split(',')
|
|
.map { |lang| lang.split(';').first.downcase.strip }
|
|
|
|
# Check for exact matches first
|
|
accepted_langs.each do |lang|
|
|
return lang if RESPONSES[lang]
|
|
|
|
# Check for language family matches (e.g., 'nb' or 'nn' -> 'no')
|
|
case lang
|
|
when /^zh/ # Chinese variants
|
|
return 'zh'
|
|
when /^es/ # Spanish variants
|
|
return 'es'
|
|
when /^hi/ # Hindi variants
|
|
return 'hi'
|
|
when /^ar/ # Arabic variants
|
|
return 'ar'
|
|
when /^bn/ # Bengali variants
|
|
return 'bn'
|
|
when /^pt/ # Portuguese variants
|
|
return 'pt'
|
|
when /^ru/ # Russian variants
|
|
return 'ru'
|
|
when /^ja/ # Japanese variants
|
|
return 'ja'
|
|
when /^tr/ # Turkish variants
|
|
return 'tr'
|
|
when /^ko/ # Korean variants
|
|
return 'ko'
|
|
when /^fr/ # French variants
|
|
return 'fr'
|
|
when /^de/ # German variants
|
|
return 'de'
|
|
when /^vi/ # Vietnamese variants
|
|
return 'vi'
|
|
when /^it/ # Italian variants
|
|
return 'it'
|
|
when /^th/ # Thai variants
|
|
return 'th'
|
|
when /^pl/ # Polish variants
|
|
return 'pl'
|
|
when /^nl/ # Dutch variants
|
|
return 'nl'
|
|
when /^ur/ # Urdu variants
|
|
return 'ur'
|
|
when /^ms/ # Malay variants
|
|
return 'ms'
|
|
when /^nb|nn/ # Norwegian Bokmål/Nynorsk
|
|
return 'no'
|
|
when /^sv/ # Swedish variants
|
|
return 'sv'
|
|
when /^da/ # Danish variants
|
|
return 'da'
|
|
when /^is/ # Icelandic variants
|
|
return 'is'
|
|
when /^fi/ # Finnish variants
|
|
return 'fi'
|
|
when /^fo/ # Faroese variants
|
|
return 'fo'
|
|
when /^se|smi/ # Sami variants
|
|
return 'smi'
|
|
end
|
|
end
|
|
end
|
|
|
|
DEFAULT_LANGUAGE
|
|
end
|
|
|
|
# Root endpoint - returns HTML by default
|
|
get '/' do
|
|
lang = determine_language(params, request.env)
|
|
no_response = get_no_response(lang)
|
|
|
|
case request.accept.first&.to_s
|
|
when %r{application/json}
|
|
content_type :json
|
|
{
|
|
answer: no_response,
|
|
language: lang,
|
|
language_name: get_language_name(lang),
|
|
timestamp: Time.now.iso8601
|
|
}.to_json
|
|
else
|
|
content_type :html
|
|
erb :index, locals: {
|
|
no_response: no_response,
|
|
language: lang,
|
|
language_name: get_language_name(lang),
|
|
available_languages: get_available_languages
|
|
}
|
|
end
|
|
end
|
|
|
|
# Languages endpoint - list available languages
|
|
get '/languages' do
|
|
content_type :json
|
|
{
|
|
languages: get_available_languages,
|
|
default: DEFAULT_LANGUAGE,
|
|
timestamp: Time.now.iso8601
|
|
}.to_json
|
|
end
|
|
|
|
# Explicit JSON endpoint with language support
|
|
get '/api/no' do
|
|
lang = determine_language(params, request.env)
|
|
|
|
content_type :json
|
|
{
|
|
answer: get_no_response(lang),
|
|
language: lang,
|
|
language_name: get_language_name(lang),
|
|
timestamp: Time.now.iso8601,
|
|
service: 'No as a Service',
|
|
version: '2.0.0'
|
|
}.to_json
|
|
end
|
|
|
|
# Language-specific endpoint
|
|
get '/api/no/:lang' do
|
|
lang = params[:lang]
|
|
|
|
unless RESPONSES[lang]
|
|
content_type :json
|
|
status 404
|
|
return {
|
|
error: 'Language not supported',
|
|
requested: lang,
|
|
available: get_available_languages.map { |l| l[:code] },
|
|
timestamp: Time.now.iso8601
|
|
}.to_json
|
|
end
|
|
|
|
content_type :json
|
|
{
|
|
answer: get_no_response(lang),
|
|
language: lang,
|
|
language_name: get_language_name(lang),
|
|
timestamp: Time.now.iso8601,
|
|
service: 'No as a Service',
|
|
version: '2.0.0'
|
|
}.to_json
|
|
end
|
|
|
|
# Health check endpoint
|
|
get '/health' do
|
|
content_type :json
|
|
{
|
|
status: 'healthy',
|
|
languages_loaded: RESPONSES.keys.size,
|
|
timestamp: Time.now.iso8601
|
|
}.to_json
|
|
end
|
|
|
|
# Catch-all route for any other endpoint
|
|
get '/*' do
|
|
lang = determine_language(params, request.env)
|
|
no_response = get_no_response(lang)
|
|
|
|
case request.accept.first&.to_s
|
|
when %r{application/json}
|
|
content_type :json
|
|
{
|
|
answer: no_response,
|
|
language: lang,
|
|
language_name: get_language_name(lang),
|
|
timestamp: Time.now.iso8601
|
|
}.to_json
|
|
else
|
|
content_type :html
|
|
erb :index, locals: {
|
|
no_response: no_response,
|
|
language: lang,
|
|
language_name: get_language_name(lang),
|
|
available_languages: get_available_languages
|
|
}
|
|
end
|
|
end
|