nexo 0.1.4 → 0.1.6

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -0
  3. data/app/controllers/nexo/element_versions_controller.rb +28 -0
  4. data/app/controllers/nexo/elements_controller.rb +64 -0
  5. data/app/controllers/nexo/folders_controller.rb +41 -0
  6. data/app/controllers/nexo/nexo_controller.rb +5 -0
  7. data/app/jobs/nexo/api_clients.rb +20 -18
  8. data/app/jobs/nexo/base_job.rb +5 -3
  9. data/app/jobs/nexo/delete_remote_resource_job.rb +11 -1
  10. data/app/jobs/nexo/fetch_remote_resource_job.rb +61 -0
  11. data/app/jobs/nexo/folder_check_status_job.rb +10 -0
  12. data/app/jobs/nexo/folder_destroy_job.rb +2 -1
  13. data/app/jobs/nexo/folder_download_job.rb +15 -0
  14. data/app/jobs/nexo/folder_sync_job.rb +6 -0
  15. data/app/jobs/nexo/synchronizable_changed_job.rb +17 -2
  16. data/app/jobs/nexo/update_remote_resource_job.rb +58 -24
  17. data/app/lib/nexo/active_record_google_token_store.rb +3 -3
  18. data/app/lib/nexo/api_client/google_auth_service.rb +11 -6
  19. data/app/lib/nexo/api_client/google_calendar_service.rb +167 -32
  20. data/app/lib/nexo/api_client/google_calendar_sync_service.rb +84 -0
  21. data/app/lib/nexo/element_service.rb +236 -0
  22. data/app/lib/nexo/errors.rb +6 -4
  23. data/app/lib/nexo/event_receiver.rb +4 -0
  24. data/app/lib/nexo/folder_service.rb +55 -28
  25. data/app/lib/nexo/import_remote_element_version.rb +75 -0
  26. data/app/lib/nexo/policy_service.rb +27 -8
  27. data/app/models/concerns/nexo/calendar_event.rb +33 -2
  28. data/app/models/concerns/nexo/synchronizable.rb +25 -9
  29. data/app/models/nexo/client.rb +9 -10
  30. data/app/models/nexo/element.rb +22 -39
  31. data/app/models/nexo/element_version.rb +12 -2
  32. data/app/models/nexo/folder.rb +29 -17
  33. data/app/models/nexo/integration.rb +4 -3
  34. data/app/models/nexo/token.rb +6 -4
  35. data/app/views/layouts/nexo.html.erb +42 -0
  36. data/app/views/nexo/element_versions/show.html.erb +16 -0
  37. data/app/views/nexo/elements/index.html.erb +32 -0
  38. data/app/views/nexo/elements/show.html.erb +56 -0
  39. data/app/views/nexo/folders/index.html.erb +22 -0
  40. data/app/views/nexo/folders/show.html.erb +22 -0
  41. data/config/environment.rb +1 -0
  42. data/config/routes.rb +25 -0
  43. data/config/spring.rb +1 -0
  44. data/db/migrate/20250505192315_create_nexo_clients.rb +1 -1
  45. data/db/migrate/20250506125057_create_nexo_tokens.rb +1 -1
  46. data/db/migrate/20250512025950_create_nexo_elements.rb +2 -2
  47. data/db/migrate/20250604124821_element_sync_status.rb +11 -0
  48. data/db/migrate/20250612002919_google_sync_tokens.rb +5 -0
  49. data/db/migrate/20250623132502_folder_sync_direction.rb +8 -0
  50. data/db/migrate/20250718012839_synchronizable_nullable.rb +6 -0
  51. data/db/seeds.rb +5 -4
  52. data/lib/nexo/engine.rb +22 -5
  53. data/lib/nexo/version.rb +1 -1
  54. metadata +38 -4
  55. data/app/jobs/nexo/sync_element_job.rb +0 -93
  56. data/app/models/concerns/nexo/folder_policy.rb +0 -24
