coursegen 0.1.3 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +48 -32
- data/coursegen.gemspec +4 -3
- data/lib/coursegen/course/data/citem.rb +22 -6
- data/lib/coursegen/course/data/data_adaptor.rb +9 -1
- data/lib/coursegen/course/data/lectures.rb +14 -5
- data/lib/coursegen/course/data/section.rb +6 -5
- data/lib/coursegen/course/data/toc.rb +10 -8
- data/lib/coursegen/course/helpers/content_helpers.rb +4 -4
- data/lib/coursegen/course/helpers/ical_feed_helpers.rb +8 -0
- data/lib/coursegen/course/helpers/list_of.rb +4 -3
- data/lib/coursegen/course/helpers/navigation_helpers.rb +4 -3
- data/lib/coursegen/course/helpers/sidebar_helpers.rb +3 -2
- data/lib/coursegen/course/lib/helpers_.rb +1 -0
- data/lib/coursegen/course/lib/ical_adaptor.rb +34 -0
- data/lib/coursegen/course/lib/search_data_generator.rb +4 -4
- data/lib/coursegen/course/schedule/schedule_def.rb +5 -2
- data/lib/coursegen/course/schedule/schedule_feed.rb +30 -0
- data/lib/coursegen/course/schedule/scheduler.rb +22 -7
- data/lib/coursegen/templates.rb +2 -0
- data/lib/coursegen/version.rb +1 -1
- data/lib/coursegen.rb +4 -2
- data/spec/citem_spec.rb +3 -2
- data/spec/lectures_spec.rb +7 -7
- data/spec/play_spec.rb +23 -0
- data/spec/spec_helper.rb +7 -8
- data/templates/.gitignore +1 -2
- data/{Guardfile → templates/Guardfile} +3 -0
- data/templates/Rules +37 -37
- data/templates/cg_config.rb +18 -5
- data/templates/cg_config.rb_sample +5 -3
- data/templates/content/content/extras/extra_content.md.erb +4 -0
- data/templates/content/content/index.md.erb +7 -1
- data/templates/content/content/intro/course_toc.md.erb +4 -0
- data/templates/content/content/intro/welcome.md.erb +8 -0
- data/templates/content/content/lectures/part1/01_first_lecture.md.erb +4 -0
- data/templates/content/content/lectures/part1/02_here_we_go.md.erb +5 -0
- data/templates/content/content/lectures/part1/index.html +6 -0
- data/templates/content/content/lectures/part2/01_start_part2.md.erb +5 -0
- data/templates/content/content/lectures/part2/02_continue_part2.md.erb +5 -0
- data/templates/content/content/lectures/part2/index.html +6 -0
- data/templates/content/content/lectures/schedule.ical.erb +5 -0
- data/templates/content/tipuesearch_logic/search.md.erb +1 -1
- data/templates/layouts/course.html +6 -6
- metadata +51 -9
- data/lib/coursegen/course/lib/toc.rb +0 -154
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b322dd02a98ca5645c7d05ccf2719621d839e81
|
4
|
+
data.tar.gz: 483636c23919921450427154eb2e1e024381fc97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 019dbe06a5ea815dd3bbca53a0c8308bfd2465dffff50c9b29da8caedfdd710c3c211441531e31562c4037058e65078cadda60c1e1d979047b7e2fec8a417698
|
7
|
+
data.tar.gz: 4054045714a2daf7044cf0f4e67f988cd3b536abbf234f36883536ad33d00bac758ff9df106fa964d71d2dd6f26f0782493a3d9d3be02e6a4d6539791c5691aa
|
data/Gemfile.lock
CHANGED
@@ -1,80 +1,93 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
coursegen (0.0
|
4
|
+
coursegen (0.3.0)
|
5
5
|
activesupport
|
6
6
|
adsf
|
7
7
|
cri
|
8
8
|
guard
|
9
9
|
guard-shell
|
10
|
+
icalendar
|
10
11
|
kramdown
|
11
|
-
nanoc
|
12
|
+
nanoc (~> 4.0.0rc2)
|
12
13
|
nokogiri
|
13
|
-
pry
|
14
|
+
pry-byebug
|
14
15
|
rubytree
|
15
16
|
thor
|
17
|
+
tzinfo
|
16
18
|
|
17
19
|
GEM
|
18
20
|
remote: https://rubygems.org/
|
19
21
|
specs:
|
20
|
-
activesupport (4.
|
21
|
-
i18n (~> 0.
|
22
|
+
activesupport (4.2.4)
|
23
|
+
i18n (~> 0.7)
|
22
24
|
json (~> 1.7, >= 1.7.7)
|
23
25
|
minitest (~> 5.1)
|
24
|
-
thread_safe (~> 0.
|
26
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
25
27
|
tzinfo (~> 1.1)
|
26
28
|
adsf (1.2.0)
|
27
29
|
rack (>= 1.0.0)
|
28
|
-
|
29
|
-
|
30
|
+
byebug (5.0.0)
|
31
|
+
columnize (= 0.9.0)
|
30
32
|
coderay (1.1.0)
|
31
33
|
colored (1.2)
|
32
|
-
|
34
|
+
columnize (0.9.0)
|
35
|
+
cri (2.7.0)
|
33
36
|
colored (~> 1.2)
|
34
|
-
ffi (1.9.
|
37
|
+
ffi (1.9.10)
|
35
38
|
formatador (0.2.5)
|
36
|
-
guard (2.
|
39
|
+
guard (2.13.0)
|
37
40
|
formatador (>= 0.2.4)
|
38
|
-
listen (
|
41
|
+
listen (>= 2.7, <= 4.0)
|
39
42
|
lumberjack (~> 1.0)
|
43
|
+
nenv (~> 0.1)
|
44
|
+
notiffany (~> 0.0)
|
40
45
|
pry (>= 0.9.12)
|
46
|
+
shellany (~> 0.0)
|
41
47
|
thor (>= 0.18.1)
|
42
|
-
guard-
|
48
|
+
guard-compat (1.2.1)
|
49
|
+
guard-shell (0.7.1)
|
43
50
|
guard (>= 2.0.0)
|
44
|
-
|
45
|
-
i18n (0.
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
51
|
+
guard-compat (~> 1.0)
|
52
|
+
i18n (0.7.0)
|
53
|
+
icalendar (2.3.0)
|
54
|
+
json (1.8.3)
|
55
|
+
kramdown (1.8.0)
|
56
|
+
listen (3.0.3)
|
50
57
|
rb-fsevent (>= 0.9.3)
|
51
58
|
rb-inotify (>= 0.9)
|
52
59
|
lumberjack (1.0.9)
|
53
60
|
method_source (0.8.2)
|
54
|
-
mini_portile (0.6.
|
55
|
-
minitest (5.
|
56
|
-
nanoc (
|
61
|
+
mini_portile (0.6.2)
|
62
|
+
minitest (5.8.0)
|
63
|
+
nanoc (4.0.0rc2)
|
57
64
|
cri (~> 2.3)
|
58
|
-
|
65
|
+
nenv (0.2.0)
|
66
|
+
nokogiri (1.6.6.2)
|
59
67
|
mini_portile (~> 0.6.0)
|
68
|
+
notiffany (0.0.7)
|
69
|
+
nenv (~> 0.1)
|
70
|
+
shellany (~> 0.0)
|
60
71
|
pry (0.10.1)
|
61
72
|
coderay (~> 1.1.0)
|
62
73
|
method_source (~> 0.8.1)
|
63
74
|
slop (~> 3.4)
|
64
|
-
|
65
|
-
|
66
|
-
|
75
|
+
pry-byebug (3.2.0)
|
76
|
+
byebug (~> 5.0)
|
77
|
+
pry (~> 0.10)
|
78
|
+
rack (1.6.4)
|
79
|
+
rake (10.4.2)
|
80
|
+
rb-fsevent (0.9.5)
|
67
81
|
rb-inotify (0.9.5)
|
68
82
|
ffi (>= 0.5.0)
|
69
|
-
rubytree (0.9.
|
83
|
+
rubytree (0.9.6)
|
70
84
|
json (~> 1.8)
|
71
|
-
structured_warnings (~> 0.
|
85
|
+
structured_warnings (~> 0.2)
|
86
|
+
shellany (0.0.1)
|
72
87
|
slop (3.6.0)
|
73
|
-
structured_warnings (0.
|
88
|
+
structured_warnings (0.2.0)
|
74
89
|
thor (0.19.1)
|
75
|
-
thread_safe (0.3.
|
76
|
-
timers (4.0.1)
|
77
|
-
hitimes
|
90
|
+
thread_safe (0.3.5)
|
78
91
|
tzinfo (1.2.2)
|
79
92
|
thread_safe (~> 0.1)
|
80
93
|
|
@@ -85,3 +98,6 @@ DEPENDENCIES
|
|
85
98
|
bundler
|
86
99
|
coursegen!
|
87
100
|
rake
|
101
|
+
|
102
|
+
BUNDLED WITH
|
103
|
+
1.10.5
|
data/coursegen.gemspec
CHANGED
@@ -22,16 +22,17 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
|
24
24
|
|
25
|
-
spec.add_dependency "nanoc"
|
25
|
+
spec.add_dependency "nanoc", '~> 4.0.0rc2'
|
26
26
|
spec.add_dependency "thor"
|
27
27
|
spec.add_dependency "rubytree"
|
28
28
|
spec.add_dependency "cri"
|
29
|
-
spec.add_dependency "pry"
|
29
|
+
spec.add_dependency "pry-byebug"
|
30
30
|
spec.add_dependency "nokogiri"
|
31
31
|
spec.add_dependency "activesupport"
|
32
32
|
spec.add_dependency "kramdown"
|
33
33
|
spec.add_dependency "adsf"
|
34
34
|
spec.add_dependency "guard"
|
35
35
|
spec.add_dependency "guard-shell"
|
36
|
-
|
36
|
+
spec.add_dependency "tzinfo"
|
37
|
+
spec.add_dependency "icalendar"
|
37
38
|
end
|
@@ -11,7 +11,7 @@ class CItem
|
|
11
11
|
|
12
12
|
# Callable with nitem=nil to create a mock
|
13
13
|
def initialize nitem=nil, ident=nil, type=nil, order=nil
|
14
|
-
if nitem
|
14
|
+
if !nitem.nil?
|
15
15
|
raise ArgumentError, "invalid CItem contruction" unless ident.nil?
|
16
16
|
@nitem = nitem
|
17
17
|
defaults_from_nitem @nitem
|
@@ -53,6 +53,20 @@ class CItem
|
|
53
53
|
@lecture_date.strftime('%a %b %-d') unless @lecture_date.nil?
|
54
54
|
end
|
55
55
|
|
56
|
+
def schedule_start_date_time
|
57
|
+
if !@lecture_date.nil?
|
58
|
+
schedule = Toc.instance.section(@section).schedule
|
59
|
+
lecture_date + schedule.start_time
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def schedule_end_date_time
|
64
|
+
if !@lecture_date.nil?
|
65
|
+
schedule = Toc.instance.section(@section).schedule
|
66
|
+
lecture_date + schedule.end_time
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
56
70
|
def lecture_number_s
|
57
71
|
"#{@section.singularize} #{@lecture_number.to_s}"
|
58
72
|
end
|
@@ -75,18 +89,20 @@ class CItem
|
|
75
89
|
end
|
76
90
|
|
77
91
|
def parse_identifier ident
|
78
|
-
parts = ident.split("/")
|
79
|
-
@section ||= parts[2]
|
80
|
-
parsed_title = parts[-1].match(/^((\d*)_)?([^\/]*)$/)
|
92
|
+
parts = ident.to_s.split("/")
|
93
|
+
@section ||= parts[2]
|
94
|
+
#parsed_title = parts[-1].match(/^((\d*)_)?([^\/]*)$/)
|
95
|
+
parsed_title = parts[-1].match(/^((\d*)_)?(\w*)/)
|
81
96
|
raise RuntimeError, "Invalid item title" if parsed_title.nil?
|
82
97
|
|
83
98
|
@order ||= parsed_title[2].to_i
|
84
99
|
@short_name = parsed_title[3]
|
85
100
|
@title ||= short_name
|
86
101
|
if @type == "subsection"
|
87
|
-
@subsection = "/#{parts[1..-
|
102
|
+
@subsection = "/#{parts[1..-2].join('/')}/"
|
103
|
+
# @subsection = "/#{parts[1..-1].join('/')}/"
|
88
104
|
elsif @type == "page"
|
89
105
|
@subsection = "/#{parts[1..-2].join('/')}/"
|
90
|
-
end
|
106
|
+
end
|
91
107
|
end
|
92
108
|
end
|
@@ -30,8 +30,16 @@ class DataAdaptor
|
|
30
30
|
citem.desc
|
31
31
|
when :homework
|
32
32
|
citem.homework
|
33
|
+
when :start_date_time
|
34
|
+
citem.schedule_start_date_time
|
35
|
+
when :end_date_time
|
36
|
+
citem.schedule_end_date_time
|
37
|
+
when :full_desc
|
38
|
+
desc = citem.desc || ""
|
39
|
+
hw = citem.homework || ""
|
40
|
+
desc + ". HW: " + hw
|
33
41
|
else
|
34
42
|
"error!"
|
35
43
|
end
|
36
44
|
end
|
37
|
-
end
|
45
|
+
end
|
@@ -16,6 +16,10 @@ class Lectures < Section
|
|
16
16
|
true
|
17
17
|
end
|
18
18
|
|
19
|
+
def schedule
|
20
|
+
@schedule
|
21
|
+
end
|
22
|
+
|
19
23
|
def build_tree
|
20
24
|
lecture_num = 1
|
21
25
|
@root = Tree::TreeNode.new("root", "root")
|
@@ -23,7 +27,7 @@ class Lectures < Section
|
|
23
27
|
i.lecture_number = lecture_num
|
24
28
|
i.lecture_date = @schedule.event_date_by_index(lecture_num - 1) # Lecture numbers are base 1
|
25
29
|
if i.type == "subsection"
|
26
|
-
@root.add(Tree::TreeNode.new(i.subsection, i))
|
30
|
+
@root.add(Tree::TreeNode.new(i.subsection, i))
|
27
31
|
elsif i.type == "page"
|
28
32
|
parent_tree_node = parent_node_of(i)
|
29
33
|
parent_tree_node.add(Tree::TreeNode.new(i.identifier, i))
|
@@ -41,11 +45,11 @@ class Lectures < Section
|
|
41
45
|
end
|
42
46
|
|
43
47
|
def treenode_of citem
|
44
|
-
@root.find do
|
45
|
-
|tree_node|
|
48
|
+
@root.find do
|
49
|
+
|tree_node|
|
46
50
|
if citem.type == "subsection"
|
47
51
|
citem.subsection == tree_node.name
|
48
|
-
else
|
52
|
+
else
|
49
53
|
citem.identifier == tree_node.name
|
50
54
|
end
|
51
55
|
end
|
@@ -75,8 +79,13 @@ class Lectures < Section
|
|
75
79
|
|
76
80
|
protected
|
77
81
|
|
82
|
+
#
|
83
|
+
# Sort all the items in this section: First by the ordering of the subseciton
|
84
|
+
# that the item belongs to, and second by the item's own indicated order.
|
85
|
+
#
|
78
86
|
def sort_items
|
79
|
-
@citems.sort_by
|
87
|
+
new_citems = @citems.sort_by { |i| [ lookup_citem_by_identifier(i.subsection+"index.html").order, ((i.type == "page" ? 100 : 1 ) * i.order) ] }
|
88
|
+
@items = new_citems
|
80
89
|
end
|
81
90
|
|
82
91
|
end
|
@@ -19,8 +19,8 @@ class Section
|
|
19
19
|
|
20
20
|
def find_by_short_name(sname)
|
21
21
|
matches = @citems.select { |c| sname == c.short_name}
|
22
|
-
raise RuntimeError,"#{sname}: invalid reference in section \"#{@section}\"" if matches.length == 0
|
23
|
-
raise RunimeError, "#{sname}: duplicate referenced in section \"#{@section}\"" if matches.length != 1
|
22
|
+
raise RuntimeError,"'#{sname}': invalid reference in section \"#{@section}\"" if matches.length == 0
|
23
|
+
raise RunimeError, "'#{sname}': duplicate referenced in section \"#{@section}\"" if matches.length != 1
|
24
24
|
matches[0]
|
25
25
|
end
|
26
26
|
|
@@ -57,14 +57,15 @@ class Section
|
|
57
57
|
protected
|
58
58
|
|
59
59
|
def lookup_citem_by_identifier identifier
|
60
|
-
res = @citems.select { |i| i.identifier == identifier }
|
61
|
-
|
60
|
+
res = @citems.select { |i| i.identifier.to_s == identifier }
|
61
|
+
fail "TOC#lookup_citem_by_identifier failed to find: '#{identifier}'" if res.length != 1
|
62
|
+
# binding.pry if res.length != 1
|
62
63
|
res[0]
|
63
64
|
end
|
64
65
|
|
65
66
|
# Remove citems that don't belong in this section, or are hidden
|
66
67
|
def section_filter citems
|
67
|
-
filtered_citems = citems.map do
|
68
|
+
filtered_citems = citems.map do
|
68
69
|
|citem|
|
69
70
|
citem.section == @section && !citem.hidden? ? citem : nil
|
70
71
|
end
|
@@ -15,7 +15,7 @@ class Toc
|
|
15
15
|
|
16
16
|
def build_sections items
|
17
17
|
@sections = {}
|
18
|
-
@section_config.each do
|
18
|
+
@section_config.each do
|
19
19
|
|sect|
|
20
20
|
selector = sect.selector.to_s
|
21
21
|
if sect.options[:type] == :lecture
|
@@ -35,7 +35,7 @@ class Toc
|
|
35
35
|
items.each do
|
36
36
|
|nitem|
|
37
37
|
citem = CItem.new(nitem)
|
38
|
-
@map_n2c[nitem] = citem
|
38
|
+
@map_n2c[nitem.identifier] = citem
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -44,11 +44,15 @@ class Toc
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def n2c nitem
|
47
|
-
@map_n2c[nitem]
|
47
|
+
@map_n2c[nitem.identifier]
|
48
48
|
end
|
49
49
|
|
50
50
|
def lookup_citem the_sect, item_short_name
|
51
|
-
section(the_sect)
|
51
|
+
section = section(the_sect)
|
52
|
+
raise "Toc.lookup_citem: Unknown section: `#{the_sect}`" if (section.nil?)
|
53
|
+
citem = section.find_by_short_name(item_short_name)
|
54
|
+
raise "Toc.lookup_citem: Unknown short name: `#{item_short_name}`" if citem.nil?
|
55
|
+
return citem
|
52
56
|
end
|
53
57
|
|
54
58
|
def reset
|
@@ -57,7 +61,7 @@ class Toc
|
|
57
61
|
|
58
62
|
def section selector
|
59
63
|
section = @sections[selector]
|
60
|
-
|
64
|
+
fail "TOC.section: Unknown section: #{selector}" if section.nil?
|
61
65
|
section
|
62
66
|
end
|
63
67
|
|
@@ -69,7 +73,7 @@ class Toc
|
|
69
73
|
|
70
74
|
|
71
75
|
def find_next_forn(nitem)
|
72
|
-
p = find_next_for(n2c(nitem))
|
76
|
+
p = find_next_for(n2c(nitem))
|
73
77
|
fail "find_next_forn" if p.nil?
|
74
78
|
p
|
75
79
|
end
|
@@ -108,8 +112,6 @@ class Toc
|
|
108
112
|
end
|
109
113
|
end
|
110
114
|
|
111
|
-
|
112
|
-
|
113
115
|
def index_in_section item
|
114
116
|
section_for(item).find_index(item)
|
115
117
|
end
|
@@ -2,18 +2,18 @@ module ContentHelpers
|
|
2
2
|
|
3
3
|
def include_topic item_symbol
|
4
4
|
incorporated_topic = lookup_nitem("topics", item_symbol.to_s)
|
5
|
-
Toc.instance.record_inclusion @item, incorporated_topic
|
6
|
-
items[incorporated_topic.identifier].compiled_content
|
5
|
+
# Toc.instance.record_inclusion @item, incorporated_topic
|
6
|
+
items[incorporated_topic.identifier.to_s].compiled_content
|
7
7
|
end
|
8
8
|
|
9
9
|
def include_from_section sect_symbol, item_symbol
|
10
10
|
incorporated_item = lookup_nitem(sect_symbol.to_s, item_symbol.to_s)
|
11
11
|
Toc.instance.record_inclusion @item, incorporated_item
|
12
|
-
items[incorporated_item.identifier].compiled_content
|
12
|
+
items[incorporated_item.identifier.to_s].compiled_content
|
13
13
|
end
|
14
14
|
|
15
15
|
def lookup_nitem the_sect, short_name
|
16
|
-
|
16
|
+
citem = Toc.instance.lookup_citem(the_sect, short_name).nitem
|
17
17
|
end
|
18
18
|
|
19
19
|
def link_to_doc label, file_name
|
@@ -73,7 +73,8 @@ class ListOf
|
|
73
73
|
|
74
74
|
def cell_content_string(row_id, col_selector, detail:)
|
75
75
|
if (col_selector == :title && detail)
|
76
|
-
link_to_unless_current(row_id.nitem[:title], row_id.identifier)
|
76
|
+
# link_to_unless_current(row_id.nitem[:title], row_id.identifier)
|
77
|
+
link_to_unless_current(row_id.nitem[:title], row_id)
|
77
78
|
elsif (col_selector == :date)
|
78
79
|
@data.cell_value(row_id, col_selector).strftime("%b %-d")
|
79
80
|
else
|
@@ -82,7 +83,7 @@ class ListOf
|
|
82
83
|
end
|
83
84
|
|
84
85
|
def include_row?(row_id)
|
85
|
-
include_by_row_type?(row_id) && include_by_subsection_path?(row_id)
|
86
|
+
include_by_row_type?(row_id) && include_by_subsection_path?(row_id)
|
86
87
|
end
|
87
88
|
|
88
89
|
def include_by_row_type?(row_id)
|
@@ -97,4 +98,4 @@ class ListOf
|
|
97
98
|
row_id.type == "subsection"
|
98
99
|
end
|
99
100
|
|
100
|
-
end
|
101
|
+
end
|
@@ -6,7 +6,7 @@ module NavigationHelpers
|
|
6
6
|
|
7
7
|
def link_to_next_lecture
|
8
8
|
the_item = Toc.instance.find_next_forn(@item)
|
9
|
-
link_to(the_item.title, the_item
|
9
|
+
link_to(the_item.title, the_item)
|
10
10
|
end
|
11
11
|
|
12
12
|
def link_to_topic item_symbol
|
@@ -38,8 +38,9 @@ module NavigationHelpers
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def link_to_section section_symbol, item_symbol
|
41
|
-
|
42
|
-
link_to_unless_current(the_item[:title], the_item.identifier)
|
41
|
+
the_item = lookup_nitem(section_symbol.to_s, item_symbol.to_s)
|
42
|
+
#link_to_unless_current(the_item[:title], the_item.identifier)
|
43
|
+
link_to(the_item[:title], the_item)
|
43
44
|
end
|
44
45
|
|
45
46
|
def link_to_next toc, item
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module SidebarHelpers
|
2
|
+
|
2
3
|
def section_helper title:nil, selector:nil
|
3
4
|
sect = Toc.instance.section(selector)
|
4
5
|
@sect_def = Toc.instance.section_def(selector)
|
@@ -23,7 +24,7 @@ module SidebarHelpers
|
|
23
24
|
"<ul class=\"tree\">
|
24
25
|
<li>
|
25
26
|
<label class=\"tree-toggler level2\">
|
26
|
-
#{collapsed_indicator(sect.content.collapsed?)}
|
27
|
+
#{collapsed_indicator(sect.content.collapsed?)}
|
27
28
|
#{sect.content.title}
|
28
29
|
</label>
|
29
30
|
#{subsection(sect, sect.content.collapsed?)}
|
@@ -51,7 +52,7 @@ module SidebarHelpers
|
|
51
52
|
disp_clause = sect.collapsed? ? "display: none" : "display: block"
|
52
53
|
str = "<ul class=\"tree\" style=\"#{disp_clause}\">"
|
53
54
|
str = sect.reduce(str) { |acc, item| acc + flat_section_item_link(item) }
|
54
|
-
str += "</ul>"
|
55
|
+
str += "</ul>"
|
55
56
|
end
|
56
57
|
|
57
58
|
def flat_section_item_link citem
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'icalendar'
|
2
|
+
require 'icalendar/tzinfo'
|
3
|
+
require 'icalendar/value'
|
4
|
+
|
5
|
+
class ICalAdaptor
|
6
|
+
def initialize
|
7
|
+
@cal = Icalendar::Calendar.new
|
8
|
+
tzid = "America/New_York"
|
9
|
+
tz = TZInfo::Timezone.get tzid
|
10
|
+
@cal.add_timezone tz.ical_timezone(Time.now)
|
11
|
+
end
|
12
|
+
|
13
|
+
def feed_begin
|
14
|
+
end
|
15
|
+
|
16
|
+
def feed_end
|
17
|
+
end
|
18
|
+
|
19
|
+
def feed_event(title, dt_start, dt_end, desc, url)
|
20
|
+
event = Icalendar::Event.new
|
21
|
+
event.dtstart = dt_start
|
22
|
+
# event.dtstart = Icalendar::Values::DateOrDateTime.new(dt_start, tzid: 'UTC').call
|
23
|
+
event.dtend = dt_end
|
24
|
+
# event.dtend = Icalendar::Values::DateOrDateTime.new(dt_end, tzid: 'UTC').call
|
25
|
+
event.summary = title
|
26
|
+
event.description = desc
|
27
|
+
# event.url = url
|
28
|
+
@cal.add_event(event)
|
29
|
+
end
|
30
|
+
|
31
|
+
def feed_render
|
32
|
+
@cal.to_ical
|
33
|
+
end
|
34
|
+
end
|
@@ -9,7 +9,7 @@ class SearchIndex
|
|
9
9
|
{ title: clean_string(item.title),
|
10
10
|
text: clean_string(nok_parse_inner_text),
|
11
11
|
tags: "",
|
12
|
-
loc: item.nitem.
|
12
|
+
loc: item.nitem.reps[:default].path }
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -19,9 +19,9 @@ class SearchIndex
|
|
19
19
|
|
20
20
|
def include_in_index?(citem)
|
21
21
|
skiplist = Regexp.union([/\/tipuesearch_logic\/.*/, /\/bootstrap\/.*/, /\/config\/.*/, /\/tipuesearch\/.*/])
|
22
|
-
citem.type == "page" &&
|
22
|
+
citem.type == "page" &&
|
23
23
|
!citem.nitem.binary? &&
|
24
|
-
!citem.identifier.match(skiplist)
|
24
|
+
!citem.identifier.to_s.match(skiplist)
|
25
25
|
end
|
26
26
|
|
27
|
-
end
|
27
|
+
end
|
@@ -1,13 +1,16 @@
|
|
1
1
|
# Define schedule scheme for a lecture series
|
2
2
|
|
3
3
|
class ScheduleDef
|
4
|
-
attr_reader :first_day, :weekdays, :number, :skips
|
4
|
+
attr_reader :first_day, :weekdays, :number, :skips, :start_time, :end_time
|
5
5
|
|
6
|
-
def initialize
|
6
|
+
def initialize(first_day: nil, weekdays: nil, number: nil,
|
7
|
+
skips: [], start_time: "12:15", end_time: "13:15")
|
7
8
|
@first_day = first_day
|
8
9
|
@weekdays = weekdays
|
9
10
|
@number = number
|
10
11
|
@skips = skips
|
12
|
+
@start_time = start_time
|
13
|
+
@end_time = end_time
|
11
14
|
end
|
12
15
|
|
13
16
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Used in generating iCal feed. Given a data_adapter (who knows how to get data out and iterate across things) and a feed_builder (who knows how to turn that data into some kind of feed), produce the feed. This same class could also generate, for example, an RSs feed.
|
2
|
+
|
3
|
+
class ScheduleFeed
|
4
|
+
def initialize feed_builder, data_adapter
|
5
|
+
@feed_builder = feed_builder
|
6
|
+
@data = data_adapter
|
7
|
+
end
|
8
|
+
|
9
|
+
def render
|
10
|
+
@feed_builder.feed_begin
|
11
|
+
render_all_events
|
12
|
+
@feed_builder.feed_end
|
13
|
+
@feed_builder.feed_render
|
14
|
+
end
|
15
|
+
|
16
|
+
def render_all_events
|
17
|
+
@data.rows do |row_id|
|
18
|
+
render_event(row_id) unless row_id.type == "subsection"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_event row_id
|
23
|
+
title = COURSE_ABBREV + ": " + @data.cell_value(row_id, :title)
|
24
|
+
dt_start = @data.cell_value(row_id, :start_date_time)
|
25
|
+
dt_end = @data.cell_value(row_id, :end_date_time)
|
26
|
+
desc = @data.cell_value(row_id, :full_desc)
|
27
|
+
url = @data.cell_value(row_id, :url)
|
28
|
+
@feed_builder.feed_event(title, dt_start, dt_end, desc, url)
|
29
|
+
end
|
30
|
+
end
|
@@ -3,16 +3,20 @@ WEEKDAYS = { sunday: 0, monday: 1, tuesday: 2,
|
|
3
3
|
|
4
4
|
# Calculate days on which each event occurs, based on the configuration info
|
5
5
|
class Scheduler
|
6
|
+
attr_reader :start_time, :end_time
|
7
|
+
|
6
8
|
def self.add_weeks(the_date, number)
|
7
9
|
the_date.to_date + Integer(number) * 7
|
8
10
|
end
|
9
11
|
|
10
|
-
def setup_from_args(start: nil, weekdays: nil, number: nil, skips: []
|
12
|
+
def setup_from_args(start: nil, weekdays: nil, number: nil, skips: [],
|
13
|
+
start_time: 0, end_time: 0)
|
11
14
|
if start.nil?
|
12
15
|
@start = nil
|
13
16
|
return
|
14
17
|
end
|
15
|
-
convert_and_verify_arguments(start, weekdays, number,
|
18
|
+
convert_and_verify_arguments(start, weekdays, number,
|
19
|
+
skips, start_time, end_time)
|
16
20
|
@weekdays.sort!
|
17
21
|
recalc_event_map
|
18
22
|
end
|
@@ -23,7 +27,7 @@ class Scheduler
|
|
23
27
|
return
|
24
28
|
end
|
25
29
|
setup_from_args(start: sdef.first_day, weekdays: sdef.weekdays,
|
26
|
-
number: sdef.number, skips: sdef.skips)
|
30
|
+
number: sdef.number, skips: sdef.skips, start_time: sdef.start_time, end_time: sdef.end_time)
|
27
31
|
end
|
28
32
|
|
29
33
|
def event_date_by_index(ind)
|
@@ -57,22 +61,33 @@ class Scheduler
|
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
60
|
-
def convert_and_verify_arguments(start, weekdays, number, skips
|
64
|
+
def convert_and_verify_arguments(start, weekdays, number, skips,
|
65
|
+
start_time, end_time)
|
61
66
|
@number = number + skips.length
|
62
67
|
@start_date = string_to_date(start)
|
63
68
|
@skips = skips.map { |d| string_to_date(d) } rescue raise(ArgumentError, "Scheduler: Invalid skip date")
|
64
69
|
|
65
|
-
raise ArgumentError, "Scheduler: invalid weekdays" unless weekdays.all? { |wd| WEEKDAYS.include? wd }
|
70
|
+
raise ArgumentError, "Scheduler: invalid weekdays" unless weekdays.all? { |wd| WEEKDAYS.include? wd }
|
66
71
|
|
67
72
|
@weekdays = weekdays.map { |wd| WEEKDAYS[wd]}
|
68
73
|
raise ArgumentError, "Scheduler: Start date is not on one of the weekdays" unless @weekdays.include? @start_date.cwday
|
69
74
|
raise ArgumentError, "Scheduler: Skip date is not on a valid weekday" if !@skips.reduce(true) { |accum, skip| accum && @weekdays.include?(skip.cwday) }
|
70
|
-
end
|
71
75
|
|
72
|
-
|
76
|
+
@start_time = time_span_to_seconds(start_time)
|
77
|
+
@end_time = time_span_to_seconds(end_time)
|
78
|
+
end
|
73
79
|
|
74
80
|
def string_to_date(string_date)
|
75
81
|
Date.strptime(string_date, "%b-%d-%Y") rescue fail "string to date in scheduler.rb"
|
82
|
+
end
|
76
83
|
|
84
|
+
def strings_to_date_time(string_date, string_time)
|
85
|
+
DateTime.strptime(string_date + " " + string_time, "%b-%d-%Y %H:%M")
|
77
86
|
end
|
87
|
+
|
88
|
+
def time_span_to_seconds(string_time)
|
89
|
+
result = string_time.match(/(\d\d):(\d\d)/)
|
90
|
+
result[1].to_i.hours + result[2].to_i.minutes
|
91
|
+
end
|
92
|
+
|
78
93
|
end
|