timeboss 0.0.6 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +23 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.gitignore +2 -0
- data/.travis.yml +4 -1
- data/.yardopts +1 -0
- data/CODE_OF_CONDUCT.md +76 -0
- data/README.md +30 -18
- data/bin/tbsh +15 -0
- data/doc/TimeBoss.html +146 -0
- data/doc/TimeBoss/Calendar.html +137 -0
- data/doc/TimeBoss/Calendar/Day.html +594 -0
- data/doc/TimeBoss/Calendar/Half.html +396 -0
- data/doc/TimeBoss/Calendar/Month.html +396 -0
- data/doc/TimeBoss/Calendar/Parser.html +386 -0
- data/doc/TimeBoss/Calendar/Period.html +841 -0
- data/doc/TimeBoss/Calendar/Quarter.html +396 -0
- data/doc/TimeBoss/Calendar/Support.html +131 -0
- data/doc/TimeBoss/Calendar/Support/Formatter.html +459 -0
- data/doc/TimeBoss/Calendar/Support/MonthBased.html +591 -0
- data/doc/TimeBoss/Calendar/Support/MonthBasis.html +437 -0
- data/doc/TimeBoss/Calendar/Support/MonthlyUnit.html +591 -0
- data/doc/TimeBoss/Calendar/Support/Navigable.html +723 -0
- data/doc/TimeBoss/Calendar/Support/Shiftable.html +138 -0
- data/doc/TimeBoss/Calendar/Support/Unit.html +1299 -0
- data/doc/TimeBoss/Calendar/Waypoints.html +155 -0
- data/doc/TimeBoss/Calendar/Waypoints/Absolute.html +1378 -0
- data/doc/TimeBoss/Calendar/Waypoints/Relative.html +4308 -0
- data/doc/TimeBoss/Calendar/Week.html +671 -0
- data/doc/TimeBoss/Calendar/Year.html +319 -0
- data/doc/TimeBoss/Calendars.html +336 -0
- data/doc/TimeBoss/Calendars/Broadcast.html +221 -0
- data/doc/TimeBoss/Calendars/Broadcast/Basis.html +278 -0
- data/doc/TimeBoss/Calendars/Entry.html +399 -0
- data/doc/TimeBoss/Support.html +115 -0
- data/doc/TimeBoss/Support/Shellable.html +249 -0
- data/doc/_index.html +416 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +496 -0
- data/doc/file.README.html +299 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +299 -0
- data/doc/js/app.js +314 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +1139 -0
- data/doc/top-level-namespace.html +110 -0
- data/lib/tasks/calendars.rake +5 -0
- data/lib/timeboss.rb +4 -0
- data/lib/timeboss/calendar.rb +22 -0
- data/lib/timeboss/calendar/day.rb +19 -6
- data/lib/timeboss/calendar/half.rb +7 -2
- data/lib/timeboss/calendar/month.rb +7 -2
- data/lib/timeboss/calendar/parser.rb +1 -0
- data/lib/timeboss/calendar/period.rb +26 -11
- data/lib/timeboss/calendar/quarter.rb +7 -2
- data/lib/timeboss/calendar/support.rb +8 -0
- data/lib/timeboss/calendar/support/formatter.rb +1 -0
- data/lib/timeboss/calendar/support/month_basis.rb +3 -0
- data/lib/timeboss/calendar/support/{month_based.rb → monthly_unit.rb} +24 -18
- data/lib/timeboss/calendar/support/navigable.rb +73 -0
- data/lib/timeboss/calendar/support/shiftable.rb +3 -2
- data/lib/timeboss/calendar/support/unit.rb +26 -0
- data/lib/timeboss/calendar/waypoints.rb +6 -80
- data/lib/timeboss/calendar/waypoints/absolute.rb +114 -0
- data/lib/timeboss/calendar/waypoints/relative.rb +268 -0
- data/lib/timeboss/calendar/week.rb +26 -18
- data/lib/timeboss/calendar/year.rb +6 -5
- data/lib/timeboss/calendars.rb +20 -3
- data/lib/timeboss/version.rb +1 -1
- data/spec/calendar/day_spec.rb +1 -1
- data/spec/calendar/support/{month_based_spec.rb → monthly_unit_spec.rb} +18 -8
- data/spec/calendar/week_spec.rb +5 -13
- data/spec/calendars/broadcast_spec.rb +27 -7
- data/spec/calendars_spec.rb +7 -1
- data/timeboss.gemspec +1 -0
- metadata +77 -8
@@ -0,0 +1,110 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>
|
7
|
+
Top Level Namespace
|
8
|
+
|
9
|
+
— Documentation by YARD 0.9.25
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
16
|
+
|
17
|
+
<script type="text/javascript">
|
18
|
+
pathId = "";
|
19
|
+
relpath = '';
|
20
|
+
</script>
|
21
|
+
|
22
|
+
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
24
|
+
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
26
|
+
|
27
|
+
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<div class="nav_wrap">
|
31
|
+
<iframe id="nav" src="class_list.html?1"></iframe>
|
32
|
+
<div id="resizer"></div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="main" tabindex="-1">
|
36
|
+
<div id="header">
|
37
|
+
<div id="menu">
|
38
|
+
|
39
|
+
<a href="_index.html">Index</a> »
|
40
|
+
|
41
|
+
|
42
|
+
<span class="title">Top Level Namespace</span>
|
43
|
+
|
44
|
+
</div>
|
45
|
+
|
46
|
+
<div id="search">
|
47
|
+
|
48
|
+
<a class="full_list_link" id="class_list_link"
|
49
|
+
href="class_list.html">
|
50
|
+
|
51
|
+
<svg width="24" height="24">
|
52
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
54
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
55
|
+
</svg>
|
56
|
+
</a>
|
57
|
+
|
58
|
+
</div>
|
59
|
+
<div class="clear"></div>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<div id="content"><h1>Top Level Namespace
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
</h1>
|
67
|
+
<div class="box_info">
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
</div>
|
80
|
+
|
81
|
+
<h2>Defined Under Namespace</h2>
|
82
|
+
<p class="children">
|
83
|
+
|
84
|
+
|
85
|
+
<strong class="modules">Modules:</strong> <span class='object_link'><a href="TimeBoss.html" title="TimeBoss (module)">TimeBoss</a></span>
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
</p>
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
</div>
|
101
|
+
|
102
|
+
<div id="footer">
|
103
|
+
Generated on Sun Jul 19 10:12:10 2020 by
|
104
|
+
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
105
|
+
0.9.25 (ruby-2.4.1).
|
106
|
+
</div>
|
107
|
+
|
108
|
+
</div>
|
109
|
+
</body>
|
110
|
+
</html>
|
data/lib/tasks/calendars.rake
CHANGED
@@ -4,6 +4,11 @@ namespace :timeboss do
|
|
4
4
|
namespace :calendars do
|
5
5
|
TimeBoss::Calendars.each do |entry|
|
6
6
|
namespace entry.name do
|
7
|
+
desc "Evaluate an expression for the #{entry.name} calendar"
|
8
|
+
task :evaluate, %i[expression] => ['timeboss:init'] do |_, args|
|
9
|
+
puts entry.calendar.parse(args[:expression])
|
10
|
+
end
|
11
|
+
|
7
12
|
desc "Open a shell with the #{entry.name} calendar"
|
8
13
|
task shell: ['timeboss:init'] do
|
9
14
|
require 'timeboss/support/shellable'
|
data/lib/timeboss.rb
CHANGED
data/lib/timeboss/calendar.rb
CHANGED
@@ -7,10 +7,32 @@ require 'active_support/core_ext/numeric/time'
|
|
7
7
|
require_relative './calendar/support/month_basis'
|
8
8
|
|
9
9
|
module TimeBoss
|
10
|
+
# A calendar is built upon a basis, and provides methods for period identification and navigation.
|
10
11
|
class Calendar
|
11
12
|
include Waypoints
|
13
|
+
|
14
|
+
# @!method parse
|
15
|
+
# Parse an identifier into a unit or period.
|
16
|
+
# Valid identifiers can include simple units (like "2020Q3", "2020M8W3", "last_quarter"),
|
17
|
+
# mathematical expressions (like "this_month+6"),
|
18
|
+
# or period expressions (like "2020W1..2020W8", "this_quarter-2..next_quarter")
|
19
|
+
# @param identifier [String]
|
20
|
+
# @return [Support::Unit, Period]
|
21
|
+
|
12
22
|
delegate :parse, to: :parser
|
13
23
|
|
24
|
+
# Get a name by which this calendar can be referenced.
|
25
|
+
# @return [String]
|
26
|
+
def name
|
27
|
+
self.class.to_s.demodulize.underscore
|
28
|
+
end
|
29
|
+
|
30
|
+
# Get a friendly title for this calendar.
|
31
|
+
# @return [String]
|
32
|
+
def title
|
33
|
+
name.titleize
|
34
|
+
end
|
35
|
+
|
14
36
|
protected
|
15
37
|
|
16
38
|
attr_reader :basis
|
@@ -3,32 +3,45 @@ require_relative './support/unit'
|
|
3
3
|
|
4
4
|
module TimeBoss
|
5
5
|
class Calendar
|
6
|
+
# Representation of a single day within a calendar.
|
6
7
|
class Day < Support::Unit
|
7
8
|
def initialize(calendar, start_date)
|
8
9
|
super(calendar, start_date, start_date)
|
9
10
|
end
|
10
11
|
|
12
|
+
# Get a simple representation of this day.
|
13
|
+
# @return [String] (e.g. "2020-08-03")
|
11
14
|
def name
|
12
15
|
start_date.to_s
|
13
16
|
end
|
14
17
|
|
18
|
+
# Get a "pretty" representation of this day.
|
19
|
+
# @return [String] (e.g. "August 3, 2020")
|
15
20
|
def title
|
16
21
|
start_date.strftime('%B %-d, %Y')
|
17
22
|
end
|
18
23
|
|
19
|
-
|
20
|
-
name
|
21
|
-
end
|
24
|
+
alias_method :to_s, :name
|
22
25
|
|
26
|
+
# Get the index of this day within its containing year.
|
27
|
+
# @return [Integer]
|
23
28
|
def index
|
24
|
-
@_index ||= (start_date -
|
29
|
+
@_index ||= (start_date - year.start_date).to_i + 1
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get the year number for this day.
|
33
|
+
# @return [Integer] (e.g. 2020)
|
34
|
+
def year_index
|
35
|
+
@_year_index ||= year.year_index
|
25
36
|
end
|
26
37
|
|
27
|
-
|
38
|
+
private
|
39
|
+
|
40
|
+
def down
|
28
41
|
self.class.new(calendar, start_date - 1.day)
|
29
42
|
end
|
30
43
|
|
31
|
-
def
|
44
|
+
def up
|
32
45
|
self.class.new(calendar, start_date + 1.day)
|
33
46
|
end
|
34
47
|
end
|
@@ -1,15 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require_relative './support/
|
2
|
+
require_relative './support/monthly_unit'
|
3
3
|
|
4
4
|
module TimeBoss
|
5
5
|
class Calendar
|
6
|
-
|
6
|
+
# Representation of a 6-month period within a calendar.
|
7
|
+
class Half < Support::MonthlyUnit
|
7
8
|
NUM_MONTHS = 6
|
8
9
|
|
10
|
+
# Get a simple representation of this half.
|
11
|
+
# @return [String] (e.g. "2020H2")
|
9
12
|
def name
|
10
13
|
"#{year_index}H#{index}"
|
11
14
|
end
|
12
15
|
|
16
|
+
# Get a "pretty" representation of this half.
|
17
|
+
# @return [String] (e.g. "H2 2020")
|
13
18
|
def title
|
14
19
|
"H#{index} #{year_index}"
|
15
20
|
end
|
@@ -1,15 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require_relative './support/
|
2
|
+
require_relative './support/monthly_unit'
|
3
3
|
|
4
4
|
module TimeBoss
|
5
5
|
class Calendar
|
6
|
-
|
6
|
+
# Representation of a single month within a calendar.
|
7
|
+
class Month < Support::MonthlyUnit
|
7
8
|
NUM_MONTHS = 1
|
8
9
|
|
10
|
+
# Get a simple representation of this month.
|
11
|
+
# @return [String] (e.g. "2020M8")
|
9
12
|
def name
|
10
13
|
"#{year_index}M#{index}"
|
11
14
|
end
|
12
15
|
|
16
|
+
# Get a "pretty" representation of this month.
|
17
|
+
# @return [String] (e.g. "August 2020")
|
13
18
|
def title
|
14
19
|
"#{Date::MONTHNAMES[index]} #{year_index}"
|
15
20
|
end
|
@@ -1,11 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module TimeBoss
|
3
3
|
class Calendar
|
4
|
+
# A calendar period represents a range of units.
|
4
5
|
class Period
|
5
6
|
attr_reader :begin, :end
|
7
|
+
|
8
|
+
# @!method start_date
|
9
|
+
# Get the start date of this period.
|
10
|
+
# @return [Date]
|
6
11
|
delegate :start_date, to: :begin
|
12
|
+
|
13
|
+
# @!method end_date
|
14
|
+
# Get the end date of this period.
|
15
|
+
# @return [Date]
|
7
16
|
delegate :end_date, to: :end
|
8
17
|
|
18
|
+
# @!method name
|
19
|
+
# Get a simple representation of this period.
|
20
|
+
# @return [String]
|
21
|
+
|
22
|
+
# @!method title
|
23
|
+
# Get a "pretty" representation of this period.
|
24
|
+
# @return [String]
|
25
|
+
|
26
|
+
# @!method to_s
|
27
|
+
# Get a stringified representation of this period.
|
28
|
+
# @return [String]
|
29
|
+
|
9
30
|
%i[name title to_s].each do |message|
|
10
31
|
define_method(message) do
|
11
32
|
text = self.begin.send(message)
|
@@ -14,7 +35,7 @@ module TimeBoss
|
|
14
35
|
end
|
15
36
|
end
|
16
37
|
|
17
|
-
%w[week month quarter half year].each do |size|
|
38
|
+
%w[day week month quarter half year].each do |size|
|
18
39
|
define_method(size.pluralize) do
|
19
40
|
entry = calendar.send("#{size}_for", self.begin.start_date)
|
20
41
|
build_entries entry
|
@@ -27,20 +48,14 @@ module TimeBoss
|
|
27
48
|
end
|
28
49
|
end
|
29
50
|
|
51
|
+
# Does this period cover the current date?
|
52
|
+
# @return [Boolean]
|
30
53
|
def current?
|
31
54
|
to_range.include?(Date.today)
|
32
55
|
end
|
33
56
|
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
def day
|
39
|
-
entries = days
|
40
|
-
return nil unless entries.length == 1
|
41
|
-
entries.first
|
42
|
-
end
|
43
|
-
|
57
|
+
# Express this period as a date range.
|
58
|
+
# @return [Range<Date, Date>]
|
44
59
|
def to_range
|
45
60
|
@_to_range ||= start_date .. end_date
|
46
61
|
end
|
@@ -1,15 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require_relative './support/
|
2
|
+
require_relative './support/monthly_unit'
|
3
3
|
|
4
4
|
module TimeBoss
|
5
5
|
class Calendar
|
6
|
-
|
6
|
+
# Representation of a 3-month period within a calendar.
|
7
|
+
class Quarter < Support::MonthlyUnit
|
7
8
|
NUM_MONTHS = 3
|
8
9
|
|
10
|
+
# Get a simple representation of this quarter.
|
11
|
+
# @return [String] (e.g. "2020Q3")
|
9
12
|
def name
|
10
13
|
"#{year_index}Q#{index}"
|
11
14
|
end
|
12
15
|
|
16
|
+
# Get a "pretty" representation of this quarter.
|
17
|
+
# @return [String] (e.g. "Q3 2020")
|
13
18
|
def title
|
14
19
|
"Q#{index} #{year_index}"
|
15
20
|
end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module TimeBoss
|
2
2
|
class Calendar
|
3
3
|
module Support
|
4
|
+
# @abstract
|
5
|
+
# Implementation of a month basis allows a custom calendar to be built.
|
6
|
+
# A month basis must return a start/end date for a given year and month index.
|
4
7
|
class MonthBasis
|
5
8
|
attr_reader :year, :month
|
6
9
|
|
@@ -4,7 +4,9 @@ require_relative './unit'
|
|
4
4
|
module TimeBoss
|
5
5
|
class Calendar
|
6
6
|
module Support
|
7
|
-
|
7
|
+
# Units that are built off of month-granularities (months, quarters, etc).
|
8
|
+
# Days and weeks are not built from these.
|
9
|
+
class MonthlyUnit < Unit
|
8
10
|
attr_reader :year_index, :index
|
9
11
|
|
10
12
|
def initialize(calendar, year_index, index, start_date, end_date)
|
@@ -13,30 +15,18 @@ module TimeBoss
|
|
13
15
|
@index = index
|
14
16
|
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
calendar.send(self.class.type, year_index + 1, 1)
|
19
|
-
else
|
20
|
-
calendar.send(self.class.type, year_index, index + 1)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def previous
|
25
|
-
if index == 1
|
26
|
-
calendar.send(self.class.type, year_index - 1, max_index)
|
27
|
-
else
|
28
|
-
calendar.send(self.class.type, year_index, index - 1)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
18
|
+
# Get a stringified representation of this unit.
|
19
|
+
# @return [String] (e.g. "2020Q3: 2020-06-29 thru 2020-09-27")
|
32
20
|
def to_s
|
33
21
|
"#{name}: #{start_date} thru #{end_date}"
|
34
22
|
end
|
35
23
|
|
24
|
+
# Get a list of weeks contained within this period.
|
25
|
+
# @return [Array<Week>]
|
36
26
|
def weeks
|
37
27
|
base = calendar.year(year_index)
|
38
28
|
num_weeks = (((base.end_date - base.start_date) + 1) / 7.0).to_i
|
39
|
-
num_weeks.times.map { |i| Week.new(calendar,
|
29
|
+
num_weeks.times.map { |i| Week.new(calendar, base.start_date + (i * 7).days, base.start_date + ((i * 7) + 6).days) }
|
40
30
|
.select { |w| w.start_date.between?(start_date, end_date) }
|
41
31
|
end
|
42
32
|
|
@@ -45,6 +35,22 @@ module TimeBoss
|
|
45
35
|
def max_index
|
46
36
|
12 / self.class::NUM_MONTHS
|
47
37
|
end
|
38
|
+
|
39
|
+
def up
|
40
|
+
if index == max_index
|
41
|
+
calendar.send(self.class.type, year_index + 1, 1)
|
42
|
+
else
|
43
|
+
calendar.send(self.class.type, year_index, index + 1)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def down
|
48
|
+
if index == 1
|
49
|
+
calendar.send(self.class.type, year_index - 1, max_index)
|
50
|
+
else
|
51
|
+
calendar.send(self.class.type, year_index, index - 1)
|
52
|
+
end
|
53
|
+
end
|
48
54
|
end
|
49
55
|
end
|
50
56
|
end
|