-
Notifications
You must be signed in to change notification settings - Fork 43
2355 - 3 #271
base: master
Are you sure you want to change the base?
2355 - 3 #271
Changes from 2 commits
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,5 @@ | ||
require 'sinatra/base' | ||
|
||
Dir.glob('./{controllers,models}/*.rb').each { |file| require file } | ||
|
||
map('/') { run IndexController } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
require 'sinatra' | ||
require 'slim' | ||
require 'ohm' | ||
|
||
# Main controller | ||
class IndexController < Sinatra::Base | ||
set :views, File.expand_path(File.join(__FILE__, '../../views')) | ||
|
||
get '/' do | ||
slim :header_footer do | ||
slim :index | ||
end | ||
end | ||
|
||
get '/add' do | ||
slim :header_footer do | ||
slim :new | ||
end | ||
end | ||
|
||
post '/add' do | ||
Ohm.redis.call 'SET', 'article' + ((Ohm.redis.call 'GET', 'articles_count').to_i + 1).to_s, params[:link].to_s | ||
Ohm.redis.call 'SET', 'articles_count', ((Ohm.redis.call 'GET', 'articles_count').to_i + 1).to_s | ||
require_relative './models/article_rate.rb' | ||
rating = ArticleRate.new(params[:link].to_s) | ||
coment_count = rating.article.comments.size | ||
Ohm.redis.call 'SET', 'article' + (Ohm.redis.call 'GET', 'articles_count') + '_comments_count', coment_count.to_s | ||
rating.article_rate | ||
rating.article.comments.size.times do |index| | ||
text = rating.article.comments[index].text | ||
Ohm.redis.call 'SET', 'article' + (Ohm.redis.call 'GET', 'articles_count') + '_comment' + (index + 1).to_s, text | ||
end | ||
Ohm.redis.call 'SET', 'article' + (Ohm.redis.call 'GET', 'articles_count') + '_rate', rating.rate.to_i.to_s | ||
redirect '/' | ||
end | ||
|
||
# I use 'id' in show.slim, so it needed here | ||
# rubocop:disable Lint/UselessAssignment | ||
get '/show/:id' do | ||
slim :header_footer do | ||
slim :show do | ||
id = params['id'] | ||
end | ||
end | ||
end | ||
# rubocop:enable Lint/UselessAssignment | ||
|
||
get '/annihilate' do | ||
slim :header_footer do | ||
slim :annihilate | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
require_relative './comment_parser.rb' | ||
|
||
# This class describes article | ||
class Article | ||
attr_reader :url, :comments | ||
|
||
def initialize(url) | ||
@url = url | ||
parser = CommentParser.new | ||
parser.parse(url) | ||
@comments = parser.comments | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
require_relative './text_analytics.rb' | ||
require_relative './article.rb' | ||
|
||
# This class is needed to get article rate | ||
class ArticleRate | ||
attr_reader :rate, :article | ||
|
||
def initialize(url) | ||
@rate = 0 | ||
@article = Article.new(url) | ||
end | ||
|
||
def all_comments_rate | ||
docs = [] | ||
@article.comments.each do |comment| | ||
docs << { 'id' => 1, 'language' => 'ru', 'text' => comment.text.to_s } | ||
end | ||
documents = { 'documents': docs } | ||
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. Lint/Syntax: unexpected token tCOLON 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. Lint/Syntax: unexpected token tCOLON |
||
TextAnalytics.new(documents).analyze['documents'] | ||
end | ||
|
||
def article_rate | ||
comments_rate = all_comments_rate | ||
comments_rate.each do |comment| | ||
@rate += ((comment['score'] * 200) - 100) | ||
end | ||
@rate /= comments_rate.size | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
require_relative './text_analytics.rb' | ||
|
||
# This class describes comment | ||
class Comment | ||
attr_reader :text, :rate | ||
|
||
def initialize(text) | ||
@text = text | ||
docs = { 'id' => 1, 'language' => 'ru', 'text' => text } | ||
documents = { 'documents': [docs] } | ||
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. Lint/Syntax: unexpected token tCOLON 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. Lint/Syntax: unexpected token tCOLON 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. Lint/Syntax: unexpected token tCOLON |
||
@rate = (TextAnalytics.new(documents).analyze['documents'][0]['score'] * 200 - 100).to_i | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
require 'selenium-webdriver' | ||
|
||
# This class parse web page for comments | ||
class CommentParser | ||
attr_reader :comments | ||
|
||
def initialize | ||
@comments = [] | ||
@driver = Selenium::WebDriver.for :chrome | ||
end | ||
|
||
def parse(url) | ||
@driver.get url | ||
begin | ||
@driver.find_element(:class, 'news-form__button').click | ||
ensure | ||
@comments = @driver.find_elements(:class, 'news-comment__speech') | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
require 'net/https' | ||
require 'uri' | ||
require 'json' | ||
|
||
# This class responsible for analyzing comments | ||
class TextAnalytics | ||
attr_reader :documents, :access_key, :uri | ||
|
||
def initialize(documents) | ||
@documents = documents | ||
@access_key = '7614507e97184bfd9f38e1d93fa130e8' # use it, if you want... I don't mind | ||
path = '/text/analytics/v2.0/sentiment' | ||
@uri = URI('https://westcentralus.api.cognitive.microsoft.com' + path) | ||
end | ||
|
||
# This method is written in accordance with the documentation of Azura, | ||
# so it's not my fault that reek swears on TooManyStatements and Rubocop swears on EVERYTHING! | ||
# This method smells of :reek:TooManyStatements | ||
# rubocop:disable Style/HashSyntax | ||
# rubocop:disable Style/NestedParenthesizedCalls | ||
# rubocop:disable Style/ColonMethodCall | ||
# rubocop:disable Style/RedundantParentheses | ||
# rubocop:disable Lint/ParenthesesAsGroupedExpression | ||
def analyze | ||
request = Net::HTTP::Post.new(uri) | ||
request['Content-Type'] = 'application/json' | ||
request['Ocp-Apim-Subscription-Key'] = @access_key | ||
request.body = @documents.to_json | ||
|
||
response = Net::HTTP.start(@uri.host, @uri.port, :use_ssl => @uri.scheme == 'https') do |http| | ||
http.request(request) | ||
end | ||
JSON.parse(JSON::pretty_generate (JSON (response.body))) | ||
end | ||
# rubocop:enable Style/HashSyntax | ||
# rubocop:enable Style/NestedParenthesizedCalls | ||
# rubocop:enable Style/ColonMethodCall | ||
# rubocop:enable Style/RedundantParentheses | ||
# rubocop:enable Lint/ParenthesesAsGroupedExpression | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
main[role="main"] | ||
section.jumbotron.text-center | ||
.container | ||
- Ohm.redis.call "FLUSHALL" | ||
- Ohm.redis.call "SET" "articles_count" "0" | ||
.alert.alert-success[role="alert"] | ||
h3.jumbotron-heading | ||
| All articles have been deleted! | ||
p.lead.text-muted | ||
| Choose what you want to do | ||
p | ||
a.btn.btn-primary.my-2[href="/add"] | ||
| Add new article | ||
a.btn.btn-primary.my-2[href="/"] | ||
| Return to main page |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
| <!doctype html> | ||
html[lang="en"] | ||
head | ||
meta[charset="utf-8"] | ||
meta[name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"] | ||
title | ||
| Onliner analyzer | ||
link[rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"] | ||
body | ||
header | ||
#navbarHeader.collapse.bg-dark | ||
.container | ||
.row | ||
.col-sm-8.col-md-7.py-4 | ||
h4.text-white | ||
| About | ||
p.text-muted | ||
| This application will help you to analyze the articles from the portal "Onliner.by" and find out their rating based on the analysis of comments. You can also find out the rating of each individual comment by viewing them in the appropriate section. It supports adding a new article for analysis, viewing the list of all added articles and rating comments. | ||
.navbar.navbar-dark.bg-dark.shadow-sm | ||
.container.d-flex.justify-content-between | ||
a.navbar-brand.d-flex.align-items-center[href="/"] | ||
svg.mr-2[xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"] | ||
path[d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"] | ||
circle[cx="12" cy="13" r="4"] | ||
strong | ||
| Onliner Analyzer | ||
button.navbar-toggler[type="button" data-toggle="collapse" data-target="#navbarHeader" aria-controls="navbarHeader" aria-expanded="false" aria-label="Toggle navigation"] | ||
span.navbar-toggler-icon | ||
== yield | ||
footer.text-muted | ||
.container | ||
p.float-right | ||
| ©WhiteNiceFlower | ||
p.float-left | ||
| 27.07.2018 | ||
script[src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"] | ||
script[src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"] | ||
script[src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
main[role="main"] | ||
section.jumbotron.text-center | ||
.container | ||
h1.jumbotron-heading | ||
| There are analyzed articles: | ||
table.table.table-striped.table-bordered | ||
thead | ||
tr | ||
th | ||
| # | ||
th | ||
| Article(Link) | ||
th | ||
| Raiting | ||
th | ||
| About | ||
tbody | ||
- if "#{Ohm.redis.call 'GET', 'articles_count'}".to_i == 0 | ||
tr | ||
th[scope="row"] | ||
| There | ||
td | ||
| are | ||
td | ||
| NO | ||
td | ||
| articles | ||
- "#{Ohm.redis.call 'GET', 'articles_count'}".to_i.times do |j| | ||
tr | ||
th[scope="row"] | ||
| #{j + 1} | ||
td | ||
a[href="#{Ohm.redis.call 'GET', 'article' + "#{j + 1}"}"] | ||
| #{Ohm.redis.call 'GET', 'article' + "#{j + 1}"} | ||
td | ||
| #{Ohm.redis.call 'GET', 'article' + "#{j + 1}" + '_rate'} | ||
td | ||
a[href="/show/#{j + 1}"] | ||
| > | ||
p.lead.text-muted | ||
| Choose what you want to do | ||
p | ||
a.btn.btn-primary.my-2[href="/add"] | ||
| Add new article | ||
a.btn.btn-primary.my-2[href="/annihilate"] | ||
| Delete all articles |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
main[role="main"] | ||
section.jumbotron.text-left | ||
.container | ||
h3.jumbotron-heading | ||
| Add new article | ||
form.form-inline[method="post"] | ||
.form-group.row | ||
label.col-sm-2.col-form-label[for="link"] | ||
| Link | ||
.col-sm-10 | ||
input#link.form-control[type="text" name="link" placeholder="https://onliner.by/..."] | ||
button.btn.btn-primary[type="submit" href="/"] | ||
| Add |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
main[role="main"] | ||
section.jumbotron.text-center | ||
.container | ||
h1.jumbotron-heading | ||
- id = yield | ||
| #{Ohm.redis.call "GET", "article" + "#{id}"} | ||
table.table.table-striped.table-bordered | ||
thead | ||
tr | ||
th | ||
| # | ||
th | ||
| Comment | ||
th | ||
| Rate | ||
tbody | ||
- "#{Ohm.redis.call "GET", "article" + "#{id}" + "_comments_count"}".to_i.times do |i| | ||
- require_relative '../models/comment.rb' | ||
- comment = Comment.new("#{Ohm.redis.call "GET", "article" + "#{id}" + "_comment" + "#{i + 1}"}") | ||
tr | ||
th | ||
| #{i + 1} | ||
th | ||
- if i == 0 | ||
| #{'Лучший комментарий: '} #{comment.text} | ||
- else | ||
| #{comment.text} | ||
th | ||
| #{comment.rate} |
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.
Lint/Syntax: unexpected token tCOLON