almanack 1.1.2 → 1.1.3.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b2b817b3542f16e0f902216bb7943efc0f8a3649ee507cceb1e667f19ef5158
4
- data.tar.gz: a50858dfdee7700c0d5e54d492695e72ca6a99e571d7a0c40e6d4803b741ba86
3
+ metadata.gz: 589e41a369c5f596904916e5bd0bc40e904da5ac13dc7506af8ccdaf8ccea919
4
+ data.tar.gz: db2f95c8d0fe54b37c3a570f0c21c2216c79b1d69c53589599bdc7676a261c8e
5
5
  SHA512:
6
- metadata.gz: 569ead2bd71123bbdb99b4b225344b94afb566c62be99be51ad713d37e86766db97c6438efdad30ecc9fc58edf6856ed7875429fba1bedfb9df911dd8c9cfbb7
7
- data.tar.gz: c4fe0b799824eadbcf57cdee660d10e55e303953b04e3d0a53ddbe4f8b6ede8e7fcb9640a001169565f75809f4ec3a8066f02dff927373e97f44908bbd083ae5
6
+ metadata.gz: 65ecf27b42e36b027bc2d06b68875788eea4a4929def3c9de1e74a14803d1d67849bee652a4327fcf2c0ba22d3ea047e79d37c2a04863b1ff376ac81c6d223ba
7
+ data.tar.gz: 6c25a187d1b60e97d5cd8c304ef6db4cad1d6b643d7ea1c26b50c24a8d9de781fee376ea7c181f5ea0940fd98285d28e810efcd6e629c4214a185076944566c4
checksums.yaml.gz.sig CHANGED
Binary file
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- almanack (1.1.2)
4
+ almanack (1.1.3.rc1)
5
5
  activesupport
6
6
  addressable
7
7
  faraday
@@ -23,7 +23,7 @@ GEM
23
23
  tzinfo (~> 1.1)
24
24
  addressable (2.6.0)
25
25
  public_suffix (>= 2.0.2, < 4.0)
26
- backports (3.14.0)
26
+ backports (3.15.0)
27
27
  coderay (1.1.2)
28
28
  concurrent-ruby (1.1.5)
29
29
  crack (0.4.3)
@@ -33,7 +33,7 @@ GEM
33
33
  multipart-post (>= 1.2, < 3)
34
34
  faraday_middleware (0.13.1)
35
35
  faraday (>= 0.7.4, < 1.0)
36
- ffi (1.10.0)
36
+ ffi (1.11.1)
37
37
  hashdiff (0.3.8)
38
38
  i18n (1.6.0)
39
39
  concurrent-ruby (~> 1.0)
data/README.md CHANGED
@@ -61,18 +61,37 @@ By default, your calendar will run on http://localhost:9292.
61
61
  See examples inside `config.ru` for iCal feeds, Meetup.com, or static events.
62
62
 
63
63
  ```ruby
64
- Almanack.config do |c|
65
- c.title = 'My Calendar'
66
- c.theme = 'my-custom-theme'
67
- c.days_lookahead = 30
68
- c.add_ical_feed 'http://example.org/events.ics'
69
- c.add_ical_feed 'http://example.org/more-events.ics'
70
- c.add_meetup_group group_urlname: 'Christchurch-Ruby-Group', key: 'mysecretkey'
64
+ Almanack.config do |config|
65
+ config.title = 'My Calendar'
66
+ config.theme = 'my-custom-theme'
67
+ config.days_lookahead = 30
68
+
69
+ # Combine sources from multiple iCal feeds
70
+ config.add_ical_feed 'http://example.org/events.ics'
71
+ config.add_ical_feed 'http://example.org/more-events.ics'
72
+
73
+ # Include a downloaded iCal
74
+ config.add_ical Pathname('downloaded-calendar.ical')
75
+
76
+ # Include Meetup events
77
+ config.add_meetup_group group_urlname: 'Christchurch-Ruby-Group', key: 'mysecretkey'
71
78
  end
72
79
  ```
73
80
 
74
81
  **Note:** You'll need your [Meetup.com API key](https://secure.meetup.com/meetup_api/key) to use Meetup.
75
82
 
