Skip to content
Permalink
Browse files

Add docker-bot

  • Loading branch information...
Vitaly Pryakhin
Vitaly Pryakhin committed Dec 26, 2016
1 parent 842431d commit 112afe77acfbb3756fa4983543793d876615729d
@@ -4,3 +4,4 @@ node_modules/
__pycache__
etc/ssl/*
.vscode
docker-bot/radio-t-docker-bot.db
@@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004

http://www.wtfpl.net/

Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. You just DO WHAT THE FUCK YOU WANT TO.
@@ -0,0 +1,8 @@
FROM ruby:2.3.3-onbuild
ADD Gemfile .
ADD Gemfile.lock .
ADD Rakefile .
RUN bundle install
RUN rake db:create
EXPOSE "8080"
CMD ["bundle", "exec", "puma", "-p", "8080", "-e", "production"]
@@ -0,0 +1,7 @@
source 'https://rubygems.org'
ruby "2.3.3"
gem 'sinatra'
gem 'daybreak'
gem 'puma'
gem 'rake'
gem 'json'
@@ -0,0 +1,31 @@
GEM
remote: https://rubygems.org/
specs:
daybreak (0.3.0)
json (2.0.2)
puma (3.6.2)
rack (1.6.5)
rack-protection (1.5.3)
rack
rake (12.0.0)
sinatra (1.4.7)
rack (~> 1.5)
rack-protection (~> 1.4)
tilt (>= 1.3, < 3)
tilt (2.0.5)

PLATFORMS
ruby

DEPENDENCIES
daybreak
json
puma
rake
sinatra

RUBY VERSION
ruby 2.4.0p0

BUNDLED WITH
1.13.7
@@ -0,0 +1,40 @@
#Бот для чата [Радио-Т](https://chat.radio-t.com)

##Описание
Если в чате кто-то жалуется на то, что ведущие слишком долго обсуждают одну из своих излюбленных тем, этот бот сообщит, сколько раз та или иная тема была упомянута в чате в ходе текущего выпуска.
Изначально этот бот проектировался для подсчёта упоминаний слова "докер", но в последствии был доработан для того, чтобы понимать также и упоминание другой популярной темы для обсуждений.

## Примеры
Сообщение:
```json
{
text: "Сколько можно про докер?",
username: "test",
display_name: "test"
}
```

Ответ:
```json
{
bot: "docker-bot",
text: "За текущий выпуск(№518) про докер упоминали уже 1000 раз."
}
```

Сообщение:
```json
{
text: "Сколько можно про apple?",
username: "test",
display_name: "test"
}
```

Ответ:
```json
{
bot: "docker-bot",
text: "За текущий выпуск(№518) про apple упоминали уже 5000000 раз."
}
```
@@ -0,0 +1,17 @@
namespace :db do

require 'daybreak'

task :create do
puts 'Trying to create database...'
db = Daybreak::DB.new "radio-t-docker-bot.db"
if db["created_at"]==nil
db["created_at"] = Time.now
else
puts "Database already created at #{db["created_at"]}"
end
db.flush
db.close
end

end
@@ -0,0 +1,11 @@
bot_name: "docker-bot"
ignored_commands:
- "докер"
- "шмокер"
- "blah blah blah"
test_cases:
- command: "Cколько можно про докер?"
result: "^За текущий выпуск(№\d\d\d) про докер упоминали уже \d* раз.$"

- command: "Cколько можно про apple?"
result: "^За текущий выпуск(№\d\d\d) про apple упоминали уже \d* раз.$"
@@ -0,0 +1,29 @@
class CommandHandler
@@valid_commands = ['сколько можно про докер?',
'сколько можно про docker?',
'сколько можно про эппл?',
'сколько можно про apple?',
]

def initialize(db, podcast)
@db = db
@podcast = podcast
end

def valid_commands
return @@valid_commands
end

def exec(cmd)
case cmd
when 'сколько можно про докер?', 'сколько можно про docker?'
count = @db.get_count(@podcast.get_current_podcast_number, 'docker')
return "За текущий выпуск(№#{@podcast.get_current_podcast_number}) про докер упоминали уже #{count} раз."
when 'сколько можно про эппл?', 'сколько можно про apple?'
count = @db.get_count(@podcast.get_current_podcast_number, 'apple')
return "За текущий выпуск(№#{@podcast.get_current_podcast_number}) про эппл упоминали уже #{count} раз."
else
return 'Так. Вы меня запутали.'
end
end
end
@@ -0,0 +1,2 @@
require './docker-bot'
run Sinatra::Application
@@ -0,0 +1,38 @@
require 'daybreak'

class DatabaseHandler
@@flush_period = 30

def initialize
@db = Daybreak::DB.new "radio-t-docker-bot.db"
@last_flush_performed = Time.now
end

def add(podcast_number, word, word_count)
if @db[podcast_number] == nil
@db[podcast_number] = {}
@db[podcast_number][word]=word_count
elsif @db[podcast_number][word] == nil
@db[podcast_number][word]=word_count
else
@db[podcast_number][word]+=word_count
end
if Time.now - @last_flush_performed > @@flush_period
self.flush
end
end

def get_count(podcast_number, word)
begin
count = @db[podcast_number][word]
rescue
count = 0
end
return count
end

def flush
@db.flush
end

end
@@ -0,0 +1,44 @@
require "sinatra"
require 'json'
require './db.rb'
require './podcast.rb'
require './commands.rb'

db = DatabaseHandler.new
podcast = PodcastHandler.new
cmd = CommandHandler.new(db, podcast)

words = [{:word => 'apple', :regex=> /apple|эппл/},
{:word => 'docker', :regex=> /docker|докер/}
]

post '/event' do
request.body.rewind
@request_payload = JSON.parse request.body.read
@podcast_number = podcast.get_current_podcast_number

message = @request_payload['text']
if cmd.valid_commands.include? message.downcase
resp = {:text => cmd.exec(message.downcase), :bot => 'docker-bot'}
content_type 'application/json'
status 201
body JSON.generate(resp)
else
words.each do |word|
word_count = message.downcase.scan(word[:regex]).length
db.add(@podcast_number,word[:word],word_count)
end
status 417
body ''
end
end

get '/info' do
content_type 'application/json'
info = {
:author => 'https://github.com/naushniki',
:info => 'Если в чате кто-то жалуется на то, что ведущие слишком долго обсуждают одну из своих излюбленных тем, этот бот сообщит, сколько раз та или иная тема была упомянута в чате в ходе текущего выпуска.',
:commands => cmd.valid_commands
}
body JSON.generate(info)
end
@@ -0,0 +1,4 @@
docker-bot:
build: .
ports:
- "8080:8080"
@@ -0,0 +1,38 @@
require 'rss'
require 'open-uri'

class PodcastHandler
@@rss_feed_url = 'http://feeds.rucast.net/radio-t'
def initialize
@current_podcast_number = nil
@last_time_podcast_number_was_successfully_detected = nil
self.detect_current_podcast_number
end

def detect_current_podcast_number
open(@@rss_feed_url) do |rss|
feed = RSS::Parser.parse(rss, false)
podcast_numbers = []
feed.items.each do |item|
number = item.title.scan(/\d\d\d/).last.to_i
podcast_numbers.push(number)
end
@current_podcast_number = podcast_numbers.max+1
@last_time_podcast_number_was_successfully_detected = Time.now
end
end

def get_current_podcast_number
begin
if Time.now.saturday? and Time.now - @last_time_podcast_number_was_successfully_detected > 60*60*24
self.detect_current_podcast_number
return @current_podcast_number
else
return @current_podcast_number
end
rescue
return @current_podcast_number
end
end

end

0 comments on commit 112afe7

Please sign in to comment.
You can’t perform that action at this time.