software_communities_plugin.rb 7.8 KB
class SoftwareCommunitiesPlugin < Noosfero::Plugin
  include ActionView::Helpers::TagHelper
  include ActionView::Helpers::FormTagHelper
  include ActionView::Helpers::FormOptionsHelper
  include ActionView::Helpers::JavaScriptHelper
  include ActionView::Helpers::AssetTagHelper
  include FormsHelper
  include ActionView::Helpers
  include ActionDispatch::Routing
  include Rails.application.routes.url_helpers

  def self.plugin_name
    'SoftwareCommunitiesPlugin'
  end

  def self.plugin_description
    _('Add Public Software and MPOG features.')
  end

  def profile_tabs
    if context.profile.community? && context.profile.software?
      return profile_tabs_software
    end
  end

  def control_panel_buttons
    if context.profile.software?
      return software_info_button
    elsif context.profile.person?
      return create_new_software_button
    end
  end

  def self.extra_blocks
    {
      SoftwareCommunitiesPlugin::SoftwaresBlock => { :type => [Environment, Person]  },
      SoftwareCommunitiesPlugin::SoftwareInformationBlock => {  :type => [Community]  },
      SoftwareCommunitiesPlugin::DownloadBlock => { :type => [Community] },
      SoftwareCommunitiesPlugin::RepositoryBlock => { :type => [Community] },
      SoftwareCommunitiesPlugin::CategoriesAndTagsBlock => { :type => [Community] },
      SoftwareCommunitiesPlugin::CategoriesSoftwareBlock => { :type => [Environment] },
      SoftwareCommunitiesPlugin::SearchCatalogBlock => { :type => [Environment] },
      SoftwareCommunitiesPlugin::SoftwareHighlightsBlock => { :type => [Environment] },
      SoftwareCommunitiesPlugin::SoftwareTabDataBlock => {:type => [Community], :position => 1},
      SoftwareCommunitiesPlugin::WikiBlock => {:type => [Community]},
      SoftwareCommunitiesPlugin::StatisticBlock => { :type => [Community] }
    }
  end

  def stylesheet?
    true
  end

  def js_files
    %w(
      vendor/jquery.maskedinput.min.js
      vendor/modulejs-1.5.0.min.js
      vendor/jquery.js
      lib/noosfero-root.js
      lib/select-element.js
      lib/select-field-choices.js
      lib/auto-complete.js
      lib/software-catalog-component.js
      views/control-panel.js
      views/edit-software.js
      views/new-software.js
      views/search-software-catalog.js
      views/profile-tabs-software.js
      views/new-community.js
      views/comments-software-extra-fields.js
      blocks/software-download.js
      initializer.js
      app.js
    )
  end

  module Hotspots
    def display_organization_average_rating organization
      nil
    end
  end

  def organization_ratings_plugin_comments_extra_fields
    if context.profile.software?
      Proc::new { render :file => 'comments_extra_fields' }
    end
  end

  def organization_ratings_plugin_star_message
    Proc::new do _("Rate this software") end
  end

  def organization_ratings_title
    title = _('Use reports')
    Proc::new do "<h1 class='title'>#{title}</h1>" end
  end

  def organization_ratings_plugin_extra_fields_show_data user_rating
    Proc::new {
      if logged_in?
        is_admin = environment.admins.include?(current_user.person)
        is_admin ||= user_rating.organization.admins.include?(current_user.person)

        if is_admin and profile.software?
            render :file => 'organization_ratings_extra_fields_show_data',
                   :locals => {:user_rating => user_rating}
        end
      end
    }
  end

  # FIXME - if in error log apears has_permission?, try to use this method
  def has_permission?(person, permission, target)
    person.has_permission_without_plugins?(permission, target)
  end


  def filter_search_scope(scope, asset)
    # Select only communities that are not related to any software.
    if asset.to_s == 'communities'
      scope = scope.joins('LEFT OUTER JOIN software_communities_plugin_software_infos as softwares
        ON profiles.id = softwares.community_id').
        where('softwares.community_id IS NULL')

      return [scope, asset]
    else
      return [scope, asset]
    end
  end

  def new_search_assets
    class_name_underscored =  "software_communities_plugin/software_infos"
    block = proc do
      prepare_software_search_page
      @scope = visible_profiles(Community)
      @asset = class_name_underscored
      @assets = [@asset]
      params[:limit] = 24
    end

    [{:name => 'software', :block => block, :common_profile_list_block => class_name_underscored}]
  end

  def find_by_contents(asset, scope, query, paginate_options={}, options={})
    if query && asset.to_s == 'software_communities_plugin/software_infos'
      community_ids = get_community_ids_from_filtered_software(query)
      scope = Community.where(:id => community_ids)
    end

    # scope = scope.like_search(query, options) unless query.blank?
    # scope = scope.send(options[:filter]) unless options[:filter].blank?
    {:results => scope.paginate(paginate_options)}
  end

  protected

  def get_community_ids_from_filtered_software query
    software_list = SoftwareCommunitiesPlugin::SoftwareInfo.search_by_query(query)

    software_list = filter_only_specific_softwares(software_list)

    software_list = filter_softwares_by_categories(software_list)

    community_ids = []

    software_list.each do |software|
      community_ids << software.community_id
    end

    community_ids
  end

  def filter_only_specific_softwares software_list
    # TODO: refatorar isso para um scope
    if context.params[:only_softwares]
      context.params[:only_softwares].collect!{ |software_name| software_name.to_slug }
      software_list = SoftwareCommunitiesPlugin::SoftwareInfo.all.select{ |s| context.params[:only_softwares].include?(s.identifier) }
      context.public_software_selected = false
    end

    software_list
  end

  def filter_softwares_by_categories software_list
    # TODO: refatorar isso para um scope
    category_ids = []
    unless context.params[:selected_categories_id].blank?
      category_ids = context.params[:selected_categories_id]
    end

    category_ids = category_ids.map(&:to_i)

    unless category_ids.empty?
      software_list.select! do |software|
        if software.nil? || software.community.nil?
          false
        else
          result_ids = (software.community.category_ids & category_ids).sort
          result_ids == category_ids.sort
        end
      end
    end

    software_list
  end

  def sort_communities_list communities_list
    communities_list.sort! {|a, b| a.name.downcase <=> b.name.downcase}

    if params[:sort] && params[:sort] == "desc"
      communities_list.reverse!
    elsif params[:sort] && params[:sort] == "relevance"
      communities_list = sort_by_relevance(communities_list, params[:query]){ |community| [community.software_info.finality, community.name] }
    end
    communities_list
  end

  def software_info_transaction
    SoftwareCommunitiesPlugin::SoftwareInfo.transaction do
      context.profile.
        software_info.
        update_attributes!(context.params[:software_info])
    end
  end

  def license_transaction
    license = SoftwareCommunitiesPlugin::LicenseInfo.find(context.params[:version])
    context.profile.software_info.license_info = license
    context.profile.software_info.save!
  end

  private

  def software_info_button
    {
      :title => _('Software Info'),
      :icon => 'edit-profile-group control-panel-software-link',
      :url => {
        :controller => 'software_communities_plugin_myprofile',
        :action => 'edit_software'
      }
    }
  end

  def create_new_software_button
    {
      :title => _('Create a new software'),
      :icon => 'design-editor',
      :url => {
        :controller => 'software_communities_plugin_myprofile',
        :action => 'new_software'
      }
    }
  end

  def profile_tabs_software
    { :title => _('Software'),
      :id => 'software-fields',
      :content => Proc::new do render :partial => 'profile/software_tab' end,
      :start => true }
  end
end