83
+ ### Time zone
84
+
85
+ To set your time zone, set your system's `TZ` environment variable.
86
+
87
+ ```bash
88
+ TZ=Pacific/Auckland
89
+ ```
90
+
91
+ On Heroku, you can do this with:
92
+
93
+ heroku config:set TZ=Pacific/Auckland
94
+
76
95
  ## Custom themes
77
96
 
78
97
  Inside your project, you can generate a new theme with:
@@ -0,0 +1 @@
1
+ 0416f69614ba947317d15dd3bc0a2fd22385a3078652a11501bccb03255f3bda
@@ -0,0 +1 @@
1
+ 142b5b870607ea6e6dca03ba4f84898eac15b6e069dd56aa5421fa0ab58b5373091f36035d057bcb23a7cd63f24f6255eba150c1c6ad156ddcf117f33f151226
@@ -58,6 +58,10 @@ module Almanack
58
58
  add_event_source EventSource::IcalFeed.new(url, connection: connection)
59
59
  end
60
60
 
61
+ def add_ical(io)
62
+ add_event_source EventSource::Ical.from(io)
63
+ end
64
+
61
65
  def add_events(events)
62
66
  add_event_source EventSource::Static.new(events)
63
67
  end
@@ -3,12 +3,18 @@ require 'ostruct'
3
3
  module Almanack
4
4
  class Event < OpenStruct
5
5
  def formatted_date
6
- formatted = "#{formatted_day(start_time)} at #{formatted_time(start_time)}"
6
+ warn "formatted_date is deprecated, please use formatted_duration instead"
7
+ formatted_duration
8
+ end
9
+
10
+ def formatted_duration
11
+ formatted = "#{formatted_day(start_time)}"
12
+ formatted << " at #{formatted_time(start_time)}" unless start_time.is_a?(Date)
7
13
 
8
14
  if end_time
9
- formatted << " to "
15
+ formatted << " to " unless is_date_ending_on_same_day?
10
16
  formatted << "#{formatted_day(end_time)} at " unless ends_on_same_day?
11
- formatted << formatted_time(end_time)
17
+ formatted << formatted_time(end_time) unless end_time.is_a?(Date)
12
18
  end
13
19
 
14
20
  formatted
@@ -79,6 +85,10 @@ module Almanack
79
85
  end
80
86
  end
81
87
 
88
+ def is_date_ending_on_same_day?
89
+ end_time.is_a?(Date) && ends_on_same_day?
90
+ end
91
+
82
92
  def ends_on_same_day?
83
93
  [start_time.year, start_time.yday] == [end_time.year, end_time.yday]
84
94
  end
@@ -0,0 +1,59 @@
1
+ module Almanack
2
+ module EventSource
3
+ class Ical
4
+ attr_reader :io
5
+
6
+ def initialize(io)
7
+ @io = io
8
+ end
9
+
10
+ def events_between(date_range)
11
+ occurrences_between(date_range).map(&method(:event_from))
12
+ end
13
+
14
+ def serialized_between(date_range)
15
+ { events: events_between(date_range).map(&:serialized) }
16
+ end
17
+
18
+ def self.from(*args)
19
+ self.new(*args)
20
+ end
21
+
22
+ private
23
+
24
+ def occurrences_between(date_range, &block)
25
+ return enum_for(__method__, date_range) unless block_given?
26
+
27
+ query = { starting: date_range.min, before: date_range.max }
28
+
29
+ each_event do |ical_event|
30
+ ical_event.occurrences(query).each(&block)
31
+ end
32
+ end
33
+
34
+ def event_from(occurrence)
35
+ Event.new(
36
+ title: occurrence.summary,
37
+ start_time: occurrence.dtstart,
38
+ end_time: occurrence.dtend,
39
+ description: occurrence.description,
40
+ location: occurrence.location
41
+ )
42
+ end
43
+
44
+ def read_io
45
+ io.respond_to?(:read) ? io.read : io
46
+ end
47
+
48
+ def entities
49
+ RiCal.parse_string(read_io)
50
+ end
51
+
52
+ def each_event(&block)
53
+ entities.each do |entity|
54
+ entity.events.each(&block) if entity.respond_to?(:events)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,64 +1,28 @@
1
1
  module Almanack
2
2
  module EventSource
3
3
  class IcalFeed
