dato 0.6.18 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7011e6d97491b0d772ce29bf518411309948246a451495aad4889e09b57e379a
4
- data.tar.gz: a90f2443479ff411ca350514bd17b4f0c78537de9d8c6acf51db0663d4d71529
3
+ metadata.gz: 5ae6a3e8219a9628772a2f4da2bdd5b8024042c765d6ea1582b94c2f86c59f81
4
+ data.tar.gz: 8d56caeecb617c3eda4072c9ff649e596fe4968c1b64b46c639804f23222fbd7
5
5
  SHA512:
6
- metadata.gz: a6036fa4504f4ba21ef83186736d7788b8c6ecb1a3b2a2944f0a51635ef8d0aac4f6fe4ecbe9eb1f7dca9679dc4d7b4c2ded2cafa38cb4526deee60d7ca33d21
7
- data.tar.gz: e605c4e7983a173a78a3432bfe4e3946cbb02666aea85759495ca5a65e40b3de1b85b2eccd556409f395d5a3adc030f16293f5545d7ad131dfe2ec096d808f3c
6
+ metadata.gz: 45fd8ebe07494123845f26eac19162a9c3a53f435607812ff0fa336567993171b73cd4f703d9f1b52f41c9c3758a366788bfde944a18f7aa92e762f8250426d4
7
+ data.tar.gz: 7078abd9cd150a79ca7d264094ef60321574fb4763020e5c473de9530c6e5c285d885ce792d6eea4f522b5a63f360c240c1dd0b3942f309df2912c74a8944ee0
@@ -1,3 +1,7 @@
1
+ # 0.7.0
2
+
3
+ * Real-time events are now much more granular and the gem avoids downloading all the content every time a change occurs
4
+
1
5
  # 0.6.18
2
6
 
3
7
  * Fixed regression where you could no longer access items' item type
@@ -3,7 +3,6 @@
3
3
  require 'thor'
4
4
  require 'dato/dump/runner'
5
5
  require 'dato/dump/ssg_detector'
6
- require 'dato/watch/site_change_watcher'
7
6
  require 'listen'
8
7
  module Dato
9
8
  class Cli < Thor
@@ -26,25 +25,26 @@ module Dato
26
25
  'X-SSG' => Dump::SsgDetector.new(Dir.pwd).detect
27
26
  }
28
27
  )
28
+ loader = Dato::Local::Loader.new(client, preview_mode)
29
+ print 'Fetching content from DatoCMS... '
30
+ loader.load
29
31
 
30
32
  if watch_mode
31
- site_id = client.request(:get, '/site')['data']['id']
32
-
33
33
  semaphore = Mutex.new
34
34
 
35
- thread_safe_dump(semaphore, config_file, client, preview_mode)
35
+ thread_safe_dump(semaphore, config_file, client, preview_mode, loader)
36
36
 
37
- Dato::Watch::SiteChangeWatcher.new(site_id).connect do
38
- thread_safe_dump(semaphore, config_file, client, preview_mode)
37
+ loader.watch do
38
+ thread_safe_dump(semaphore, config_file, client, preview_mode, loader)
39
39
  end
40
40
 
41
41
  watch_config_file(config_file) do
42
- thread_safe_dump(semaphore, config_file, client, preview_mode)
42
+ thread_safe_dump(semaphore, config_file, client, preview_mode, loader)
43
43
  end
44
44
 
45
45
  sleep
46
46
  else
47
- Dump::Runner.new(config_file, client, preview_mode).run
47
+ Dump::Runner.new(config_file, client, preview_mode, loader).run
48
48
  end
49
49
  end
50
50
 
@@ -78,9 +78,9 @@ module Dato
78
78
  ).start
79
79
  end
80
80
 
81
- def thread_safe_dump(semaphore, config_file, client, preview_mode)
81
+ def thread_safe_dump(semaphore, config_file, client, preview_mode, loader)
82
82
  semaphore.synchronize do
83
- Dump::Runner.new(config_file, client, preview_mode).run
83
+ Dump::Runner.new(config_file, client, preview_mode, loader).run
84
84
  end
85
85
  end
86
86
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'dato/dump/format/toml'
4
4
  require 'dato/dump/format/yaml'
5
+ require 'dato/dump/format/json'
5
6
 
6
7
  module Dato
7
8
  module Dump
@@ -8,20 +8,17 @@ require 'dato/local/loader'
8
8
  module Dato
9
9
  module Dump
10
10
  class Runner
11
- attr_reader :config_path, :client, :destination_path, :preview_mode
11
+ attr_reader :config_path, :client, :destination_path, :preview_mode, :loader
12
12
 
13
- def initialize(config_path, client, preview_mode, destination_path = Dir.pwd)
13
+ def initialize(config_path, client, preview_mode, loader, destination_path = Dir.pwd)
14
14
  @config_path = config_path
15
15
  @preview_mode = preview_mode
16
16
  @client = client
