-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from martinsabo/master
Automatické postovanie do fóra, closes #2
- Loading branch information
Showing
21 changed files
with
2,856 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,10 @@ | ||
class Uvobot | ||
def initialize(notifier, scraper) | ||
@notifier = notifier | ||
@scraper = scraper | ||
end | ||
|
||
def run(release_date) | ||
if @scraper.issue_ready?(release_date) | ||
notify_announcements(release_date) | ||
else | ||
@notifier.new_issue_not_published | ||
end | ||
end | ||
|
||
private | ||
|
||
def notify_announcements(release_date) | ||
page_info, announcements = @scraper.get_announcements(release_date) | ||
|
||
if announcements.count > 0 | ||
@notifier.matching_announcements_found(page_info, announcements) | ||
else | ||
@notifier.no_announcements_found | ||
end | ||
end | ||
require_relative 'uvobot/worker' | ||
require_relative 'uvobot/uvo_scraper' | ||
require_relative 'uvobot/uvo_parser' | ||
require_relative 'uvobot/discourse_client' | ||
require_relative 'uvobot/notifications/discourse_notifier' | ||
require_relative 'uvobot/notifications/slack_notifier' | ||
require_relative 'uvobot/worker' | ||
|
||
module Uvobot | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
require 'discourse_api' | ||
|
||
module Uvobot | ||
class DiscourseClient | ||
def initialize(host, api_key, api_username) | ||
@client = DiscourseApi::Client.new(host, api_key, api_username) | ||
end | ||
|
||
def create_topic(args = {}) | ||
@client.create_topic(args) | ||
rescue DiscourseApi::Error | ||
return nil | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
require_relative 'notifier' | ||
|
||
module Uvobot | ||
module Notifications | ||
class DiscourseNotifier < Notifier | ||
def initialize(discourse_client, category, scraper) | ||
@client = discourse_client | ||
@category = category | ||
@scraper = scraper | ||
end | ||
|
||
def no_announcements_found | ||
# noop | ||
end | ||
|
||
def new_issue_not_published | ||
# noop | ||
end | ||
|
||
def matching_announcements_found(_page_info, announcements) | ||
announcements.each do |a| | ||
topic = announcement_to_topic(a) | ||
@client.create_topic( | ||
title: topic[:title], | ||
raw: topic[:body], | ||
category: @category | ||
) | ||
end | ||
end | ||
|
||
private | ||
|
||
def announcement_to_topic(announcement) | ||
detail = @scraper.get_announcement_detail(announcement[:link][:href]) | ||
|
||
{ | ||
title: announcement[:procurement_subject].to_s, | ||
body: ["**Obstarávateľ:** #{announcement[:procurer]} ", | ||
"**Predmet obstarávania:** #{announcement[:procurement_subject]} ", | ||
detail_message(detail), | ||
"**Zdroj:** [#{announcement[:link][:text]}](#{announcement[:link][:href]})"].join("\n") | ||
} | ||
end | ||
|
||
def detail_message(detail) | ||
if detail | ||
"**Cena:** #{detail[:amount]} EUR " | ||
else | ||
"**Detaily sa nepodarilo extrahovať.** " | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
require 'abstract_type' | ||
|
||
module Uvobot | ||
module Notifications | ||
class Notifier | ||
include AbstractType | ||
|
||
abstract_method :matching_announcements_found | ||
abstract_method :no_announcements_found | ||
abstract_method :new_issue_not_published | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
require 'json' | ||
require 'curb' | ||
require_relative 'notifier' | ||
|
||
module Uvobot | ||
module Notifications | ||
class SlackNotifier < Notifier | ||
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 | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
require 'nokogiri' | ||
|
||
module Uvobot | ||
class UvoParser | ||
def self.parse_announcements(html) | ||
announcements = [] | ||
|
||
doc(html).css('.oznamenie').each do |a| | ||
link = a.css('.ozn1 a').first | ||
procurer = a.css('.ozn2').text.strip | ||
procurement_subject = a.css('.ozn3').text.strip | ||
|
||
announcements << { | ||
link: { text: link.text, href: link['href'] }, | ||
procurer: procurer, | ||
procurement_subject: procurement_subject | ||
} | ||
end | ||
announcements | ||
end | ||
|
||
def self.parse_detail(html) | ||
# there are multiple formats of detail page, this method does not handle them all for now | ||
detail = {} | ||
h_doc = doc(html) | ||
amount_node = h_doc.xpath('//div[text()="Hodnota "]').css('span').first | ||
return nil if amount_node.nil? | ||
|
||
detail[:amount] = amount_node.text | ||
detail | ||
end | ||
|
||
def self.parse_page_info(html) | ||
doc(html).css('.search-results').first.text.strip | ||
end | ||
|
||
def self.parse_issue_header(html) | ||
doc(html).css('h1')[1].text | ||
end | ||
|
||
def self.doc(html) | ||
Nokogiri::HTML(html) | ||
end | ||
end | ||
end |
Oops, something went wrong.