Skip to content
This repository has been archived by the owner on Jun 27, 2019. It is now read-only.

2226 - 3 #285

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions 2226/3/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
source 'https://rubygems.org'

gem 'json'
gem 'mechanize'
gem 'ohm'
gem 'sinatra'

group :development do
gem 'pry'
gem 'shotgun'
end
74 changes: 74 additions & 0 deletions 2226/3/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
GEM
remote: https://rubygems.org/
specs:
coderay (1.1.2)
connection_pool (2.2.2)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
hiredis (0.6.1)
http-cookie (1.0.3)
domain_name (~> 0.5)
json (2.1.0)
mechanize (2.7.6)
domain_name (~> 0.5, >= 0.5.1)
http-cookie (~> 1.0)
mime-types (>= 1.17.2)
net-http-digest_auth (~> 1.1, >= 1.1.1)
net-http-persistent (>= 2.5.2)
nokogiri (~> 1.6)
ntlm-http (~> 0.1, >= 0.1.1)
webrobots (>= 0.0.9, < 0.2)
method_source (0.9.0)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mini_portile2 (2.3.0)
mustermann (1.0.2)
nest (3.1.1)
redic
net-http-digest_auth (1.4.1)
net-http-persistent (3.0.0)
connection_pool (~> 2.2)
nokogiri (1.8.4)
mini_portile2 (~> 2.3.0)
ntlm-http (0.1.1)
ohm (3.1.1)
nest (~> 3)
redic (~> 1.5.0)
stal
pry (0.11.3)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
rack (2.0.5)
rack-protection (2.0.3)
rack
redic (1.5.0)
hiredis
shotgun (0.9.2)
rack (>= 1.0)
sinatra (2.0.3)
mustermann (~> 1.0)
rack (~> 2.0)
rack-protection (= 2.0.3)
tilt (~> 2.0)
stal (0.3.0)
redic (~> 1.5)
tilt (2.0.8)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.5)
webrobots (0.1.2)

PLATFORMS
ruby

DEPENDENCIES
json
mechanize
ohm
pry
shotgun
sinatra

BUNDLED WITH
1.16.1
10 changes: 10 additions & 0 deletions 2226/3/config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Bundler.require(:default, :development)

Dir.glob('./{models,helpers,controllers}/*.rb').each { |file| require file }

Article.redis = Redic.new('redis://127.0.0.1:6379/0')
Comment.redis = Redic.new('redis://127.0.0.1:6379/1')

use Rack::MethodOverride

map('/') { run ApplicationController }
32 changes: 32 additions & 0 deletions 2226/3/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# App controller
class ApplicationController < Sinatra::Base
set :views, File.expand_path(File.join(__FILE__, '../../views'))

get '/' do
@articles = Article.all
erb :index
end

get '/article/add' do
erb :new
end

get '/article/:id' do
@articles = Article.all
@article = @articles[params[:id]]
erb :show
end

post '/article/add' do
article = Article.create(link: params['link'])
ArticleAnalyser.new(article).launch
redirect '/'
end

delete '/articles/:id/delete' do
@articles = Article.all
@article = @articles[params[:id]]
@article.delete
redirect '/'
end
end
43 changes: 43 additions & 0 deletions 2226/3/helpers/article_analyser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Analyse article
class ArticleAnalyser
attr_reader :article, :text_body, :ratings

def initialize(article)
@article = article
@text_body = launch_comments_parser
@ratings = launch_rating_counter
end

def launch
refresh_article_title
build_article_stat
refresh_article_rating
end

private

def launch_comments_parser
CommentsParser.new(article.link).launch_parser
end

def launch_rating_counter
CommentRatingCounter.new(text_body).launch_counter
end

def refresh_article_title
page = Mechanize.new.get(article.link)
@article.update(title: page.title)
end

def build_article_stat
text_body.each_with_index do |text, index|
comment = Comment.create(text: text, rating: ratings[index])
article.comments.add(comment)
end
end

def refresh_article_rating
article_rating = (ratings.sum / text_body.size).to_i
@article.update(rating: article_rating)
end
end
35 changes: 35 additions & 0 deletions 2226/3/helpers/comment_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'json'
require 'mechanize'

