facebook-google-calendar-sync 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,6 +7,7 @@ require 'facebook_google_calendar_sync/google_calendar'
7
7
  require 'facebook_google_calendar_sync/google_calendar_client'
8
8
  require 'active_support/core_ext/hash/indifferent_access'
9
9
 
10
+
10
11
  module FacebookGoogleCalendarSync
11
12
 
12
13
  extend Logging
@@ -2,39 +2,22 @@ module FacebookGoogleCalendarSync
2
2
 
3
3
  class EventConverter
4
4
 
5
- attr_accessor :facebook_event, :google_calendar_id, :timezone
5
+ attr_accessor :facebook_event, :google_calendar_id
6
6
  STATUS_MAPPINGS = {'NEEDS-ACTION' => 'needsAction', 'ACCEPTED' => 'accepted'}
7
7
 
8
- def initialize facebook_event, google_calendar_id, timezone
8
+ def initialize facebook_event, google_calendar_id
9
9
  @facebook_event = facebook_event
10
10
  @google_calendar_id = google_calendar_id
11
- @timezone = timezone
12
- end
13
-
14
- def uid
15
- facebook_event.uid
16
- end
17
-
18
- def last_modified
19
- facebook_event.last_modified.convert_time_zone(timezone)
20
- end
21
-
22
- def summary
23
- facebook_event.summary
24
- end
25
-
26
- def created
27
- facebook_event.created
28
11
  end
29
12
 
30
13
  def to_hash
31
14
  {
32
- 'summary' => facebook_event.summary,
33
- 'start' => date_hash(facebook_event.dtstart),
34
- 'end' => date_hash(facebook_event.dtend),
35
- 'iCalUID' => facebook_event.uid,
15
+ 'summary' => summary,
16
+ 'start' => date_hash(dtstart),
17
+ 'end' => date_hash(dtend),
18
+ 'iCalUID' => uid,
36
19
  'description' => description,
37
- 'location' => facebook_event.location,
20
+ 'location' => location,
38
21
  'organizer' => organiser,
39
22
  'attendees' => attendees,
40
23
  'transparency' => transparency
@@ -58,7 +41,7 @@ module FacebookGoogleCalendarSync
58
41
  end
59
42
 
60
43
  def organiser_name
61
- matches = facebook_event.organizer_property.to_s.scan(/CN=(.*):MAILTO:(.*)/).flatten
44
+ matches = organizer_property.to_s.scan(/CN=(.*):MAILTO:(.*)/).flatten
62
45
  matches[0]
63
46
  end
64
47
 
@@ -68,13 +51,21 @@ module FacebookGoogleCalendarSync
68
51
  }
69
52
  end
70
53
 
54
+ def method_missing(method, *args, &block)
55
+ if facebook_event.respond_to?(method)
56
+ facebook_event.send(method, *args, &block)
57
+ else
58
+ super
59
+ end
60
+ end
61
+
71
62
  private
72
63
 
73
64
  def date_hash date_time
74
65
  if date_time.instance_of? Date
75
66
  {'date' => date_time.strftime('%Y-%m-%d')}
76
67
  else
77
- {'dateTime' => date_time.convert_time_zone(timezone).strftime('%Y-%m-%dT%H:%M:%S.000%:z')}
68
+ {'dateTime' => date_time.strftime('%Y-%m-%dT%H:%M:%S.000%:z')}
78
69
  end
79
70
  end
80
71
  end
@@ -77,7 +77,7 @@ end
77
77
 
78
78
  def make_call params
79
79
  result = client.execute(params.merge(:headers => {'Content-Type' => 'application/json'}))
80
- check_for_success result
80
+ check_for_success result, params
81
81
  result.data
82
82
  end
83
83
 
@@ -89,8 +89,8 @@ end
89
89
  @@calendar_service
90
90
  end
91
91
 
92
- def check_for_success result
93
- raise SyncException.new(result.status.to_s + " " + result.body) unless result.status == 200
92
+ def check_for_success result, params
93
+ raise SyncException.new(result.status.to_s + "\nResponse:" + result.body + "\nRequest: #{params}") unless result.status == 200
94
94
  end
95
95
 
96
96
  end
@@ -1,21 +1,23 @@
1
+ require 'time_zone_hack'
1
2
  require 'facebook_google_calendar_sync/google_calendar_client'
2
3
  require 'facebook_google_calendar_sync/google_calendar_description'
3
- require 'time_zone_hack'
4
4
  require 'facebook_google_calendar_sync/event_converter'
5
+ require 'facebook_google_calendar_sync/timezone'
5
6
 
6
7
  module FacebookGoogleCalendarSync
7
8
  class Synchroniser
8
9
  include Logging
9
10
  include GoogleCalendarDescription
10
11
  include GoogleCalendarClient
12
+ include Timezone
11
13
 
12
14
  def initialize(facebook_calendar, google_calendar)
13
- @facebook_calendar = facebook_calendar
14
- @google_calendar = google_calendar
15
+ @google_calendar = with_timezone(google_calendar, google_calendar.timezone)
16
+ @events = facebook_calendar.events.collect{ | facebook_event | with_google_calendar_timezone(facebook_event) }
15
17
  end
16
18
 
17
- def facebook_calendar
18
- @facebook_calendar
19
+ def events
20
+ @events
19
21
  end
20
22
 
21
23
  def google_calendar
@@ -27,17 +29,29 @@ module FacebookGoogleCalendarSync
27
29
  update_last_known_event_update
