class PackagesController < ApplicationController protect_from_forgery :except => :legacy_uploadfile def list @packages = query_packages.paginate(page: params[:page], per_page: 6) end def grid @packages = query_packages.paginate(page: params[:page], per_page: 24) end def details @package = Package.find_by(name: params[:name]) unless @package @packagename = params[:name] render 'notfound' end end def upload @package = Package.find_by!(name: params[:name]) end # POST target of the screenshots upload form. # Receives uploaded images. Checks if they are valid. Asks for description. def upload_image # Remember the user by the cookie session create_user_token @package = Package.find_by!(name: params[:name]) # @images = params[:screenshot][:image] @images = [] # Save the images already if they are valid. # params[:screenshot][:image].each do |img| # successful_upload_count = 0 params[:file].each do |img| new_screenshot = @package.screenshots.new(image: img) # Check if the image was valid @images.push new_screenshot if new_screenshot.valid? new_screenshot.uploaderhash = session[:token] new_screenshot.uploaderip = session[:ip] new_screenshot.version = @package.version new_screenshot.save # successful_upload_count += 1 Log.log "Screenshot #{new_screenshot.id} uploaded successfully." # else # errors = new_screenshot.errors[:image].join(' and ') # flash['alert'] = "Sorry - the image #{errors}" end # if successful_upload_count > 0 # flash['notice'] = "#{successful_upload_count} #{'screenshot'.pluralize(successful_upload_count)} uploaded successfully." # end end # redirect_to package_path end # Legacy action to upload an image along with metadata. # This was used in Debshots 1.x as the default upload method. # This method allows that old-style way to upload screenshots. # It is probably used by screenshotting tools. # # Parameters: # - packagename # - version # - description # - file def legacy_uploadfile @package = Package.find_by!(name: params[:packagename]) new_screenshot = @package.screenshots.new(image: params[:file]) # Check if the image was valid if new_screenshot.valid? # new_screenshot.uploaderhash = session[:token] new_screenshot.uploaderip = session[:ip] new_screenshot.version = @package.version new_screenshot.save Log.log "Screenshot #{new_screenshot.id} uploaded successfully from legacy upload form." redirect_to package_path(params[:packagename]) else Log.log "Screenshot upload rejected. Errors: #{new_screenshot.errors.to_a}" head :not_acceptable end end def delete_screenshot # Is the user allowed to delete the screenshot? @screenshot = Screenshot.find(params[:id]) if user_can_alter_screenshot? @screenshot.destroy flash['notice'] = "Screenshot deleted." redirect_to :back else head :forbidden end end def approve_screenshot @screenshot = Screenshot.find(params[:id]) @screenshot.approve_screenshot! flash['notice'] = "Screenshot approved." redirect_to :back end # Returns a 160x120 thumbnail image if posssible. # If the package is not found it returns a dummy image along with status 404. # If the package is found but has no screenshots then it also returns a # dummy image along with status 404. def thumbnail @package = Package.find_by(name: params[:name]) unless @package thumbnail404 return end # Called as /thumbnail-with-version/:name/:version if params[:version] @screenshot = @package.best_screenshot_for_version(params[:version]) # Called as /thumbnail/:name else @screenshot = @package.screenshots.first end # Return a 404 if the package has no screenshots or the image was not found unless @screenshot and @screenshot.image.path thumbnail404 return end # Send the thumbnail (uses X-Sendfile or similar if possible) send_file @screenshot.image.path(:thumb), type: "image/png", disposition: 'inline' end # Returns a large screenshot image if posssible. # If the package is not found it returns a dummy image along with status 404. # If the package is found but has no screenshots then it also returns a # dummy image along with status 404. def screenshot @package = Package.find_by(name: params[:name]) unless @package screenshot404 return end # Called as /thumbnail-with-version/:name/:version if params[:version] @screenshot = @package.best_screenshot_for_version(params[:version]) # Called as /thumbnail/:name else @screenshot = @package.screenshots.first end # Return a 404 if the package has no screenshots or the image was not found unless @screenshot and @screenshot.image.path screenshot404 return end # Send the thumbnail (uses X-Sendfile or similar if possible) send_file @screenshot.image.path(:large), type: "image/png", disposition: 'inline' end # Receives a form with a simple text field 'description' so that users can update # the description of their screenshot. def update_screenshot_description @screenshot = Screenshot.find(params[:id]) @screenshot.description = params[:description] @screenshot.save! flash['notice'] = "Description updated." redirect_to :back end # Receive an anonymous report from a user to have a screenshot removed. def report_screenshot @screenshot = Screenshot.find(params[:id]) if verify_recaptcha @screenshot.delete_reason = params[:delete_reason] @screenshot.markedfordelete = true if @screenshot.valid? @screenshot.save! flash['notice'] = "Screenshot reported. The moderators will deal with it." else errors = @screenshot.errors.to_a.join(' and ') flash['alert'] = "Sorry. #{errors}" end end redirect_to :back end # Show an HTML partial with reviews of this package from the Ubuntu API def reviews expires_in 1.day, public: true @reviews = Package.find_by_name!(params[:name]).ubuntu_reviews render '_reviews', layout: false end private # Send a dummy thumbnail reading "No screenshot available. Sorry." def thumbnail404 send_file Rails.root.join('public/images/dummy/thumbnail404.png'), type: "image/png", disposition: 'inline', status: 404 end def screenshot404 send_file Rails.root.join('public/images/dummy/screenshot404.png'), type: "image/png", disposition: 'inline', status: 404 end # Return packages matching the criteria given by parameters def query_packages packages = Package.includes(:screenshots) # text search if params[:search].present? logger.debug "Searching for #{params[:search]}" packages = packages.general_search(params[:search]) end case params[:show] when 'with' packages = packages.with_screenshots logger.debug 'Limiting packages to those with screenshots' when 'without' packages = packages.without_screenshots logger.debug 'Limiting packages to those without screenshots' end return packages end # Check if the user is allowed to do changed to a screenshot def user_can_alter_screenshot? # - Is this the user's own screenshot? # - Is the user an admin (=logged in)? @screenshot.uploaderhash == session[:token] or user_signed_in? end # Store a random identifier and the client's IP address in the session # for later identification. def create_user_token session[:token] ||= SecureRandom.hex session[:ip] ||= request.remote_ip end end