<commit_before>require 'language'
require 'unicode'
require 'iconv'
require 'yaml'
#require 'manual_support'

class Page < ActiveRecord::Base
	
	serialize :redirect_to
	
	# Relations
	belongs_to   :author, :class_name => "User", :foreign_key => :user_id
	has_and_belongs_to_many :categories, :join_table => :pages_categories

	belongs_to_image        :image
	has_and_belongs_to_many :images

	has_many :comments, :class_name => 'PageComment', :dependent => :destroy
	has_many :files, :class_name => 'PageFile', :dependent => :destroy, :order => :position

	acts_as_list :scope => :parent_page
	acts_as_tree :order => :position, :foreign_key => :parent_page_id

	acts_as_textable [ "name", "body", "excerpt", "headline", "boxout" ], :allow_any => true
	acts_as_taggable
	
	# Page status labels
	STATUS_LABELS = [ "Draft", "Reviewed", "Published", "Hidden", "Deleted" ]
	
	@@available_templates_cached = nil
	
	validate do |page|
		#page.errors.add( :name, 'must have a title' ) if page.name.empty? # and !page.deleted?
		page.template ||= page.default_template
	end
	
	before_save    { |page| page.published_at = Time.now unless page.published_at? }
	
	# fuck a ferret
	#acts_as_ferret :fields => { :names_for_search => { :boost => 2 }, :content_for_search => {} }
	
	# define_index do
	# 	# fields
	# 	#indexes [author.realname, author.email], :as => author_name
	# 	
	# 	# attributes
	# 	has published_at, status, user_id, template, parent_page_id
	# 
	# 	#set_property :delta => true
	# end
	

	# ---- CLASS METHODS ------------------------------------------------------

	class << self
		
		# Finds pages due for auto publishing and publishes them.
		def autopublish!(options={})
			options[:fuzziness] ||= 1.minute
			publish_timestamp = Time.now + options[:fuzziness]
			pages = self.find(:all, :conditions => ['autopublish = 1 AND autopublish_at < ?', publish_timestamp])
			pages.each do |p|
				p.update_attribute(:autopublish, false)
			end
			pages
		end
		
		# Finds pages with comments, ordered by date of last comment.
		#
		# === Parameters
		# * <tt>:limit</tt> - An integer determining the limit on the number of results that should be returned. 
		#
		# Example:
		#   Page.last_commented(:limit => 10)
		def last_commented(options={})
			find_query = "SELECT p.* FROM pages p, page_comments c 
			              WHERE c.page_id = p.id AND p.status = 2 
			              GROUP BY c.page_id ORDER BY c.created_at DESC"
			find_query << " LIMIT #{options[:limit]}" if options[:limit]
			Page.find_by_sql(find_query)
		end
	
		# Finds pages with comments, ordered by number of comments.
		#
		# === Parameters
		# * <tt>:limit</tt> - An integer determining the limit on the number of results that should be returned. 
		#
		# Example:
		#   Page.most_commented(:limit => 10)
		def most_commented(options={})
			find_query = "SELECT p.*, COUNT(c.id) as comments_count FROM pages p, page_comments c 
			              WHERE c.page_id = p.id AND p.status = 2 
			              GROUP BY c.page_id ORDER BY comments_count DESC"
			find_query << " LIMIT #{options[:limit]}" if options[:limit]
			Page.find_by_sql(find_query)
		end

		def get_pages_options(options={})
			options.symbolize_keys!

			# Clean up depreceated options
			options.keys.each do |key|
				if key.to_s =~ /^show_/
					new_key = key.to_s.gsub(/^show_/,'').to_sym
					logger.warn "DEPRECEATED: Option :#{key} is deprecated, use :#{new_key}"
					options[new_key] = options[key]
				end
			end

			options[:all]           ||= false
			options[:deleted]       ||= options[:all]
			options[:hidden]        ||= options[:all]
			options[:drafts]        ||= options[:all]
			options[:autopublish]   ||= options[:all]
			options[:all_languages] ||= false
			options[:order]         ||= "position"
			options[:parent]        = options[:parents] if options[:parents]
			options[:include]       ||= [:textbits, :categories, :image, :author]
			
			find_options = {
				:conditions => [[]]
			}

			# Ordering subpages
			#options[:order] = options[:order].split( /,[\s]*/ ).map{ |c| (c =~ /^pages\./ ) ? c : "pages."+c }.join(", ")
			find_options[:order] = options[:order]
			
			# Parent check
			if options[:parent] && options[:parent] == :root
				find_options[:conditions].first << "parent_page_id IS NULL"
			elsif options[:parent] && options[:parent].kind_of?(Enumerable)
				parent_ids = options[:parent].map{|p| p.kind_of?(Page) ? p.id : p}
				find_options[:conditions].first << "parent_page_id IN (" + parent_ids.join(", ") + ")"
			elsif options[:parent]
				parent_id = options[:parent]
				parent_id = parent_id.id if parent_id.kind_of?(Page)
				find_options[:conditions].first << "parent_page_id = #{parent_id}"
			end

			# Status check
			unless options[:all] || options[:deleted] || options[:hidden] || options[:drafts]
				find_options[:conditions].first << "status = 2"
			else
				find_options[:conditions].first << "status < 4"   unless options[:deleted]
				find_options[:conditions].first << "status != 3"  unless options[:hidden]
				find_options[:conditions].first << "status >= 2"  unless options[:drafts]
			end
			find_options[:conditions].first << "autopublish = 0" unless options[:autopublish]
		
			# Date limit check
			if options[:published_within]
				options[:published_before] = options[:published_within].last
				options[:published_after]  = options[:published_within].first
			end
			if options[:published_before] || options[:published_after]
				if options[:published_before]
					find_options[:conditions].first << "published_at <= ?"
					find_options[:conditions] << options[:published_before]
				end
				if options[:published_after]
					find_options[:conditions].first << " AND published_at >= ?"
					find_options[:conditions] << options[:published_after]
				end
			end
			
			# Language check
			if options[:language] && !options[:all_languages]
				find_options[:joins] ||= ""
				options[:language] = options[:language].to_s
				raise "Not a valid language code" unless options[:language] =~ /^[\w]{2,3}$/
				find_options[:joins] += "JOIN `textbits` ON `textbits`.textable_type = \"Page\" AND `textbits`.textable_id = `pages`.id AND `textbits`.language = '#{options[:language]}' "
				find_options[:group] = "`pages`.id"
			end
			
			# Category check
			if options[:category]
				find_options[:joins] ||= ""
				# Multiple categories
				if options[:category].kind_of?(Enumerable)
					find_options[:joins] += "JOIN `pages_categories` ON `pages_categories`.page_id = `pages`.id AND `pages_categories`.category_id IN ("+(options[:category].map{|c| c.kind_of?(Category) ? c.id : c}.join(", "))+")"
				else
					find_options[:joins] += "JOIN `pages_categories` ON `pages_categories`.page_id = `pages`.id AND `pages_categories`.category_id = "+options[:category].kind_of?(Category) ? options[:category].id : options[:category]
				end
				
			end
			
			# Map conditions to string
			conditions = find_options[:conditions].first.join(" AND ")
			find_options[:conditions][0] = conditions
			[options, find_options]
		end
