gitlabhq/app/models/project.rb
2011-12-07 01:27:07 +02:00

236 lines
5.5 KiB
Ruby

require "grit"
class Project < ActiveRecord::Base
PROJECT_N = 0
PROJECT_R = 1
PROJECT_RW = 2
PROJECT_RWA = 3
belongs_to :owner, :class_name => "User"
has_many :merge_requests, :dependent => :destroy
has_many :issues, :dependent => :destroy, :order => "position"
has_many :users_projects, :dependent => :destroy
has_many :users, :through => :users_projects
has_many :notes, :dependent => :destroy
has_many :snippets, :dependent => :destroy
acts_as_taggable
validates :name,
:uniqueness => true,
:presence => true,
:length => { :within => 0..255 }
validates :path,
:uniqueness => true,
:presence => true,
:format => { :with => /^[a-zA-Z0-9_\-]*$/,
:message => "only letters, digits & '_' '-' allowed" },
:length => { :within => 0..255 }
validates :description,
:length => { :within => 0..2000 }
validates :code,
:presence => true,
:uniqueness => true,
:format => { :with => /^[a-zA-Z0-9_\-]*$/,
:message => "only letters, digits & '_' '-' allowed" },
:length => { :within => 3..255 }
validates :owner,
:presence => true
validate :check_limit
validate :repo_name
after_destroy :destroy_repository
after_save :update_repository
attr_protected :private_flag, :owner_id
scope :public_only, where(:private_flag => false)
def self.access_options
{
"Denied" => PROJECT_N,
"Read" => PROJECT_R,
"Report" => PROJECT_RW,
"Admin" => PROJECT_RWA
}
end
def repository
@repository ||= Repository.new(self)
end
delegate :repo,
:url_to_repo,
:path_to_repo,
:update_repository,
:destroy_repository,
:tags,
:repo_exists?,
:commit,
:commits,
:tree,
:heads,
:commits_since,
:fresh_commits,
:to => :repository, :prefix => nil
def to_param
code
end
def team_member_by_name_or_email(email = nil, name = nil)
user = users.where("email like ? or name like ?", email, name).first
users_projects.find_by_user_id(user.id) if user
end
def fresh_issues(n)
issues.includes(:project, :author).order("created_at desc").first(n)
end
def fresh_notes(n)
notes.inc_author_project.order("created_at desc").first(n)
end
def common_notes
notes.where(:noteable_type => ["", nil]).inc_author_project
end
def build_commit_note(commit)
notes.new(:noteable_id => commit.id, :noteable_type => "Commit")
end
def commit_notes(commit)
notes.where(:noteable_id => commit.id, :noteable_type => "Commit")
end
def has_commits?
!!commit
end
def add_access(user, *access)
opts = { :user => user }
access.each { |name| opts.merge!(name => true) }
users_projects.create(opts)
end
def reset_access(user)
users_projects.where(:project_id => self.id, :user_id => user.id).destroy if self.id
end
def repository_readers
keys = Key.joins({:user => :users_projects}).
where("users_projects.project_id = ? AND users_projects.repo_access = ?", id, Repository::REPO_R)
keys.map(&:identifier)
end
def repository_writers
keys = Key.joins({:user => :users_projects}).
where("users_projects.project_id = ? AND users_projects.repo_access = ?", id, Repository::REPO_RW)
keys.map(&:identifier)
end
def readers
@readers ||= users_projects.includes(:user).where(:project_access => [PROJECT_R, PROJECT_RW, PROJECT_RWA]).map(&:user)
end
def writers
@writers ||= users_projects.includes(:user).where(:project_access => [PROJECT_RW, PROJECT_RWA]).map(&:user)
end
def admins
@admins ||= users_projects.includes(:user).where(:project_access => PROJECT_RWA).map(&:user)
end
def root_ref
"master"
end
def public?
!private_flag
end
def private?
private_flag
end
def last_activity
updates(1).first
rescue
nil
end
def last_activity_date
last_activity.try(:created_at)
end
# Get project updates from cache
# or calculate.
def cached_updates(limit, expire = 2.minutes)
activities_key = "project_#{id}_activities"
cached_activities = Rails.cache.read(activities_key)
if cached_activities
activities = cached_activities
else
activities = updates(limit)
Rails.cache.write(activities_key, activities, :expires_in => 60.seconds)
end
activities
end
# Get 20 events for project like
# commits, issues or notes
def updates(n = 3)
[
fresh_commits(n),
fresh_issues(n),
fresh_notes(n)
].compact.flatten.sort do |x, y|
y.created_at <=> x.created_at
end[0...n]
end
def check_limit
unless owner.can_create_project?
errors[:base] << ("Your own projects limit is #{owner.projects_limit}! Please contact administrator to increase it")
end
rescue
errors[:base] << ("Cant check your ability to create project")
end
def repo_name
if path == "gitolite-admin"
errors.add(:path, " like 'gitolite-admin' is not allowed")
end
end
def valid_repo?
repo
rescue
errors.add(:path, "Invalid repository path")
false
end
end
# == Schema Information
#
# Table name: projects
#
# id :integer not null, primary key
# name :string(255)
# path :string(255)
# description :text
# created_at :datetime
# updated_at :datetime
# private_flag :boolean default(TRUE), not null
# code :string(255)
# owner_id :integer
#