147 lines
3.4 KiB
Ruby
147 lines
3.4 KiB
Ruby
|
|
ActiveRecord::Schema.define do
|
|
create_table :ranges_v2 do |table|
|
|
table.column :granularity, :float
|
|
table.column :author, :string
|
|
table.column :time_start, :date
|
|
table.column :time_stop, :date
|
|
end
|
|
end
|
|
|
|
module TimeCost
|
|
class RangeV2 < ActiveRecord::Base
|
|
has_many :commits_v2
|
|
|
|
GRANULARITY_DEFAULT = 0.5
|
|
|
|
def to_s show_authors = true
|
|
val = "(%s)\t%s - %s\n" % [diff, fixed_start, @time_stop]
|
|
if show_authors then
|
|
val += "\tby %s\n" % @commits.first.author
|
|
end
|
|
@commits.each do |commit|
|
|
lines = []
|
|
lines.concat commit.note.split(/\n/)
|
|
r = lines.map{ |s| "\t %s" % s }.join "\n"
|
|
r[1] = '*'
|
|
val += r + "\n"
|
|
end
|
|
return val
|
|
end
|
|
end
|
|
|
|
class Range
|
|
attr_accessor :time_start, :time_stop, :commits, :author
|
|
|
|
GRANULARITY_DEFAULT = 0.5
|
|
|
|
def initialize commit, options = {}
|
|
@granularity = options[:granularity] || GRANULARITY_DEFAULT
|
|
|
|
# FIXME: First approximation for users
|
|
# later, we'll replace with @user = User.parse(commit.author)
|
|
@author = commit.author
|
|
|
|
@time_stop = DateTime.parse(commit.date)
|
|
@time_start = @time_stop - (@granularity * 3 / 24.0)
|
|
@commits = [commit]
|
|
self
|
|
end
|
|
|
|
def merge range
|
|
# B -----[----]----
|
|
# A --[----]------
|
|
# = ---[------]----
|
|
|
|
# minimum of both
|
|
new_start = if range.time_start < @time_start then range.time_start
|
|
else @time_start
|
|
end
|
|
|
|
new_end = if range.time_stop >= @time_stop then range.time_stop
|
|
else @time_stop
|
|
end
|
|
|
|
@time_start = new_start
|
|
@time_stop = new_end
|
|
@commits.concat range.commits
|
|
end
|
|
|
|
def overlap? range
|
|
result = false
|
|
|
|
# return early result if ranges come from different authors
|
|
return false if (@author != range.author)
|
|
|
|
# Ref ----[----]-----
|
|
# overlapping :
|
|
# A -[----]--------
|
|
# B -------[----]--
|
|
# C -[----------]--
|
|
# D ------[]-------
|
|
# non-overlapping :
|
|
# E -[]------------
|
|
# F -----------[]--
|
|
|
|
start_before_start = (range.time_start < @time_start)
|
|
start_after_start = (range.time_start >= @time_start)
|
|
start_after_stop = (range.time_start >= @time_stop)
|
|
start_before_stop = (range.time_start < @time_stop)
|
|
|
|
stop_before_stop = (range.time_stop < @time_stop)
|
|
stop_after_stop = (range.time_stop >= @time_stop)
|
|
stop_before_start = (range.time_stop < @time_start)
|
|
stop_after_start = (range.time_stop >= @time_start)
|
|
|
|
# A case
|
|
if start_before_start and start_before_stop and
|
|
stop_after_start and stop_before_stop then
|
|
result = true
|
|
end
|
|
|
|
# B case
|
|
if start_after_start and start_before_stop and
|
|
stop_after_start and stop_after_stop then
|
|
result = true
|
|
end
|
|
|
|
# C case
|
|
if start_before_start and start_before_stop and
|
|
stop_after_start and stop_after_stop then
|
|
result = true
|
|
end
|
|
|
|
# D case
|
|
if start_after_start and start_before_stop and
|
|
stop_after_start and stop_before_stop then
|
|
result = true
|
|
end
|
|
|
|
return result
|
|
end
|
|
|
|
def fixed_start
|
|
return @time_start + (@granularity/24.0)
|
|
end
|
|
|
|
def diff
|
|
return ("%.2f" % ((@time_stop - fixed_start).to_f * 24)).to_f
|
|
end
|
|
|
|
def to_s show_authors = true
|
|
val = "(%s)\t%s - %s\n" % [diff, fixed_start, @time_stop]
|
|
if show_authors then
|
|
val += "\tby %s\n" % @commits.first.author
|
|
end
|
|
@commits.each do |commit|
|
|
lines = []
|
|
lines.concat commit.note.split(/\n/)
|
|
r = lines.map{ |s| "\t %s" % s }.join "\n"
|
|
r[1] = '*'
|
|
val += r + "\n"
|
|
end
|
|
return val
|
|
end
|
|
end
|
|
end
|
|
|