rooftop-spektrix_sync 0.0.2.15

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 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: []