infopark_cloud_connector 6.8.3.174.51542603 → 6.9.0.3.197272233
Sign up to get free protection for your applications and to get access to all the features.
- data/app/controllers/rails_connector/objs_controller.rb +44 -9
- data/app/helpers/rails_connector/cms_tag_helper.rb +45 -8
- data/app/helpers/rails_connector/editing_helper.rb +1 -6
- data/app/helpers/rails_connector/widget_helper.rb +13 -0
- data/app/views/rails_connector/_editing_javascript.html.erb +9 -0
- data/app/views/rails_connector/objs/create_widget.html.erb +1 -0
- data/config/routes.rb +6 -1
- data/lib/assets/fonts/infopark_icons-webfont.eot +0 -0
- data/lib/assets/fonts/infopark_icons-webfont.ttf +0 -0
- data/lib/assets/fonts/infopark_icons-webfont.woff +0 -0
- data/lib/assets/images/180x120.gif +0 -0
- data/lib/assets/images/irongrip.png +0 -0
- data/lib/assets/javascripts/infopark_editing.js +11267 -3387
- data/lib/assets/stylesheets/infopark_editing.css +1362 -12
- data/lib/generators/cms/migration/migration_generator.rb +7 -1
- data/lib/rails_connector/backend_not_available.rb +4 -0
- data/lib/rails_connector/basic_obj.rb +27 -1
- data/lib/rails_connector/cloud_engine.rb +13 -1
- data/lib/rails_connector/cms_api_search_request.rb +0 -3
- data/lib/rails_connector/cms_backend.rb +25 -7
- data/lib/rails_connector/cms_cache_storage.rb +4 -4
- data/lib/rails_connector/content_service.rb +36 -12
- data/lib/rails_connector/content_state_caching.rb +0 -18
- data/lib/rails_connector/default_search_request.rb +0 -1
- data/lib/rails_connector/migrations/migrator.rb +4 -1
- data/lib/rails_connector/widget_renderer.rb +41 -0
- data/lib/rails_connector/workspace.rb +4 -0
- data/lib/rails_connector/workspace_data_from_service.rb +35 -0
- metadata +9 -3
@@ -4,12 +4,18 @@ module Cms
|
|
4
4
|
|
5
5
|
source_root File.expand_path('../templates', __FILE__)
|
6
6
|
|
7
|
+
class_option :path,
|
8
|
+
type: :string,
|
9
|
+
default: 'cms/migrate',
|
10
|
+
desc: 'Relative path to Rails.root where to place the migration file. Defaults to "cms/migrate".',
|
11
|
+
banner: 'PATH'
|
12
|
+
|
7
13
|
def self.next_migration_number(dirname)
|
8
14
|
Time.now.utc.strftime('%Y%m%d%H%M%S')
|
9
15
|
end
|
10
16
|
|
11
17
|
def create_migration_file
|
12
|
-
migration_template('migration.rb', "
|
18
|
+
migration_template('migration.rb', "#{options[:path]}/#{file_name}")
|
13
19
|
end
|
14
20
|
end
|
15
21
|
end
|
@@ -666,6 +666,29 @@ module RailsConnector
|
|
666
666
|
data_from_cms.has_custom_attribute?(name.to_s)
|
667
667
|
end
|
668
668
|
|
669
|
+
def widgets(attribute_name)
|
670
|
+
unless (type_of_attribute(attribute_name) == 'widget')
|
671
|
+
raise "Not a widget field: #{attribute_name}."
|
672
|
+
end
|
673
|
+
|
674
|
+
widgets = read_attribute(attribute_name.to_s, false)
|
675
|
+
|
676
|
+
return [] unless widgets.present?
|
677
|
+
|
678
|
+
output_objs = []
|
679
|
+
(widgets['layout'] || []).each do |widget_hash|
|
680
|
+
begin
|
681
|
+
widget_obj = self.class.find(widget_hash['widget'])
|
682
|
+
rescue RailsConnector::ResourceNotFound => e
|
683
|
+
end
|
684
|
+
if widget_obj.present? && widget_obj.path.start_with?("/_widgets/#{id}/")
|
685
|
+
output_objs << widget_obj
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
output_objs
|
690
|
+
end
|
691
|
+
|
669
692
|
private
|
670
693
|
|
671
694
|
attr_accessor :data_from_cms
|
@@ -675,7 +698,10 @@ module RailsConnector
|
|
675
698
|
@attribute_cache = {}
|
676
699
|
end
|
677
700
|
|
678
|
-
def read_attribute(attribute_name)
|
701
|
+
def read_attribute(attribute_name, skip_widgets = true)
|
702
|
+
if skip_widgets && (type_of_attribute(attribute_name) == 'widget')
|
703
|
+
raise "Field #{attribute_name} not (yet) available, since it's a widget"
|
704
|
+
end
|
679
705
|
@attribute_cache.fetch(attribute_name) do
|
680
706
|
(raw_value, attribute_type) = data_from_cms.value_and_type_of(attribute_name)
|
681
707
|
@attribute_cache[attribute_name] =
|
@@ -4,6 +4,18 @@ module ::RailsConnector
|
|
4
4
|
# Specify which file should be precompiled for packaging
|
5
5
|
app.config.assets.precompile += %w( infopark_editing.js infopark_editing.css )
|
6
6
|
end
|
7
|
+
|
8
|
+
initializer "rails issue 4911 workaround" do
|
9
|
+
if Rails.version < '4'
|
10
|
+
max_size = [ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE, 228].min
|
11
|
+
silence_warnings { ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE = max_size }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
initializer "widgets.attach_router" do |app|
|
16
|
+
::RailsConnector::WidgetRenderer.class_eval do
|
17
|
+
include app.routes.url_helpers
|
18
|
+
end
|
19
|
+
end
|
7
20
|
end
|
8
21
|
end
|
9
|
-
|
@@ -3,7 +3,6 @@ module RailsConnector
|
|
3
3
|
# This class provides a basic implementation for accessing the search using the cms api.
|
4
4
|
# It can be activated by making it the superclass of SearchRequest.
|
5
5
|
# It should be customized by subclassing.
|
6
|
-
# @api public
|
7
6
|
class CmsApiSearchRequest
|
8
7
|
|
9
8
|
# Takes +query_string+ and +options+ for accessing Cms Api Search.
|
@@ -12,14 +11,12 @@ module RailsConnector
|
|
12
11
|
#
|
13
12
|
# <tt>:limit</tt>:: The maximum number of hits
|
14
13
|
# <tt>:offset</tt>:: The search offset
|
15
|
-
# @api public
|
16
14
|
def initialize(query_string, options = {})
|
17
15
|
@query_string = query_string
|
18
16
|
@options = options
|
19
17
|
end
|
20
18
|
|
21
19
|
# Accesses Cms Api Search using #query and fetches search hits.
|
22
|
-
# @api public
|
23
20
|
def fetch_hits
|
24
21
|
search_enum = search_results
|
25
22
|
|
@@ -82,17 +82,26 @@ module RailsConnector
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def find_workspace_data_by_id(id)
|
85
|
-
|
85
|
+
workspace_data_from_cache = WorkspaceDataFromService.find_from_cache(id)
|
86
|
+
from_content_state_id = workspace_data_from_cache.try(:content_state_id)
|
87
|
+
|
86
88
|
request_params = {:workspace_id => id}
|
87
89
|
request_params[:content_state_id] = from_content_state_id if from_content_state_id
|
88
|
-
|
90
|
+
|
91
|
+
raw_data = if id == 'published' && workspace_data_from_cache
|
92
|
+
begin
|
93
|
+
ContentService.query('workspaces/query', request_params, timeout: 1)
|
94
|
+
rescue BackendNotAvailable => e
|
95
|
+
warn_backend_not_available(id, from_content_state_id, e.message)
|
96
|
+
return workspace_data_from_cache
|
97
|
+
end
|
98
|
+
else
|
99
|
+
ContentService.query('workspaces/query', request_params)
|
100
|
+
end
|
101
|
+
|
89
102
|
if raw_workspace_data = raw_data['workspace']
|
90
103
|
workspace_data = WorkspaceDataFromService.new(raw_workspace_data)
|
91
|
-
if from_content_state_id != workspace_data.content_state_id
|
92
|
-
ContentStateCaching.store_content_state(workspace_data)
|
93
|
-
ContentStateCaching.store_content_state_id(workspace_data.id,
|
94
|
-
workspace_data.content_state_id)
|
95
|
-
end
|
104
|
+
workspace_data.store_in_cache if from_content_state_id != workspace_data.content_state_id
|
96
105
|
workspace_data
|
97
106
|
end
|
98
107
|
end
|
@@ -198,6 +207,15 @@ module RailsConnector
|
|
198
207
|
raise ArgumentError, "invalid index name '#{index}'" unless VALID_INDEX_NAMES.include?(index)
|
199
208
|
end
|
200
209
|
|
210
|
+
def warn_backend_not_available(workspace_id, content_state_id, error_message)
|
211
|
+
message = <<-EOS
|
212
|
+
Couldn't connect to content service for workspace with id=#{workspace_id} and content_state_id=#{content_state_id}.
|
213
|
+
#{error_message}
|
214
|
+
Serving from cache.
|
215
|
+
EOS
|
216
|
+
Rails.logger.warn(message)
|
217
|
+
end
|
218
|
+
|
201
219
|
end
|
202
220
|
|
203
221
|
end
|
@@ -15,12 +15,12 @@ module CmsCacheStorage
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
cache.read("workspace/#{workspace_id}
|
18
|
+
def read_workspace_data(workspace_id)
|
19
|
+
cache.read("workspace/#{workspace_id}")
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
cache.write("workspace/#{workspace_id}
|
22
|
+
def write_workspace_data(workspace_id, workspace_data)
|
23
|
+
cache.write("workspace/#{workspace_id}", workspace_data)
|
24
24
|
end
|
25
25
|
|
26
26
|
def read_content_state(content_state_id)
|
@@ -1,8 +1,20 @@
|
|
1
1
|
module RailsConnector
|
2
2
|
class ContentService
|
3
3
|
DEFAULT_PROTOCOL = 'https'.freeze
|
4
|
-
|
5
|
-
|
4
|
+
DEFAULT_TIMEOUT = 10.freeze
|
5
|
+
|
6
|
+
SOCKET_ERRORS = [
|
7
|
+
EOFError,
|
8
|
+
Errno::ECONNABORTED,
|
9
|
+
Errno::ECONNREFUSED,
|
10
|
+
Errno::ECONNRESET,
|
11
|
+
Errno::EINVAL,
|
12
|
+
Errno::EPIPE,
|
13
|
+
Errno::ETIMEDOUT,
|
14
|
+
IOError,
|
15
|
+
SocketError,
|
16
|
+
Timeout::Error,
|
17
|
+
].freeze
|
6
18
|
|
7
19
|
class RateLimitExceeded < StandardError
|
8
20
|
def initialize(retry_after)
|
@@ -33,15 +45,16 @@ class ContentService
|
|
33
45
|
class << self
|
34
46
|
@next_request_not_before = nil
|
35
47
|
|
36
|
-
def query(path, payload)
|
48
|
+
def query(path, payload, options={})
|
49
|
+
timeout = options.fetch(:timeout, DEFAULT_TIMEOUT)
|
37
50
|
retry_once_on_socket_error do
|
38
51
|
retry_until_timeout_on_rate_limit_exceeded do
|
39
|
-
ConnectionManager.ensure_started(uri)
|
52
|
+
ConnectionManager.ensure_started(uri, timeout)
|
40
53
|
request = build_request(path, payload)
|
41
54
|
if @next_request_not_before && @next_request_not_before > (now = Time.now)
|
42
55
|
sleep @next_request_not_before - now
|
43
56
|
end
|
44
|
-
handle_response(ConnectionManager.connection.request(request))
|
57
|
+
handle_response(ConnectionManager.connection(timeout).request(request))
|
45
58
|
end
|
46
59
|
end
|
47
60
|
end
|
@@ -57,8 +70,8 @@ class ContentService
|
|
57
70
|
retried = false
|
58
71
|
begin
|
59
72
|
yield
|
60
|
-
rescue *SOCKET_ERRORS
|
61
|
-
raise if retried
|
73
|
+
rescue *SOCKET_ERRORS => e
|
74
|
+
raise BackendNotAvailable.from_socket_error(e) if retried
|
62
75
|
ConnectionManager.ensure_finished
|
63
76
|
retried = true
|
64
77
|
retry
|
@@ -129,7 +142,8 @@ class ContentService
|
|
129
142
|
end
|
130
143
|
|
131
144
|
module ConnectionManager
|
132
|
-
def self.connection
|
145
|
+
def self.connection(timeout=DEFAULT_TIMEOUT)
|
146
|
+
configure_timeout(@connection, timeout) if @connection
|
133
147
|
@connection
|
134
148
|
end
|
135
149
|
|
@@ -137,7 +151,7 @@ class ContentService
|
|
137
151
|
@connection = conn
|
138
152
|
end
|
139
153
|
|
140
|
-
def self.ensure_started(uri)
|
154
|
+
def self.ensure_started(uri, timeout=DEFAULT_TIMEOUT)
|
141
155
|
return if @connection && @connection.started?
|
142
156
|
conn = Net::HTTP.new(uri.host, uri.port)
|
143
157
|
if uri.scheme == 'https'
|
@@ -145,7 +159,10 @@ class ContentService
|
|
145
159
|
conn.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
146
160
|
conn.ca_file = RailsConnector::Configuration.ca_file
|
147
161
|
end
|
148
|
-
|
162
|
+
configure_timeout(conn, timeout)
|
163
|
+
retry_twice_on_socket_error do
|
164
|
+
conn.start
|
165
|
+
end
|
149
166
|
@connection = conn
|
150
167
|
end
|
151
168
|
|
@@ -161,12 +178,19 @@ class ContentService
|
|
161
178
|
attempt = 0
|
162
179
|
begin
|
163
180
|
yield
|
164
|
-
rescue *ContentService::SOCKET_ERRORS
|
165
|
-
raise if attempt == 2
|
181
|
+
rescue *ContentService::SOCKET_ERRORS => e
|
182
|
+
raise BackendNotAvailable.from_socket_error(e) if attempt == 2
|
166
183
|
attempt += 1
|
167
184
|
retry
|
168
185
|
end
|
169
186
|
end
|
187
|
+
|
188
|
+
def configure_timeout(connection, timeout)
|
189
|
+
connection.open_timeout = timeout
|
190
|
+
connection.read_timeout = timeout
|
191
|
+
connection.ssl_timeout = timeout
|
192
|
+
end
|
193
|
+
|
170
194
|
end
|
171
195
|
end
|
172
196
|
end
|
@@ -14,24 +14,6 @@ module ContentStateCaching
|
|
14
14
|
# to the current content state's cache. Default depth is 5.
|
15
15
|
attr_accessor :cache_replication_depth
|
16
16
|
|
17
|
-
# Creates a new content state for given workspace with given ancetor and returns it.
|
18
|
-
def store_content_state(workspace_data)
|
19
|
-
ContentState.create(content_state_id: workspace_data.to_content_state_id,
|
20
|
-
changes: workspace_data.changes,
|
21
|
-
from_content_state_id: workspace_data.from_content_state_id)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Fetches last known content state id for a given workspace id.
|
25
|
-
# Returns nil if there is no content state for that workspace.
|
26
|
-
def find_content_state_id(workspace_id)
|
27
|
-
CmsCacheStorage.read_workspace_content_state_id(workspace_id)
|
28
|
-
end
|
29
|
-
|
30
|
-
# Stores current content state id for workspace with given id.
|
31
|
-
def store_content_state_id(workspace_id, content_state_id)
|
32
|
-
CmsCacheStorage.write_workspace_content_state_id(workspace_id, content_state_id)
|
33
|
-
end
|
34
|
-
|
35
17
|
# Updates caches with data from given workspace.
|
36
18
|
# Should be called every time a new OBJ data has been fetched.
|
37
19
|
def store_obj_data(workspace_data, index, key, data)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
|
3
|
+
class WidgetRenderer < AbstractController::Base
|
4
|
+
include AbstractController::Rendering
|
5
|
+
include AbstractController::Helpers
|
6
|
+
|
7
|
+
helper :cms, "rails_connector/widget"
|
8
|
+
|
9
|
+
self.view_paths = [File.join('app', 'widgets')]
|
10
|
+
|
11
|
+
def initialize(request)
|
12
|
+
@_request = request
|
13
|
+
end
|
14
|
+
|
15
|
+
def show(widget, obj, widget_field_name, container)
|
16
|
+
@widget = widget
|
17
|
+
@obj = obj
|
18
|
+
@widget_field_name = widget_field_name
|
19
|
+
@container = container
|
20
|
+
|
21
|
+
render_to_string "#{widget.obj_class.underscore}/show"
|
22
|
+
end
|
23
|
+
|
24
|
+
def thumbnail(widget_dir)
|
25
|
+
begin
|
26
|
+
render_to_string "#{widget_dir}/thumbnail"
|
27
|
+
rescue ActionView::MissingTemplate => e
|
28
|
+
view_context.widget_thumbnail(
|
29
|
+
widget_dir.titleize,
|
30
|
+
'thumbnail.html.erb does not existing. Please provide one.',
|
31
|
+
view_context.image_tag('180x120.gif')
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def request
|
37
|
+
@_request
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end # module RailsConnector
|
@@ -1,6 +1,14 @@
|
|
1
1
|
module RailsConnector
|
2
2
|
|
3
3
|
class WorkspaceDataFromService
|
4
|
+
# Fetches a workspace data previously store in cache storage.
|
5
|
+
# Returns nil if not found.
|
6
|
+
def self.find_from_cache(id)
|
7
|
+
if data = CmsCacheStorage.read_workspace_data(id)
|
8
|
+
new(data)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
4
12
|
def initialize(data)
|
5
13
|
@data = data
|
6
14
|
end
|
@@ -13,6 +21,10 @@ class WorkspaceDataFromService
|
|
13
21
|
@data["id"]
|
14
22
|
end
|
15
23
|
|
24
|
+
def title
|
25
|
+
@data["title"]
|
26
|
+
end
|
27
|
+
|
16
28
|
# remove this method after DynamoCmsBackend has been removed from the Cloud Connector
|
17
29
|
def content_cache_id=(id)
|
18
30
|
# ignore, since not using content caches
|
@@ -41,6 +53,29 @@ class WorkspaceDataFromService
|
|
41
53
|
def to_content_state_id
|
42
54
|
diff && diff['to_content_state_id']
|
43
55
|
end
|
56
|
+
|
57
|
+
# Serializes and stores a workspace data in cache storage.
|
58
|
+
# Also creates an appropriate content state if needed.
|
59
|
+
def store_in_cache
|
60
|
+
create_content_state if content_state_id
|
61
|
+
CmsCacheStorage.write_workspace_data(id, to_hash)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def to_hash
|
67
|
+
{
|
68
|
+
'id' => id,
|
69
|
+
'revision_id' => revision_id,
|
70
|
+
'title' => title,
|
71
|
+
'content_state_id' => content_state_id,
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def create_content_state
|
76
|
+
ContentState.create(content_state_id: to_content_state_id, changes: changes,
|
77
|
+
from_content_state_id: from_content_state_id)
|
78
|
+
end
|
44
79
|
end
|
45
80
|
|
46
81
|
end # module RailsConnector
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: infopark_cloud_connector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.9.0.3.197272233
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
@@ -73,10 +73,15 @@ files:
|
|
73
73
|
- app/helpers/rails_connector/cms_tag_helper.rb
|
74
74
|
- app/helpers/rails_connector/editing_helper.rb
|
75
75
|
- app/helpers/rails_connector/marker_helper.rb
|
76
|
+
- app/helpers/rails_connector/widget_helper.rb
|
77
|
+
- app/views/rails_connector/_editing_javascript.html.erb
|
78
|
+
- app/views/rails_connector/objs/create_widget.html.erb
|
76
79
|
- config/routes.rb
|
77
80
|
- lib/assets/fonts/infopark_icons-webfont.eot
|
78
81
|
- lib/assets/fonts/infopark_icons-webfont.ttf
|
79
82
|
- lib/assets/fonts/infopark_icons-webfont.woff
|
83
|
+
- lib/assets/images/180x120.gif
|
84
|
+
- lib/assets/images/irongrip.png
|
80
85
|
- lib/assets/javascripts/infopark_editing.js
|
81
86
|
- lib/assets/stylesheets/infopark_editing.css
|
82
87
|
- lib/generators/cms/migration/USAGE
|
@@ -122,6 +127,7 @@ files:
|
|
122
127
|
- lib/rails_connector/obj_data_from_service.rb
|
123
128
|
- lib/rails_connector/obj_search_enumerator.rb
|
124
129
|
- lib/rails_connector/rack_middlewares.rb
|
130
|
+
- lib/rails_connector/widget_renderer.rb
|
125
131
|
- lib/rails_connector/workspace.rb
|
126
132
|
- lib/rails_connector/workspace_data_from_service.rb
|
127
133
|
- lib/rails_connector/workspace_selection_middleware.rb
|
@@ -140,7 +146,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
140
146
|
version: '0'
|
141
147
|
segments:
|
142
148
|
- 0
|
143
|
-
hash:
|
149
|
+
hash: 779053553
|
144
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
151
|
none: false
|
146
152
|
requirements:
|