almanack 0.0.1.alpha3 → 1.0.0.pre
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/README.md +55 -13
- data/almanac.gemspec +2 -1
- data/bin/almanack +3 -0
- data/example.ru +18 -14
- data/lib/almanack.rb +16 -13
- data/lib/almanack/calendar.rb +35 -3
- data/lib/almanack/cli.rb +131 -0
- data/lib/almanack/configuration.rb +20 -4
- data/lib/almanack/event.rb +26 -1
- data/lib/almanack/event_source/ical_feed.rb +62 -0
- data/lib/almanack/event_source/meetup_group.rb +98 -0
- data/lib/almanack/event_source/static.rb +23 -0
- data/lib/almanack/server.rb +75 -4
- data/lib/almanack/themes/legacy/stylesheets/calendar.scss +168 -0
- data/lib/almanack/themes/legacy/views/error.erb +13 -0
- data/lib/almanack/themes/legacy/views/events.erb +4 -2
- data/lib/almanack/themes/legacy/views/layout.erb +9 -6
- data/lib/almanack/themes/starter/javascripts/calendar.js +5 -0
- data/lib/almanack/themes/starter/stylesheets/calendar.scss +27 -0
- data/lib/almanack/themes/starter/views/error.erb +13 -0
- data/lib/almanack/themes/starter/views/events.erb +31 -0
- data/lib/almanack/themes/starter/views/layout.erb +32 -0
- data/lib/almanack/version.rb +4 -1
- data/spec/almanack_spec.rb +8 -0
- data/spec/calendar_spec.rb +29 -25
- data/spec/configuration_spec.rb +19 -3
- data/spec/{ical_feed_spec.rb → event_source/ical_feed_spec.rb} +4 -4
- data/spec/{meetup_group_spec.rb → event_source/meetup_group_spec.rb} +4 -4
- data/spec/event_source/static_spec.rb +23 -0
- data/spec/event_spec.rb +24 -4
- data/spec/features/calendar_feature_spec.rb +7 -5
- data/spec/features/subscription_feature_spec.rb +60 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/support/server_support.rb +2 -1
- data/spec/support/time_comparison_matchers.rb +14 -0
- data/templates/gitignore +2 -0
- data/templates/new/Gemfile +3 -0
- data/templates/new/config.ru.tt +24 -0
- metadata +45 -13
- data/lib/almanack/ical_feed.rb +0 -60
- data/lib/almanack/meetup_group.rb +0 -96
- data/lib/almanack/simple_event_collection.rb +0 -11
- data/lib/almanack/themes/legacy/views/stylesheets/legacy.css.sass +0 -119
- data/spec/simple_event_collection_spec.rb +0 -23
@@ -0,0 +1,13 @@
|
|
1
|
+
<% title 'Something went wrong' %>
|
2
|
+
|
3
|
+
<div id="error">
|
4
|
+
<h1>Oops.</h1>
|
5
|
+
|
6
|
+
<p>Something went wrong.</p>
|
7
|
+
|
8
|
+
<% if request.path == '/' %>
|
9
|
+
<p>Sorry about that. Check back later!</p>
|
10
|
+
<% else %>
|
11
|
+
<p><a href="/">Return home</a></p>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
@@ -1,5 +1,7 @@
|
|
1
|
+
<% title 'Upcoming events' %>
|
2
|
+
|
1
3
|
<div class="events">
|
2
|
-
<%
|
4
|
+
<% calendar.events.each do |event| %>
|
3
5
|
<div class="event">
|
4
6
|
<div class="date">
|
5
7
|
<div class="month"><%= event.start_date.strftime('%a') %></div>
|
@@ -21,7 +23,7 @@
|
|
21
23
|
<% end %>
|
22
24
|
|
23
25
|
<dt>When</dt>
|
24
|
-
<dd><%= event.
|
26
|
+
<dd><%= event.formatted_date %></dd>
|
25
27
|
</dl>
|
26
28
|
</div>
|
27
29
|
</div>
|
@@ -2,22 +2,25 @@
|
|
2
2
|
<html>
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8">
|
5
|
-
<title
|
6
|
-
<link rel="stylesheet" type="text/css" href="/stylesheets/
|
5
|
+
<title><%= page_title %></title>
|
6
|
+
<link rel="stylesheet" type="text/css" href="/stylesheets/calendar.css">
|
7
7
|
</head>
|
8
8
|
<body>
|
9
9
|
|
10
10
|
<header>
|
11
|
-
<h1><%=
|
12
|
-
<h2>The Next <%=
|
11
|
+
<h1><a href="/"><%= calendar.title %></a></h1>
|
12
|
+
<h2>The Next <%= calendar.days_lookahead %> Days</h2>
|
13
13
|
</header>
|
14
14
|
|
15
15
|
<%= yield %>
|
16
16
|
|
17
17
|
<footer>
|
18
|
+
<div class="subscribe">
|
19
|
+
<a href="<%= feed_url %>">Subscribe to Calendar</a>
|
20
|
+
</div>
|
21
|
+
|
18
22
|
<div class="fork">
|
19
|
-
Powered by <a href="
|
20
|
-
<a href="http://github.com/Aupajo/sinatra-gcal/issues">Bugs? Features?</a>
|
23
|
+
Powered by <a href="<%= almanack_project_url %>">Almanack</a>.
|
21
24
|
</div>
|
22
25
|
</footer>
|
23
26
|
|
@@ -0,0 +1,5 @@
|
|
1
|
+
// If you need jQuery, see views/layout.erb for an example of how to include it.
|
2
|
+
//
|
3
|
+
// CoffeeScript can also be added by adding `gem "coffee_script"` to your
|
4
|
+
// calendar's Gemfile and running `bundle install`. Name your CoffeeScript files
|
5
|
+
// with a .coffee extension.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
// SCSS or regular CSS supported.
|
2
|
+
// http://sass-lang.com/
|
3
|
+
|
4
|
+
body {
|
5
|
+
font: 12pt/1.6em "Helvetica Neue", Arial, sans-serif;
|
6
|
+
margin: 4em;
|
7
|
+
}
|
8
|
+
|
9
|
+
header {
|
10
|
+
border-bottom: 2px solid;
|
11
|
+
}
|
12
|
+
|
13
|
+
footer {
|
14
|
+
border-top: 2px solid;
|
15
|
+
}
|
16
|
+
|
17
|
+
.event {
|
18
|
+
border-bottom: 1px solid #ccc;
|
19
|
+
padding: 2em 0;
|
20
|
+
|
21
|
+
.date {
|
22
|
+
.month, .day {
|
23
|
+
display: inline;
|
24
|
+
font-weight: bold;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<% title 'Something went wrong' %>
|
2
|
+
|
3
|
+
<div id="error">
|
4
|
+
<h1>Oops.</h1>
|
5
|
+
|
6
|
+
<p>Something went wrong.</p>
|
7
|
+
|
8
|
+
<% if request.path == '/' %>
|
9
|
+
<p>Sorry about that. Check back later!</p>
|
10
|
+
<% else %>
|
11
|
+
<p><a href="/">Return home</a></p>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<% title 'Upcoming events' %>
|
2
|
+
|
3
|
+
<div class="events">
|
4
|
+
<% calendar.events.each do |event| %>
|
5
|
+
<div class="event">
|
6
|
+
<div class="date">
|
7
|
+
<div class="month"><%= event.start_date.strftime('%a') %></div>
|
8
|
+
<div class="day"><%= event.start_date.strftime('%d') %></div>
|
9
|
+
</div>
|
10
|
+
<div class="details">
|
11
|
+
<h3 class="title"><%= event.title %></h3>
|
12
|
+
|
13
|
+
<% if event.description %>
|
14
|
+
<div class="description">
|
15
|
+
<%= event.description %>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<dl>
|
20
|
+
<% if event.location %>
|
21
|
+
<dt>Where</dt>
|
22
|
+
<dd><%= event.location %></dd>
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
<dt>When</dt>
|
26
|
+
<dd><%= event.formatted_date %></dd>
|
27
|
+
</dl>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
<% end %>
|
31
|
+
</div>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title><%= page_title %></title>
|
6
|
+
<link rel="stylesheet" type="text/css" href="/stylesheets/calendar.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
|
10
|
+
<header>
|
11
|
+
<h1><a href="/"><%= calendar.title %></a></h1>
|
12
|
+
<h2>The Next <%= calendar.days_lookahead %> Days</h2>
|
13
|
+
</header>
|
14
|
+
|
15
|
+
<%= yield %>
|
16
|
+
|
17
|
+
<footer>
|
18
|
+
<div class="subscribe">
|
19
|
+
<a href="<%= feed_url %>">Subscribe to Calendar</a>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div class="fork">
|
23
|
+
<!-- Don't feel any obligation to keep this link if you don't want to -->
|
24
|
+
Powered by <a href="<%= almanack_project_url %>">Almanack</a>.
|
25
|
+
</div>
|
26
|
+
</footer>
|
27
|
+
|
28
|
+
<!-- Uncomment the following like to include jQuery -->
|
29
|
+
<!-- <script src="//code.jquery.com/jquery-1.11.0.min.js"></script> -->
|
30
|
+
<script src="/javascripts/calendar.js"></script>
|
31
|
+
</body>
|
32
|
+
</html>
|
data/lib/almanack/version.rb
CHANGED
data/spec/calendar_spec.rb
CHANGED
@@ -13,39 +13,43 @@ module Almanack
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe "#events" do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
config.add_events [
|
20
|
-
{ title: "Hogswatch" }
|
21
|
-
]
|
16
|
+
it "calls events_between with now and the days lookahead" do
|
17
|
+
config = Configuration.new
|
18
|
+
calendar = Calendar.new(config)
|
22
19
|
|
23
|
-
|
20
|
+
now = Time.now
|
21
|
+
lookahead = 42
|
22
|
+
future = now + lookahead * 24 * 60 * 60
|
24
23
|
|
25
|
-
|
26
|
-
expect(calendar
|
24
|
+
Timecop.freeze(now) do
|
25
|
+
expect(calendar).to receive(:days_lookahead) { lookahead }
|
26
|
+
expect(calendar).to receive(:events_between) do |date_range|
|
27
|
+
expect(date_range.min).to eq_time(now)
|
28
|
+
expect(date_range.max).to eq_time(future)
|
29
|
+
:results
|
30
|
+
end
|
31
|
+
|
32
|
+
expect(calendar.events).to eq(:results)
|
27
33
|
end
|
28
34
|
end
|
35
|
+
end
|
29
36
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
calendar = Calendar.new(config)
|
37
|
+
describe "#events_between" do
|
38
|
+
it "collects the event sources' events between two dates" do
|
39
|
+
today = Time.now
|
40
|
+
yesterday = today - 1
|
41
|
+
tomorrow = today + 1
|
36
42
|
|
37
|
-
|
43
|
+
config = Configuration.new
|
44
|
+
config.add_events [
|
45
|
+
{ title: 'Today', start_date: today },
|
46
|
+
{ title: 'Yesterday', start_date: yesterday },
|
47
|
+
{ title: 'Tomorrow', start_date: tomorrow },
|
48
|
+
]
|
38
49
|
|
39
|
-
|
40
|
-
VCR.use_cassette('google_calendar') do
|
41
|
-
events = calendar.events
|
42
|
-
end
|
43
|
-
end
|
50
|
+
calendar = Calendar.new(config)
|
44
51
|
|
45
|
-
|
46
|
-
expect(events).to all_have_properties(:title, :start_date)
|
47
|
-
expect(events).to be_in_order
|
48
|
-
end
|
52
|
+
expect(calendar.events_between(today..tomorrow).map(&:title)).to eq(%w( Today Tomorrow ))
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
data/spec/configuration_spec.rb
CHANGED
@@ -11,6 +11,22 @@ module Almanack
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
describe "#theme" do
|
15
|
+
it "can be set and accessed" do
|
16
|
+
config = Configuration.new
|
17
|
+
config.theme = "custom"
|
18
|
+
expect(config.theme).to eq("custom")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#theme_root" do
|
23
|
+
specify "it raises an error if no theme can be found" do
|
24
|
+
config = Configuration.new
|
25
|
+
config.theme = "nonexistent"
|
26
|
+
expect { config.theme_root }.to raise_error(Configuration::ThemeNotFound)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
14
30
|
describe "#add_events" do
|
15
31
|
it "adds a simple event collection event source" do
|
16
32
|
config = Configuration.new
|
@@ -21,7 +37,7 @@ module Almanack
|
|
21
37
|
]
|
22
38
|
|
23
39
|
expect(config.event_sources.size).to eq(1)
|
24
|
-
expect(config.event_sources.first).to be_an_instance_of(
|
40
|
+
expect(config.event_sources.first).to be_an_instance_of(EventSource::Static)
|
25
41
|
end
|
26
42
|
end
|
27
43
|
|
@@ -33,7 +49,7 @@ module Almanack
|
|
33
49
|
config.add_ical_feed "https://www.google.com/calendar/ical/61s2re9bfk01abmla4d17tojuo%40group.calendar.google.com/public/basic.ics"
|
34
50
|
|
35
51
|
expect(config.event_sources.size).to eq(1)
|
36
|
-
expect(config.event_sources.first).to be_an_instance_of(IcalFeed)
|
52
|
+
expect(config.event_sources.first).to be_an_instance_of(EventSource::IcalFeed)
|
37
53
|
end
|
38
54
|
end
|
39
55
|
|
@@ -45,7 +61,7 @@ module Almanack
|
|
45
61
|
config.add_meetup_group(group_urlname: "CHC-JS", key: "secrettoken")
|
46
62
|
|
47
63
|
expect(config.event_sources.size).to eq(1)
|
48
|
-
expect(config.event_sources.first).to be_an_instance_of(MeetupGroup)
|
64
|
+
expect(config.event_sources.first).to be_an_instance_of(EventSource::MeetupGroup)
|
49
65
|
end
|
50
66
|
end
|
51
67
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
module Almanack
|
3
|
+
module Almanack::EventSource
|
4
4
|
describe IcalFeed do
|
5
5
|
it "accepts a URL" do
|
6
6
|
IcalFeed.new("http://example.org/ical.ics")
|
@@ -13,8 +13,8 @@ module Almanack
|
|
13
13
|
|
14
14
|
Timecop.freeze(2014, 4, 3) do
|
15
15
|
VCR.use_cassette('google_calendar') do
|
16
|
-
from =
|
17
|
-
to = from + 30
|
16
|
+
from = Time.now
|
17
|
+
to = from + 30 * 24 * 60 * 60
|
18
18
|
events = feed.events_between(from..to)
|
19
19
|
end
|
20
20
|
end
|
@@ -27,4 +27,4 @@ module Almanack
|
|
27
27
|
end
|
28
28
|
|
29
29
|
end
|
30
|
-
end
|
30
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
module Almanack
|
3
|
+
module Almanack::EventSource
|
4
4
|
describe MeetupGroup do
|
5
5
|
describe "#events_between" do
|
6
6
|
it "returns a list of events" do
|
@@ -9,8 +9,8 @@ module Almanack
|
|
9
9
|
|
10
10
|
Timecop.freeze(2014, 5, 24) do
|
11
11
|
VCR.use_cassette('meetup') do
|
12
|
-
from =
|
13
|
-
to = from + 30
|
12
|
+
from = Time.now
|
13
|
+
to = from + 30 * 24 * 60 * 60
|
14
14
|
events = feed.events_between(from..to)
|
15
15
|
end
|
16
16
|
end
|
@@ -23,4 +23,4 @@ module Almanack
|
|
23
23
|
end
|
24
24
|
|
25
25
|
end
|
26
|
-
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Almanack::EventSource
|
4
|
+
describe Static do
|
5
|
+
describe "#events_between" do
|
6
|
+
it "returns events between two dates" do
|
7
|
+
now = Time.now
|
8
|
+
yesterday = now - 1
|
9
|
+
tomorrow = now + 1
|
10
|
+
|
11
|
+
source = Static.new [
|
12
|
+
{ title: 'Yesterday', start_date: yesterday },
|
13
|
+
{ title: 'Today', start_date: now },
|
14
|
+
{ title: 'Tomorrow', start_date: tomorrow }
|
15
|
+
]
|
16
|
+
|
17
|
+
expect(source.events_between(yesterday..tomorrow).map(&:title)).to eq(%w( Yesterday Today Tomorrow ))
|
18
|
+
expect(source.events_between(now..tomorrow).map(&:title)).to eq(%w( Today Tomorrow ))
|
19
|
+
expect(source.events_between(yesterday..now).map(&:title)).to eq(%w( Yesterday Today ))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/event_spec.rb
CHANGED
@@ -9,13 +9,13 @@ module Almanack
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "has a start date" do
|
12
|
-
event = Event.new(start_date:
|
13
|
-
expect(event.start_date).to
|
12
|
+
event = Event.new(start_date: Time.new(2014, 01, 01))
|
13
|
+
expect(event.start_date).to eq_time(Time.new(2014, 01, 01))
|
14
14
|
end
|
15
15
|
|
16
16
|
it "has a end date" do
|
17
|
-
event = Event.new(end_date:
|
18
|
-
expect(event.end_date).to
|
17
|
+
event = Event.new(end_date: Time.new(2014, 01, 02))
|
18
|
+
expect(event.end_date).to eq_time(Time.new(2014, 01, 02))
|
19
19
|
end
|
20
20
|
|
21
21
|
it "has a location" do
|
@@ -28,5 +28,25 @@ module Almanack
|
|
28
28
|
expect(event.description).to eq("Be there or be a rectangular thynge.")
|
29
29
|
end
|
30
30
|
|
31
|
+
describe "#formatted_date" do
|
32
|
+
it "handles events without an end date" do
|
33
|
+
event = Event.new(start_date: Time.parse("2014-07-06 06:24:00 UTC"))
|
34
|
+
expect(event.formatted_date).to eq("July 6 2014 at 6:24am")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "handles events with an end date on the same day" do
|
38
|
+
event = Event.new(start_date: Time.parse("2014-07-06 06:24:00 UTC"),
|
39
|
+
end_date: Time.parse("2014-07-06 13:20:00 UTC"))
|
40
|
+
expect(event.formatted_date).to eq("July 6 2014 at 6:24am to 1:20pm")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "handles events with an end date on a different day" do
|
44
|
+
event = Event.new(start_date: Time.parse("2014-07-06 06:00:00 UTC"),
|
45
|
+
end_date: Time.parse("2014-08-07 10:00:00 UTC"))
|
46
|
+
expect(event.formatted_date).to eq("July 6 2014 at 6:00am to August 7 2014 at 10:00am")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
31
51
|
end
|
32
52
|
end
|
@@ -4,15 +4,17 @@ describe "Viewing a calendar", :feature do
|
|
4
4
|
before { Almanack.reset! }
|
5
5
|
|
6
6
|
it "displays all upcoming events" do
|
7
|
-
|
7
|
+
now = Time.now
|
8
8
|
|
9
9
|
Almanack.config.add_events [
|
10
|
-
{ title: "Hogswatch", start_date:
|
11
|
-
{ title: "Soul Cake Tuesday", start_date:
|
12
|
-
{ title: "Eve of Small Gods", start_date:
|
10
|
+
{ title: "Hogswatch", start_date: now },
|
11
|
+
{ title: "Soul Cake Tuesday", start_date: now + 10 * 24 * 60 * 60 },
|
12
|
+
{ title: "Eve of Small Gods", start_date: now + 30 * 24 * 60 * 60 },
|
13
13
|
]
|
14
14
|
|
15
|
-
|
15
|
+
Timecop.freeze(now) do
|
16
|
+
get "/"
|
17
|
+
end
|
16
18
|
|
17
19
|
expect(last_response).to have_event_on_page("Hogswatch")
|
18
20
|
expect(last_response).to have_event_on_page("Soul Cake Tuesday")
|