nexo 0.1.5 → 0.1.7
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 +4 -4
- data/README.md +17 -0
- data/app/controllers/nexo/element_versions_controller.rb +26 -0
- data/app/controllers/nexo/elements_controller.rb +70 -0
- data/app/controllers/nexo/folders_controller.rb +41 -0
- data/app/controllers/nexo/nexo_controller.rb +11 -0
- data/app/jobs/nexo/api_clients.rb +20 -18
- data/app/jobs/nexo/base_job.rb +5 -3
- data/app/jobs/nexo/delete_remote_resource_job.rb +23 -1
- data/app/jobs/nexo/fetch_remote_resource_job.rb +61 -0
- data/app/jobs/nexo/folder_check_status_job.rb +10 -0
- data/app/jobs/nexo/folder_destroy_job.rb +2 -1
- data/app/jobs/nexo/folder_download_job.rb +15 -0
- data/app/jobs/nexo/folder_sync_job.rb +6 -0
- data/app/jobs/nexo/synchronizable_changed_job.rb +17 -2
- data/app/jobs/nexo/update_remote_resource_job.rb +56 -26
- data/app/lib/nexo/api_client/google_auth_service.rb +9 -8
- data/app/lib/nexo/api_client/google_calendar_service.rb +162 -38
- data/app/lib/nexo/api_client/google_calendar_sync_service.rb +88 -0
- data/app/lib/nexo/element_service.rb +249 -0
- data/app/lib/nexo/errors.rb +6 -5
- data/app/lib/nexo/event_receiver.rb +4 -0
- data/app/lib/nexo/folder_service.rb +55 -28
- data/app/lib/nexo/import_remote_element_version.rb +75 -0
- data/app/lib/nexo/policy_service.rb +27 -8
- data/app/models/concerns/nexo/calendar_event.rb +39 -2
- data/app/models/concerns/nexo/synchronizable.rb +28 -9
- data/app/models/nexo/element.rb +23 -34
- data/app/models/nexo/element_version.rb +17 -2
- data/app/models/nexo/folder.rb +29 -17
- data/app/models/nexo/integration.rb +0 -3
- data/app/models/nexo/token.rb +2 -0
- data/app/views/layouts/error.html.erb +8 -0
- data/app/views/layouts/nexo.html.erb +40 -0
- data/app/views/nexo/element_versions/show.html.erb +16 -0
- data/app/views/nexo/elements/index.html.erb +40 -0
- data/app/views/nexo/elements/show.html.erb +60 -0
- data/app/views/nexo/folders/index.html.erb +22 -0
- data/app/views/nexo/folders/show.html.erb +22 -0
- data/config/environment.rb +1 -0
- data/config/routes.rb +26 -0
- data/config/spring.rb +1 -0
- data/db/migrate/20250604124821_element_sync_status.rb +13 -0
- data/db/migrate/20250612002919_google_sync_tokens.rb +5 -0
- data/db/migrate/20250623132502_folder_sync_direction.rb +8 -0
- data/db/migrate/20250718012839_synchronizable_nullable.rb +6 -0
- data/db/seeds.rb +3 -2
- data/lib/nexo/engine.rb +26 -5
- data/lib/nexo/version.rb +1 -1
- metadata +39 -4
- data/app/jobs/nexo/sync_element_job.rb +0 -93
- data/app/models/concerns/nexo/folder_policy.rb +0 -24
@@ -0,0 +1,16 @@
|
|
1
|
+
<h1>Element version</h1>
|
2
|
+
<%= link_to "Back to element", element_path(@element_version.element) %>
|
3
|
+
|
4
|
+
<%= form_with(url: sync_element_version_path(@element_version)) do |f| %>
|
5
|
+
<%= hidden_field_tag "operation", "import" %>
|
6
|
+
<%= f.submit "Import" %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<%= form_with(url: sync_element_version_path(@element_version)) do |f| %>
|
10
|
+
<%= hidden_field_tag "operation", "update_remote" %>
|
11
|
+
<%= f.submit "Update remote" %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<pre>
|
15
|
+
<%= JSON.pretty_generate @element_version.as_json %>
|
16
|
+
</pre>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<%= link_to "All", "?" %>
|
2
|
+
<%= link_to "Not synced", "?not_synced=1" %>
|
3
|
+
<%= link_to "Without synchronizable", "?without_synchronizable=1" %>
|
4
|
+
<h1>Elements</h1>
|
5
|
+
<table>
|
6
|
+
<tr>
|
7
|
+
<th></th>
|
8
|
+
<th>ID</th>
|
9
|
+
<th>User</th>
|
10
|
+
<th>Folder</th>
|
11
|
+
<th>Synchronizable</th>
|
12
|
+
<th>Status</th>
|
13
|
+
<th>Updated at</th>
|
14
|
+
<th>Created at</th>
|
15
|
+
<th>Remote status</th>
|
16
|
+
<th>Flagged for removal?</th>
|
17
|
+
<th>Discarded at</th>
|
18
|
+
</tr>
|
19
|
+
<% @elements.each do |element| %>
|
20
|
+
<tr>
|
21
|
+
<td><%= link_to "Show", element_path(element) %></td>
|
22
|
+
<td><%= element.id %></td>
|
23
|
+
<td><%= element.folder.integration.user %></td>
|
24
|
+
<td><%= element.folder %></td>
|
25
|
+
<td><%= truncate "#{element.synchronizable_type}: #{element.synchronizable}", length: 50 %></td>
|
26
|
+
<td><%= element.ne_status %></td>
|
27
|
+
<td><%= element.updated_at %></td>
|
28
|
+
<td><%= element.created_at %></td>
|
29
|
+
<td><%= element.last_remote_version&.remote_status %></td>
|
30
|
+
<td><%= element.flagged_for_removal %></td>
|
31
|
+
<td><%= element.discarded_at %></td>
|
32
|
+
</tr>
|
33
|
+
<% end %>
|
34
|
+
</table>
|
35
|
+
|
36
|
+
<div class="paginator">
|
37
|
+
<%= page_entries_info @elements %>
|
38
|
+
<%= paginate @elements %>
|
39
|
+
<%#= paginate @elements, theme: 'kaminari' %>
|
40
|
+
</div>
|
@@ -0,0 +1,60 @@
|
|
1
|
+
<h1>Element: <%= @element.synchronizable %></h1>
|
2
|
+
|
3
|
+
<%= link_to "Back to list", elements_path %>
|
4
|
+
<br>
|
5
|
+
<%= form_with(url: fetch_remote_element_path(@element)) do |f| %>
|
6
|
+
<%= f.submit "Fetch remote" %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<%= form_with(url: resolve_conflict_element_path(@element)) do |f| %>
|
10
|
+
<%= f.submit "Resolve conflict" %>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<%= form_with(url: modify_local_element_path(@element)) do |f| %>
|
14
|
+
<%= f.submit "Modify" %>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<%= form_with(url: update_status_element_path(@element)) do |f| %>
|
18
|
+
<%= f.submit "Update status" %>
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<%= form_with(url: modify_element_path(@element)) do |f| %>
|
22
|
+
<%= f.button(:operation, value: "delete") { "Delete" } %>
|
23
|
+
<% end %>
|
24
|
+
<br>
|
25
|
+
|
26
|
+
<h4>Element</h4>
|
27
|
+
<pre>
|
28
|
+
<%= JSON.pretty_generate @element.as_json %>
|
29
|
+
</pre>
|
30
|
+
|
31
|
+
<h4><%= @element.synchronizable_type %></h4>
|
32
|
+
<pre>
|
33
|
+
<%= JSON.pretty_generate @element.synchronizable.as_json %>
|
34
|
+
</pre>
|
35
|
+
|
36
|
+
<h3>Versions</h3>
|
37
|
+
<table>
|
38
|
+
<tr>
|
39
|
+
<th></th>
|
40
|
+
<th>Origin</th>
|
41
|
+
<th>nev_status</th>
|
42
|
+
<th>Sequence</th>
|
43
|
+
<th>Payload status</th>
|
44
|
+
<th>ETag</th>
|
45
|
+
<th>Created at</th>
|
46
|
+
<th>Updated at</th>
|
47
|
+
</tr>
|
48
|
+
<% @element.element_versions.order(id: :desc).each do |version| %>
|
49
|
+
<tr>
|
50
|
+
<td><%= link_to "Show", element_version_path(version) %></td>
|
51
|
+
<td><%= version.origin %></td>
|
52
|
+
<td><%= version.nev_status %></td>
|
53
|
+
<td><%= version.sequence %></td>
|
54
|
+
<td><%= version.remote_status %></td>
|
55
|
+
<td><%= version.etag %></td>
|
56
|
+
<td><%= version.created_at %></td>
|
57
|
+
<td><%= version.updated_at %></td>
|
58
|
+
</tr>
|
59
|
+
<% end %>
|
60
|
+
</table>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<h1>Folders</h1>
|
2
|
+
Showing <%= @folders.count %> folders from a total of <%= Nexo::Folder.count %>
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th></th>
|
6
|
+
<th>User</th>
|
7
|
+
<th>Name</th>
|
8
|
+
<th>Status</th>
|
9
|
+
<th>Updated at</th>
|
10
|
+
<th>Created at</th>
|
11
|
+
</tr>
|
12
|
+
<% @folders.each do |folder| %>
|
13
|
+
<tr>
|
14
|
+
<td><%= link_to "Show", folder_path(folder) %></td>
|
15
|
+
<td><%= folder.integration.user %></td>
|
16
|
+
<td><%= folder.name %></td>
|
17
|
+
<td><%= folder.nf_status %></td>
|
18
|
+
<td><%= folder.updated_at %></td>
|
19
|
+
<td><%= folder.created_at %></td>
|
20
|
+
</tr>
|
21
|
+
<% end %>
|
22
|
+
</table>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<h1>Folder: <%= @folder.name %></h1>
|
2
|
+
|
3
|
+
<%= link_to "Back to list", folders_path %>
|
4
|
+
<br>
|
5
|
+
<!--
|
6
|
+
<%= form_with(url: full_sync_folder_path(@folder)) do |f| %>
|
7
|
+
<%= f.submit "Full sync" %>
|
8
|
+
<% end %>
|
9
|
+
<%= form_with(url: incremental_sync_folder_path(@folder)) do |f| %>
|
10
|
+
<%= f.submit "Incremental sync" %>
|
11
|
+
<% end %>
|
12
|
+
-->
|
13
|
+
<%= form_with(url: sync_folder_path(@folder)) do |f| %>
|
14
|
+
<%= f.submit "Sync" %>
|
15
|
+
<% end %>
|
16
|
+
<%= form_with(url: check_status_folder_path(@folder)) do |f| %>
|
17
|
+
<%= f.submit "Check status" %>
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<pre>
|
21
|
+
<%= JSON.pretty_generate @folder.as_json %>
|
22
|
+
</pre>
|
@@ -0,0 +1 @@
|
|
1
|
+
# for vim-rails to get its a rails project
|
data/config/routes.rb
CHANGED
@@ -1,2 +1,28 @@
|
|
1
1
|
Nexo::Engine.routes.draw do
|
2
|
+
resources :folders do
|
3
|
+
member do
|
4
|
+
post :sync
|
5
|
+
post :full_sync
|
6
|
+
post :incremental_sync
|
7
|
+
post :check_status
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
resources :elements do
|
12
|
+
member do
|
13
|
+
post :fetch_remote
|
14
|
+
post :resolve_conflict
|
15
|
+
post :modify_local
|
16
|
+
post :update_status
|
17
|
+
post :modify
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
resources :element_versions do
|
22
|
+
member do
|
23
|
+
post :sync
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
root to: redirect('elements')
|
2
28
|
end
|
data/config/spring.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Spring.application_root = 'spec/dummy'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ElementSyncStatus < ActiveRecord::Migration[7.2]
|
2
|
+
def change
|
3
|
+
add_column :nexo_elements, :ne_status, :integer
|
4
|
+
change_column_null :nexo_elements, :ne_status, false, -1
|
5
|
+
remove_column :nexo_elements, :conflicted, :boolean, default: false, null: false
|
6
|
+
|
7
|
+
add_column :nexo_element_versions, :nev_status, :integer
|
8
|
+
change_column_null :nexo_element_versions, :nev_status, false, -1
|
9
|
+
|
10
|
+
add_index :nexo_element_versions, [:element_id, :sequence], unique: true, where: "sequence IS NOT NULL"
|
11
|
+
add_index :nexo_element_versions, [:element_id, :etag], unique: true, where: "etag IS NOT NULL"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class FolderSyncDirection < ActiveRecord::Migration[7.2]
|
2
|
+
def change
|
3
|
+
add_column :nexo_folders, :sync_direction, :integer
|
4
|
+
change_column_null :nexo_folders, :sync_direction, false, 0
|
5
|
+
|
6
|
+
add_column :nexo_folders, :nf_status, :integer, null: false, default: 0
|
7
|
+
end
|
8
|
+
end
|
data/db/seeds.rb
CHANGED
@@ -8,7 +8,7 @@ module Nexo
|
|
8
8
|
service: "google",
|
9
9
|
secret: JSON.parse(ENV.fetch('SEED_GOOGLE_APIS_CLIENT_SECRET'))
|
10
10
|
)
|
11
|
-
user = User.first
|
11
|
+
user = User.first || FactoryBot.create(:user)
|
12
12
|
integration = Nexo::Integration.create!(
|
13
13
|
user:,
|
14
14
|
client:,
|
@@ -21,8 +21,9 @@ module Nexo
|
|
21
21
|
integration:,
|
22
22
|
secret: ENV.fetch('SEED_GOOGLE_APIS_TOKEN'),
|
23
23
|
nt_status: :active,
|
24
|
-
environment:
|
24
|
+
environment: Rails.env
|
25
25
|
)
|
26
|
+
puts "WARN: token not valid" unless integration.token?
|
26
27
|
end
|
27
28
|
end
|
28
29
|
end
|
data/lib/nexo/engine.rb
CHANGED
@@ -1,13 +1,29 @@
|
|
1
1
|
require "googleauth"
|
2
2
|
require "google-apis-oauth2_v2"
|
3
3
|
require "google-apis-calendar_v3"
|
4
|
+
require "kaminari"
|
4
5
|
|
5
6
|
module Nexo
|
6
|
-
def self.
|
7
|
+
def self.folder_rules
|
7
8
|
::Nexo::PolicyService.instance
|
8
9
|
end
|
9
10
|
|
11
|
+
def self.plain_logger
|
12
|
+
@plain_logger ||=
|
13
|
+
ActiveSupport::Logger.new(Rails.root.join("log/nexo-#{Rails.env}.log"))
|
14
|
+
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
|
15
|
+
.tap { |logger| logger.level = ENV.fetch("NEXO_LOG_LEVEL", "debug") }
|
16
|
+
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.logger
|
20
|
+
@logger ||= ActiveSupport::BroadcastLogger.new(plain_logger, Rails.logger)
|
21
|
+
end
|
22
|
+
|
10
23
|
mattr_accessor :api_jobs_throttle
|
24
|
+
mattr_accessor :admin_controller_parent_class
|
25
|
+
|
26
|
+
self.admin_controller_parent_class = ActionController::Base
|
11
27
|
|
12
28
|
# @!visibility private
|
13
29
|
class Engine < ::Rails::Engine
|
@@ -19,10 +35,11 @@ module Nexo
|
|
19
35
|
end
|
20
36
|
|
21
37
|
initializer "nexo.setup_google_logger" do
|
22
|
-
Google::Apis.logger =
|
23
|
-
|
24
|
-
|
25
|
-
|
38
|
+
# Google::Apis.logger = Nexo.plain_logger
|
39
|
+
Google::Apis.logger =
|
40
|
+
ActiveSupport::Logger.new(Rails.root.join("log/google_apis.log"))
|
41
|
+
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
|
42
|
+
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }
|
26
43
|
end
|
27
44
|
|
28
45
|
initializer "configurar_generators" do
|
@@ -31,5 +48,9 @@ module Nexo
|
|
31
48
|
g.orm :active_record
|
32
49
|
end
|
33
50
|
end
|
51
|
+
|
52
|
+
initializer "nexo.set_factory_paths", after: "factory_bot.set_factory_paths" do
|
53
|
+
FactoryBot.definition_file_paths << "#{root}/spec/factories"
|
54
|
+
end
|
34
55
|
end
|
35
56
|
end
|
data/lib/nexo/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martín Rosso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.14'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: kaminari
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.2'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.2'
|
69
83
|
description:
|
70
84
|
email:
|
71
85
|
- mrosso10@gmail.com
|
@@ -76,13 +90,19 @@ files:
|
|
76
90
|
- MIT-LICENSE
|
77
91
|
- README.md
|
78
92
|
- Rakefile
|
93
|
+
- app/controllers/nexo/element_versions_controller.rb
|
94
|
+
- app/controllers/nexo/elements_controller.rb
|
95
|
+
- app/controllers/nexo/folders_controller.rb
|
96
|
+
- app/controllers/nexo/nexo_controller.rb
|
79
97
|
- app/helpers/nexo/controller_helper.rb
|
80
98
|
- app/jobs/nexo/api_clients.rb
|
81
99
|
- app/jobs/nexo/base_job.rb
|
82
100
|
- app/jobs/nexo/delete_remote_resource_job.rb
|
101
|
+
- app/jobs/nexo/fetch_remote_resource_job.rb
|
102
|
+
- app/jobs/nexo/folder_check_status_job.rb
|
83
103
|
- app/jobs/nexo/folder_destroy_job.rb
|
104
|
+
- app/jobs/nexo/folder_download_job.rb
|
84
105
|
- app/jobs/nexo/folder_sync_job.rb
|
85
|
-
- app/jobs/nexo/sync_element_job.rb
|
86
106
|
- app/jobs/nexo/synchronizable_changed_job.rb
|
87
107
|
- app/jobs/nexo/update_remote_resource_job.rb
|
88
108
|
- app/lib/nexo/active_record_google_token_store.rb
|
@@ -90,14 +110,16 @@ files:
|
|
90
110
|
- app/lib/nexo/api_client/calendar_service.rb
|
91
111
|
- app/lib/nexo/api_client/google_auth_service.rb
|
92
112
|
- app/lib/nexo/api_client/google_calendar_service.rb
|
113
|
+
- app/lib/nexo/api_client/google_calendar_sync_service.rb
|
93
114
|
- app/lib/nexo/api_client/google_dummy_calendar_service.rb
|
115
|
+
- app/lib/nexo/element_service.rb
|
94
116
|
- app/lib/nexo/errors.rb
|
95
117
|
- app/lib/nexo/event_receiver.rb
|
96
118
|
- app/lib/nexo/folder_service.rb
|
119
|
+
- app/lib/nexo/import_remote_element_version.rb
|
97
120
|
- app/lib/nexo/policy_service.rb
|
98
121
|
- app/lib/nexo/service_builder.rb
|
99
122
|
- app/models/concerns/nexo/calendar_event.rb
|
100
|
-
- app/models/concerns/nexo/folder_policy.rb
|
101
123
|
- app/models/concerns/nexo/synchronizable.rb
|
102
124
|
- app/models/nexo/application_record.rb
|
103
125
|
- app/models/nexo/client.rb
|
@@ -106,13 +128,26 @@ files:
|
|
106
128
|
- app/models/nexo/folder.rb
|
107
129
|
- app/models/nexo/integration.rb
|
108
130
|
- app/models/nexo/token.rb
|
131
|
+
- app/views/layouts/error.html.erb
|
132
|
+
- app/views/layouts/nexo.html.erb
|
133
|
+
- app/views/nexo/element_versions/show.html.erb
|
134
|
+
- app/views/nexo/elements/index.html.erb
|
135
|
+
- app/views/nexo/elements/show.html.erb
|
136
|
+
- app/views/nexo/folders/index.html.erb
|
137
|
+
- app/views/nexo/folders/show.html.erb
|
138
|
+
- config/environment.rb
|
109
139
|
- config/routes.rb
|
140
|
+
- config/spring.rb
|
110
141
|
- db/migrate/20250505192315_create_nexo_clients.rb
|
111
142
|
- db/migrate/20250505195429_create_nexo_integrations.rb
|
112
143
|
- db/migrate/20250506125057_create_nexo_tokens.rb
|
113
144
|
- db/migrate/20250512025423_create_nexo_folders.rb
|
114
145
|
- db/migrate/20250512025950_create_nexo_elements.rb
|
115
146
|
- db/migrate/20250512030530_create_nexo_element_versions.rb
|
147
|
+
- db/migrate/20250604124821_element_sync_status.rb
|
148
|
+
- db/migrate/20250612002919_google_sync_tokens.rb
|
149
|
+
- db/migrate/20250623132502_folder_sync_direction.rb
|
150
|
+
- db/migrate/20250718012839_synchronizable_nullable.rb
|
116
151
|
- db/seeds.rb
|
117
152
|
- lib/nexo.rb
|
118
153
|
- lib/nexo/engine.rb
|
@@ -1,93 +0,0 @@
|
|
1
|
-
module Nexo
|
2
|
-
# Handles synchronization of an Element. Its called anytime there is an internal or external change
|
3
|
-
#
|
4
|
-
# Always must be executed asynchronously to ensure the concurrency limit applies
|
5
|
-
#
|
6
|
-
# Responsabilities:
|
7
|
-
# - Triggering the DeleteRemoteResourceJob
|
8
|
-
# - Triggering the UpdateRemoteResourceJob
|
9
|
-
# - Removing/discarding Element's
|
10
|
-
# - Flagging Synchronizable's as conflicted
|
11
|
-
# - Updating Synchronizable's on external incoming changes
|
12
|
-
#
|
13
|
-
# TODO: implement external ElementVersion creation, not here, on another place
|
14
|
-
class SyncElementJob < BaseJob
|
15
|
-
limits_concurrency key: ->(element) { element.to_gid }
|
16
|
-
|
17
|
-
# TODO!: set priority based on date distance to today
|
18
|
-
|
19
|
-
# discard_on Errors::SyncElementJobError
|
20
|
-
# retry_on StandardError, wait: :polynomially_longer
|
21
|
-
|
22
|
-
def perform(element)
|
23
|
-
validate_element_state!(element)
|
24
|
-
|
25
|
-
if element.flagged_for_deletion?
|
26
|
-
DeleteRemoteResourceJob.perform_later(element)
|
27
|
-
|
28
|
-
element.discard!
|
29
|
-
else
|
30
|
-
current_sequence = element.synchronizable.sequence
|
31
|
-
last_synced_sequence = element.last_synced_sequence
|
32
|
-
|
33
|
-
if element.external_unsynced_change?
|
34
|
-
# :nocov: TODO
|
35
|
-
raise Errors::SyncElementJobError, "not yet implemented"
|
36
|
-
# :nocov:
|
37
|
-
|
38
|
-
# if current_sequence == last_synced_sequence
|
39
|
-
# sync_to_local_element(element)
|
40
|
-
# elsif current_sequence > last_synced_sequence
|
41
|
-
# element.flag_as_conflicted!
|
42
|
-
# else
|
43
|
-
# # :nocov: type: borderline
|
44
|
-
# report_sequence_bigger_than_current_one!
|
45
|
-
# # :nocov:
|
46
|
-
# end
|
47
|
-
else
|
48
|
-
if current_sequence == last_synced_sequence
|
49
|
-
# TODO: log "Element already synced: #{element.to_gid}"
|
50
|
-
elsif current_sequence > last_synced_sequence
|
51
|
-
UpdateRemoteResourceJob.perform_later(element)
|
52
|
-
else
|
53
|
-
# :nocov: borderline
|
54
|
-
raise Errors::LastSyncedSequenceBiggerThanCurrentOne, element
|
55
|
-
# :nocov:
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def validate_element_state!(element)
|
64
|
-
if element.discarded?
|
65
|
-
# TODO: maybe check the case of external incoming changes to flag the element as conflicted
|
66
|
-
raise Errors::ElementDiscarded, element
|
67
|
-
end
|
68
|
-
|
69
|
-
if element.synchronizable.blank? && !element.flagged_for_deletion?
|
70
|
-
# element should have been flagged for deletion
|
71
|
-
raise Errors::SynchronizableNotFound, element
|
72
|
-
end
|
73
|
-
|
74
|
-
if element.conflicted?
|
75
|
-
raise Errors::ElementConflicted, element
|
76
|
-
end
|
77
|
-
|
78
|
-
if element.synchronizable.present? && element.synchronizable.conflicted?
|
79
|
-
raise Errors::SynchronizableConflicted, element
|
80
|
-
end
|
81
|
-
|
82
|
-
if element.synchronizable.present? && element.synchronizable.sequence.nil?
|
83
|
-
raise Errors::SynchronizableSequenceIsNull, element
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# def sync_to_local_element(element)
|
88
|
-
# last_external_unsynced_version = element.last_external_unsynced_version
|
89
|
-
|
90
|
-
# element.synchronizable.update_from!(last_external_unsynced_version)
|
91
|
-
# end
|
92
|
-
end
|
93
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module Nexo
|
2
|
-
module FolderPolicy
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
# include ActiveModel::Model
|
5
|
-
include ActiveModel::Validations
|
6
|
-
|
7
|
-
# TODO: add belongs_to :folder ?
|
8
|
-
|
9
|
-
# validates_inclusion_of :sync_policy, in: %w( include exclude )
|
10
|
-
# TODO!: check if this is being used
|
11
|
-
included do
|
12
|
-
validates :sync_policy, inclusion: { in: %w[ bla ] }
|
13
|
-
validates :priority, numericality: true
|
14
|
-
end
|
15
|
-
|
16
|
-
def match?(synchronizable)
|
17
|
-
# :nocov: borderline
|
18
|
-
raise "must be implemented in subclass"
|
19
|
-
# :nocov:
|
20
|
-
end
|
21
|
-
|
22
|
-
attr_reader :priority, :sync_policy
|
23
|
-
end
|
24
|
-
end
|