almanack 1.1.2 → 1.1.3.rc1

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 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