17
17
  @destination_path = destination_path
18
+ @loader = loader
18
19
  end
19
20
 
20
21
  def run
21
- print 'Fetching content from DatoCMS... '
22
-
23
- loader.load
24
-
25
22
  I18n.available_locales = loader.items_repo.available_locales
26
23
  I18n.locale = I18n.available_locales.first
27
24
 
@@ -39,10 +36,6 @@ module Dato
39
36
  def operation
40
37
  @operation ||= Operation::Root.new(destination_path)
41
38
  end
42
-
43
- def loader
44
- @loader ||= Dato::Local::Loader.new(client, preview_mode)
45
- end
46
39
  end
47
40
  end
48
41
  end
@@ -9,14 +9,7 @@ module Dato
9
9
 
10
10
  def initialize(*payloads)
11
11
  @entities = {}
12
-
13
- payloads.each do |payload|
14
- EntitiesRepo.payload_entities(payload).each do |entity_payload|
15
- object = JsonApiEntity.new(entity_payload, self)
16
- @entities[object.type] ||= {}
17
- @entities[object.type][object.id] = object
18
- end
19
- end
12
+ upsert_entities(*payloads)
20
13
  end
21
14
 
22
15
  def find_entities_of_type(type)
@@ -27,6 +20,27 @@ module Dato
27
20
  entities.fetch(type, {}).fetch(id, nil)
28
21
  end
29
22
 
23
+ def destroy_entities(type, ids)
24
+ ids.each do |id|
25
+ entities.fetch(type, {}).delete(id)
26
+ end
27
+ end
28
+
29
+ def destroy_item_type(id)
30
+ entities.fetch('item', {}).delete_if { |_item_id, item| item.item_type.id == id }
31
+ entities.fetch('item_type', {}).delete(id)
32
+ end
33
+
34
+ def upsert_entities(*payloads)
35
+ payloads.each do |payload|
36
+ EntitiesRepo.payload_entities(payload).each do |entity_payload|
37
+ object = JsonApiEntity.new(entity_payload, self)
38
+ @entities[object.type] ||= {}
39
+ @entities[object.type][object.id] = object
40
+ end
41
+ end
42
+ end
43
+
30
44
  def self.payload_entities(payload)
31
45
  acc = []
32
46
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pusher-client'
4
+
3
5
  require 'dato/local/entities_repo'
4
6
  require 'dato/local/items_repo'
5
7
 
@@ -11,6 +13,8 @@ module Dato
11
13
  attr_reader :items_repo
12
14
  attr_reader :preview_mode
13
15
 
16
+ PUSHER_API_KEY = '75e6ef0fe5d39f481626'
17
+
14
18
  def initialize(client, preview_mode = false)
15
19
  @client = client
16
20
  @preview_mode = preview_mode
@@ -34,8 +38,122 @@ module Dato
34
38
  @items_repo = ItemsRepo.new(@entities_repo)
35
39
  end
36
40
 
41
+ def watch(&block)
42
+ site_id = client.request(:get, '/site')['data']['id']
43
+
44
+ return if pusher && pusher.connected
45
+
46
+ pusher.subscribe("private-site-#{site_id}")
47
+
48
+ bind_on_item_destroy(&block)
49
+ bind_on_item_upsert(&block)
50
+ bind_on_item_type_upsert(&block)
51
+ bind_on_item_type_destroy(&block)
52
+ bind_on_upload_upsert(&block)
53
+ bind_on_upload_destroy(&block)
54
+
55
+ pusher.connect(true)
56
+ end
57
+
58
+ def stop_watch
59
+ pusher.disconnect if pusher && pusher.connected
60
+ end
61
+
37
62
  private
38
63
 
