redmine_remotes 0.12.0 → 0.13.0

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 (25) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/remote_trackers_controller.rb +4 -1
  3. data/app/models/redmine_remotes/tableless/remote_issue_fetch/base.rb +10 -0
  4. data/app/models/redmine_remotes/tableless/remote_issue_fetch/base/_remote_issue.rb +23 -0
  5. data/app/models/redmine_remotes/tableless/remote_issue_fetch/create.rb +1 -10
  6. data/app/models/redmine_remotes/tableless/remote_issue_fetch/create/_remote_issue.rb +0 -7
  7. data/app/models/redmine_remotes/tableless/remote_issue_fetch/update.rb +0 -7
  8. data/app/models/redmine_remotes/tableless/remote_tracker_fetch.rb +51 -0
  9. data/app/models/redmine_remotes/tableless/remote_tracker_fetch/provider.rb +17 -0
  10. data/app/models/redmine_remotes/tableless/remote_tracker_fetch/remote_issues.rb +31 -0
  11. data/app/models/redmine_remotes/tableless/remote_tracker_fetch/remote_tracker.rb +20 -0
  12. data/app/models/remote_issue.rb +11 -0
  13. data/app/models/remote_tracker.rb +6 -0
  14. data/app/models/remote_tracker/remote.rb +30 -8
  15. data/config/locales/en.yml +1 -0
  16. data/config/locales/pt-BR.yml +1 -0
  17. data/db/migrate/20200602192120_add_outdated_at_to_remote_issues.rb +7 -0
  18. data/db/migrate/20200602194753_add_fetched_at_to_remote_issues.rb +7 -0
  19. data/db/migrate/20200602203020_add_fetched_at_to_remote_trackers.rb +7 -0
  20. data/lib/redmine_remotes/esosti/instance.rb +25 -0
  21. data/lib/redmine_remotes/jobs/fetch_issues.rb +31 -0
  22. data/lib/redmine_remotes/jobs/fetch_trackers.rb +30 -0
  23. data/lib/redmine_remotes/version.rb +1 -1
  24. data/lib/tasks/redmine_remotes.rake +12 -0
  25. metadata +14 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70c4977d8154fa08f7d03093a35dc948c5bd78639a2a2ce42352e58c5d737050
4
- data.tar.gz: 8c56794c3633be3b5e731800025a61a73a8df6e17c50776a87790659e0b3235d
3
+ metadata.gz: 58582fa98456cc3680589a4484b45bda211d8db71b78a47418b2bd3208ca6997
4
+ data.tar.gz: 17d859506c16a9a5529bca6dcec6d5b200e1a0aed24b712b048ae4c254be1671
5
5
  SHA512:
6
- metadata.gz: 546876674ce5856dacf18ed183ddca546dcbdbe2ae17ede908b2512e18af12512f9fd8449d829a82105c654994f62a6a01589c42a2b7e055f5e94a64a182cec2
7
- data.tar.gz: 2e821818b0294b9e8b889612666a7a10c0eb494abe661743bc8f9122ca741285364aea93e679bb30068b73c9aec7f53aa25f1c1e96b95a0ba2d887199509c280
6
+ metadata.gz: 654d4c3c6cf0db58ba7bd17c672dbd2bb88b936496d541f08282f5c09dd859f3b79ef000e8b9e71c834a82cbc73149596597c0d061021711fba933a7d2420925
7
+ data.tar.gz: 8d30c37a42a67e84b1db2d1ba74d1c75008014315d9871935e94059d7ec0ce6018a0b374df03a34941ef8bdb858913b38df002670a5307c1cb2fee811165a253
@@ -14,7 +14,10 @@ class RemoteTrackersController < ApplicationController
14
14
  conf.columns[:password].form_ui = :password
15
15
  conf.columns[:profile].form_ui = :select
16
16
  conf.columns[:default_local_user].form_ui = :select
17
- %w[list show].each { |action| conf.send(action).columns.exclude :password }
17
+ %w[list show].each do |action|
18
+ conf.send(action).columns.exclude :password
19
+ conf.send(action).columns << :fetched_at
20
+ end
18
21
  end
19
22
 
20
23
  private
@@ -11,6 +11,7 @@ module RedmineRemotes
11
11
  require_sub __FILE__
12
12
  include ::EacRailsUtils::Models::FetchErrors
13
13
 
