<commit_before>class UsersController < ApplicationController  
  before_filter :authenticate_user!, :except => [:index, :show, :new, :create, :activate, :relationships]
  before_filter :find_user, :only => [:suspend, :unsuspend, :destroy, :purge, 
    :show, :edit, :update, :relationships, :add_role, :remove_role]
  before_filter :ensure_user_is_current_user_or_admin, :only => [:edit, :update, :destroy, :suspend, :unsuspend]
  before_filter :admin_required, :only => [:curation]
  before_filter :return_here, :only => [:index, :show, :relationships, :dashboard, :curation]
  
  MOBILIZED = [:show, :dashboard, :new, :create]
  before_filter :unmobilized, :except => MOBILIZED
  before_filter :mobilized, :only => MOBILIZED
  
  caches_action :dashboard,
    :expires_in => 1.hour,
    :cache_path => Proc.new {|c| c.send(:home_url, :user_id => c.instance_variable_get("@current_user").id)},
    :if => Proc.new {|c| (c.params.keys - %w(action controller)).blank? }
  cache_sweeper :user_sweeper, :only => [:update]
  
  def new
    @user = User.new
  end
 
  def create
    logout_keeping_session!
    @user = User.new(params[:user])
    params[:user].each do |k,v|
      if k =~ /^prefer/
        params[:user].delete(k)
      else
        next
      end
      @user.send("#{k}=", v)
    end
    @user.register! if @user && @user.valid?
    success = @user && @user.valid?
    if success && @user.errors.empty?
      flash[:notice] = "Welcome to iNaturalist!  Please check for your confirmation email, but feel free to start cruising the site."
      self.current_user = @user
      @user.update_attribute(:last_ip, request.env['REMOTE_ADDR'])
      redirect_back_or_default(dashboard_path)
    else
      respond_to do |format|
        format.html { render :action => 'new' }
        format.mobile { render :action => 'new' }
      end
    end
  end

  # this method should have been replaced by Devise, but there are probably some activation emails lingering in people's inboxes
  def activate
    user = current_user
    case
    when user && user.suspended?
      redirect_back_or_default('/')
    when (!params[:activation_code].blank?) && user && !user.confirmed?
      user.confirm!
      flash[:notice] = "Your #{APP_CONFIG[:site_name]} account has been verified! Please sign in to continue."
      if logged_in? && current_user.is_admin?
        redirect_back_or_default('/')
      else
        redirect_to '/login'
      end
    when params[:activation_code].blank?
      flash[:error] = "Your activation code was missing.  Please follow the URL from your email."
      redirect_back_or_default('/')
    else 
      flash[:error]  = "We couldn't find a user with that activation code. You may have already activated your account, please try signing in."
      redirect_back_or_default('/')
    end
  end

  # Don't take these out yet, useful for admin user management down the road

  def suspend
     @user.suspend! 
     flash[:notice] = "The user #{@user.login} has been suspended"
     redirect_back_or_default(@user)
  end
   
  def unsuspend
    @user.unsuspend! 
    flash[:notice] = "The user #{@user.login} has been unsuspended"
    redirect_back_or_default(@user)
  end
  
  def add_role
    unless @role = Role.find_by_name(params[:role])
      flash[:error] = "That role doesn't exist"
      return redirect_to :back
    end
    
    if !current_user.has_role?(@role.name) || (@user.is_admin? && !current_user.is_admin?)
      flash[:error] = "Sorry, you don't have permission to do that"
      return redirect_to :back
    end
    
    @user.roles << @role
    flash[:notice] = "Made #{@user.login} a(n) #{@role.name}"
    redirect_to :back
  end
  
  def remove_role
    unless @role = Role.find_by_name(params[:role])
      flash[:error] = "That role doesn't exist"
      return redirect_to :back
    end
    
    unless current_user.has_role?(@role.name)
      flash[:error] = "Sorry, you don't have permission to do that"
      return redirect_to :back
    end
    
    if @user.roles.delete(@role)
      flash[:notice] = "Removed #{@role.name} status from #{@user.login}"
    else
      flash[:error] = "#{@user.login} doesn't have #{@role.name} status"
    end
    redirect_to :back
  end
  
  def destroy
    unless @user.project_users.blank? #remove any curator id's this user might have made
      @user.project_users.each do |pu|
        unless pu.role.nil?
          Project.delay.update_curator_idents_on_remove_curator(pu.project_id, @user.id)
        end
      end
    end
    @user.destroy
    flash[:notice] = "#{@user.login} removed from iNaturalist"
    redirect_to users_path
  end
  
  # Methods below here are added by iNaturalist
  
  def index
    unless fragment_exist?("recently_active")
      @updates = []
      [Observation, Identification, Post, Comment].each do |klass|
        @updates += klass.limit(10).
          order("#{klass.table_name}.id DESC").
          where("#{klass.table_name}.created_at > ?", 1.week.ago).
          includes(:user)
      end
      hash = {}
      @updates.sort_by(&:created_at).each do |record|
        hash[record.user_id] = record
      end
      @updates = hash.values.sort_by(&:created_at).reverse[0..11]
    end

    @most_species_key = "most_observations"
    unless fragment_exist?("most_observations")
      counts = Observation.group(:user_id).
        where("EXTRACT(YEAR FROM observed_on) = ?", Time.now.year).
        where("EXTRACT(MONTH FROM observed_on) = ?", Time.now.month).
        count.to_a.sort_by(&:last).reverse[0..4]
      users = User.where("id IN (?)", counts.map(&:first))
      @most_observations = counts.inject({}) do |memo, item|
        memo[users.detect{|u| u.id == item.first}] = item.last
        memo
      end
    end

    @most_species_key = "most_species_1"
    unless fragment_exist?(@most_species_key)
      counts = Observation.group(:user_id, :taxon_id).
        joins(:taxon).
        where("EXTRACT(YEAR FROM observed_on) = ?", Time.now.year).
        where("EXTRACT(MONTH FROM observed_on) = ?", Time.now.month).
        where("taxa.rank_level <= ?", Taxon::SPECIES_LEVEL).
        count.to_a.sort_by(&:last).reverse
      users = User.where("id IN (?)", counts.map{|item| item[0][0]})
      @most_species = counts.inject({}) do |memo, item|
        memo[users.detect{|u| u.id == item[0][0]}] ||= 0
        memo[users.detect{|u| u.id == item[0][0]}] += 1
        memo
      end.to_a
      @most_species = @most_species.sort_by(&:last).reverse[0..4]
    end

    @most_identifications_key = "most_identifications_1"
    unless fragment_exist?(@most_identifications_key)
      counts = Identification.group("identifications.user_id").
        joins(:observation).
        where("identifications.user_id != observations.user_id").
        where("EXTRACT(YEAR FROM identifications.created_at) = ?", Time.now.year).
        where("EXTRACT(MONTH FROM identifications.created_at) = ?", Time.now.month).
        order('count_all desc').
        limit(5).
        count.to_a #.sort_by(&:last).reverse[0..4]
      users = User.where("id IN (?)", counts.map(&:first))
      @most_identifications = counts.inject({}) do |memo, item|
        memo[users.detect{|u| u.id == item.first}] = item.last
        memo
      end
    end
  end<commit_msg>Made sure people/index caches are site and locale specific.<commit_after>class UsersController < ApplicationController  
  before_filter :authenticate_user!, :except => [:index, :show, :new, :create, :activate, :relationships]
  before_filter :find_user, :only => [:suspend, :unsuspend, :destroy, :purge, 
    :show, :edit, :update, :relationships, :add_role, :remove_role]
  before_filter :ensure_user_is_current_user_or_admin, :only => [:edit, :update, :destroy, :suspend, :unsuspend]
  before_filter :admin_required, :only => [:curation]
  before_filter :return_here, :only => [:index, :show, :relationships, :dashboard, :curation]
  
  MOBILIZED = [:show, :dashboard, :new, :create]
  before_filter :unmobilized, :except => MOBILIZED
  before_filter :mobilized, :only => MOBILIZED
  
  caches_action :dashboard,
    :expires_in => 1.hour,
    :cache_path => Proc.new {|c| c.send(:home_url, :user_id => c.instance_variable_get("@current_user").id)},
    :if => Proc.new {|c| (c.params.keys - %w(action controller)).blank? }
  cache_sweeper :user_sweeper, :only => [:update]
  
  def new
    @user = User.new
  end
 
  def create
    logout_keeping_session!
    @user = User.new(params[:user])
    params[:user].each do |k,v|
      if k =~ /^prefer/
        params[:user].delete(k)
      else
        next
      end
      @user.send("#{k}=", v)
    end
    @user.register! if @user && @user.valid?
    success = @user && @user.valid?
    if success && @user.errors.empty?
      flash[:notice] = "Welcome to iNaturalist!  Please check for your confirmation email, but feel free to start cruising the site."
      self.current_user = @user
      @user.update_attribute(:last_ip, request.env['REMOTE_ADDR'])
      redirect_back_or_default(dashboard_path)
    else
      respond_to do |format|
        format.html { render :action => 'new' }
        format.mobile { render :action => 'new' }
      end
    end
  end

  # this method should have been replaced by Devise, but there are probably some activation emails lingering in people's inboxes
  def activate
    user = current_user
    case
    when user && user.suspended?
      redirect_back_or_default('/')
    when (!params[:activation_code].blank?) && user && !user.confirmed?
      user.confirm!
      flash[:notice] = "Your #{APP_CONFIG[:site_name]} account has been verified! Please sign in to continue."
      if logged_in? && current_user.is_admin?
        redirect_back_or_default('/')
      else
        redirect_to '/login'
      end
    when params[:activation_code].blank?
      flash[:error] = "Your activation code was missing.  Please follow the URL from your email."
      redirect_back_or_default('/')
    else 
      flash[:error]  = "We couldn't find a user with that activation code. You may have already activated your account, please try signing in."
      redirect_back_or_default('/')
    end
  end

  # Don't take these out yet, useful for admin user management down the road

  def suspend
     @user.suspend! 
     flash[:notice] = "The user #{@user.login} has been suspended"
     redirect_back_or_default(@user)
  end
   
  def unsuspend
    @user.unsuspend! 
    flash[:notice] = "The user #{@user.login} has been unsuspended"
    redirect_back_or_default(@user)
  end
  
  def add_role
    unless @role = Role.find_by_name(params[:role])
      flash[:error] = "That role doesn't exist"
      return redirect_to :back
    end
    
    if !current_user.has_role?(@role.name) || (@user.is_admin? && !current_user.is_admin?)
      flash[:error] = "Sorry, you don't have permission to do that"
      return redirect_to :back
    end
    
    @user.roles << @role
    flash[:notice] = "Made #{@user.login} a(n) #{@role.name}"
    redirect_to :back
  end
  
  def remove_role
    unless @role = Role.find_by_name(params[:role])
      flash[:error] = "That role doesn't exist"
      return redirect_to :back
    end
    
    unless current_user.has_role?(@role.name)
      flash[:error] = "Sorry, you don't have permission to do that"
      return redirect_to :back
    end
    
    if @user.roles.delete(@role)
      flash[:notice] = "Removed #{@role.name} status from #{@user.login}"
    else
      flash[:error] = "#{@user.login} doesn't have #{@role.name} status"
    end
    redirect_to :back
  end
  
  def destroy
    unless @user.project_users.blank? #remove any curator id's this user might have made
      @user.project_users.each do |pu|
        unless pu.role.nil?
          Project.delay.update_curator_idents_on_remove_curator(pu.project_id, @user.id)
        end
      end
    end
    @user.destroy
    flash[:notice] = "#{@user.login} removed from iNaturalist"
    redirect_to users_path
  end
  
  # Methods below here are added by iNaturalist
  
  def index
    unless fragment_exist?("recently_active")
      @updates = []
      [Observation, Identification, Post, Comment].each do |klass|
        @updates += klass.limit(10).
          order("#{klass.table_name}.id DESC").
          where("#{klass.table_name}.created_at > ?", 1.week.ago).
          includes(:user)
      end
      hash = {}
      @updates.sort_by(&:created_at).each do |record|
        hash[record.user_id] = record
      end
      @updates = hash.values.sort_by(&:created_at).reverse[0..11]
    end

    @most_species_key = "most_observations_#{I18n.locale}_#{SITE_NAME}"
    unless fragment_exist?("most_observations")
      counts = Observation.group(:user_id).
        where("EXTRACT(YEAR FROM observed_on) = ?", Time.now.year).
        where("EXTRACT(MONTH FROM observed_on) = ?", Time.now.month).
        count.to_a.sort_by(&:last).reverse[0..4]
      users = User.where("id IN (?)", counts.map(&:first))
      @most_observations = counts.inject({}) do |memo, item|
        memo[users.detect{|u| u.id == item.first}] = item.last
        memo
      end
    end

    @most_species_key = "most_species_#{I18n.locale}_#{SITE_NAME}"
    unless fragment_exist?(@most_species_key)
      counts = Observation.group(:user_id, :taxon_id).
        joins(:taxon).
        where("EXTRACT(YEAR FROM observed_on) = ?", Time.now.year).
        where("EXTRACT(MONTH FROM observed_on) = ?", Time.now.month).
        where("taxa.rank_level <= ?", Taxon::SPECIES_LEVEL).
        count.to_a.sort_by(&:last).reverse
      users = User.where("id IN (?)", counts.map{|item| item[0][0]})
      @most_species = counts.inject({}) do |memo, item|
        memo[users.detect{|u| u.id == item[0][0]}] ||= 0
        memo[users.detect{|u| u.id == item[0][0]}] += 1
        memo
      end.to_a
      @most_species = @most_species.sort_by(&:last).reverse[0..4]
    end

    @most_identifications_key = "most_identifications_#{I18n.locale}_#{SITE_NAME}"
    unless fragment_exist?(@most_identifications_key)
      counts = Identification.group("identifications.user_id").
        joins(:observation).
        where("identifications.user_id != observations.user_id").
        where("EXTRACT(YEAR FROM identifications.created_at) = ?", Time.now.year).
        where("EXTRACT(MONTH FROM identifications.created_at) = ?", Time.now.month).
        order('count_all desc').
        limit(5).
        count.to_a #.sort_by(&:last).reverse[0..4]
      users = User.where("id IN (?)", counts.map(&:first))
      @most_identifications = counts.inject({}) do |memo, item|
        memo[users.detect{|u| u.id == item.first}] = item.last
        memo
      end
    end
  end
{'fraction_non_alphanumeric': 0.13727495908346973, 'fraction_numerical': 0.0035460992907801418, 'mean_word_length': 3.0713492504164353, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7372616', 'n_tokens_mistral': 4889, 'n_tokens_neox': 4804, 'n_words': 1105}