<commit_msg>pages: Forgot the braces<commit_after>require 'language'
require 'unicode'
require 'iconv'
require 'yaml'
#require 'manual_support'

class Page < ActiveRecord::Base
	
	serialize :redirect_to
	
	# Relations
	belongs_to   :author, :class_name => "User", :foreign_key => :user_id
	has_and_belongs_to_many :categories, :join_table => :pages_categories

	belongs_to_image        :image
	has_and_belongs_to_many :images

	has_many :comments, :class_name => 'PageComment', :dependent => :destroy
	has_many :files, :class_name => 'PageFile', :dependent => :destroy, :order => :position

	acts_as_list :scope => :parent_page
	acts_as_tree :order => :position, :foreign_key => :parent_page_id

	acts_as_textable [ "name", "body", "excerpt", "headline", "boxout" ], :allow_any => true
	acts_as_taggable
	
	# Page status labels
	STATUS_LABELS = [ "Draft", "Reviewed", "Published", "Hidden", "Deleted" ]
	
	@@available_templates_cached = nil
	
	validate do |page|
		#page.errors.add( :name, 'must have a title' ) if page.name.empty? # and !page.deleted?
		page.template ||= page.default_template
	end
	
	before_save    { |page| page.published_at = Time.now unless page.published_at? }
	
	# fuck a ferret
	#acts_as_ferret :fields => { :names_for_search => { :boost => 2 }, :content_for_search => {} }
	
	# define_index do
	# 	# fields
	# 	#indexes [author.realname, author.email], :as => author_name
	# 	
	# 	# attributes
	# 	has published_at, status, user_id, template, parent_page_id
	# 
	# 	#set_property :delta => true
	# end
	

	# ---- CLASS METHODS ------------------------------------------------------

	class << self
		
		# Finds pages due for auto publishing and publishes them.
		def autopublish!(options={})
			options[:fuzziness] ||= 1.minute
			publish_timestamp = Time.now + options[:fuzziness]
			pages = self.find(:all, :conditions => ['autopublish = 1 AND autopublish_at < ?', publish_timestamp])
			pages.each do |p|
				p.update_attribute(:autopublish, false)
			end
			pages
		end
		
		# Finds pages with comments, ordered by date of last comment.
		#
		# === Parameters
		# * <tt>:limit</tt> - An integer determining the limit on the number of results that should be returned. 
		#
		# Example:
		#   Page.last_commented(:limit => 10)
		def last_commented(options={})
			find_query = "SELECT p.* FROM pages p, page_comments c 
			              WHERE c.page_id = p.id AND p.status = 2 
			              GROUP BY c.page_id ORDER BY c.created_at DESC"
			find_query << " LIMIT #{options[:limit]}" if options[:limit]
			Page.find_by_sql(find_query)
		end
	
		# Finds pages with comments, ordered by number of comments.
		#
		# === Parameters
		# * <tt>:limit</tt> - An integer determining the limit on the number of results that should be returned. 
		#
		# Example:
		#   Page.most_commented(:limit => 10)
		def most_commented(options={})
			find_query = "SELECT p.*, COUNT(c.id) as comments_count FROM pages p, page_comments c 
			              WHERE c.page_id = p.id AND p.status = 2 
			              GROUP BY c.page_id ORDER BY comments_count DESC"
			find_query << " LIMIT #{options[:limit]}" if options[:limit]
			Page.find_by_sql(find_query)
		end

		def get_pages_options(options={})
			options.symbolize_keys!

			# Clean up depreceated options
			options.keys.each do |key|
				if key.to_s =~ /^show_/
					new_key = key.to_s.gsub(/^show_/,'').to_sym
					logger.warn "DEPRECEATED: Option :#{key} is deprecated, use :#{new_key}"
					options[new_key] = options[key]
				end
			end

			options[:all]           ||= false
			options[:deleted]       ||= options[:all]
			options[:hidden]        ||= options[:all]
			options[:drafts]        ||= options[:all]
			options[:autopublish]   ||= options[:all]
			options[:all_languages] ||= false
			options[:order]         ||= "position"
			options[:parent]        = options[:parents] if options[:parents]
			options[:include]       ||= [:textbits, :categories, :image, :author]
			
			find_options = {
				:conditions => [[]]
			}

			# Ordering subpages
			#options[:order] = options[:order].split( /,[\s]*/ ).map{ |c| (c =~ /^pages\./ ) ? c : "pages."+c }.join(", ")
			find_options[:order] = options[:order]
			
			# Parent check
			if options[:parent] && options[:parent] == :root
				find_options[:conditions].first << "parent_page_id IS NULL"
			elsif options[:parent] && options[:parent].kind_of?(Enumerable)
				parent_ids = options[:parent].map{|p| p.kind_of?(Page) ? p.id : p}
				find_options[:conditions].first << "parent_page_id IN (" + parent_ids.join(", ") + ")"
			elsif options[:parent]
				parent_id = options[:parent]
				parent_id = parent_id.id if parent_id.kind_of?(Page)
				find_options[:conditions].first << "parent_page_id = #{parent_id}"
			end

			# Status check
			unless options[:all] || options[:deleted] || options[:hidden] || options[:drafts]
				find_options[:conditions].first << "status = 2"
			else
				find_options[:conditions].first << "status < 4"   unless options[:deleted]
				find_options[:conditions].first << "status != 3"  unless options[:hidden]
				find_options[:conditions].first << "status >= 2"  unless options[:drafts]
			end
			find_options[:conditions].first << "autopublish = 0" unless options[:autopublish]
		
			# Date limit check
			if options[:published_within]
				options[:published_before] = options[:published_within].last
				options[:published_after]  = options[:published_within].first
			end
			if options[:published_before] || options[:published_after]
				if options[:published_before]
					find_options[:conditions].first << "published_at <= ?"
					find_options[:conditions] << options[:published_before]
				end
				if options[:published_after]
					find_options[:conditions].first << " AND published_at >= ?"
					find_options[:conditions] << options[:published_after]
				end
			end
			
			# Language check
			if options[:language] && !options[:all_languages]
				find_options[:joins] ||= ""
				options[:language] = options[:language].to_s
				raise "Not a valid language code" unless options[:language] =~ /^[\w]{2,3}$/
				find_options[:joins] += "JOIN `textbits` ON `textbits`.textable_type = \"Page\" AND `textbits`.textable_id = `pages`.id AND `textbits`.language = '#{options[:language]}' "
				find_options[:group] = "`pages`.id"
			end
			
			# Category check
			if options[:category]
				find_options[:joins] ||= ""
				# Multiple categories
				if options[:category].kind_of?(Enumerable)
					find_options[:joins] += "JOIN `pages_categories` ON `pages_categories`.page_id = `pages`.id AND `pages_categories`.category_id IN ("+(options[:category].map{|c| c.kind_of?(Category) ? c.id : c}.join(", "))+")"
				else
					find_options[:joins] += "JOIN `pages_categories` ON `pages_categories`.page_id = `pages`.id AND `pages_categories`.category_id = "+(options[:category].kind_of?(Category) ? options[:category].id : options[:category]).to_s
				end
				
			end
			
			# Map conditions to string
			conditions = find_options[:conditions].first.join(" AND ")
			find_options[:conditions][0] = conditions
			[options, find_options]
		end

{'fraction_non_alphanumeric': 0.15387882219705548, 'fraction_numerical': 0.002406568516421291, 'mean_word_length': 3.652288442541982, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 59, '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': 2, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7346430', 'n_tokens_mistral': 5237, 'n_tokens_neox': 4516, 'n_words': 1041}