BigW Consortium Gitlab

event.rb 5.42 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
# == Schema Information
#
# Table name: events
#
#  id          :integer          not null, primary key
#  target_type :string(255)
#  target_id   :integer
#  title       :string(255)
#  data        :text
#  project_id  :integer
Dmitriy Zaporozhets committed
11 12
#  created_at  :datetime
#  updated_at  :datetime
13 14 15 16
#  action      :integer
#  author_id   :integer
#

17
class Event < ActiveRecord::Base
18
  default_scope { where.not(author_id: nil) }
19

20 21 22 23 24 25 26 27 28
  CREATED   = 1
  UPDATED   = 2
  CLOSED    = 3
  REOPENED  = 4
  PUSHED    = 5
  COMMENTED = 6
  MERGED    = 7
  JOINED    = 8 # User joined project
  LEFT      = 9 # User left project
29

30 31 32
  delegate :name, :email, to: :author, prefix: true, allow_nil: true
  delegate :title, to: :issue, prefix: true, allow_nil: true
  delegate :title, to: :merge_request, prefix: true, allow_nil: true
33
  delegate :title, to: :note, prefix: true, allow_nil: true
34

randx committed
35
  belongs_to :author, class_name: "User"
36
  belongs_to :project
37
  belongs_to :target, polymorphic: true
38

39 40
  # For Hash only
  serialize :data
41

42 43 44
  # Callbacks
  after_create :reset_project_activity

Andrey Kumanyaev committed
45
  # Scopes
46
  scope :recent, -> { order("created_at DESC") }
47
  scope :code_push, -> { where(action: PUSHED) }
48
  scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent }
49

Andrey Kumanyaev committed
50
  class << self
51
    def create_ref_event(project, user, ref, action = 'add', prefix = 'refs/heads')
52 53
      commit = project.repository.commit(ref.target)

54 55
      if action.to_s == 'add'
        before = '00000000'
56
        after = commit.id
57
      else
58
        before = commit.id
59 60 61
        after = '00000000'
      end

62 63 64 65
      Event.create(
        project: project,
        action: Event::PUSHED,
        data: {
66
          ref: "#{prefix}/#{ref.name}",
67 68
          before: before,
          after: after
69 70 71 72
        },
        author_id: user.id
      )
    end
73 74 75 76 77 78

    def reset_event_cache_for(target)
      Event.where(target_id: target.id, target_type: target.class.to_s).
        order('id DESC').limit(100).
        update_all(updated_at: Time.now)
    end
Dmitriy Zaporozhets committed
79 80
  end

81 82 83 84 85 86 87 88
  def proper?
    if push?
      true
    elsif membership_changed?
      true
    else
      (issue? || merge_request? || note? || milestone?) && target
    end
89 90
  end

91 92
  def project_name
    if project
93
      project.name_with_namespace
94
    else
95
      "(deleted project)"
96 97 98
    end
  end

99
  def target_title
100 101 102
    if target && target.respond_to?(:title)
      target.title
    end
103 104
  end

105
  def push?
106
    action == self.class::PUSHED && valid_push?
107 108
  end

109
  def merged?
110
    action == self.class::MERGED
111 112
  end

113
  def closed?
114
    action == self.class::CLOSED
115 116 117
  end

  def reopened?
118
    action == self.class::REOPENED
119 120
  end

121 122 123 124 125 126 127 128
  def milestone?
    target_type == "Milestone"
  end

  def note?
    target_type == "Note"
  end

129
  def issue?
130
    target_type == "Issue"
131 132
  end

133
  def merge_request?
134
    target_type == "MergeRequest"
135 136
  end

137
  def joined?
138
    action == JOINED
139 140 141
  end

  def left?
142
    action == LEFT
143 144 145 146
  end

  def membership_changed?
    joined? || left?
147 148
  end

149
  def issue
150 151 152 153 154 155 156
    target if target_type == "Issue"
  end

  def merge_request
    target if target_type == "MergeRequest"
  end

157 158 159 160
  def note
    target if target_type == "Note"
  end

161 162 163 164
  def action_name
    if closed?
      "closed"
    elsif merged?
165
      "accepted"
166 167
    elsif joined?
      'joined'
168 169
    elsif left?
      'left'
170
    else
171
      "opened"
172 173
    end
  end
Dmitriy Zaporozhets committed
174 175

  def valid_push?
176
    data[:ref] && ref_name.present?
Dmitriy Zaporozhets committed
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
  rescue => ex
    false
  end

  def tag?
    data[:ref]["refs/tags"]
  end

  def branch?
    data[:ref]["refs/heads"]
  end

  def new_ref?
    commit_from =~ /^00000/
  end

  def rm_ref?
    commit_to =~ /^00000/
  end

  def md_ref?
    !(rm_ref? || new_ref?)
  end

  def commit_from
    data[:before]
  end

  def commit_to
    data[:after]
  end

  def ref_name
    if tag?
      tag_name
    else
      branch_name
    end
  end

  def branch_name
    @branch_name ||= data[:ref].gsub("refs/heads/", "")
  end

  def tag_name
    @tag_name ||= data[:ref].gsub("refs/tags/", "")
  end

  # Max 20 commits from push DESC
  def commits
227
    @commits ||= (data[:commits] || []).reverse
Dmitriy Zaporozhets committed
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
  end

  def commits_count
    data[:total_commits_count] || commits.count || 0
  end

  def ref_type
    tag? ? "tag" : "branch"
  end

  def push_action_name
    if new_ref?
      "pushed new"
    elsif rm_ref?
      "deleted"
    else
      "pushed to"
    end
  end

  def push_with_commits?
249
    md_ref? && commits.any? && commit_from && commit_to
Dmitriy Zaporozhets committed
250 251 252 253 254 255 256 257 258 259
  end

  def last_push_to_non_root?
    branch? && project.default_branch != branch_name
  end

  def note_commit_id
    target.commit_id
  end

260 261 262 263
  def target_iid
    target.respond_to?(:iid) ? target.iid : target_id
  end

Dmitriy Zaporozhets committed
264
  def note_short_commit_id
265
    Commit.truncate_sha(note_commit_id)
Dmitriy Zaporozhets committed
266 267 268 269 270 271
  end

  def note_commit?
    target.noteable_type == "Commit"
  end

Andrew8xx8 committed
272 273 274 275
  def note_project_snippet?
    target.noteable_type == "Snippet"
  end

Dmitriy Zaporozhets committed
276 277 278 279 280 281 282 283 284 285 286 287
  def note_target
    target.noteable
  end

  def note_target_id
    if note_commit?
      target.commit_id
    else
      target.noteable_id.to_s
    end
  end

Dmitriy Zaporozhets committed
288 289 290 291 292 293 294 295
  def note_target_iid
    if note_target.respond_to?(:iid)
      note_target.iid
    else
      note_target_id
    end.to_s
  end

Dmitriy Zaporozhets committed
296 297 298 299 300 301 302
  def note_target_type
    if target.noteable_type.present?
      target.noteable_type.titleize
    else
      "Wall"
    end.downcase
  end
303 304 305 306 307 308 309 310 311 312

  def body?
    if push?
      push_with_commits?
    elsif note?
      true
    else
      target.respond_to? :title
    end
  end
313 314 315

  def reset_project_activity
    if project
Dmitriy Zaporozhets committed
316
      project.update_column(:last_activity_at, self.created_at)
317 318
    end
  end
319
end