@@ -0,0 +1,42 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= content_for(:title) || "Nexo" %></title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <meta name="apple-mobile-web-app-capable" content="yes">
7
+ <%= csrf_meta_tags %>
8
+ <%= csp_meta_tag %>
9
+
10
+ <%= yield :head %>
11
+
12
+ <style>
13
+ table th {
14
+ font-weight: bold;
15
+ }
16
+ table th, table td {
17
+ border: 1px solid lightgrey;
18
+ padding: 0.4em;
19
+ }
20
+ </style>
21
+ </head>
22
+
23
+ <body>
24
+ <h1><%= link_to "NEXO", root_path %></h1>
25
+ <% flash.each do |flash_type, message| %>
26
+ <% if flash_type == "alert" %>
27
+ <div style="color: red">
28
+ <% else %>
29
+ <div style="color: blue">
30
+ <% end %>
31
+ <%= flash_type %>:
32
+ <%= message %>
33
+ </div>
34
+ <% end %>
35
+ <%= link_to "Folders", folders_path %>
36
+ <%= link_to "Elements", elements_path %>
37
+ |
38
+ <%= link_to "Home", main_app.root_path %>
39
+ <hr>
40
+ <%= yield %>
41
+ </body>
42
+ </html>
@@ -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,32 @@
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>User</th>
9
+ <th>Folder</th>
10
+ <th>Synchronizable</th>
11
+ <th>Status</th>
12
+ <th>Updated at</th>
13
+ <th>Created at</th>
14
+ </tr>
15
+ <% @elements.each do |element| %>
16
+ <tr>
17
+ <td><%= link_to "Show", element_path(element) %></td>
18
+ <td><%= element.folder.integration.user %></td>
19
+ <td><%= element.folder %></td>
20
+ <td><%= "#{element.synchronizable_type}: #{element.synchronizable}" %></td>
21
+ <td><%= element.ne_status %></td>
22
+ <td><%= element.updated_at %></td>
23
+ <td><%= element.created_at %></td>
24
+ </tr>
25
+ <% end %>
26
+ </table>
27
+
28
+ <div class="paginator">
29
+ <%= page_entries_info @elements %>
30
+ <%= paginate @elements %>
31
+ </div>
32
+
@@ -0,0 +1,56 @@
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
+ <br>
21
+
22
+ <h4>Element</h4>
23
+ <pre>
24
+ <%= JSON.pretty_generate @element.as_json %>
25
+ </pre>
26
+
27
+ <h4><%= @element.synchronizable_type %></h4>
28
+ <pre>
29
+ <%= JSON.pretty_generate @element.synchronizable.as_json %>
30
+ </pre>
31
+
32
+ <h3>Versions</h3>
33
+ <table>
34
+ <tr>
35
+ <th></th>
36
+ <th>Origin</th>
37
+ <th>nev_status</th>
38
+ <th>Sequence</th>
39
+ <th>Payload status</th>
40
+ <th>ETag</th>
41
+ <th>Created at</th>
42
+ <th>Updated at</th>
43
+ </tr>
44
+ <% @element.element_versions.order(id: :desc).each do |version| %>
45
+ <tr>
46
+ <td><%= link_to "Show", element_version_path(version) %></td>
47
+ <td><%= version.origin %></td>
48
+ <td><%= version.nev_status %></td>
49
+ <td><%= version.sequence %></td>
50
+ <td><%= version.payload["status"] %></td>
51
+ <td><%= version.etag %></td>
52
+ <td><%= version.created_at %></td>
53
+ <td><%= version.updated_at %></td>
54
+ </tr>
55
+ <% end %>
56
+ </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,27 @@
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
+ end
18
+ end
19
+
20
+ resources :element_versions do
21
+ member do
22
+ post :sync
23
+ end
24
+ end
25
+
26
+ root to: redirect('elements')
2
27
  end
data/config/spring.rb ADDED
@@ -0,0 +1 @@
1
+ Spring.application_root = 'spec/dummy'
@@ -3,7 +3,7 @@ class CreateNexoClients < ActiveRecord::Migration[7.2]
3
3
  create_table :nexo_clients do |t|
4
4
  t.integer :service
5
5
  t.string :secret
6
- t.integer :tcp_status
6
+ t.integer :nc_status
7
7
  t.integer :brand_name
8
8
 
9
9
  t.timestamps
@@ -3,7 +3,7 @@ class CreateNexoTokens < ActiveRecord::Migration[7.2]
3
3
  create_table :nexo_tokens do |t|
4
4
  t.references :integration, null: false, foreign_key: { to_table: :nexo_integrations }
5
5
  t.string :secret
6
- t.integer :tpt_status, null: false
6
+ t.integer :nt_status, null: false
7
7
  t.string :environment, null: false
8
8
 
9
9
  t.timestamps
@@ -5,8 +5,8 @@ class CreateNexoElements < ActiveRecord::Migration[7.2]
5
5
  t.integer :synchronizable_id, null: false, index: true
6
6
  t.string :synchronizable_type, null: false, index: true
7
7
  t.string :uuid
8
- t.boolean :flag_deletion, null: false
9
- t.integer :deletion_reason
8
+ t.boolean :flagged_for_removal, null: false
9
+ t.integer :removal_reason
10
10
  t.boolean :conflicted, null: false, default: false
11
11
  t.datetime :discarded_at, index: true
12
12
 
@@ -0,0 +1,11 @@
1
+ class ElementSyncStatus < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_column :nexo_elements, :ne_status, :integer, null: false
4
+ remove_column :nexo_elements, :conflicted, :boolean, default: false, null: false
5
+
6
+ add_column :nexo_element_versions, :nev_status, :integer, null: false
7
+
8
+ add_index :nexo_element_versions, [:element_id, :sequence], unique: true, where: "sequence IS NOT NULL"
9
+ add_index :nexo_element_versions, [:element_id, :etag], unique: true, where: "etag IS NOT NULL"
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class GoogleSyncTokens < ActiveRecord::Migration[7.2]
2
+ def change
3
+ add_column :nexo_folders, :google_next_sync_token, :string
4
+ end
5
+ 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
@@ -0,0 +1,6 @@
1
+ class SynchronizableNullable < ActiveRecord::Migration[7.2]
2
+ def change
3
+ change_column_null :nexo_elements, :synchronizable_id, true
4
+ change_column_null :nexo_elements, :synchronizable_type, true
5
+ end
6
+ end
data/db/seeds.rb CHANGED
@@ -4,11 +4,11 @@ module Nexo
4
4
 
