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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/Gemfile.lock +3 -3
- data/README.md +26 -7
- data/checksums/almanack-1.1.2.gem.sha256 +1 -0
- data/checksums/almanack-1.1.2.gem.sha512 +1 -0
- data/lib/almanack/configuration.rb +4 -0
- data/lib/almanack/event.rb +13 -3
- data/lib/almanack/event_source/ical.rb +59 -0
- data/lib/almanack/event_source/ical_feed.rb +11 -47
- data/lib/almanack/representation/built_ical_event.rb +65 -0
- data/lib/almanack/representation/ical_feed.rb +1 -13
- data/lib/almanack/themes/legacy/views/events.erb +1 -1
- data/lib/almanack/themes/starter/views/events.erb +1 -1
- data/lib/almanack/version.rb +1 -1
- data/lib/almanack.rb +3 -0
- data.tar.gz.sig +0 -0
- metadata +8 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 589e41a369c5f596904916e5bd0bc40e904da5ac13dc7506af8ccdaf8ccea919
|
4
|
+
data.tar.gz: db2f95c8d0fe54b37c3a570f0c21c2216c79b1d69c53589599bdc7676a261c8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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.
|
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 |
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
data/lib/almanack/event.rb
CHANGED
@@ -3,12 +3,18 @@ require 'ostruct'
|
|
3
3
|
module Almanack
|
4
4
|
class Event < OpenStruct
|
5
5
|
def formatted_date
|
6
|
-
|
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
|
-
|
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
|
-
|
6
|
+
attr_reader :ical, :connection
|
32
7
|
|
33
|
-
|
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
|
-
|
10
|
+
def initialize(url, connection:)
|
11
|
+
@url = url
|
12
|
+
@connection = connection
|
40
13
|
end
|
41
14
|
|
42
|
-
def
|
43
|
-
|
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
|
-
|
53
|
-
RiCal.parse_string(response.body)
|
54
|
-
end
|
19
|
+
private
|
55
20
|
|
56
|
-
def
|
57
|
-
@
|
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
|
-
|
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
|
data/lib/almanack/version.rb
CHANGED
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.
|
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-
|
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:
|
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
|