64
+ def bind_on_item_upsert(&block)
65
+ event_type = preview_mode ? 'preview_mode' : 'published_mode'
66
+
67
+ bind_on("item:#{event_type}:upsert", block) do |data|
68
+ payload = client.items.all(
69
+ {
70
+ 'filter[ids]' => data[:ids].join(','),
71
+ version: item_version
72
+ },
73
+ deserialize_response: false,
74
+ all_pages: true
75
+ )
76
+
77
+ @entities_repo.upsert_entities(payload)
78
+ end
79
+ end
80
+
81
+ def bind_on_item_destroy(&block)
82
+ event_type = preview_mode ? 'preview_mode' : 'published_mode'
83
+
84
+ bind_on("item:#{event_type}:destroy", block) do |data|
85
+ @entities_repo.destroy_entities('item', data[:ids])
86
+ end
87
+ end
88
+
89
+ def bind_on_upload_upsert(&block)
90
+ bind_on("upload:upsert", block) do |data|
91
+ payload = client.uploads.all(
92
+ {
93
+ 'filter[ids]' => data[:ids].join(',')
94
+ },
95
+ deserialize_response: false,
96
+ all_pages: true
97
+ )
98
+
99
+ @entities_repo.upsert_entities(payload)
100
+ end
101
+ end
102
+
103
+ def bind_on_upload_destroy(&block)
104
+ bind_on('upload:destroy', block) do |data|
105
+ @entities_repo.destroy_entities('upload', data[:ids])
106
+ end
107
+ end
108
+
109
+ def bind_on_item_type_upsert(&block)
110
+ bind_on('item_type:upsert', block) do |data|
111
+ data[:ids].each do |id|
112
+ payload = client.item_types.find(id, {}, deserialize_response: false)
113
+ @entities_repo.upsert_entities(payload)
114
+
115
+ payload = client.items.all(
116
+ { 'filter[type]' => id },
117
+ deserialize_response: false,
118
+ all_pages: true
119
+ )
120
+
121
+ @entities_repo.upsert_entities(payload)
122
+ end
123
+ end
124
+ end
125
+
126
+ def bind_on_item_type_destroy(&block)
127
+ bind_on('item_type:destroy', block) do |data|
128
+ data[:ids].each do |id|
129
+ @entities_repo.destroy_item_type(id)
130
+ end
131
+ end
132
+ end
133
+
134
+ def bind_on(event_name, user_block, &block)
135
+ pusher.bind(event_name) do |data|
136
+ parsed_data = JSON.parse(data)
137
+ block.call(parsed_data.deep_symbolize_keys)
138
+ update_items_repo!
139
+ user_block.call
140
+ end
141
+ end
142
+
143
+ def update_items_repo!
144
+ @items_repo = ItemsRepo.new(@entities_repo)
145
+ end
146
+
147
+ def pusher
148
+ PusherClient.logger.level = Logger::WARN
149
+
150
+ @pusher ||= PusherClient::Socket.new(
151
+ PUSHER_API_KEY,
152
+ secure: true,
153
+ auth_method: method(:pusher_auth_method)
154
+ )
155
+ end
156
+
39
157
  def site
40
158
  include = ['item_types', 'item_types.fields']
41
159
  client.request(:get, '/site', include: include)
@@ -43,18 +161,28 @@ module Dato
43
161
 
44
162
  def all_items
45
163
  client.items.all(
46
- { version: preview_mode ? 'latest' : 'published' },
164
+ { version: item_version },
47
165
  deserialize_response: false,
48
166
  all_pages: true
49
167
  )
50
168
  end
51
169
 
52
170
  def all_uploads
53
- client.uploads.all(
54
- { 'filter[type]' => 'used' },
55
- deserialize_response: false,
56
- all_pages: true
57
- )
171
+ client.uploads.all({},
172
+ deserialize_response: false,
173
+ all_pages: true)
174
+ end
175
+
176
+ def item_version
177
+ if preview_mode
178
+ 'latest'
179
+ else
180
+ 'published'
181
+ end
182
+ end
183
+
184
+ def pusher_auth_method(socket_id, channel)
185
+ client.pusher_token(socket_id, channel.name)["auth"]
58
186
  end
59
187
  end
60
188
  end
@@ -20,6 +20,14 @@ module Dato
20
20
  file = Upload::Image.new(self, path_or_url)
21
21
  file.upload
22
22
  end
23
+
24
+ def pusher_token(socket_id, channel)
25
+ request(
26
+ :post,
27
+ "/pusher/authenticate",
28
+ { socket_id: socket_id, channel_name: channel}
29
+ )
30
+ end
23
31
  end
24
32
  end
25
33
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dato
4
- VERSION = '0.6.18'
4
+ VERSION = '0.7.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dato
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.18
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefano Verna
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-30 00:00:00.000000000 Z
11
+ date: 2019-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -456,7 +456,6 @@ files:
456
456
  - lib/dato/utils/meta_tags/twitter_site.rb
457
457
  - lib/dato/utils/seo_tags_builder.rb
458
458
  - lib/dato/version.rb
459
- - lib/dato/watch/site_change_watcher.rb
460
459
  homepage: https://github.com/datocms/ruby-datocms-client
461
460
  licenses:
462
461
  - MIT
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'pusher-client'
4
-
5
- module Dato
6
- module Watch
7
- class SiteChangeWatcher
8
- attr_reader :site_id
9
-
10
- PUSHER_API_KEY = '75e6ef0fe5d39f481626'
11
-
12
- def initialize(site_id)
13
- PusherClient.logger.level = Logger::WARN
14
- @site_id = site_id
15
- @socket = nil
16
- end
17
-
18
- def connect(&block)
19
- return if connected?
20
-
21
- @socket = PusherClient::Socket.new(PUSHER_API_KEY, secure: true)
22
- @socket.subscribe("site-#{site_id}")
23
- @socket.bind('site:change', &block)
24
- @socket.connect(true)
25
-
26
- self
27
- end
28
-
29
- def connected?
30
- @socket && @socket.connected
31
- end
32
-
33
- def disconnect!
34
- connected? && @socket.disconnect
35
- end
36
- end
37
- end
38
- end