4
- def initialize(url, options = {})
5
- @url = url
6
- @options = options
7
- end
8
-
9
- def events_between(date_range)
10
- occurrences_between(date_range).map do |occurrence|
11
- event_from(occurrence)
12
- end
13
- end
14
-
15
- def serialized_between(date_range)
16
- { events: events_between(date_range).map(&:serialized) }
17
- end
18
-
19
- private
20
-
21
- def each_ical_event(&block)
22
- entities.each do |entity|
23
- entity.events.each(&block) if entity.respond_to?(:events)
24
- end
25
- end
26
-
27
- def occurrences_between(date_range)
28
- to_date = date_range.max
29
- from_date = date_range.min
4
+ extend Forwardable
30
5
 
31
- occurrences = []
6
+ attr_reader :ical, :connection
32
7
 
33
- each_ical_event do |ical_event|
34
- ical_event.occurrences(starting: from_date, before: to_date).each do |occurrence|
35
- occurrences << occurrence
36
- end
37
- end
8
+ def_delegators :ical, :events_between, :serialized_between
38
9
 
39
- occurrences
10
+ def initialize(url, connection:)
11
+ @url = url
12
+ @connection = connection
40
13
  end
41
14
 
42
- def event_from(occurrence)
43
- Event.new(
44
- title: occurrence.summary,
45
- start_time: occurrence.dtstart,
46
- end_time: occurrence.dtend,
47
- description: occurrence.description,
48
- location: occurrence.location
49
- )
15
+ def ical
16
+ @ical ||= Ical.from(response.body)
50
17
  end
51
18
 
52
- def entities
53
- RiCal.parse_string(response.body)
54
- end
19
+ private
55
20
 
56
- def connection
57
- @options[:connection]
21
+ def uri
22
+ Addressable::URI.parse(@url)
58
23
  end
59
24
 
60
25
  def response
61
- uri = Addressable::URI.parse(@url)
62
26
  connection.get(uri)
63
27
  end
64
28
 
@@ -0,0 +1,65 @@
1
+ module Almanack
2
+ module Representation
3
+ class BuiltIcalEvent
4
+ attr_reader :event
5
+
6
+ def initialize(event)
7
+ @event = event
8
+ end
9
+
10
+ def ical_event
11
+ @ical_event ||= build!
12
+ end
13
+
14
+ def self.for(event)
15
+ new(event).ical_event
16
+ end
17
+
18
+ private
19
+
20
+ def build!
21
+ @ical_event = RiCal.Event
22
+ set_summary
23
+ set_start_time
24
+ set_end_time
25
+ set_description
26
+ set_location
27
+ ical_event
28
+ end
29
+
30
+ def set_summary
31
+ ical_event.summary = event.title
32
+ end
33
+
34
+ def set_start_time
35
+ if event.start_time.is_a?(Date)
36
+ ical_event.dtstart = event.start_time
37
+ else
38
+ ical_event.dtstart = event.start_time.utc
39
+ end
40
+ end
41
+
42
+ def set_end_time
43
+ if event.end_time.is_a?(Date)
44
+ ical_event.dtend = event.end_time
45
+ else
46
+ ical_event.dtend = (event.end_time || event.start_time + default_event_duration ).utc
47
+ end
48
+ end
49
+
50
+ def set_description
51
+ ical_event.description = event.description if event.description
52
+ end
53
+
54
+ def set_location
55
+ ical_event.location = event.location if event.location
56
+ end
57
+
58
+ def default_event_duration
59
+ # Three hours is the duration for events missing end dates, a
60
+ # recommendation suggested by Meetup.com.
61
+ 3 * ONE_HOUR
62
+ end
63
+ end
64
+ end
65
+ end
@@ -32,25 +32,13 @@ module Almanack
32
32
  end
33
33
 
34
34
  def ical_event_for(event)
35
- ical_event = RiCal.Event
36
- ical_event.summary = event.title
37
- ical_event.dtstart = event.start_time.utc
38
- ical_event.dtend = (event.end_time || event.start_time + default_event_duration ).utc
39
- ical_event.description = event.description if event.description
40
- ical_event.location = event.location if event.location
41
- ical_event
35
+ BuiltIcalEvent.for(event)
42
36
  end
43
37
 
44
38
  def lookahead
45
39
  now + calendar.feed_lookahead * ONE_DAY