14
+ validates :fetched_at, presence: true
14
15
  validates :local_tracker, presence: true
15
16
  validates :remote_tracker, presence: true
16
17
  validates :issue_remote_code, presence: true
@@ -33,6 +34,15 @@ module RedmineRemotes
33
34
  errors.add(:remote_code,
34
35
  "Demanda remota não encontrada com o código \"#{issue_remote_code}\"")
35
36
  end
37
+
38
+ def save
39
+ ::Issue.transaction do
40
+ return false unless valid?
41
+ return false unless save_local_issue
42
+ return false unless save_remote_issue
43
+ end
44
+ true
45
+ end
36
46
  end
37
47
  end
38
48
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RedmineRemotes
4
+ module Tableless
5
+ module RemoteIssueFetch
6
+ class Base < ::EacRailsUtils::Models::Tableless
7
+ private
8
+
9
+ def fetched_at_uncached
10
+ ::Time.zone.now
11
+ end
12
+
13
+ def save_remote_issue
14
+ remote_issue.fetched_at = fetched_at
15
+ return true if remote_issue.save
16
+
17
+ fetch_record_errors(remote_issue, default_column: default_error_column)
18
+ false
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -19,21 +19,12 @@ module RedmineRemotes
19
19
 
20
20
  validate :tracker_in_project
21
21
 
22
- def create
23
- ::Issue.transaction do
24
- return false unless valid?
25
- return false unless save_local_issue
26
- return false unless create_remote_issue
27
- end
28
- true
29
- end
30
-
31
22
  def default_error_column
32
23
  :issue_remote_code
33
24
  end
34
25
 
35
26
  def save
36
- remote_issue_by_remote_code.present? ? update : create
27
+ remote_issue_by_remote_code.present? ? update : super
37
28
  end
38
29
 
39
30
  def tracker_in_project
@@ -6,13 +6,6 @@ module RedmineRemotes
6
6
  class Create < ::RedmineRemotes::Tableless::RemoteIssueFetch::Base
7
7
  private
8
8
 
9
- def create_remote_issue
10
- return true if remote_issue.save
11
-
12
- fetch_record_errors(remote_issue, default_column: default_error_column)
13
- false
14
- end
15
-
16
9
  def remote_issue_uncached
17
10
  remote_issue_by_remote_code.if_blank do
