rooftop-spektrix_sync 0.0.2.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bb6fd037cce26a2e0f142bf431ef45fc4c1989a9
4
+ data.tar.gz: a7a3bb0ae24fe58aa5c0d8af3b3f51e8d8a2091e
5
+ SHA512:
6
+ metadata.gz: b4d00862c48da22fc7cb8dface4fba4b0a9546d2ce964427d9dc59a83a715cf9073f3f21e25f05b23cd89151cf454b20d401a8c97db3d38232d5a36c9ec98ec4
7
+ data.tar.gz: 129902d9ea10654f3d6737bc759154306256286a408810a15c12dd8bbc8c9c044f7031b0a3ed4e1ea34891e366ee5b9d07d960815a7e089db29fa17331d2951c
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .idea
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ rooftop-spektrix_sync
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rooftop-spektrix_sync.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Ed Jones
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Rooftop::SpektrixSync
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rooftop-spektrix_sync'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rooftop-spektrix_sync
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/rooftop-spektrix_sync/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,92 @@
1
+ module Rooftop
2
+ module SpektrixSync
3
+ class EventSync
4
+ attr_reader :spektrix_event,
5
+ :rooftop_event,
6
+ :rooftop_price_lists,
7
+ :logger
8
+
9
+ def initialize(spektrix_event, sync_task)
10
+ @rooftop_events = sync_task.rooftop_events
11
+ @spektrix_events = sync_task.spektrix_events
12
+ @logger = sync_task.logger
13
+ @spektrix_event = spektrix_event
14
+ @rooftop_event = @rooftop_events.find {|e| e.meta_attributes[:spektrix_id].try(:to_i) == @spektrix_event.id.to_i}
15
+ @rooftop_price_lists = sync_task.rooftop_price_lists
16
+ end
17
+
18
+ def sync_to_rooftop
19
+ begin
20
+ # find the event
21
+ @rooftop_event ||= Rooftop::Events::Event.new({
22
+ title: @spektrix_event.title,
23
+ content: {basic: {content: @spektrix_event.description}},
24
+ meta_attributes: {},
25
+ status: nil
26
+ })
27
+ sync()
28
+ rescue => e
29
+ @logger.error(e.to_s)
30
+ end
31
+ end
32
+
33
+ def sync
34
+ update_meta_attributes
35
+ update_on_sale
36
+ if @rooftop_event.persisted?
37
+ # Ensure we're not overwriting newer stuff in RT with older stuff from this sync by
38
+ # removing the title and content if this is a PUT request (i.e. it already exists in RT)
39
+ @rooftop_event.restore_title!
40
+ @rooftop_event.restore_content!
41
+ @rooftop_event.restore_slug!
42
+ @rooftop_event.restore_link!
43
+ @rooftop_event.restore_event_instance_availabilities!
44
+ end
45
+
46
+ if @rooftop_event.save!
47
+ @logger.debug("Saved event: #{@rooftop_event.title} #{@rooftop_event.id}")
48
+ sync_instances
49
+ end
50
+ end
51
+
52
+ private
53
+ def update_meta_attributes
54
+ @rooftop_event.meta_attributes ||= {}
55
+ @rooftop_event.meta_attributes[:spektrix_id] = @spektrix_event.id
56
+ @spektrix_event.custom_attributes.each do |key, value|
57
+ @rooftop_event.meta_attributes[key] = value
58
+ end
59
+ @rooftop_event.meta_attributes[:duration] = @spektrix_event.duration.to_i
60
+ end
61
+
62
+ def update_on_sale
63
+ if SpektrixSync.configuration.present? && SpektrixSync.configuration[:on_sale_if_new_event]
64
+ @rooftop_event.status = @spektrix_event.is_on_sale ? 'publish' : 'draft'
65
+ else
66
+ @rooftop_event.restore_status! #don't send status with the request
67
+ end
68
+ end
69
+
70
+ def sync_instances
71
+ @rooftop_instances = @rooftop_event.instances.to_a
72
+ @spektrix_instances = @spektrix_event.instances.to_a
73
+ @spektrix_instances.each_with_index do |instance, i|
74
+ begin
75
+ tries ||= 2
76
+ instance_sync = Rooftop::SpektrixSync::InstanceSync.new(instance, self)
77
+ instance_sync.sync
78
+ rescue
79
+ retry unless (tries -= 1 ).zero?
80
+ end
81
+ end
82
+
83
+ update_event_metadata unless @rooftop_instances.empty?
84
+ end
85
+
86
+ def update_event_metadata
87
+ @logger.debug("Saved event instances. Updating event metadata")
88
+ Rooftop::Events::Event.post("#{@rooftop_event.class.collection_path}/#{@rooftop_event.id}/update_metadata")
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,76 @@
1
+ module Rooftop
2
+ module SpektrixSync
3
+ class InstanceSync
4
+
5
+ def initialize(spektrix_instance, event_sync)
6
+ @spektrix_event = event_sync.spektrix_event
7
+ @rooftop_event = event_sync.rooftop_event
8
+ @logger = event_sync.logger
9
+ @spektrix_instance = spektrix_instance
10
+ @rooftop_instance = find_rooftop_instance_by_spektrix_id(@spektrix_instance.id) || @rooftop_event.instances.build(status: nil, meta_attributes: {})
11
+ @rooftop_price_lists = event_sync.rooftop_price_lists
12
+ end
13
+
14
+ def sync
15
+ # This is a bit of a hack: we have to create a new instance and assign all the attributes from the old one, so it has an _event_id param.
16
+ if @rooftop_instance.persisted?
17
+ @rooftop_instance = @rooftop_event.instances.build(@rooftop_instance.attributes)
18
+ instance_updated = true
19
+ end
20
+ update_price
21
+ if @rooftop_instance.price_list_id.nil?
22
+ @logger.warn("No price list for Spektrix instance id #{@spektrix_instance.id}")
23
+ return
24
+ end
25
+ update_meta_attributes
26
+ update_availability
27
+ update_on_sale
28
+ if @rooftop_instance.save!
29
+ @logger.debug("#{instance_updated ? "Updated" : "Created"} Rooftop instance #{@rooftop_instance.id}")
30
+ end
31
+ end
32
+
33
+ private
34
+ def find_rooftop_instance_by_spektrix_id(spektrix_id)
35
+ @rooftop_event.instances.to_a.find {|i| i.meta_attributes[:spektrix_id] == spektrix_id }
36
+ end
37
+
38
+ def update_price
39
+ @rooftop_instance.price_list_id = @rooftop_price_lists.find {|l| l.meta_attributes[:spektrix_id].to_i == @spektrix_instance.price_list_id}.try(:id)
40
+ end
41
+
42
+ def update_meta_attributes
43
+ @rooftop_instance.meta_attributes = @spektrix_instance.custom_attributes.merge(spektrix_id: @spektrix_instance.id)
44
+ end
45
+
46
+ def update_on_sale
47
+ # TODO: there is a bug in the Rooftop events plugin which means that instances which are draft won't be shown
48
+ # as assigned to the event. Because it's a nested resource, there's no real risk to publishing
49
+ # the instance immediately.
50
+ # if SpektrixSync.configuration.present? && SpektrixSync.configuration[:on_sale_if_new_event]
51
+ # @rooftop_instance.status = @spektrix_instance.is_on_sale ? 'publish' : 'draft'
52
+ # else
53
+ # @rooftop_instance.status ||= "draft"
54
+ # end
55
+ # @rooftop_instance.status = "publish"
56
+
57
+ @rooftop_instance.status = @spektrix_instance.is_on_sale=="true" ? 'publish' : 'draft'
58
+ end
59
+
60
+ def update_availability
61
+ availability = {
62
+ availability: {
63
+ starts_at: @spektrix_instance.start.iso8601,
64
+ stops_at: @spektrix_instance.start.advance(seconds: @rooftop_event.meta_attributes[:duration]),
65
+ seats_capacity: @spektrix_instance.status.capacity,
66
+ seats_available: @spektrix_instance.status.available
67
+ }
68
+ }
69
+ @rooftop_instance.title = @rooftop_event.title + ": " + @spektrix_instance.start.strftime("%d %b %Y %H:%M")
70
+ @rooftop_instance.meta_attributes.merge!(availability)
71
+ end
72
+
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,110 @@
1
+ module Rooftop
2
+ module SpektrixSync
3
+ class PriceListSync
4
+
5
+ def initialize(sync_task)
6
+ @spektrix_price_lists = sync_task.spektrix_price_lists
7
+ @rooftop_price_lists = sync_task.rooftop_price_lists
8
+ @rooftop_ticket_types = sync_task.rooftop_ticket_types
9
+ @rooftop_price_bands = sync_task.rooftop_price_bands
10
+ @logger = sync_task.logger
11
+ end
12
+
13
+ def run
14
+ sync_price_lists
15
+ # Todo we need to put this in a rake task instead of running every time.
16
+ # remove_orphan_price_lists
17
+ end
18
+
19
+ private
20
+
21
+ def sync_price_lists
22
+ # begin
23
+ @spektrix_price_lists.each do |spektrix_price_list|
24
+ # Don't bother syncing a price list where none of the prices have bands.
25
+ if spektrix_price_list.prices.select {|p| !p.band.nil?}.empty?
26
+ @logger.warn("Spektrix price list ID #{spektrix_price_list.id} has prices with missing bands.")
27
+ end
28
+
29
+ # find or create a price list
30
+ @rooftop_price_list = @rooftop_price_lists.find {|l| l.meta_attributes[:spektrix_id] == spektrix_price_list.id.to_s} || Rooftop::Events::PriceList.new(title: spektrix_price_list.id, meta_attributes: {})
31
+ @rooftop_price_list.meta_attributes[:spektrix_id] = spektrix_price_list.id
32
+
33
+ new_price_list = @rooftop_price_list.new?
34
+ # save the price list to rooftop
35
+ if @rooftop_price_list.save!
36
+ @logger.debug("#{new_price_list ? "Created" : "Updated"} price list #{spektrix_price_list.id}")
37
+ sync_prices(spektrix_price_list, @rooftop_price_list)
38
+ end
39
+ end
40
+ # rescue => e
41
+ # @logger.warn(e.to_s)
42
+ # end
43
+ end
44
+
45
+ def sync_prices(spektrix_price_list, rooftop_price_list)
46
+ # begin
47
+ spektrix_price_list.prices.each_with_index do |spektrix_price, i |
48
+ @logger.debug("syncing price #{i+1} / #{spektrix_price_list.prices.count}")
49
+ # skip ones without a band
50
+ if spektrix_price.band.nil?
51
+ @logger.warn("Spektrix price list ID: #{spektrix_price_list.id}: Price #{spektrix_price.price} with ticket type #{spektrix_price.ticket_type.name} does not have a band")
52
+ next
53
+ end
54
+ current_rooftop_price = find_rooftop_price(rooftop_price_list, spektrix_price)
55
+ # because updating a price is hard with a nested resource, we'll destroy and recreate with the same settings
56
+ new_price = rooftop_price_list.prices.build
57
+ if current_rooftop_price
58
+ new_price.assign_attributes(current_rooftop_price.attributes)
59
+ end
60
+
61
+ new_price.meta_attributes = {
62
+ is_band_default: (spektrix_price.is_band_default == "true"),
63
+ ticket_type_id: find_rooftop_ticket_type(spektrix_price).id,
64
+ price_band_id: find_rooftop_price_band(spektrix_price).id,
65
+ ticket_price: spektrix_price.price.to_f
66
+ }
67
+
68
+ new_price.title = "#{spektrix_price.band.name} (£#{new_price.meta_attributes[:ticket_price]})"
69
+ if new_price.save!
70
+ @logger.debug("Spektrix price list ID: #{spektrix_price_list.id}: Saved price £#{new_price.meta_attributes[:ticket_price]} with ticket type #{spektrix_price.ticket_type.name} for price band #{spektrix_price.band.name}")
71
+ end
72
+ end
73
+ # rescue => e
74
+ # @logger.error(e.to_s)
75
+ # end
76
+ end
77
+
78
+ def remove_orphan_price_lists
79
+ begin
80
+ rooftop_spektrix_ids = @rooftop_price_lists.collect {|l| l.meta_attributes[:spektrix_id].to_i}
81
+ spektrix_ids = @spektrix_price_lists.collect {|l| l.id.to_i}
82
+ spektrix_ids_to_remove = (rooftop_spektrix_ids - (rooftop_spektrix_ids & spektrix_ids))
83
+ rooftop_ids_to_remove = spektrix_ids_to_remove.collect do |spektrix_id|
84
+ @rooftop_price_lists.find {|l| l.meta_attributes[:spektrix_id].to_i == spektrix_id}.id
85
+ end
86
+ Rooftop::Events::PriceList.where(post__in: rooftop_ids_to_remove).each do |pricelist|
87
+ if pricelist.destroy
88
+ @logger.debug("Removed rooftop price list #{id} which didn't exist in spektrix")
89
+ end
90
+ end
91
+ rescue => e
92
+ @logger.error(e.to_s)
93
+ end
94
+ end
95
+
96
+ def find_rooftop_price(rooftop_price_list,spektrix_price)
97
+ rooftop_price_list.prices.to_a.find {|p| p.meta_attributes[:spektrix_id] == spektrix_price.id}
98
+ end
99
+
100
+ def find_rooftop_ticket_type(spektrix_price)
101
+ @rooftop_ticket_types.find {|t| CGI::unescapeHTML(t.title.gsub(/&#8211\;/, '-')) == CGI::unescapeHTML(spektrix_price.ticket_type.name)}
102
+ end
103
+
104
+ def find_rooftop_price_band(spektrix_price)
105
+ @rooftop_price_bands.find {|b| CGI::unescapeHTML(b.title.gsub(/&#8211\;/, '-')) == CGI::unescapeHTML(spektrix_price.band.name)}
106
+ end
107
+
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,227 @@
1
+ module Rooftop
2
+ module SpektrixSync
3
+ class SyncTask
4
+ attr_accessor :starting_at, :logger, :error_file
5
+ attr_reader :spektrix_events,
6
+ :rooftop_events,
7
+ :spektrix_price_lists,
8
+ :rooftop_price_lists,
9
+ :rooftop_ticket_types,
10
+ :rooftop_price_bands,
11
+ :options
12
+
13
+ PIDPATH = "/tmp/rooftop-spektrix-sync.pid"
14
+
15
+ def initialize(starting_at, opts={})
16
+ begin
17
+ Rooftop.preview = true
18
+ if defined?(Rooftop::Rails)
19
+ Rooftop::Rails.configuration.perform_object_caching = false
20
+ end
21
+ @starting_at = starting_at || DateTime.now
22
+ @logger = SpektrixSync.logger || Logger.new(STDOUT)
23
+ default_opts = {
24
+ import_price_bands: false,
25
+ import_ticket_types: false,
26
+ import_prices: false,
27
+ import_events: true,
28
+ delete_orphan_events: false,
29
+ accept_empty_rooftop_events: false
30
+ }
31
+ @options = default_opts.merge!(opts)
32
+ @logger.debug("*************************************************************************")
33
+ @logger.debug("Running with options: #{@options.select {|k,v| k if v}.keys.join(", ")}")
34
+ @logger.debug("*************************************************************************")
35
+ rescue => e
36
+ @logger.error("Couldn't start sync: #{e}")
37
+ end
38
+ end
39
+
40
+ def fetch_rooftop_and_spektrix_data
41
+ @logger.debug("Fetching all Spektrix events")
42
+ @spektrix_events = @spektrix_events.present? ? @spektrix_events : Spektrix::Events::Event.all(instance_start_from: @starting_at.iso8601).to_a
43
+ if @options[:spektrix_event_id]
44
+ @spektrix_events = @spektrix_events.select {|e| e.id == @options[:spektrix_event_id].to_s}
45
+ end
46
+ @logger.debug("Fetching all Rooftop events")
47
+ @rooftop_events = Rooftop::Events::Event.all.to_a
48
+ unless @options[:accept_empty_rooftop_events]
49
+ raise StandardError, "Rooftop returned an empty set of events which is probably wrong" if @rooftop_events.empty?
50
+ end
51
+ @logger.debug("Fetching all Spektrix price lists")
52
+ @spektrix_price_lists = @spektrix_price_lists.present? ? @spektrix_price_lists : Spektrix::Tickets::PriceList.all.to_a
53
+ @logger.debug("Fetching all Rooftop Price lists")
54
+ @rooftop_price_lists = Rooftop::Events::PriceList.all.to_a
55
+ @logger.debug("Fetching all Rooftop ticket types")
56
+ @rooftop_ticket_types = Rooftop::Events::TicketType.all.to_a
57
+ @logger.debug("Fetching all Rooftop price bands")
58
+ @rooftop_price_bands = Rooftop::Events::PriceBand.all.to_a
59
+ end
60
+
61
+
62
+
63
+ def self.run(starting_at=nil, opts={})
64
+ sync_pid = Process.get_pid(Rooftop::SpektrixSync::SyncTask::PIDPATH)
65
+
66
+ if sync_pid && Process.exists?(sync_pid.to_i)
67
+ raise 'Rooftop::SpektrixSync::SyncRunning'
68
+ end
69
+
70
+ # if we're here, we can create a new pidfile and start the sync
71
+ Process.create_pid(Rooftop::SpektrixSync::SyncTask::PIDPATH)
72
+ self.new(starting_at,opts).run
73
+
74
+ # remove the pid
75
+ Process.remove_pidfile(Rooftop::SpektrixSync::SyncTask::PIDPATH)
76
+ end
77
+
78
+ def self.run_events_import(starting_at=nil, event_id=nil)
79
+ opts = event_id.present? ? {spektrix_event_id: event_id} : {}
80
+ self.run(starting_at, opts)
81
+ end
82
+
83
+ def self.run_full_import(starting_at=nil)
84
+ self.run(starting_at, {
85
+ import_price_bands: true,
86
+ import_ticket_types: true,
87
+ import_prices: true,
88
+ import_events: true,
89
+ delete_orphan_events: false
90
+ })
91
+ end
92
+
93
+ def self.run_prices_import(starting_at=nil)
94
+ self.run(starting_at, {
95
+ import_price_bands: true,
96
+ import_ticket_types: true,
97
+ import_prices: true,
98
+ import_events: false,
99
+ delete_orphan_events: false
100
+ })
101
+ end
102
+
103
+
104
+ def run
105
+ begin
106
+ if @options[:import_price_bands]
107
+ fetch_rooftop_and_spektrix_data
108
+ create_or_update_price_bands
109
+ end
110
+ if @options[:import_ticket_types]
111
+ fetch_rooftop_and_spektrix_data
112
+ create_or_update_ticket_types
113
+ end
114
+ if @options[:import_prices]
115
+ fetch_rooftop_and_spektrix_data
116
+ create_or_update_prices
117
+ end
118
+ if @options[:import_events]
119
+ fetch_rooftop_and_spektrix_data
120
+ create_or_update_events
121
+ end
122
+ # TODO: the delete method is over-eager. Resolve the issue.
123
+ # if @options[:delete_orphan_events]
124
+ # fetch_event_data
125
+ # delete_orphan_spektrix_events
126
+ # end
127
+ rescue => e
128
+ @logger.error(e)
129
+ end
130
+
131
+ end
132
+
133
+ private
134
+
135
+ def create_or_update_events
136
+ begin
137
+ tries ||= 2
138
+ @spektrix_events.each_with_index do |event, i|
139
+ @logger.debug("Sync #{i+1} / #{@spektrix_events.length}: #{event.title}")
140
+ item = EventSync.new(event, self)
141
+ item.sync_to_rooftop
142
+ end
143
+ rescue => e
144
+ @logger.error(e.to_s)
145
+ retry unless (tries -= 1).zero?
146
+ end
147
+ end
148
+
149
+ # Mop up any Rooftop events which don't exist in spektrix, if they have spektrix ID
150
+ def delete_orphan_spektrix_events
151
+ @spektrix_event_ids = @spektrix_events.collect {|e| e.id.to_i}
152
+ @rooftop_event_ids = @rooftop_events.inject({}) do |hash, e|
153
+ hash[e.id] = e.meta_attributes[:spektrix_id].to_i
154
+ hash
155
+ end
156
+ @rooftop_event_ids.reject! {|k,v| v == 0} #remove events with no spektrix ID; we don't want to remove them.
157
+ spektrix_ids_to_delete = (@rooftop_event_ids.values - (@rooftop_event_ids.values & @spektrix_event_ids))
158
+ rooftop_ids_to_delete = @rooftop_event_ids.select {|k,v| spektrix_ids_to_delete.include?(v)}.keys
159
+ Rooftop::Events::Event.where(post__in: rooftop_ids_to_delete).each do |rooftop_event|
160
+ title = rooftop_event.title
161
+ if rooftop_event.destroy
162
+ @logger.debug("Removed Rooftop event #{title} which doesn't exist in Spektrix")
163
+ end
164
+ end
165
+ end
166
+
167
+ def create_or_update_price_bands
168
+ begin
169
+ rooftop_bands = Rooftop::Events::PriceBand.all.to_a
170
+ spektrix_bands = Spektrix::Tickets::Band.all.to_a
171
+ # create or update existing
172
+ spektrix_bands.each do |band|
173
+ @logger.debug("Updating band #{band.name}")
174
+ rooftop_band = rooftop_bands.find {|b| b.title == band.name} || Rooftop::Events::PriceBand.new
175
+ rooftop_band.title = band.name
176
+ rooftop_band.save!
177
+ end
178
+
179
+ #delete ones on rooftop which aren't in spektrix
180
+ rooftop_titles = rooftop_bands.collect(&:title)
181
+ spektrix_titles = spektrix_bands.collect(&:name)
182
+ (rooftop_titles - (rooftop_titles & spektrix_titles)).each do |title|
183
+ rooftop_bands.find {|b| b.title == title}.destroy
184
+ end
185
+ rescue => e
186
+ @logger.error(e.to_s)
187
+ end
188
+
189
+
190
+ end
191
+
192
+ def create_or_update_ticket_types
193
+ begin
194
+ rooftop_ticket_types = Rooftop::Events::TicketType.all.to_a
195
+ spektrix_ticket_types = Spektrix::Tickets::Type.all.to_a
196
+ # create or update exiting
197
+ spektrix_ticket_types.each do |type|
198
+ @logger.debug("Updating ticket type #{type.name}")
199
+ rooftop_ticket_type = rooftop_ticket_types.find {|t| t.title == type.name} || Rooftop::Events::TicketType.new
200
+ rooftop_ticket_type.title = type.name
201
+ rooftop_ticket_type.save!
202
+ end
203
+
204
+ #delete ones on rooftop which aren't in spektrix
205
+ rooftop_titles = rooftop_ticket_types.collect(&:title)
206
+ spektrix_titles = spektrix_ticket_types.collect(&:name)
207
+ (rooftop_titles - (rooftop_titles & spektrix_titles)).each do |title|
208
+ rooftop_ticket_types.find {|b| b.title == title}.destroy
209
+ end
210
+ rescue => e
211
+ @logger.error(e.to_s)
212
+ end
213
+ end
214
+
215
+ # This is where we generate a price list sync instance
216
+ def create_or_update_prices
217
+ PriceListSync.new(self).run
218
+ #In this circumstance, we need to assume some prices have changed, so we'll invalidate the
219
+ # instance variable which contains the collection of prices on both sides. This means that
220
+ # next time fetch_rooftop_and_spektrix_data is called, the latest will be pulled from the APIs.
221
+ @spektrix_price_lists = nil
222
+ @rooftop_price_lists = nil
223
+
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,26 @@
1
+ module Process
2
+ def exists?(pid)
3
+ Process.kill(0, pid)
4
+ true
5
+ rescue => e
6
+ false
7
+ end
8
+
9
+ def create_pid(path)
10
+ Pathname(path).write(Process.pid)
11
+ end
12
+
13
+ def get_pid(path)
14
+ File.read(path).to_i
15
+ rescue Errno::ENOENT
16
+ false
17
+ end
18
+
19
+ def remove_pidfile(path)
20
+ File.delete(path)
21
+ rescue Errno::ENOENT
22
+ false
23
+ end
24
+
25
+ module_function :exists?, :create_pid, :get_pid, :remove_pidfile
26
+ end
@@ -0,0 +1,10 @@
1
+ module Rooftop
2
+ module SpektrixSync
3
+ class Railtie < ::Rails::Railtie
4
+
5
+ rake_tasks do
6
+ load "rooftop/spektrix_sync/tasks/import.rake"
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,33 @@
1
+ namespace :rooftop do
2
+ namespace :spektrix do
3
+
4
+ task :prepare, [:since, :logger_path] do |task, args|
5
+ logger_path = args[:logger_path] || STDOUT
6
+ Rooftop::SpektrixSync.logger = Logger.new(logger_path, 'daily')
7
+ @since = eval(args[:since]) rescue DateTime.now
8
+ end
9
+
10
+
11
+ desc "Synchronise events from Spektrix to Rooftop"
12
+ task :sync_events, [:since, :logger_path] => [:environment, :prepare] do |task, args|
13
+ Rooftop::SpektrixSync::SyncTask.run_events_import(@since)
14
+ end
15
+
16
+ desc "Synchronise events and prices from Spektrix to Rooftop"
17
+ task :sync_all, [:since, :logger_path] => [:environment, :prepare] do |task, args|
18
+ Rooftop::SpektrixSync::SyncTask.run_full_import(@since)
19
+ end
20
+
21
+ desc "Synchronise events and prices from Spektrix to Rooftop"
22
+ task :sync_prices, [:since, :logger_path] => [:environment, :prepare] do |task, args|
23
+ Rooftop::SpektrixSync::SyncTask.run_prices_import(@since)
24
+ end
25
+
26
+ desc "Sync specific event"
27
+ task :sync_event, [:spektrix_event_id, :since, :logger_path] => [:environment, :prepare] do |task, args|
28
+ Rooftop::SpektrixSync::SyncTask.run_events_import(@since, args[:spektrix_event_id])
29
+ end
30
+
31
+
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module Rooftop
2
+ module SpektrixSync
3
+ VERSION = "0.0.2.15"
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ require 'active_support'
2
+ require 'colorize'
3
+
4
+ require "rooftop/spektrix_sync/version"
5
+ require 'require_all'
6
+ require_rel 'spektrix_sync/lib'
7
+
8
+ module Rooftop
9
+ module SpektrixSync
10
+
11
+ class << self
12
+ attr_accessor :logger, :configuration
13
+ end
14
+
15
+ if defined?(::Rails)
16
+ require 'rooftop/spektrix_sync/railtie'
17
+ end
18
+
19
+ require 'rooftop/spektrix_sync/process'
20
+
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rooftop/spektrix_sync/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rooftop-spektrix_sync"
8
+ spec.version = Rooftop::SpektrixSync::VERSION
9
+ spec.authors = ["Ed Jones"]
10
+ spec.email = ["ed@errorstudio.co.uk"]
11
+ spec.summary = %q{A set of tasks to sync events between Spektrix and Rooftop CMS}
12
+ spec.description = %q{A set of tasks to sync events between Spektrix and Rooftop CMS}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_dependency 'colorize'
25
+ spec.add_dependency 'activesupport'
26
+ spec.add_dependency 'require_all'
27
+ spec.add_dependency "rooftop-events"
28
+ spec.add_dependency 'rooftop', '~> 0.1.0'
29
+ spec.add_dependency "spektrix"
30
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rooftop-spektrix_sync
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2.15
5
+ platform: ruby
6
+ authors:
7
+ - Ed Jones
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: colorize
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: require_all
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rooftop-events
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rooftop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.1.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.1.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: spektrix
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: A set of tasks to sync events between Spektrix and Rooftop CMS
126
+ email:
127
+ - ed@errorstudio.co.uk
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".ruby-gemset"
134
+ - ".ruby-version"
135
+ - Gemfile
136
+ - LICENSE.txt
137
+ - README.md
138
+ - Rakefile
139
+ - lib/rooftop/spektrix_sync.rb
140
+ - lib/rooftop/spektrix_sync/lib/event_sync.rb
141
+ - lib/rooftop/spektrix_sync/lib/instance_sync.rb
142
+ - lib/rooftop/spektrix_sync/lib/price_list_sync.rb
143
+ - lib/rooftop/spektrix_sync/lib/sync_task.rb
144
+ - lib/rooftop/spektrix_sync/process.rb
145
+ - lib/rooftop/spektrix_sync/railtie.rb
146
+ - lib/rooftop/spektrix_sync/tasks/import.rake
147
+ - lib/rooftop/spektrix_sync/version.rb
148
+ - rooftop-spektrix_sync.gemspec
149
+ homepage: ''
150
+ licenses:
151
+ - MIT
152
+ metadata: {}
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 2.4.5.1
170
+ signing_key:
171
+ specification_version: 4
172
+ summary: A set of tasks to sync events between Spektrix and Rooftop CMS
173
+ test_files: []