This commit is contained in:
Ole-Morten Duesund 2025-05-13 07:58:31 +02:00
commit 871d8975ca
13 changed files with 653 additions and 0 deletions

7
extra/no-as-a-service/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
*.log
*.gem
.bundle
vendor/
.DS_Store
.env

View file

@ -0,0 +1,19 @@
FROM ruby:3.2
# Set working directory
WORKDIR /app
# Copy dependencies
COPY Gemfile .
# Install Sinatra and other gems
RUN bundle install
# Copy application
COPY app.rb .
# Expose Sinatra port
EXPOSE 4567
# Run the app
CMD ["ruby", "app.rb"]

View file

@ -0,0 +1,8 @@
FROM ruby:3.2
WORKDIR /usr/src/app
COPY Gemfile .
RUN bundle install
COPY app.rb .
EXPOSE 4567
CMD ["ruby", "app.rb"]

View file

@ -0,0 +1,3 @@
source 'https://rubygems.org'
gem 'sinatra'

View file

@ -0,0 +1,12 @@
---
### 📄 `LICENSE`
You can use the [MIT License](https://opensource.org/license/mit/) if you want to keep it simple:
```text
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy...

View file

@ -0,0 +1,18 @@
# Polite No Service
A simple Ruby + Sinatra microservice that returns polite (or impolite) ways to say "No" in various languages.
## 🌐 Example
JSON:
http://localhost:4567/?language=Japanese&tone=Polite
HTML:
http://localhost:4567/?style=Blunt&format=html
## 🚀 Run with Docker
```bash
docker build -t polite-no-service .
docker run -p 4567:4567 polite-no-service

View file

@ -0,0 +1,302 @@
require 'sinatra'
require 'json'
set :port, 4567
PHRASES = [
# English Phrases
{
language: "English",
style: "Formal",
tone: "Polite",
phrase: "I'm afraid I must decline, but thank you for asking."
},
{
language: "English",
style: "Informal",
tone: "Polite",
phrase: "Nah, but I appreciate it!"
},
{
language: "English",
style: "Blunt",
tone: "Impolite",
phrase: "Nope. Not interested."
},
{
language: "English",
style: "Sarcastic",
tone: "Impolite",
phrase: "Oh sure, let me cancel everything for *that*."
},
{
language: "English",
style: "Apologetic",
tone: "Empathetic",
phrase: "I'm so sorry, but I really can't manage this right now."
},
{
language: "English",
style: "Professional",
tone: "Neutral",
phrase: "After careful consideration, I must respectfully decline."
},
{
language: "English",
style: "Witty",
tone: "Playful",
phrase: "I'd love to, but my schedule is already having a midlife crisis."
},
{
language: "English",
style: "Overexplained",
tone: "Anxious",
phrase: "I've thought about this for hours, analyzed every possible angle, and I just can't see a way to make this work."
},
{
language: "English",
style: "Dramatic",
tone: "Emotional",
phrase: "The universe is conspiring to prevent me from saying yes!"
},
{
language: "English",
style: "Cryptic",
tone: "Mysterious",
phrase: "Some things are not meant to be, and this is one of them."
},
# French Phrases
{
language: "French",
style: "Formal",
tone: "Polite",
phrase: "Je suis désolé, mais je dois refuser poliment."
},
{
language: "French",
style: "Informal",
tone: "Polite",
phrase: "Non merci, pas aujourd'hui."
},
{
language: "French",
style: "Blunt",
tone: "Impolite",
phrase: "Non. C'est tout."
},
{
language: "French",
style: "Sarcastic",
tone: "Impolite",
phrase: "Ah oui, bien sûr... Et pendant qu'on y est!"
},
{
language: "French",
style: "Poetic",
tone: "Refined",
phrase: "Hélas, mon cœur doit décliner votre proposition."
},
{
language: "French",
style: "Diplomatic",
tone: "Neutral",
phrase: "Je comprends votre proposition, mais je ne peux pas accepter."
},
{
language: "French",
style: "Dramatic",
tone: "Emotional",
phrase: "Mon Dieu! C'est absolument impossible!"
},
{
language: "French",
style: "Philosophical",
tone: "Reflective",
phrase: "Les circonstances de la vie me poussent à refuser."
},
{
language: "French",
style: "Witty",
tone: "Playful",
phrase: "Mon agenda et moi sommes en pleine négociation, et la réponse est non."
},
{
language: "French",
style: "Overexplained",
tone: "Anxious",
phrase: "J'ai passé des heures à réfléchir, et franchement, c'est un non catégorique."
},
# Japanese Phrases
{
language: "Japanese",
style: "Formal",
tone: "Polite",
phrase: "申し訳ありませんが、お断りさせていただきます。"
},
{
language: "Japanese",
style: "Informal",
tone: "Polite",
phrase: "ごめん、ちょっと無理かも。"
},
{
language: "Japanese",
style: "Cold",
tone: "Impolite",
phrase: "無理です。以上。"
},
{
language: "Japanese",
style: "Humble",
tone: "Polite",
phrase: "誠に恐縮ですが、お断りさせていただきます。"
},
{
language: "Japanese",
style: "Indirect",
tone: "Diplomatic",
phrase: "少し難しい状況でして..."
},
{
language: "Japanese",
style: "Apologetic",
tone: "Empathetic",
phrase: "本当に申し訳ありません。"
},
{
language: "Japanese",
style: "Poetic",
tone: "Refined",
phrase: "心の中で、静かに拒絶の花が咲きます。"
},
{
language: "Japanese",
style: "Dramatic",
tone: "Emotional",
phrase: "天と地が、この申し出を許しません!"
},
{
language: "Japanese",
style: "Cryptic",
tone: "Mysterious",
phrase: "運命は別の道を示しています。"
},
{
language: "Japanese",
style: "Overexplained",
tone: "Anxious",
phrase: "深く考えた末、どうしても受け入れられない理由が山ほどあります。"
},
# Sign Language Conceptual Variations
{
language: "Sign Language",
style: "Formal",
tone: "Polite",
phrase: "Respectful decline with a gentle head shake and apologetic facial expression."
},
{
language: "Sign Language",
style: "Blunt",
tone: "Impolite",
phrase: "Sharp, abrupt hand wave signaling absolute rejection."
},
{
language: "Sign Language",
style: "Dramatic",
tone: "Emotional",
phrase: "Exaggerated full-body 'No' with wide eyes and dramatic hand gesture."
},
{
language: "Sign Language",
style: "Playful",
tone: "Humorous",
phrase: "Cheeky wink followed by a playful 'No' sign."
},
{
language: "Sign Language",
style: "Subtle",
tone: "Diplomatic",
phrase: "Soft, almost imperceptible head tilt with a nuanced hand movement."
},
# Emoji Communication
{
language: "Emoji",
style: "Formal",
tone: "Polite",
phrase: "🙇‍♀️🚫 (Bowing apologetically with a stop sign)"
},
{
language: "Emoji",
style: "Casual",
tone: "Impolite",
phrase: "🙅‍♂️😤 (Crossed arms with frustrated face)"
},
{
language: "Emoji",
style: "Dramatic",
tone: "Emotional",
phrase: "😱🚫🌋 (Shocked face, stop sign, volcano)"
},
{
language: "Emoji",
style: "Witty",
tone: "Playful",
phrase: "🤷‍♀️🤦‍♂️😂 (Shrug, facepalm, laughing)"
},
{
language: "Emoji",
style: "Cryptic",
tone: "Mysterious",
phrase: "🕳️🔮❌ (Hole, crystal ball, cancel)"
}
]
# Method to find phrases by language or style
def find_phrases(language: nil, style: nil)
PHRASES.select do |phrase|
(language.nil? || phrase[:language] == language) &&
(style.nil? || phrase[:style] == style)
end
end
# Method to generate a random decline phrase
def random_decline
PHRASES.sample
end
# Method to find most dramatic phrases
def dramatic_phrases
find_phrases(style: "Dramatic")
end
# Method to get unique languages
def languages
PHRASES.map { |phrase| phrase[:language] }.uniq
end
get '/' do
content_type :json
language = params['language']
style = params['style']
tone = params['tone']
format = params['format'] || 'json'
filtered = PHRASES.select do |phrase|
(language.nil? || phrase[:language].casecmp(language) == 0) &&
(style.nil? || phrase[:style].casecmp(style) == 0) &&
(tone.nil? || phrase[:tone].casecmp(tone) == 0)
end
case format
when 'html'
content_type :html
"<ul>" + filtered.map { |p| "<li><strong>#{p[:language]}</strong> (#{p[:style]}, #{p[:tone]}): #{p[:phrase]}</li>" }.join + "</ul>"
else
JSON.pretty_generate(filtered)
end
end