<commit_before>require 'digest/sha1'

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :confirmable, :omniauthable, #:reconfirmable,
         :recoverable, :rememberable, :trackable, :validatable

  include BlogKitModelHelper, TutorialAssigneesHelper
  #include Rails.application.routes.url_helpers
  
  validates_presence_of     :login
  validates_length_of       :login,    :within => 3..40
  validates_uniqueness_of   :login
  validates_format_of       :login,    :with => AuthenticationModule.login_regex, :message => AuthenticationModule.bad_login_message
  
  validates_presence_of     :name
  validates_format_of       :name,     :with => AuthenticationModule.name_regex, :allow_nil => true
  validates_length_of       :name,     :maximum => 50
  
  validates_format_of       :surname,     :with => AuthenticationModule.name_regex, :allow_nil => true
  validates_length_of       :surname,     :maximum => 50
  
  validates_length_of       :email,    :within => 6..50 #<EMAIL>
  validates_format_of       :email,    :with => AuthenticationModule.email_regex, :message => AuthenticationModule.bad_email_message
  validates_uniqueness_of   :email
  
  
  validates_acceptance_of   :accept_conditions, :message => "E' necessario accettare le condizioni d'uso"
  
  #colonne assegnabili massivamente
  attr_accessible :login, :name, :email, :surname, :password, :password_confirmation, :blog_image_url, :sex, :remember_me, :accept_conditions, :email_alerts
  
  #relations
  has_many :proposal_presentations, :class_name => 'ProposalPresentation'
  has_many :proposals, :through => :proposal_presentations, :class_name => 'Proposal'
  has_many :notifications, :through => :user_alerts, :class_name => 'Notification'
  has_many :proposal_watches, :class_name => 'ProposalWatch'
  has_many :meeting_partecipations, :class_name => 'MeetingPartecipation'
  has_one  :blog, :class_name => 'Blog'
  has_many :blog_comments, :class_name => 'BlogComment'
  has_many :blog_posts, :class_name => 'BlogPost'
  has_many :blocked_alerts, :class_name => 'BlockedAlert'
  has_many :group_partecipations, :class_name => 'GroupPartecipation'
  
  has_many :groups,:through => :group_partecipations, :class_name => 'Group'  
  
  has_many :partecipation_roles,:through => :group_partecipations, :class_name => 'PartecipationRole'  
  has_many :group_follows, :class_name => 'GroupFollow'
  has_many :followed_groups,:through => :group_follows, :class_name => 'Group', :source => :group
  has_many :user_votes, :class_name => 'UserVote'
  has_many :proposal_comments, :class_name => 'ProposalComment'
  has_many :proposal_comment_rankings, :class_name => 'ProposalCommentRanking'
  has_many :proposal_rankings, :class_name => 'ProposalRanking'
  belongs_to :user_type, :class_name => 'UserType', :foreign_key => :user_type_id
  belongs_to :places, :class_name => 'Place', :foreign_key => :residenza_id
  belongs_to :places, :class_name => 'Place', :foreign_key => :nascita_id
  belongs_to :image, :class_name => 'Image', :foreign_key => :image_id
  has_many :authentications, :class_name => 'Authentication'

  has_many :user_borders, :class_name => 'UserBorder'
  
  #confini di interesse
  has_many :interest_borders,:through => :user_borders, :class_name => 'InterestBorder'  
  
  has_many :user_alerts, :class_name => 'UserAlert', :order => 'created_at DESC'
  has_many :blocked_notifications, :through => :blocked_alerts, :class_name => 'NotificationType', :source => :notification_type
  
  has_many :group_partecipation_requests, :class_name => 'GroupPartecipationRequest'

  #record di tutti coloro che mi seguono
  has_many :followers_user_follow, :class_name => "UserFollow", :foreign_key => :followed_id  
  #tutti coloro che mi seguono
  has_many :followers,:through => :followers_user_follow, :class_name => "User", :source => :followed
  
  #record di tutti coloro che seguo
  has_many :followed_user_follow, :class_name => "UserFollow", :foreign_key => :follower_id  
  #tutti coloro che seguo
  has_many :followed,:through => :followed_user_follow, :class_name => "User", :source => :follower
  
  has_many :tutorial_assignees, :class_name => 'TutorialAssignee'
  has_many :tutorial_progresses, :class_name => 'TutorialProgress'
  has_many :todo_tutorial_assignees, :class_name => 'TutorialAssignee', :conditions => 'tutorial_assignees.completed = false'
  #tutorial assegnati all'utente
  has_many :tutorials, :through => :tutorial_assignees, :class_name => 'Tutorial', :source => :user
  has_many :todo_tutorials, :through => :todo_tutorial_assignees, :class_name => 'Tutorial', :source => :user
  
  
  #affinità con i gruppi
  has_many :group_affinities, :class_name => 'GroupAffinity'
  
  has_many :suggested_groups, :through => :group_affinities, :class_name => "Group", :order => "group_affinities.value desc", :limit => 10, :source => :group
  
  
  #candidature
  has_many :candidates, :class_name => 'Candidate'
  
  
  #fake columns
  attr_accessor :image_url, :accept_conditions

  before_create :init
  
  after_create :assign_tutorials


  #dopo aver creato un nuovo utente glia ssegno il primo tutorial
  def assign_tutorials
    tutorial = Tutorial.find_by_name("Welcome Tutorial")
    assign_tutorial(self,tutorial)      
    tutorial = Tutorial.find_by_name("First Proposal")
    assign_tutorial(self,tutorial)
    tutorial = Tutorial.find_by_name("Rank Bar")
    assign_tutorial(self,tutorial)
  end

  def init
    self.rank  ||= 0 #imposta il rank a zero se non è valorizzato     
  end


 #restituisce l'elenco delle partecipazioni ai gruppi dell'utente
 #all'interno dei quali possiede un determinato permesso
 def scoped_group_partecipations(abilitation)
   return self.group_partecipations.joins(" INNER JOIN partecipation_roles ON partecipation_roles.id = group_partecipations.partecipation_role_id"+
                                   " LEFT JOIN action_abilitations ON action_abilitations.partecipation_role_id = partecipation_roles.id "+
                                   " and action_abilitations.group_id = group_partecipations.group_id")
                                   .find(:all, 
                                         :conditions => "(partecipation_roles.name = 'portavoce' or action_abilitations.group_action_id = " + abilitation.to_s + ")")
 end

 def self.new_with_session(params, session)
    super.tap do |user|
      fdata = session["devise.facebook_data"]
      if fdata && data = fdata["extra"]["raw_info"]
        user.email = data["email"]
      end
    end
  end
  
  def last_blog_comment
    self.blog_comments
  end
  
  
  def image_url
    if (self.blog_image_url != nil)
      return self.blog_image_url
    elsif (self.image_id)
      return self.image.image.url
    else
      return ""      
    end
  end
  
  
  def login=(value)
    write_attribute :login, (value ? value.downcase : nil)
  end
  
  def email=(value)
    if (self.account_type != 'facebook' && !self.email)
   # if (false) #al momento non è consentito cambiare l'email<commit_msg>corretto bug caricamento immagine utente<commit_after>require 'digest/sha1'

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :confirmable, :omniauthable, #:reconfirmable,
         :recoverable, :rememberable, :trackable, :validatable

  include BlogKitModelHelper, TutorialAssigneesHelper
  #include Rails.application.routes.url_helpers
  
  validates_presence_of     :login
  validates_length_of       :login,    :within => 3..40
  validates_uniqueness_of   :login
  validates_format_of       :login,    :with => AuthenticationModule.login_regex, :message => AuthenticationModule.bad_login_message
  
  validates_presence_of     :name
  validates_format_of       :name,     :with => AuthenticationModule.name_regex, :allow_nil => true
  validates_length_of       :name,     :maximum => 50
  
  validates_format_of       :surname,     :with => AuthenticationModule.name_regex, :allow_nil => true
  validates_length_of       :surname,     :maximum => 50
  
  validates_length_of       :email,    :within => 6..50 #<EMAIL>
  validates_format_of       :email,    :with => AuthenticationModule.email_regex, :message => AuthenticationModule.bad_email_message
  validates_uniqueness_of   :email
  
  
  validates_acceptance_of   :accept_conditions, :message => "E' necessario accettare le condizioni d'uso"
  
  #colonne assegnabili massivamente
  attr_accessible :login, :name, :email, :surname, :password, :password_confirmation, :blog_image_url, :sex, :remember_me, :accept_conditions, :email_alerts
  
  #relations
  has_many :proposal_presentations, :class_name => 'ProposalPresentation'
  has_many :proposals, :through => :proposal_presentations, :class_name => 'Proposal'
  has_many :notifications, :through => :user_alerts, :class_name => 'Notification'
  has_many :proposal_watches, :class_name => 'ProposalWatch'
  has_many :meeting_partecipations, :class_name => 'MeetingPartecipation'
  has_one  :blog, :class_name => 'Blog'
  has_many :blog_comments, :class_name => 'BlogComment'
  has_many :blog_posts, :class_name => 'BlogPost'
  has_many :blocked_alerts, :class_name => 'BlockedAlert'
  has_many :group_partecipations, :class_name => 'GroupPartecipation'
  
  has_many :groups,:through => :group_partecipations, :class_name => 'Group'  
  
  has_many :partecipation_roles,:through => :group_partecipations, :class_name => 'PartecipationRole'  
  has_many :group_follows, :class_name => 'GroupFollow'
  has_many :followed_groups,:through => :group_follows, :class_name => 'Group', :source => :group
  has_many :user_votes, :class_name => 'UserVote'
  has_many :proposal_comments, :class_name => 'ProposalComment'
  has_many :proposal_comment_rankings, :class_name => 'ProposalCommentRanking'
  has_many :proposal_rankings, :class_name => 'ProposalRanking'
  belongs_to :user_type, :class_name => 'UserType', :foreign_key => :user_type_id
  belongs_to :places, :class_name => 'Place', :foreign_key => :residenza_id
  belongs_to :places, :class_name => 'Place', :foreign_key => :nascita_id
  belongs_to :image, :class_name => 'Image', :foreign_key => :image_id
  has_many :authentications, :class_name => 'Authentication'

  has_many :user_borders, :class_name => 'UserBorder'
  
  #confini di interesse
  has_many :interest_borders,:through => :user_borders, :class_name => 'InterestBorder'  
  
  has_many :user_alerts, :class_name => 'UserAlert', :order => 'created_at DESC'
  has_many :blocked_notifications, :through => :blocked_alerts, :class_name => 'NotificationType', :source => :notification_type
  
  has_many :group_partecipation_requests, :class_name => 'GroupPartecipationRequest'

  #record di tutti coloro che mi seguono
  has_many :followers_user_follow, :class_name => "UserFollow", :foreign_key => :followed_id  
  #tutti coloro che mi seguono
  has_many :followers,:through => :followers_user_follow, :class_name => "User", :source => :followed
  
  #record di tutti coloro che seguo
  has_many :followed_user_follow, :class_name => "UserFollow", :foreign_key => :follower_id  
  #tutti coloro che seguo
  has_many :followed,:through => :followed_user_follow, :class_name => "User", :source => :follower
  
  has_many :tutorial_assignees, :class_name => 'TutorialAssignee'
  has_many :tutorial_progresses, :class_name => 'TutorialProgress'
  has_many :todo_tutorial_assignees, :class_name => 'TutorialAssignee', :conditions => 'tutorial_assignees.completed = false'
  #tutorial assegnati all'utente
  has_many :tutorials, :through => :tutorial_assignees, :class_name => 'Tutorial', :source => :user
  has_many :todo_tutorials, :through => :todo_tutorial_assignees, :class_name => 'Tutorial', :source => :user
  
  
  #affinità con i gruppi
  has_many :group_affinities, :class_name => 'GroupAffinity'
  
  has_many :suggested_groups, :through => :group_affinities, :class_name => "Group", :order => "group_affinities.value desc", :limit => 10, :source => :group
  
  
  #candidature
  has_many :candidates, :class_name => 'Candidate'
  
  
  #fake columns
  attr_accessor :image_url, :accept_conditions

  before_create :init
  
  after_create :assign_tutorials


  #dopo aver creato un nuovo utente glia ssegno il primo tutorial
  def assign_tutorials
    tutorial = Tutorial.find_by_name("Welcome Tutorial")
    assign_tutorial(self,tutorial)      
    tutorial = Tutorial.find_by_name("First Proposal")
    assign_tutorial(self,tutorial)
    tutorial = Tutorial.find_by_name("Rank Bar")
    assign_tutorial(self,tutorial)
  end

  def init
    self.rank  ||= 0 #imposta il rank a zero se non è valorizzato     
  end


 #restituisce l'elenco delle partecipazioni ai gruppi dell'utente
 #all'interno dei quali possiede un determinato permesso
 def scoped_group_partecipations(abilitation)
   return self.group_partecipations.joins(" INNER JOIN partecipation_roles ON partecipation_roles.id = group_partecipations.partecipation_role_id"+
                                   " LEFT JOIN action_abilitations ON action_abilitations.partecipation_role_id = partecipation_roles.id "+
                                   " and action_abilitations.group_id = group_partecipations.group_id")
                                   .find(:all, 
                                         :conditions => "(partecipation_roles.name = 'portavoce' or action_abilitations.group_action_id = " + abilitation.to_s + ")")
 end

 def self.new_with_session(params, session)
    super.tap do |user|
      fdata = session["devise.facebook_data"]
      if fdata && data = fdata["extra"]["raw_info"]
        user.email = data["email"]
      end
    end
  end
  
  def last_blog_comment
    self.blog_comments
  end
  
  
  def image_url
    if (self.blog_image_url && !self.blog_image_url.blank?)
      return self.blog_image_url
    elsif (self.image_id)
      return self.image.image.url
    else
      return ""      
    end
  end
  
  
  def login=(value)
    write_attribute :login, (value ? value.downcase : nil)
  end
  
  def email=(value)
    if (self.account_type != 'facebook' && !self.email)
   # if (false) #al momento non è consentito cambiare l'email
{'fraction_non_alphanumeric': 0.10460048426150122, 'fraction_numerical': 0.001937046004842615, 'mean_word_length': 4.424390243902439, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 171, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4694500', 'n_tokens_mistral': 4968, 'n_tokens_neox': 4773, 'n_words': 1013}