-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatické postovanie do fóra. #7
Changes from 5 commits
9bcbfd9
cea5844
6412f1b
dcfd7bd
7e3cb8c
b788a24
083d9c8
dfcd0f0
bffdcb3
9aa28ca
a9921e8
29af179
9cdbc24
0c3eacd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
require 'discourse_api' | ||
|
||
class DiscourseClient < DiscourseApi::Client | ||
class Error < StandardError | ||
attr_reader :wrapped_exception | ||
|
||
def initialize(exception = $ERROR_INFO) | ||
@wrapped_exception = exception | ||
exception.respond_to?(:message) ? super(exception.message) : super(exception.to_s) | ||
end | ||
end | ||
|
||
def create_topic(args = {}) | ||
super(args) | ||
rescue DiscourseApi::Error => e | ||
raise Error.new(e) | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
require_relative 'notifiers/base' | ||
require_relative 'notifiers/slack' | ||
require_relative 'notifiers/discourse' | ||
|
||
module Notifiers | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Toto sa mne moc neosvedcilo, resp. ak namespace tak potom There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Neosvedcilo v akom zmysle, ake problemy, alebo komplikacie tam hrozia? Na namespacingu sa najprv ujednotme, ten sa mi nechce prerabat iterativne :). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Za mna to schovajme do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moze byt. Upravim. |
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module Notifiers | ||
class Base | ||
def matching_announcements_found(page_info, announcements) | ||
fail 'Interface method not implemented!' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. na toto je fajn gem There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A chceme dalsi gem? Nemam problem to prehodit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dajme, mozeme potom vyrazit tie testy na metody. Druha moznost je shared test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dame gem. |
||
end | ||
|
||
def no_announcements_found | ||
fail 'Interface method not implemented!' | ||
end | ||
|
||
def new_issue_not_published | ||
fail 'Interface method not implemented!' | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
require_relative './base' | ||
|
||
module Notifiers | ||
class Discourse < Base | ||
def initialize(discourse_client, category = 'Štátne projekty') | ||
@client = discourse_client | ||
@category = category | ||
end | ||
|
||
def no_announcements_found | ||
# Does nothing for now. | ||
end | ||
|
||
def new_issue_not_published | ||
# Does nothing for now. | ||
end | ||
|
||
def matching_announcements_found(page_info, announcements) | ||
announcements.each do |a| | ||
begin | ||
topic = announcement_to_topic(a) | ||
@client.create_topic(title: topic[:title], | ||
raw: topic[:body], | ||
category: @category) | ||
rescue @client.class::Error => e | ||
# discourse api/faraday bug - most probably | ||
next if e.message == "757: unexpected token at 'null'" | ||
puts "API Error: #{e.message}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Toto je zhltnuta exception? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ano. Ta prva z faraday je odignorovana uplne. Api errors sa len vypisuju zatial, kym sa nedoriesi unikatnost, exception reporting a validacie. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Co keby ten There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Takze v nasom kliente by som hltal discourse_api gem exceptions a vracal nil ak sa nepodari vytvorit topic? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Jo, DiscourseClient je aj tak zviazany s tym gemom, tak moze vediet ake exceptions to hadze. |
||
end | ||
end | ||
end | ||
|
||
private | ||
|
||
def announcement_to_topic(announcement) | ||
{ | ||
title: announcement[:procurement_subject].to_s, | ||
body: "**Obstarávateľ:** #{announcement[:procurer]} \n" \ | ||
"**Predmet obstarávania:** #{announcement[:procurement_subject]} \n" \ | ||
"**Cena:** #{announcement[:amount]} EUR \n" \ | ||
"**Zdroj:** [#{announcement[:link][:text]}](#{announcement[:link][:href]})" | ||
} | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
require 'json' | ||
require 'curb' | ||
require_relative './base' | ||
|
||
module Notifiers | ||
class Slack < Base | ||
def initialize(slack_webhook, http_client = Curl) | ||
@slack_webhook = slack_webhook | ||
@http_client = http_client | ||
end | ||
|
||
def new_issue_not_published | ||
send_message('*Fíha, dnes na ÚVO nevyšlo nové vydanie vestníka?*') | ||
end | ||
|
||
def matching_announcements_found(page, announcements) | ||
send_message("Našiel som niečo nové na ÚVO! (#{page})") | ||
|
||
announcements.each do |a| | ||
send_message("<#{a[:link][:href]}|#{a[:link][:text]}>: *#{a[:procurer]}* #{a[:procurement_subject]}") | ||
end | ||
end | ||
|
||
def no_announcements_found | ||
send_message('Dnes som nenašiel žiadne nové IT zákazky.') | ||
end | ||
|
||
private | ||
|
||
def send_message(text) | ||
@http_client.post(@slack_webhook, payload(text)) | ||
end | ||
|
||
def payload(text) | ||
{ | ||
text: text, | ||
channel: '#general', | ||
username: 'uvobot', | ||
icon_emoji: ':mag_right:' | ||
}.to_json | ||
end | ||
end | ||
end |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,26 @@ | ||
class Uvobot | ||
def initialize(notifier, scraper) | ||
@notifier = notifier | ||
def initialize(notifiers, scraper) | ||
@notifiers = notifiers | ||
@scraper = scraper | ||
end | ||
|
||
def run(release_date) | ||
if @scraper.issue_ready?(release_date) | ||
notify_announcements(release_date) | ||
else | ||
@notifier.new_issue_not_published | ||
@notifiers.each { |n| n.send(:new_issue_not_published) } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. preco There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lebo som truba :D. Omg. Opravim. |
||
end | ||
end | ||
|
||
private | ||
|
||
def notify_announcements(release_date) | ||
page_info, announcements = @scraper.get_announcements(release_date) | ||
page_info, announcements = @scraper.get_full_announcements(release_date) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Toto je zbytocne pridavanie roboty. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nj, povodne to bolo rozdelene prave kvoli tomu aby detail parsing nevyradil vsetko. Notifier by potom bral v konstruktore aj scraper a dotahoval by si detail. Co je z funkcneho hladiska OK, akurat mi to uplne nesedi co tyka SRP. Keby sme mu posunuli scraper spolu s ostatnymi datami ako nejaky proc object predchystany. Dotahovanie detailu by bolo potom lazy. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Podla mna vsetko info co na stiahnutie detailu potrebujes sa uz posiela. Mas tam v Violation SRP nevidim. Resp. na SRP v OOP mam taky dost kontroverzny nazor. Podla mna je to bullshit ;) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ano je tam vsetko na stiahnutie okrem scrapera. |
||
|
||
if announcements.count > 0 | ||
@notifier.matching_announcements_found(page_info, announcements) | ||
@notifiers.each { |n| n.send(:matching_announcements_found, page_info, announcements) } | ||
else | ||
@notifier.no_announcements_found | ||
@notifiers.each { |n| n.send(:no_announcements_found) } | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
require './lib/notifiers/base' | ||
|
||
RSpec.describe Notifiers::Base do | ||
let(:base) { Notifiers::Base.new } | ||
|
||
describe '.matching_announcements_found' do | ||
it 'fails if not overriden' do | ||
expect { base.matching_announcements_found('test', 'test') }.to raise_error 'Interface method not implemented!' | ||
end | ||
end | ||
|
||
describe '.no_announcements_found' do | ||
it 'fails if not overriden' do | ||
expect { base.no_announcements_found }.to raise_error 'Interface method not implemented!' | ||
end | ||
end | ||
|
||
describe '.new_issue_not_published' do | ||
it 'fails if not overriden' do | ||
expect { base.new_issue_not_published }.to raise_error 'Interface method not implemented!' | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
require './lib/notifiers/discourse' | ||
|
||
RSpec.describe Notifiers::Discourse do | ||
let(:client_double) { double } | ||
let(:client_exception_class_double) { double } | ||
let(:publisher) { Notifiers::Discourse.new(client_double, 'dummy category') } | ||
|
||
describe '.match_announcements_found' do | ||
it 'creates new topic for each announcement' do | ||
allow(client_double).to receive_message_chain('create_topic') { true } | ||
announcements = [{ link: { href: 'href', text: 'text' }, | ||
procurer: 'procurer', procurement_subject: 'subject', amount: '1000' }] | ||
|
||
params = { | ||
title: 'subject', | ||
raw: "**Obstarávateľ:** procurer \n**Predmet obstarávania:** subject" \ | ||
" \n**Cena:** 1000 EUR \n**Zdroj:** [text](href)", | ||
category: 'dummy category' | ||
} | ||
expect(client_double).to receive(:create_topic).with(params) | ||
|
||
publisher.matching_announcements_found('page info', announcements) | ||
end | ||
|
||
it 'handles validations errors' do | ||
end | ||
end | ||
|
||
describe '.no_announcements_found' do | ||
end | ||
|
||
describe '.new_issue_not_published' do | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Toto nerozumiem co riesi.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chcel som aby bol Discourse notifier zavisly iba na interface injektnuteho klienta. A tento koncept narusal fakt, ze musim chytat custom exception class z discourse gemu. Tak som urobil nas discource klient, ktory momentalne len wrapne ten z gemu a takisto prelozi ich exception na exception nasho klienta.
A tu exception potrebujem na to, aby som vedel odfiltrovat discourse api errory od ostatnych.