18
11
  ::RemoteIssue.new(remote_tracker: remote_tracker, remote_code: issue_remote_code,
@@ -16,13 +16,6 @@ module RedmineRemotes
16
16
  def default_error_column
17
17
  :remote_issue_id
18
18
  end
19
-
20
- def save
21
- return false unless valid?
22
- return false unless save_local_issue
23
-
24
- true
25
- end
26
19
  end
27
20
  end
28
21
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module RedmineRemotes
6
+ module Tableless
7
+ class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
8
+ require_sub __FILE__, include_modules: true, require_dependency: true
9
+ enable_simple_cache
10
+ include ::EacRailsUtils::Models::FetchErrors
11
+
12
+ attribute :remote_tracker_id, ::Integer
13
+ belongs_to :remote_tracker, class_name: 'RemoteTracker'
14
+
15
+ validates :remote_tracker, presence: true
16
+ validates :start_time, presence: true
17
+ validates :end_time, presence: true
18
+ validate :remote_tracker_fetchable_validation
19
+
20
+ def save
21
+ ::Issue.transaction do
22
+ return false unless valid?
23
+ return false unless save_remote_issues
24
+ return false unless save_remote_tracker
25
+ end
26
+ true
27
+ end
28
+
29
+ def default_error_column
30
+ :remote_tracker_id
31
+ end
32
+
33
+ private
34
+
35
+ def end_time_uncached
36
+ ::Time.zone.now
37
+ end
38
+
39
+ def start_time_uncached
40
+ remote_tracker.try(:fetched_at) || end_time
41
+ end
42
+
43
+ def remote_tracker_fetchable_validation
44
+ return if remote_tracker.blank?
45
+ return if remote_tracker.fetchable?
46
+
47
+ errors.add(:remote_tracker, "Remote tracker \"#{remote_tracker}\" is not fetchable")
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module RedmineRemotes
6
+ module Tableless
7
+ class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
8
+ module Provider
9
+ private
10
+
11
+ def provider_issues_codes
12
+ remote_tracker.remote_instance.fetch_issues_changed(start_time, end_time)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module RedmineRemotes
6
+ module Tableless
7
+ class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
8
+ module RemoteIssues
9
+ private
10
+
11
+ def save_remote_issues
12
+ remote_issues.all? { |remote_issue| save_remote_issue(remote_issue) }
13
+ end
14
+
15
+ def save_remote_issue(remote_issue)
16
+ return true if remote_issue.update(outdated_at: end_time)
17
+
18
+ fetch_record_errors(remote_issue, default_column: default_error_column)
19
+ false
20
+ end
21
+
22
+ def remote_issues_uncached
23
+ provider_issues_codes.map do |code|
24
+ ::RemoteIssue.where(remote_tracker: remote_tracker,
25
+ remote_code: ::RemoteIssue.remote_code_sanitize(code)).first
26
+ end.reject(&:blank?)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module RedmineRemotes
6
+ module Tableless
7
+ class RemoteTrackerFetch < ::EacRailsUtils::Models::Tableless
8
+ module RemoteTracker
9
+ private
10
+
11
+ def save_remote_tracker
12
+ return true if remote_tracker.update(fetched_at: end_time)
13
+
14
+ fetch_record_errors(remote_tracker, default_column: default_error_column)
15
+ false
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -12,6 +12,17 @@ class RemoteIssue < ActiveRecord::Base
12
12
  validates :remote_tracker, presence: true
13
13
  validates :remote_code, presence: true, uniqueness: { scope: [:remote_tracker] }
14
14
 
15
+ scope :outdated, lambda {
16
+ t = arel_table
17
+ where(
18
+ t[:fetched_at].eq(nil)
19
+ .or(
20
+ t[:outdated_at].not_eq(nil)
21
+ .and(t[:fetched_at].lt(t[:outdated_at]))
22
+ )
23
+ )
24
+ }
25
+
15
26
  def to_s
16
27
  "#{remote_tracker}|#{remote_code}"
17
28
  end
@@ -27,6 +27,12 @@ class RemoteTracker < ActiveRecord::Base
27
27
  validates :password, presence: true
28
28
  validates :default_local_user, presence: true
29
29
 
30
+ scope :fetchable, -> { where(profile: fetchable_profiles) }
31
+
32
+ def fetchable?
33
+ self.class.fetchable_profiles.include?(profile)
34
+ end
35
+
30
36
  def find_local_issue_status(local_tracker, remote_status_name, register_not_found = false)
31
37
  ::RemoteTracker::FindIssueLocalStatus.new(self, local_tracker, remote_status_name,
32
38
  register_not_found).result
@@ -1,19 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'eac_ruby_utils/core_ext'
4
+
3
5
  class RemoteTracker < ActiveRecord::Base
4
6
  module Remote
5
- def find_remote_issue(issue_id)
6
- remote_instance.find_issue(issue_id)
7
- end
7
+ common_concern
8
+
9
+ module ClassMethods
10
+ def fetchable_profiles
11
+ @fetchable_profiles ||= lists.profile.values.select do |profile|
12
+ profile_fetchable?(profile)
13
+ end
14
+ end
8
15
 
9
- def remote_instance
10
- remote_instance_class.new(self, root_url, username, password)
16
+ def profile_fetchable?(profile)
17
+ provider_instance_class(profile).method_defined?(:fetch_issues_changed)
18
+ end
19
+
20
+ def provider_instance_class(profile)
21
+ lists.profile.value_validate!(profile)
22
+
23
+ ::RedmineRemotes.const_get(profile.capitalize).const_get('Instance')
24
+ end
11
25
  end
12
26
 
13
- def remote_instance_class
14
- raise 'Profile blank' if profile.blank?
27
+ module InstanceMethods
28
+ def find_remote_issue(issue_id)
29
+ remote_instance.find_issue(issue_id)
30
+ end
31
+
32
+ def remote_instance
33
+ remote_instance_class.new(self, root_url, username, password)
34
+ end
15
35
 
16
- ::RedmineRemotes.const_get(profile.capitalize).const_get('Instance')
36
+ def remote_instance_class
37
+ self.class.provider_instance_class(profile)
38
+ end
17
39
  end
18
40
  end
19
41
  end
@@ -22,3 +22,4 @@ en:
22
22
  label_remote_issue_statuses: Remote issue statuses
23
23
  label_remote_users: Remote users
24
24
  label_remotes: Remotes
25
+ menu_redmine_remotes: Remotes
@@ -22,3 +22,4 @@ pt-BR:
22
22
  label_remote_issue_statuses: Situações de demandas remotas
23
23
  label_remote_users: Usuários remotos
24
24
  label_remotes: Remotos
25
+ menu_redmine_remotes: Remotos
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddOutdatedAtToRemoteIssues < ActiveRecord::Migration
4
+ def change
5
+ add_column :remote_issues, :outdated_at, :datetime
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddFetchedAtToRemoteIssues < ActiveRecord::Migration
4
+ def change
5
+ add_column :remote_issues, :fetched_at, :timestamp
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddFetchedAtToRemoteTrackers < ActiveRecord::Migration
4
+ def change
5
+ add_column :remote_trackers, :fetched_at, :datetime
6
+ end
7
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'avmtrf1/esosti/raw_data_sanitizer'
4
+
3
5
  module RedmineRemotes
4
6
  module Esosti
5
7
  class Instance < ::RedmineRemotes::RestProvider::Instance
@@ -25,6 +27,29 @@ module RedmineRemotes
25
27
  def issue_human_view_url(ticket_uid)
26
28
  "#{root_url}/itsm/ui/maximo.jsp?event=loadapp&value=ms_viewsr&uniqueid=#{ticket_uid}"
27
29
  end
30
+
31
+ def fetch_issues_changed(start_time, _end_time)
32
+ changed_parse_result(request(changed_url_suffix(start_time)))
33
+ end
34
+
35
+ private
36
+
37
+ def changed_parse_result(raw_data)
38
+ ::Avmtrf1::Esosti::RawDataSanitizer.sanitize(
39
+ raw_data.fetch('TICKETMboSet').fetch('TICKET')
40
+ ).map do |ticket|
41
+ ::RemoteIssue.remote_code_sanitize(ticket.fetch('Attributes').fetch('TICKETID'))
42
+ end
43
+ end
44
+
45
+ def changed_url_suffix(since)
46
+ '/mbo/ticket?_includecols=ticketid&changedate=~gt~' +
47
+ ::CGI.escape(formatted_time(since))
48
+ end
49
+
50
+ def formatted_time(time)
51
+ time.strftime('%FT%T%:z')
52
+ end
28
53
  end
29
54
  end
30
55
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RedmineRemotes
4
+ module Jobs
5
+ class FetchIssues
6
+ enable_simple_cache
7
+
8
+ def run
9
+ ::Rails.logger.info("Issues to fetch: #{issues_to_fetch.count}")
10
+ issues_to_fetch.each { |issue| fetch_issue(issue) }
11
+ end
12
+
13
+ private
14
+
15
+ def issues_to_fetch_uncached
16
+ ::RemoteIssue.outdated
17
+ end
18
+
19
+ def fetch_issue(remote_issue)
20
+ ::Rails.logger.info 'Fetching remote issue ' \
21
+ "\"#{remote_issue}|\##{remote_issue.local_issue.id}\""
22
+ record = ::RedmineRemotes::Tableless::RemoteIssueFetch::Update.new(
23
+ remote_issue: remote_issue
24
+ )
25
+ return if record.save
26
+
27
+ ::Rails.logger.warn "Fetch failed with errors: #{record.errors.messages}"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RedmineRemotes
4
+ module Jobs
5
+ class FetchTrackers
6
+ enable_simple_cache
7
+
8
+ def run
9
+ ::Rails.logger.info("Trackers to fetch: #{trackers_to_fetch.count}")
10
+ trackers_to_fetch.each { |tracker| fetch_tracker(tracker) }
11
+ end
12
+
13
+ private
14
+
15
+ def fetch_tracker(remote_tracker)
16
+ ::Rails.logger.info "Fetch remote tracker \"#{remote_tracker}\"..."
17
+ record = ::RedmineRemotes::Tableless::RemoteTrackerFetch.new(
18
+ remote_tracker: remote_tracker
19
+ )
20
+ return if record.save
21
+
22
+ ::Rails.logger.warn "Fetched failed with errors: #{record.errors.messages}"
23
+ end
24
+
25
+ def trackers_to_fetch_uncached
26
+ ::RemoteTracker.where(profile: ::RemoteTracker::PROFILE_ESOSTI)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -3,7 +3,7 @@
3
3
  module RedmineRemotes
4
4
  SLUG = 'redmine_remotes'
5
5
  NAME = 'Redmine Remotes'
6
- VERSION = '0.12.0'
6
+ VERSION = '0.13.0'
7
7
  AUTHOR = 'Eduardo Henrique Bogoni'
8
8
  SUMMARY = 'Integração do Redmine com trackers diversos.'
9
9
  end
@@ -38,5 +38,17 @@ namespace :redmine_remotes do
38
38
  ::Rails.logger.info "[Failed] #{add.errors.messages.pretty_inspect}"
39
39
  end
40
40
  end
41
+
42
+ desc 'Fetch all remote issues.'
43
+ task fetch: :environment do
44
+ ::RedmineRemotes::Jobs::FetchIssues.new.run
45
+ end
46
+ end
47
+
48
+ namespace :trackers do
49
+ desc 'Fetch all remote trackers.'
50
+ task fetch: :environment do
51
+ ::RedmineRemotes::Jobs::FetchTrackers.new.run
52
+ end
41
53
  end
42
54
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redmine_remotes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo Henrique Bogoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-02 00:00:00.000000000 Z
11
+ date: 2020-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aranha-parsers
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.28'
33
+ version: '0.29'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.28'
40
+ version: '0.29'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: curb
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -124,12 +124,17 @@ files:
124
124
  - app/models/redmine_remotes/tableless/remote_issue_fetch/base.rb
125
125
  - app/models/redmine_remotes/tableless/remote_issue_fetch/base/_local_issue.rb
126
126
  - app/models/redmine_remotes/tableless/remote_issue_fetch/base/_provider_issue.rb
127
+ - app/models/redmine_remotes/tableless/remote_issue_fetch/base/_remote_issue.rb
127
128
  - app/models/redmine_remotes/tableless/remote_issue_fetch/create.rb
128
129
  - app/models/redmine_remotes/tableless/remote_issue_fetch/create/_local_issue.rb
129
130
  - app/models/redmine_remotes/tableless/remote_issue_fetch/create/_remote_issue.rb
130
131
  - app/models/redmine_remotes/tableless/remote_issue_fetch/update.rb
131
132
  - app/models/redmine_remotes/tableless/remote_issue_fetch/update/_local_issue.rb
132
133
  - app/models/redmine_remotes/tableless/remote_issue_fetch/update/_remote_issue.rb
134
+ - app/models/redmine_remotes/tableless/remote_tracker_fetch.rb
135
+ - app/models/redmine_remotes/tableless/remote_tracker_fetch/provider.rb
136
+ - app/models/redmine_remotes/tableless/remote_tracker_fetch/remote_issues.rb
137
+ - app/models/redmine_remotes/tableless/remote_tracker_fetch/remote_tracker.rb
133
138
  - app/models/remote_issue.rb
134
139
  - app/models/remote_issue_status.rb
135
140
  - app/models/remote_tracker.rb
@@ -158,6 +163,9 @@ files:
158
163
  - db/migrate/20200505153200_add_timestamps_to_redmine_trackers.rb
159
164
  - db/migrate/20200505160938_add_timestamps_to_remote_issues.rb
160
165
  - db/migrate/20200505161002_add_timestamps_to_remote_users.rb
166
+ - db/migrate/20200602192120_add_outdated_at_to_remote_issues.rb
167
+ - db/migrate/20200602194753_add_fetched_at_to_remote_issues.rb
168
+ - db/migrate/20200602203020_add_fetched_at_to_remote_trackers.rb
161
169
  - init.rb
162
170
  - lib/redmine_remotes.rb
163
171
  - lib/redmine_remotes/esosti.rb
@@ -165,6 +173,8 @@ files:
165
173
  - lib/redmine_remotes/esosti/instance.rb
166
174
  - lib/redmine_remotes/jira/entities/issue.rb
167
175
  - lib/redmine_remotes/jira/instance.rb
176
+ - lib/redmine_remotes/jobs/fetch_issues.rb
177
+ - lib/redmine_remotes/jobs/fetch_trackers.rb
168
178
  - lib/redmine_remotes/patches/issue.rb
169
179
  - lib/redmine_remotes/patches/issue_status.rb
170
180
  - lib/redmine_remotes/patches/project.rb