diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 361f957..9b2247c 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -19,3 +19,21 @@ //= require_tree . $(function(){ $(document).foundation(); }); + +// Load reviews on package's details page +load_reviews = function() { + // Display message while loading reviews + // $('#reviews').html("Loading reviews..."); + + // Hide the DIV so that in can be faded in later + $('#reviews').hide(); + + // The URL is specified in the #reviews's DIV data attribute + var url = $('#reviews').attr('data-package-reviews-url'); + $('#reviews').load(url, null, + // Fade in the reviews as soon as the DIV is loaded and filled + function(){ + $(this).fadeIn('slow') + } + ); +}; diff --git a/app/controllers/packages_controller.rb b/app/controllers/packages_controller.rb index d71cfdd..02be9ba 100644 --- a/app/controllers/packages_controller.rb +++ b/app/controllers/packages_controller.rb @@ -191,6 +191,12 @@ class PackagesController < ApplicationController redirect_to :back end + # Show an HTML partial with reviews of this package from the Ubuntu API + def reviews + @reviews = Package.find_by_name!(params[:name]).ubuntu_reviews + render '_reviews', layout: false + end + private # Send a dummy thumbnail reading "No screenshot available. Sorry." diff --git a/app/helpers/packages_helper.rb b/app/helpers/packages_helper.rb index 86925f4..3cae56c 100644 --- a/app/helpers/packages_helper.rb +++ b/app/helpers/packages_helper.rb @@ -16,4 +16,11 @@ module PackagesHelper end end + # Show filled/empty star icons from FontAwesome + # depending on the rating (1-5) + def star_rating(rating) + filled_stars = fa_icon('star') * rating + empty_stars = fa_icon('star-o') * (5-rating) + (filled_stars+empty_stars).html_safe + end end diff --git a/app/models/package.rb b/app/models/package.rb index 16a7e72..751adb0 100644 --- a/app/models/package.rb +++ b/app/models/package.rb @@ -1,3 +1,6 @@ +require 'open-uri' # allows to load URLs using open() +require 'json' + class Package < ActiveRecord::Base # PostgreSQL-based full-text search: # https://github.com/Casecommons/pg_search @@ -57,6 +60,20 @@ class Package < ActiveRecord::Base self.screenshots.to_a.sort { |x,y| version_compare(x.version,y.version) } end + # Get reviews of this package from the Ubuntu API + def ubuntu_reviews + # Use the URL defined in the configuration to get a JSON string + json = open(Rails.configuration.ubuntu_reviews_api_url % self.name).read + # Turn JSON into a Ruby data structure + json = JSON.parse(json) + # Only show english reviews + # TODO: Support further languages + json = json.select {|x| x['language']=='en'} + # Sort by 'usefulness_total' (how many people found this review useful) + json = json.sort { |x,y| y['usefulness_total'].to_i <=> x['usefulness_total'].to_i} + return json + end + # Return the newest screenshot that is not newer than the given version. # This algorithm collects all image # versions of a package and determines the (second) newest version. diff --git a/app/views/packages/_reviews.slim b/app/views/packages/_reviews.slim new file mode 100644 index 0000000..09e7d91 --- /dev/null +++ b/app/views/packages/_reviews.slim @@ -0,0 +1,22 @@ +- if @reviews.count > 0 + + .subtitle Reviews + + - @reviews.each do |review| + p + div + b = review['summary'] + ' … + = review['review_text'] + .text-right + em + = review['reviewer_displayname'] + ' – + = time_ago_in_words(DateTime.parse(review['date_created'])) + ' ago – + = star_rating(review['rating']) + +/ - else + +/ p +/ em No reviews available. diff --git a/app/views/packages/details.slim b/app/views/packages/details.slim index 650ad8c..155d1a0 100644 --- a/app/views/packages/details.slim +++ b/app/views/packages/details.slim @@ -43,7 +43,6 @@ onclick="return confirm('Really delete your screenshot again?');" ] Delete your screenshot - // or is the user not related to the screenshot and the screenshot is public? - elsif screenshot.approved = render(partial: 'report_dropdown', locals: {screenshot: screenshot}) @@ -55,7 +54,18 @@ // TODO: Enable comments in a later version // = partial '/package/comments' + // Load reviews from the Ubuntu API through our own (cached) URL. + // Use asynchronous load to keep loading times low if the review + // was not yet cached. + / = render(partial: 'reviews', locals: {pkg: @package}) + #reviews data-package-reviews-url=package_reviews_path(@package.name) + .small-5.medium-5.columns = render(partial: 'details_rightbox', locals: {pkg: @package}) = render(partial: 'details_uploadmodal') + +javascript: + $( function() { + load_reviews() + }) diff --git a/config/environments/development.rb b/config/environments/development.rb index b750e0b..58982ce 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -46,6 +46,10 @@ Debshots::Application.configure do } ] + # Example file for development to avoid queries to online service + config.ubuntu_reviews_api_url = 'test/files/ubuntu-review-api/cream' + # config.ubuntu_reviews_api_url = 'https://reviews.ubuntu.com/reviews/api/1.0/reviews/filter/en/any/any/any/%s' + config.images_path = Rails.root.join('public', 'screenshots') config.image_sizes = { diff --git a/config/environments/production.rb b/config/environments/production.rb index a2433ae..03cc44a 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -97,6 +97,9 @@ Debshots::Application.configure do } ] + # URL to fetch reviews from the Ubuntu JSON API + config.ubuntu_reviews_api_url = 'https://reviews.ubuntu.com/reviews/api/1.0/reviews/filter/en/any/any/any/%s' + config.images_path = Rails.root.join('public', 'screenshots') config.image_sizes = { diff --git a/config/routes.rb b/config/routes.rb index a940968..caf3224 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,6 +16,7 @@ Debshots::Application.routes.draw do get 'packages/list' => 'packages#list', as: :packages_list get 'moderate' => 'moderate#index' get 'package/:name' => 'packages#details', as: :package, name: /[^\/]+/ + get 'package_reviews/:name' => 'packages#reviews', as: :package_reviews, name: /[^\/]+/ get 'upload', to: redirect('/packages') # legacy upload form post 'uploadfile' => 'packages#legacy_uploadfile' get 'upload/:name' => 'packages#upload', as: :upload_package_by_name diff --git a/test/files/ubuntu-review-api/cream.json b/test/files/ubuntu-review-api/cream similarity index 100% rename from test/files/ubuntu-review-api/cream.json rename to test/files/ubuntu-review-api/cream