# Comments parser
class CommentsParser
attr_reader :agent, :path_to_page

def initialize(link)
@agent = Mechanize.new
@path_to_page = link
end

def launch_parser
parse_comments_from_page
end

private

def parse_comments_from_page
response = parse_comments
comments = JSON.parse(response.body)['comments']
comments.map do |elem|
elem['text'].sub("\n", ' ')
end
end

def parse_page_code
agent.get(path_to_page).parser.css('span.news_view_count').last.values[1]
end

def parse_comments
on_url = "https://comments.api.onliner.by/news/tech.post/#{parse_page_code}/comments?limit=100&_=0.9046614793472092"
agent.get(on_url)
end
end
50 changes: 50 additions & 0 deletions 2226/3/helpers/comment_rating_counter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require 'net/https'
require 'uri'
require 'json'

# Rating Counter
class CommentRatingCounter
URL = 'https://westcentralus.api.cognitive.microsoft.com'.freeze
PATH = '/text/analytics/v2.0/sentiment'.freeze
KEY = YAML.load_file('config.yml')['KEY']

attr_reader :uri, :documents, :request

def initialize(texts)
@uri = URI(URL + PATH)
build_documents(texts)
end

def launch_counter
build_answer
end

private

def build_documents(text_body)
@documents = { documents: [] }
text_body.each_with_index do |text, index|
documents[:documents].push('id' => index.to_s, 'language' => 'ru', 'text' => text)
end
end

def build_answer
JSON.parse(build_response.body)['documents'].map do |document|
(document['score'] * 200).to_i - 100
end
end

def build_response
build_request
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(request)
end
end

def build_request
@request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Ocp-Apim-Subscription-Key'] = KEY
request.body = documents.to_json
end
end
7 changes: 7 additions & 0 deletions 2226/3/models/article.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Article model
class Article < Ohm::Model
attribute :link
attribute :title
set :comments, :Comment
attribute :rating
end
5 changes: 5 additions & 0 deletions 2226/3/models/comment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Comment model
class Comment < Ohm::Model
attribute :text
attribute :rating
end
4 changes: 4 additions & 0 deletions 2226/3/views/application.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<head>
<meta charset='UTF-8' />
<title>Articles Anylazer</title>
</head>
31 changes: 31 additions & 0 deletions 2226/3/views/index.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<%= erb :application %>
<body>
<h1>Articles Analyser</h1>
<table>
<tr>
<th>Link</th>
<th>Rating</th>
</tr>
<% @articles.each do |article| %>
<tr>
<td>
<div>
<a href='/article/<%= article.id %>'>
<%= article.title %>
</a>
</div>
</td>
<td>
<%= article.rating %>
</td>
</tr>
<% end %>
</table>
<br/>
<br/>
<div>
<a href='/article/add'>
Add new link
</a>
</div>
</body>
17 changes: 17 additions & 0 deletions 2226/3/views/new.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<%= erb :application %>
<body action='show'>
<div>Add link to article for analysis</div>
<form method='post'>
<ul>
<input type='text' name='link' id='link' />
</ul>
<button type='submit'>
Submit
</button>
<div>
<a href='/'>
Watch all articles
</a>
</div>
</form>
</body>
40 changes: 40 additions & 0 deletions 2226/3/views/show.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<%= erb :application %>
<body>
<div>
<a href='<%[email protected] %>'>
<%[email protected] %>
</a>
</div>
<div>
<a href='/'>
Watch all articles
</a>
</div>
<div>
<form action="/articles/<%= @article.id %>/delete" method="post">
<input id="hidden" type="hidden" name="_method" value="delete">
<input type="submit" onclick="return confirm('Do you realy need to delete this article?')" value="Delete article">
</form>
</div>
<h1>
<%= @article.title %>
</h1>
<table>
<tr>
<th>Comments</th>
<th>Ratings</th>
</tr>
<% @article.comments.each do |comment| %>
<tr>
<td>
<div>
<%= comment.text %>
</div>
</td>
<td>
<%= comment.rating %>
</td>
</tr>
<% end %>
</table>
</body>