46
40
  end
47
41
 
48
- def default_event_duration
49
- # Three hours is the duration for events missing end dates, a
50
- # recommendation suggested by Meetup.com.
51
- 3 * ONE_HOUR
52
- end
53
-
54
42
  def now
55
43
  @now ||= Time.now
56
44
  end
@@ -23,7 +23,7 @@
23
23
  <% end %>
24
24
 
25
25
  <dt>When</dt>
26
- <dd><%= event.formatted_date %></dd>
26
+ <dd><%= event.formatted_duration %></dd>
27
27
  </dl>
28
28
  </div>
29
29
  </div>
@@ -23,7 +23,7 @@
23
23
  <% end %>
24
24
 
25
25
  <dt>When</dt>
26
- <dd><%= event.formatted_date %></dd>
26
+ <dd><%= event.formatted_duration %></dd>
27
27
  </dl>
28
28
  </div>
29
29
  </div>
@@ -1,6 +1,6 @@
1
1
  module Almanack
2
2
  CODENAME = "Garlick"
3
- VERSION = "1.1.2"
3
+ VERSION = "1.1.3.rc1"
4
4
  HOMEPAGE = "https://github.com/Aupajo/almanack"
5
5
  ISSUES = "https://github.com/Aupajo/almanack/issues"
6
6
  end
data/lib/almanack.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "pathname"
2
+ require "forwardable"
2
3
  require "json"
3
4
  require "ri_cal"
4
5
  require "addressable/uri"
@@ -11,9 +12,11 @@ require "almanack/version"
11
12
  require "almanack/configuration"
12
13
  require "almanack/calendar"
13
14
  require "almanack/serialized_transformation"
15
+ require "almanack/representation/built_ical_event"
14
16
  require "almanack/representation/ical_feed"
15
17
  require "almanack/representation/json_feed"
16
18
  require "almanack/event"
17
19
  require "almanack/event_source/static"
18
20
  require "almanack/event_source/meetup_group"
21
+ require "almanack/event_source/ical"
19
22
  require "almanack/event_source/ical_feed"
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: almanack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pete Nicholls
@@ -34,7 +34,7 @@ cert_chain:
34
34
  dZpUW6Gfv2VtOtiN0Q3PjLK+TRjHtqYBjbxa771Msax3xs40e2cSVU/dO+OY5NmR
35
35
  a61dVmZ1PIJiY+jyzJSb8ohHVx4=
36
36
  -----END CERTIFICATE-----
37
- date: 2019-05-18 00:00:00.000000000 Z
37
+ date: 2019-06-08 00:00:00.000000000 Z
38
38
  dependencies:
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: sinatra
@@ -326,6 +326,8 @@ files:
326
326
  - certs/aupajo.pem
327
327
  - checksums/almanack-1.1.1.gem.sha256
328
328
  - checksums/almanack-1.1.1.gem.sha512
329
+ - checksums/almanack-1.1.2.gem.sha256
330
+ - checksums/almanack-1.1.2.gem.sha512
329
331
  - example.ru
330
332
  - exe/almanack
331
333
  - lib/almanack.rb
@@ -334,9 +336,11 @@ files:
334
336
  - lib/almanack/cli.rb
335
337
  - lib/almanack/configuration.rb
336
338
  - lib/almanack/event.rb
339
+ - lib/almanack/event_source/ical.rb
337
340
  - lib/almanack/event_source/ical_feed.rb
338
341
  - lib/almanack/event_source/meetup_group.rb
339
342
  - lib/almanack/event_source/static.rb
343
+ - lib/almanack/representation/built_ical_event.rb
340
344
  - lib/almanack/representation/ical_feed.rb
341
345
  - lib/almanack/representation/json_feed.rb
342
346
  - lib/almanack/serialized_transformation.rb
@@ -372,9 +376,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
372
376
  version: '0'
373
377
  required_rubygems_version: !ruby/object:Gem::Requirement
374
378
  requirements:
375
- - - ">="
379
+ - - ">"
376
380
  - !ruby/object:Gem::Version
377
- version: '0'
381
+ version: 1.3.1
378
382
  requirements: []
379
383
  rubygems_version: 3.0.3
380
384
  signing_key:
metadata.gz.sig CHANGED
Binary file