class User < ActiveRecord::Base cattr_reader :per_page @@per_page = 20 before_validation :strip_and_and_put_to_lowercase has_many :search_keywords has_many :article_statuses has_many :sent_articles, :through => :article_statuses, :source => :article, :conditions => "status = '#{ArticleStatus::STATUS_SENT}'", :order => :created_at has_many :viewed_articles, :through => :article_statuses, :source => :article, :conditions => "status ='#{ArticleStatus::STATUS_VIEWED}'", :order => :created_at USERNAME_MIN_LENGTH = 4 USERNAME_MAX_LENGTH = 20 PASSWORD_MIN_LENGTH = 4 PASSWORD_MAX_LENGTH = 40 EMAIL_MAX_LENGTH = 50 USERNAME_RANGE = USERNAME_MIN_LENGTH..USERNAME_MAX_LENGTH PASSWORD_RANGE = PASSWORD_MIN_LENGTH..PASSWORD_MAX_LENGTH MAX_NUMBER_OF_ARTICLES_PER_NEWSUPDATE = 10 MAX_SIZE_OF_A_MAIL_IN_CHARACTERS = 10000 NEWSUPDATE_RECENT_NUMBER_OF_DAYS = 120 =begin validates_uniqueness_of :username, :email validates_confirmation_of :password validates_length_of :username, :within => USERNAME_RANGE validates_length_of :password, :within => PASSWORD_RANGE validates_length_of :email, :maximum => EMAIL_MAX_LENGTH validates_format_of :username, :with => /^[a-z_][a-z0-9_]*$/, :message => I18n.t(:given_username_is_not_correct_validation_error) validates_format_of :email, :with => /^[A-Z0-9._%-]+@([A-Z0-9-]+\.)+[A-Z]{2,4}$/i, :message => I18n.t(:given_email_is_not_correct_validation_error) =end acts_as_authentic acts_as_authorization_subject #FIXME: is not unittested def post_recent_news recent_articles = collect_recent_articles do |article| article.size <= User::MAX_SIZE_OF_A_MAIL_IN_CHARACTERS end recent_articles.each do |article| UserMailer.deliver_newsupdate(self, article) article.set_user_status(self, ArticleStatus::STATUS_SENT) logger.info <<-EOF Email notification about article #{article.title} was sent to #{self.username}, address #{self.email} EOF end end def self.post_recent_news_for_every_user logger.info 'Starting to send the recent news for every user through email.' User.all.each do |user| user.post_recent_news end logger.info 'Sending recent news for every user finished.' end def collect_recent_articles(&article_condition) Sunspot.commit_if_dirty =begin searchquery = search_keywords.map do |search_keyword| "(#{search_keyword.query})" end.join(' OR ') search = Sunspot.search(Article) do keywords searchquery with(:published_at).greater_than Time.now - NEWSUPDATE_RECENT_NUMBER_OF_DAYS.day dynamic :status do without Article.give_user_status_symbol(self, ArticleStatus::STATUS_VIEWED), true without Article.give_user_status_symbol(self, ArticleStatus::STATUS_SENT), true end order_by(:published_at, :desc) paginate(:page => 1, :per_page => MAX_NUMBER_OF_ARTICLES_PER_NEWSUPDATE) end search.results =end set_all_articles = Set.new search_keywords.each do |search_keyword| article_update = recent_articles_for_search_keyword(search_keyword) set_all_articles += article_update end arr_all_articles = set_all_articles.to_a arr_all_articles = arr_all_articles.find_all { |article| article_condition.call(article) } if article_condition arr_all_articles.sort! { |article1, article2| article2.published_at <=> article1.published_at } arr_all_articles = arr_all_articles[0, MAX_NUMBER_OF_ARTICLES_PER_NEWSUPDATE] arr_all_articles end def recent_articles_for_search_keyword(search_keyword) searchquery = search_keyword.query search = Sunspot.search(Article) do keywords searchquery with(:published_at).greater_than Time.now - NEWSUPDATE_RECENT_NUMBER_OF_DAYS.day dynamic :status do without Article.give_user_status_symbol(self, ArticleStatus::STATUS_VIEWED), true without Article.give_user_status_symbol(self, ArticleStatus::STATUS_SENT), true end order_by(:published_at, :desc) paginate(:page => 1, :per_page => MAX_NUMBER_OF_ARTICLES_PER_NEWSUPDATE) end search.results end def can_be_modified_by(user) !user.nil? and (user==self or user.has_role?(:admin)) end private def strip_and_and_put_to_lowercase self.email.strip! self.email.downcase! end end