28
30
  end
29
31
 
32
+ def convert facebook_event
33
+ EventConverter.new(facebook_event, google_calendar.id)
34
+ end
35
+
36
+ def with_google_calendar_timezone target
37
+ with_timezone(target, google_calendar.timezone)
38
+ end
39
+
40
+ #TODO: Fix this method!
30
41
  def synchronise_events
31
- facebook_calendar.events.each do | facebook_event |
42
+ errors = []
43
+ events.each do | facebook_event |
44
+ converted_event = nil
32
45
  begin
33
- synchronise_event EventConverter.new(facebook_event, google_calendar.id, google_calendar.timezone)
46
+ converted_event = convert(facebook_event)
47
+ synchronise_event converted_event
34
48
  rescue StandardError => e
35
49
  logger.error e
36
- logger.error "Error synchronising event. Please note that if this was a new event, it will not have been added to your calendar."
37
- logger.error facebook_event.summary
38
- raise e
50
+ logger.error "Error synchronising event. #{converted_event.to_hash}" rescue nil
51
+ errors << e
39
52
  end
40
53
  end
54
+ raise "Errors synchronising calendar" if errors.any?
41
55
  end
42
56
 
43
57
  def synchronise_event facebook_event
@@ -45,7 +59,7 @@ module FacebookGoogleCalendarSync
45
59
  if google_event == nil
46
60
  handle_google_event_not_found facebook_event
47
61
  else
48
- handle_google_event_found facebook_event, google_event
62
+ handle_google_event_found facebook_event, with_google_calendar_timezone(google_event)
49
63
  end
50
64
  end
51
65
 
@@ -63,7 +77,7 @@ module FacebookGoogleCalendarSync
63
77
  logger.info "Updating '#{facebook_event.summary}' in #{google_calendar.summary}"
64
78
  update_event google_calendar.id, google_event.id, facebook_event.to_hash.merge(google_event)
65
79
  else
66
- logger.info "Not updating '#{facebook_event.summary}' in #{google_calendar.summary} as #{facebook_event.last_modified} is not later than #{to_local(google_event.updated)}"
80
+ logger.info "Not updating '#{facebook_event.summary}' in #{google_calendar.summary} as #{facebook_event.last_modified} is not later than #{google_event.updated}"
67
81
  end
68
82
  end
69
83
 
@@ -82,21 +96,19 @@ module FacebookGoogleCalendarSync
82
96
  details = google_calendar.details.to_hash.merge({'description' => create_description(date_of_most_recent_event_update, current_time_in_google_calendar_timezone)})
83
97
  update_calendar google_calendar.id, details
84
98
  else
85
- logger.info "Not updating description of '#{google_calendar.summary}' as the date of the most recent update has not changed from #{to_local(google_calendar.last_known_event_update)}."
99
+ logger.info "Not updating description of '#{google_calendar.summary}' as the date of the most recent update has not changed from #{google_calendar.last_known_event_update}."
86
100
  end
87
101
  end
88
102
 
89
103
  def current_time_in_google_calendar_timezone
90
- to_local(DateTime.now)
91
- end
92
-
93
- def to_local date_or_time
94
- date_or_time.convert_time_zone(google_calendar.timezone)
104
+ DateTime.now.convert_time_zone(google_calendar.timezone)
95
105
  end
96
106
 
107
+ #Use the date of the most recent event update as our 'line in the sand' rather than the Google calendar's updated
108
+ #property, because of the slight differences in the clocks between Facebook and Google calendar and the fact that
109
+ #this script takes a non-zero amount of time to run, which could lead to inconsitencies in the synchronisation logic.
97
110
  def date_of_most_recent_event_update
98
- most_recently_modified_event = facebook_calendar.events.max{ | event_a, event_b | event_a.last_modified <=> event_b.last_modified }
99
- most_recently_modified_event.last_modified
111
+ events.max{ | event_a, event_b | event_a.last_modified <=> event_b.last_modified }.last_modified
100
112
  end
101
113
  end
102
114
  end
@@ -0,0 +1,32 @@
1
+ require 'time_zone_hack'
2
+
3
+ module FacebookGoogleCalendarSync
4
+
5
+ module Timezone
6
+
7
+ def with_timezone target, timezone
8
+ TimeZoneProxy.new(target, timezone)
9
+ end
10
+
11
+ class TimeZoneProxy < BasicObject
12
+ def initialize target, timezone
13
+ @target = target
14
+ @timezone = timezone
15
+ end
16
+
17
+ def method_missing(method, *args, &block)
18
+ result = @target.send(method, *args, &block)
19
+ convert_timezone_if_date(result)
20
+ end
21
+
22
+ def convert_timezone_if_date result
23
+ if result.respond_to?(:convert_time_zone)
24
+ result.convert_time_zone(@timezone)
25
+ else
26
+ result
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ end
@@ -1,3 +1,3 @@
1
1
  module FacebookGoogleCalendarSync
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: facebook-google-calendar-sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -165,6 +165,7 @@ files:
165
165
  - lib/facebook_google_calendar_sync/google_calendar_description.rb
166
166
  - lib/facebook_google_calendar_sync/logging.rb
167
167
  - lib/facebook_google_calendar_sync/synchroniser.rb
168
+ - lib/facebook_google_calendar_sync/timezone.rb
168
169
  - lib/facebook_google_calendar_sync/version.rb
169
170
  - lib/time_zone_hack.rb
170
171
  - spec/facebook-google-calendar-sync_spec.rb