diff --git a/2269/3/Gemfile b/2269/3/Gemfile new file mode 100755 index 000000000..80facf1c8 --- /dev/null +++ b/2269/3/Gemfile @@ -0,0 +1,8 @@ +source 'https://rubygems.org' + +gem 'mechanize' +gem 'ohm' +gem 'shotgun' +gem 'sidekiq' +gem 'sinatra' +gem 'thin' diff --git a/2269/3/Gemfile.lock b/2269/3/Gemfile.lock new file mode 100755 index 000000000..5205c3d33 --- /dev/null +++ b/2269/3/Gemfile.lock @@ -0,0 +1,87 @@ +GEM + remote: https://rubygems.org/ + specs: + coderay (1.1.2) + concurrent-ruby (1.0.5) + connection_pool (2.2.2) + daemons (1.2.6) + domain_name (0.5.20180417) + unf (>= 0.0.5, < 1.0.0) + eventmachine (1.2.7) + hiredis (0.6.1) + http-cookie (1.0.3) + domain_name (~> 0.5) + 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 + redis (4.0.1) + shotgun (0.9.2) + rack (>= 1.0) + sidekiq (5.1.3) + concurrent-ruby (~> 1.0) + connection_pool (~> 2.2, >= 2.2.0) + rack-protection (>= 1.5.0) + redis (>= 3.3.5, < 5) + 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) + thin (1.7.2) + daemons (~> 1.0, >= 1.0.9) + eventmachine (~> 1.0, >= 1.0.4) + rack (>= 1, < 3) + tilt (2.0.8) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.5) + webrobots (0.1.2) + +PLATFORMS + ruby + +DEPENDENCIES + mechanize + ohm + pry + shotgun + sidekiq + sinatra + thin + +BUNDLED WITH + 1.16.2 diff --git a/2269/3/config.ru b/2269/3/config.ru new file mode 100755 index 000000000..078cc30ab --- /dev/null +++ b/2269/3/config.ru @@ -0,0 +1,10 @@ +require 'bundler' +Bundler.require + +Dir.glob('./{models,controllers,helpers}/*.rb').each { |file| require_relative file } + +Article.redis = Redic.new('redis://127.0.0.1:6379/0') +Comment.redis = Redic.new('redis://127.0.0.1:6379/0') + +map('/articles') { run ArticlesController } +map('/') { run ApplicationController } diff --git a/2269/3/controllers/application_controller.rb b/2269/3/controllers/application_controller.rb new file mode 100755 index 000000000..49dcacd04 --- /dev/null +++ b/2269/3/controllers/application_controller.rb @@ -0,0 +1,9 @@ +# Class +class ApplicationController < Sinatra::Base + set :views, File.expand_path(File.join(__FILE__, '../../views')) + set :method_override, true + + get '/' do + redirect '/articles' + end +end diff --git a/2269/3/controllers/articles_controller.rb b/2269/3/controllers/articles_controller.rb new file mode 100755 index 000000000..0d3215d02 --- /dev/null +++ b/2269/3/controllers/articles_controller.rb @@ -0,0 +1,34 @@ +require_relative './application_controller.rb' + +# Controller +class ArticlesController < ApplicationController + # index + get '/' do + @articles = Article.all + erb :'/articles/index' + end + + # new + get '/new' do + erb :'/articles/create' + end + + # show + get '/:id' do + @article = Article[params[:id]] + erb :'/articles/show' + end + + # create + post '/' do + ArticleHelper.new(params[:url]) + redirect '/' + end + + # delete + delete '/:id' do + Article[params[:id]].comments.each(&:delete) + Article[params[:id]].delete + redirect '/' + end +end diff --git a/2269/3/helpers/article_helper.rb b/2269/3/helpers/article_helper.rb new file mode 100755 index 000000000..366beb2ff --- /dev/null +++ b/2269/3/helpers/article_helper.rb @@ -0,0 +1,28 @@ +# Class +class ArticleHelper + def initialize(url) + @agent = Mechanize.new { |agnt| agnt.user_agent_alias = 'Mac Safari' } + @agent.history_added = proc { sleep 1 } + @article = Article.create(url: url, title: retrieve_title(url)) + update_article(url) + end + + attr_reader :agent, :article + + def retrieve_title(url) + page = @agent.get(url) + page.title + end + + def update_article(url) + helper = CommentHelper.new + contents = helper.retrieve_comments(url) + ratings = helper.retrieve_rating(contents) + contents.each_with_index do |content, index| + comment = Comment.create(content: content, rate: ratings[index]) + @article.comments.add(comment) + end + article_rate = (ratings.sum / contents.size).to_i + @article.update(rating: article_rate) + end +end diff --git a/2269/3/helpers/comment_helper.rb b/2269/3/helpers/comment_helper.rb new file mode 100755 index 000000000..60b3c09df --- /dev/null +++ b/2269/3/helpers/comment_helper.rb @@ -0,0 +1,49 @@ +# Class +class CommentHelper + def initialize + @agent = Mechanize.new { |agnt| agnt.user_agent_alias = 'Mac Safari' } + @agent.history_added = proc { sleep 1 } + end + + attr_reader :agent, :data + + def retrieve_comments(path) + article_id = @agent.get(path).css('.news_view_count').last.values[1] + url = "https://comments.api.onliner.by/news/tech.post/#{article_id}/comments?limit=50&_=0.9841189675826583" + response = agent.get(url) + comments = [] + JSON.parse(response.body)['comments'].each { |elem| comments << elem['text'].tr("\n", ' ') } + comments + end + + def retrieve_rating(comments) + @data = { documents: [] } + comments.each_with_index do |comment, index| + @data[:documents] << { 'id' => index.to_s, 'language' => 'ru', 'text' => comment } + end + calculate_rating + end + + def calculate_rating + url = URI('https://westeurope.api.cognitive.microsoft.com/text/analytics/v2.0/sentiment') + response = send_request(url) + rating = [] + JSON.parse(response.body)['documents'].map do |value| + rating << ((value['score'] * 200).round(0) - 100) + end + rating + end + + def send_request(url) + Net::HTTP.start(url.host, url.port, use_ssl: url.scheme == 'https') do |http| + http.request(build_request(url)) + end + end + + def build_request(url) + key = File.read('api_key') + request = Net::HTTP::Post.new(url, 'Content-Type' => 'application/json', 'Ocp-Apim-Subscription-Key' => key) + request.body = @data.to_json + request + end +end diff --git a/2269/3/models/article.rb b/2269/3/models/article.rb new file mode 100755 index 000000000..37700b3a8 --- /dev/null +++ b/2269/3/models/article.rb @@ -0,0 +1,7 @@ +# Class that represents model of Article +class Article < Ohm::Model + attribute :url + attribute :title + set :comments, :Comment + attribute :rating +end diff --git a/2269/3/models/comment.rb b/2269/3/models/comment.rb new file mode 100755 index 000000000..48d63e2e4 --- /dev/null +++ b/2269/3/models/comment.rb @@ -0,0 +1,5 @@ +# Class that represents model of Comment to a Article +class Comment < Ohm::Model + attribute :content + attribute :rate +end diff --git a/2269/3/views/articles/create.erb b/2269/3/views/articles/create.erb new file mode 100755 index 000000000..a9010e1ad --- /dev/null +++ b/2269/3/views/articles/create.erb @@ -0,0 +1,8 @@ +
ID | +
+ Article's title
+ |
+ Rating | +Actions |
+
---|---|---|---|
<%= article.id %> | +<%= article.title %> |
+ <%= article.rating %> | +
+
+
+
+ |
+
Comment text |
+ Rating | +
---|---|
<%= comment.content %> | +<%= comment.rate %> |
+