5
5
  if ENV.fetch('SEED_GOOGLE_APIS_CLIENT_SECRET', nil)
6
6
  client = Client.create!(
7
- tcp_status: 0,
7
+ nc_status: 0,
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:,
@@ -20,9 +20,10 @@ module Nexo
20
20
  Nexo::Token.create!(
21
21
  integration:,
22
22
  secret: ENV.fetch('SEED_GOOGLE_APIS_TOKEN'),
23
- tpt_status: :active,
24
- environment: "development"
23
+ nt_status: :active,
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
@@ -3,10 +3,22 @@ require "google-apis-oauth2_v2"
3
3
  require "google-apis-calendar_v3"
4
4
 
5
5
  module Nexo
6
- def self.folder_policies
6
+ def self.folder_rules
7
7
  ::Nexo::PolicyService.instance
8
8
  end
9
9
 
10
+ def self.plain_logger
11
+ @plain_logger ||=
12
+ ActiveSupport::Logger.new(Rails.root.join("log/nexo-#{Rails.env}.log"))
13
+ .tap { |logger| logger.formatter = ::Logger::Formatter.new }
14
+ .tap { |logger| logger.level = ENV.fetch("NEXO_LOG_LEVEL", "debug") }
15
+ .then { |logger| ActiveSupport::TaggedLogging.new(logger) }
16
+ end
17
+
18
+ def self.logger
19
+ @logger ||= ActiveSupport::BroadcastLogger.new(plain_logger, Rails.logger)
20
+ end
21
+
10
22
  mattr_accessor :api_jobs_throttle
11
23
 
12
24
  # @!visibility private
@@ -19,10 +31,11 @@ module Nexo
19
31
  end
20
32
 
21
33
  initializer "nexo.setup_google_logger" do
22
- Google::Apis.logger = ActiveSupport::Logger.new(Rails.root.join("log/google_apis.log"))
23
- .tap { |logger| logger.formatter = ::Logger::Formatter.new }
24
- .then { |logger| ActiveSupport::TaggedLogging.new(logger) }
25
- # .tap { |logger| logger.push_tags("FOO") }
34
+ # Google::Apis.logger = Nexo.plain_logger
35
+ Google::Apis.logger =
36
+ ActiveSupport::Logger.new(Rails.root.join("log/google_apis.log"))
37
+ .tap { |logger| logger.formatter = ::Logger::Formatter.new }
38
+ .then { |logger| ActiveSupport::TaggedLogging.new(logger) }
26
39
  end
27
40
 
28
41
  initializer "configurar_generators" do
@@ -31,5 +44,9 @@ module Nexo
31
44
  g.orm :active_record
32
45
  end
33
46
  end
47
+
48
+ initializer "nexo.set_factory_paths", after: "factory_bot.set_factory_paths" do
49
+ FactoryBot.definition_file_paths << "#{root}/spec/factories"
50
+ end
34
51
  end
35
52
  end
data/lib/nexo/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # :nocov: non-viable
2
2
  module Nexo
3
- VERSION = "0.1.4"
3
+ VERSION = "0.1.6"
4
4
  end
5
5
  # :nocov:
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
4
+ version: 0.1.6
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-05-23 00:00:00.000000000 Z
11
+ date: 2025-07-18 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,25 @@ 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/nexo.html.erb
132
+ - app/views/nexo/element_versions/show.html.erb
133
+ - app/views/nexo/elements/index.html.erb
134
+ - app/views/nexo/elements/show.html.erb
135
+ - app/views/nexo/folders/index.html.erb
136
+ - app/views/nexo/folders/show.html.erb
137
+ - config/environment.rb
109
138
  - config/routes.rb
139
+ - config/spring.rb
110
140
  - db/migrate/20250505192315_create_nexo_clients.rb
111
141
  - db/migrate/20250505195429_create_nexo_integrations.rb
112
142
  - db/migrate/20250506125057_create_nexo_tokens.rb
113
143
  - db/migrate/20250512025423_create_nexo_folders.rb
114
144
  - db/migrate/20250512025950_create_nexo_elements.rb
115
145
  - db/migrate/20250512030530_create_nexo_element_versions.rb
146
+ - db/migrate/20250604124821_element_sync_status.rb
147
+ - db/migrate/20250612002919_google_sync_tokens.rb
148
+ - db/migrate/20250623132502_folder_sync_direction.rb
149
+ - db/migrate/20250718012839_synchronizable_nullable.rb
116
150
  - db/seeds.rb
117
151
  - lib/nexo.rb
118
152
  - 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