redmine_remotes 0.10.0 → 0.14.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 (36) 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 +13 -3
  4. data/app/models/redmine_remotes/tableless/remote_issue_fetch/base/_local_issue.rb +9 -14
  5. data/app/models/redmine_remotes/tableless/remote_issue_fetch/base/_provider_issue.rb +2 -2
  6. data/app/models/redmine_remotes/tableless/remote_issue_fetch/base/_remote_issue.rb +23 -0
  7. data/app/models/redmine_remotes/tableless/remote_issue_fetch/create.rb +1 -10
  8. data/app/models/redmine_remotes/tableless/remote_issue_fetch/create/_remote_issue.rb +0 -7
  9. data/app/models/redmine_remotes/tableless/remote_issue_fetch/update.rb +0 -8
  10. data/app/models/redmine_remotes/tableless/remote_tracker_fetch.rb +51 -0
  11. data/app/models/redmine_remotes/tableless/remote_tracker_fetch/provider.rb +17 -0
  12. data/app/models/redmine_remotes/tableless/remote_tracker_fetch/remote_issues.rb +31 -0
  13. data/app/models/redmine_remotes/tableless/remote_tracker_fetch/remote_tracker.rb +20 -0
  14. data/app/models/remote_issue.rb +11 -0
  15. data/app/models/remote_issue_status.rb +0 -11
  16. data/app/models/remote_tracker.rb +11 -0
  17. data/app/models/remote_tracker/find_issue_local_status.rb +40 -0
  18. data/app/models/remote_tracker/remote.rb +32 -8
  19. data/config/initializers/001_patches.rb +1 -0
  20. data/config/locales/en.yml +1 -0
  21. data/config/locales/pt-BR.yml +1 -0
  22. data/db/migrate/20200602192120_add_outdated_at_to_remote_issues.rb +7 -0
  23. data/db/migrate/20200602194753_add_fetched_at_to_remote_issues.rb +7 -0
  24. data/db/migrate/20200602203020_add_fetched_at_to_remote_trackers.rb +7 -0
  25. data/lib/redmine_remotes/esosti/entities/issue.rb +8 -0
  26. data/lib/redmine_remotes/esosti/instance.rb +8 -5
  27. data/lib/redmine_remotes/jira/entities/issue.rb +6 -2
  28. data/lib/redmine_remotes/jira/instance.rb +4 -17
  29. data/lib/redmine_remotes/jobs/fetch_issues.rb +31 -0
  30. data/lib/redmine_remotes/jobs/fetch_trackers.rb +30 -0
  31. data/lib/redmine_remotes/patches/avmtrf1_rest_provider_instance.rb +22 -0
  32. data/lib/redmine_remotes/version.rb +1 -1
  33. data/lib/tasks/redmine_remotes.rake +12 -0
  34. metadata +21 -18
  35. data/lib/redmine_remotes/rest_provider/http_response.rb +0 -31
  36. data/lib/redmine_remotes/rest_provider/instance.rb +0 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a0671e339c9e225c9413feb402fed23e0ac5e930a3e72027aa2b183749441d5
4
- data.tar.gz: eb1245a9f15262922b95bec5574bdbb3dbc84f286d7fed371970b759657f6e2d
3
+ metadata.gz: 8b69ffeb75da1b7cdee13641076954cbbab68343584a359b213a607918eb619e
4
+ data.tar.gz: 890479aa66e8d40a76809386d34f56d823c644d0a21aade8e9aaa5308fe05046
5
5
  SHA512:
6
- metadata.gz: 0af87885a31cc69c7ec0cc8f1bbd7201b189b8c5f260382d990189affb7ab642b5eba050231e3e7c0a78f5d65a134c21490148d5461858c61af9ad92c813e578
7
- data.tar.gz: 322120abe8ba4dde501c3d6cccc3a3315933d18f585d4c7eb9a86b8c147ec797c0dcb2bff8b08ac29001466eb12e2824cb29a1ef7394b5db1d8f21cbe4c31778
6
+ metadata.gz: ea705a044abece2d36ea6332ec1b11d28020195c7779e6ca4dc98b5f0d127f97763689bba612e28f281a2fd65522cfcf4adc5b8784e12d896604f0a8e02bef21
7
+ data.tar.gz: ce32ae83e8430cef00ed296e67a0fa905adf33583ffee1869e09a4582ac265c8a7660cad52a0f00868966338bb61ef636cf26c7d31abad2107ddb2e9930a3497
@@ -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
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'eac/model'
3
+ require 'eac_rails_utils/models/fetch_errors'
4
4
  require 'eac_ruby_utils/core_ext'
5
5
 
6
6
  module RedmineRemotes
7
7
  module Tableless
8
8
  module RemoteIssueFetch
9
- class Base < ::EacRailsUtils::TablelessModel
9
+ class Base < ::EacRailsUtils::Models::Tableless
10
10
  enable_simple_cache
11
11
  require_sub __FILE__
12
- include ::Eac::Model
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
@@ -3,7 +3,7 @@
3
3
  module RedmineRemotes
4
4
  module Tableless
5
5
  module RemoteIssueFetch
6
- class Base < ::EacRailsUtils::TablelessModel
6
+ class Base < ::EacRailsUtils::Models::Tableless
7
7
  private
8
8
 
9
9
  def save_local_issue
@@ -54,23 +54,18 @@ module RedmineRemotes
54
54
  end
55
55
 
56
56
  def local_issue_status
57
- local_issue_status_from_remote_tracker || local_issue_status_from_local_tracker
57
+ remote_tracker.try(:find_local_issue_status, local_tracker, provider_issue.status_name,
58
+ true)
58
59
  end
59
60
 
60
- def local_issue_status_from_remote_tracker
61
- ::RemoteIssueStatus.find_local_issue_status(
62
- provider_issue.status_name,
63
- remote_tracker,
64
- local_tracker
65
- )
66
- end
61
+ def local_issue_description
62
+ <<~DESCRIPTION
63
+ #{provider_issue.description}
67
64
 
68
- def local_issue_status_from_local_tracker
69
- local_tracker.default_status
70
- end
65
+ ----
71
66
 
72
- def local_issue_description
73
- provider_issue.description
67
+ _Demanda remota importada de #{provider_issue.human_view_url}._
68
+ DESCRIPTION
74
69
  end
75
70
  end
76
71
  end
@@ -3,14 +3,14 @@
3
3
  module RedmineRemotes
4
4
  module Tableless
5
5
  module RemoteIssueFetch
6
- class Base < ::EacRailsUtils::TablelessModel
6
+ class Base < ::EacRailsUtils::Models::Tableless
7
7
  private
8
8
 
9
9
  def provider_issue_uncached
10
10
  return nil if [remote_tracker, issue_remote_code].any?(&:blank?)
11
11
 
12
12
  remote_tracker.find_remote_issue(issue_remote_code)
13
- rescue ::RedmineRemotes::RestProvider::HttpResponse => e
13
+ rescue ::Avmtrf1::RestProvider::Response => e
14
14
  errors.add(default_error_column,
15
15
  "Requisição a \"#{e.url}\" retornou com status #{e.status}")
16
16
  ::Rails.logger.warn(e.body)
@@ -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,
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_ruby_utils/core_ext'
4
- require 'eac/model'
5
4
 
6
5
  module RedmineRemotes
7
6
  module Tableless
@@ -17,13 +16,6 @@ module RedmineRemotes
17
16
  def default_error_column
18
17
  :remote_issue_id
19
18
  end
20
-
21
- def save
22
- return false unless valid?
23
- return false unless save_local_issue
24
-
25
- true
26
- end
27
19
  end
28
20
  end
29
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
@@ -13,15 +13,4 @@ class RemoteIssueStatus < ActiveRecord::Base
13
13
  validates :remote_tracker, presence: true
14
14
  validates :local_tracker, presence: true
15
15
  validates :local_issue_status, presence: true
16
-
17
- class << self
18
- def find_local_issue_status(remote_name, remote_tracker, local_tracker)
19
- record = ::RemoteIssueStatus.where(
20
- remote_name: remote_name_sanitize(remote_name),
21
- remote_tracker: remote_tracker,
22
- local_tracker: local_tracker
23
- ).first
24
- record ? record.local_issue_status : nil
25
- end
26
- end
27
16
  end
@@ -27,6 +27,17 @@ 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
+
36
+ def find_local_issue_status(local_tracker, remote_status_name, register_not_found = false)
37
+ ::RemoteTracker::FindIssueLocalStatus.new(self, local_tracker, remote_status_name,
38
+ register_not_found).result
39
+ end
40
+
30
41
  def to_s
31
42
  "#{root_url} [#{profile_label}, #{username}]"
32
43
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ class RemoteTracker < ActiveRecord::Base
6
+ class FindIssueLocalStatus
7
+ common_constructor :remote_tracker, :local_tracker, :remote_status_name, :register_not_found
8
+
9
+ # @return [Tracker]
10
+ def result
11
+ result_by_remote_issue_status || result_by_register_not_found || result_by_local_issue_status
12
+ end
13
+
14
+ private
15
+
16
+ def result_by_register_not_found
17
+ return nil unless register_not_found
18
+
19
+ ::RemoteIssueStatus.create!(
20
+ remote_issue_status_find_attributes.merge(local_issue_status: result_by_local_issue_status)
21
+ ).local_issue_status
22
+ end
23
+
24
+ def result_by_remote_issue_status
25
+ ::RemoteIssueStatus.where(remote_issue_status_find_attributes).first.try(:local_issue_status)
26
+ end
27
+
28
+ def result_by_local_issue_status
29
+ local_tracker.default_status
30
+ end
31
+
32
+ def remote_issue_status_find_attributes
33
+ {
34
+ remote_name: ::RemoteIssueStatus.remote_name_sanitize(remote_status_name),
35
+ remote_tracker: remote_tracker,
36
+ local_tracker: local_tracker
37
+ }
38
+ end
39
+ end
40
+ end
@@ -1,19 +1,43 @@
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
+ r = remote_instance_class.new(root_url, username, password)
34
+ r.send('remote_tracker=', self)
35
+ r
36
+ end
15
37
 
16
- ::RedmineRemotes.const_get(profile.capitalize).const_get('Instance')
38
+ def remote_instance_class
39
+ self.class.provider_instance_class(profile)
40
+ end
17
41
  end
18
42
  end
19
43
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'redmine_remotes/patches/avmtrf1_rest_provider_instance'
3
4
  require 'redmine_remotes/patches/issue'
4
5
  require 'redmine_remotes/patches/issue_status'
5
6
  require 'redmine_remotes/patches/project'
@@ -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
@@ -6,6 +6,10 @@ module RedmineRemotes
6
6
  module Esosti
7
7
  module Entities
8
8
  class Issue < ::Avmtrf1::Esosti::Entities::Issue
9
+ def human_view_url
10
+ instance.issue_human_view_url(uid)
11
+ end
12
+
9
13
  def author_login
10
14
  attributes.fetch('CREATEDBY').if_present { |v| v.gsub(/@[^@]+\z/, '') }
11
15
  end
@@ -39,6 +43,10 @@ module RedmineRemotes
39
43
  def subject
40
44
  attributes.fetch('DESCRIPTION')
41
45
  end
46
+
47
+ def uid
48
+ attributes.fetch('TICKETUID').fetch('content')
49
+ end
42
50
  end
43
51
  end
44
52
  end
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'avmtrf1/esosti/instance'
4
+ require 'avmtrf1/esosti/raw_data_sanitizer'
5
+
3
6
  module RedmineRemotes
4
7
  module Esosti
5
- class Instance < ::RedmineRemotes::RestProvider::Instance
8
+ class Instance < ::Avmtrf1::Esosti::Instance
6
9
  ISSUE_ID_PATTERN = /\A(?:ss|in)[0-9]+\z/i.freeze
7
10
 
8
11
  class << self
@@ -14,12 +17,12 @@ module RedmineRemotes
14
17
  end
15
18
  end
16
19
 
17
- def build_service_url(service_url_suffix)
18
- "#{root_url}/maxrest/rest#{service_url_suffix}"
20
+ def issue_human_view_url(ticket_uid)
21
+ "#{root_url}/itsm/ui/?event=loadapp&value=ms_sr&uniqueid=#{ticket_uid}"
19
22
  end
20
23
 
21
- def issue_get_url_suffix(provider_issue_id)
22
- "/os/MS_RMTICKET/?ticketid=#{provider_issue_id}"
24
+ def fetch_issues_changed(start_time, _end_time)
25
+ changed(start_time)
23
26
  end
24
27
  end
25
28
  end
@@ -1,11 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'avmtrf1/rest_provider/entity'
3
+ require 'avmtrf1/jira/entities/issue'
4
4
 
5
5
  module RedmineRemotes
6
6
  module Jira
7
7
  module Entities
8
- class Issue < ::Avmtrf1::RestProvider::Entity
8
+ class Issue < ::Avmtrf1::Jira::Entities::Issue
9
+ def human_view_url
10
+ instance.issue_human_view_url(code)
11
+ end
12
+
9
13
  def code
10
14
  data.fetch('key')
11
15
  end
@@ -1,33 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_ruby_utils/core_ext'
4
+ require 'avmtrf1/jira/instance'
4
5
 
5
6
  module RedmineRemotes
6
7
  module Jira
7
- class Instance < ::RedmineRemotes::RestProvider::Instance
8
- ISSUE_ID_PATTERN = /\A([a-z][a-z0-9]+)\-(\d+)\z/i.freeze
8
+ class Instance < ::Avmtrf1::Jira::Instance
9
9
  DEFAULT_DESCRIPTION_FIELD = 'description'
10
10
 
11
- class << self
12
- def parse_issue_id(global_issue_id)
13
- m = ISSUE_ID_PATTERN.match(global_issue_id)
14
- return nil unless m
15
-
16
- ::OpenStruct.new(provider_issue_id: m[0], project_id: m[1], project_issue_id: m[2])
17
- end
18
- end
19
-
20
- def build_service_url(service_url_suffix)
21
- "#{root_url}/rest/api/latest#{service_url_suffix}"
22
- end
23
-
24
11
  def description_field
25
12
  remote_tracker.setting_value(::RemoteTrackerSetting::NAME_FIELD_DESCRIPTION)
26
13
  .if_present(DEFAULT_DESCRIPTION_FIELD)
27
14
  end
28
15
 
29
- def issue_get_url_suffix(provider_issue_id)
30
- "/issue/#{provider_issue_id}"
16
+ def issue_human_view_url(issue_code)
17
+ "#{root_url}/browse/#{issue_code.to_s.upcase}"
31
18
  end
32
19
  end
33
20
  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
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avmtrf1/rest_provider/instance'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module RedmineRemotes
7
+ module Patches
8
+ module Avmtrf1RestProviderInstance
9
+ common_concern
10
+
11
+ module InstanceMethods
12
+ attr_reader :remote_tracker
13
+
14
+ private
15
+
16
+ attr_writer :remote_tracker
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ ::Avmtrf1::RestProvider::Instance.patch(::RedmineRemotes::Patches::Avmtrf1RestProviderInstance)
@@ -3,7 +3,7 @@
3
3
  module RedmineRemotes
4
4
  SLUG = 'redmine_remotes'
5
5
  NAME = 'Redmine Remotes'
6
- VERSION = '0.10.0'
6
+ VERSION = '0.14.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.10.0
4
+ version: 0.14.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-05-25 00:00:00.000000000 Z
11
+ date: 2020-07-24 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
@@ -64,34 +64,28 @@ dependencies:
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '0.5'
67
+ version: '0.11'
68
68
  type: :runtime
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '0.5'
74
+ version: '0.11'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: eac_ruby_utils
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '0.10'
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- version: 0.10.1
81
+ version: '0.35'
85
82
  type: :runtime
86
83
  prerelease: false
87
84
  version_requirements: !ruby/object:Gem::Requirement
88
85
  requirements:
89
86
  - - "~>"
90
87
  - !ruby/object:Gem::Version
91
- version: '0.10'
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- version: 0.10.1
88
+ version: '0.35'
95
89
  - !ruby/object:Gem::Dependency
96
90
  name: validate_url
97
91
  requirement: !ruby/object:Gem::Requirement
@@ -130,15 +124,21 @@ files:
130
124
  - app/models/redmine_remotes/tableless/remote_issue_fetch/base.rb
131
125
  - app/models/redmine_remotes/tableless/remote_issue_fetch/base/_local_issue.rb
132
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
133
128
  - app/models/redmine_remotes/tableless/remote_issue_fetch/create.rb
134
129
  - app/models/redmine_remotes/tableless/remote_issue_fetch/create/_local_issue.rb
135
130
  - app/models/redmine_remotes/tableless/remote_issue_fetch/create/_remote_issue.rb
136
131
  - app/models/redmine_remotes/tableless/remote_issue_fetch/update.rb
137
132
  - app/models/redmine_remotes/tableless/remote_issue_fetch/update/_local_issue.rb
138
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
139
138
  - app/models/remote_issue.rb
140
139
  - app/models/remote_issue_status.rb
141
140
  - app/models/remote_tracker.rb
141
+ - app/models/remote_tracker/find_issue_local_status.rb
142
142
  - app/models/remote_tracker/remote.rb
143
143
  - app/models/remote_tracker_setting.rb
144
144
  - app/models/remote_user.rb
@@ -163,6 +163,9 @@ files:
163
163
  - db/migrate/20200505153200_add_timestamps_to_redmine_trackers.rb
164
164
  - db/migrate/20200505160938_add_timestamps_to_remote_issues.rb
165
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
166
169
  - init.rb
167
170
  - lib/redmine_remotes.rb
168
171
  - lib/redmine_remotes/esosti.rb
@@ -170,13 +173,14 @@ files:
170
173
  - lib/redmine_remotes/esosti/instance.rb
171
174
  - lib/redmine_remotes/jira/entities/issue.rb
172
175
  - lib/redmine_remotes/jira/instance.rb
176
+ - lib/redmine_remotes/jobs/fetch_issues.rb
177
+ - lib/redmine_remotes/jobs/fetch_trackers.rb
178
+ - lib/redmine_remotes/patches/avmtrf1_rest_provider_instance.rb
173
179
  - lib/redmine_remotes/patches/issue.rb
174
180
  - lib/redmine_remotes/patches/issue_status.rb
175
181
  - lib/redmine_remotes/patches/project.rb
176
182
  - lib/redmine_remotes/patches/tracker.rb
177
183
  - lib/redmine_remotes/patches/user.rb
178
- - lib/redmine_remotes/rest_provider/http_response.rb
179
- - lib/redmine_remotes/rest_provider/instance.rb
180
184
  - lib/redmine_remotes/sanitizer.rb
181
185
  - lib/redmine_remotes/version.rb
182
186
  - lib/tasks/redmine_remotes.rake
@@ -198,8 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
198
202
  - !ruby/object:Gem::Version
199
203
  version: '0'
200
204
  requirements: []
201
- rubyforge_project:
202
- rubygems_version: 2.7.7
205
+ rubygems_version: 3.0.6
203
206
  signing_key:
204
207
  specification_version: 4
205
208
  summary: Integração do Redmine com trackers diversos.
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RedmineRemotes
4
- module RestProvider
5
- class HttpResponse < ::StandardError
6
- class << self
7
- def new_from_curl_easy(curl_easy)
8
- new(
9
- curl_easy.url,
10
- curl_easy.status.to_i,
11
- curl_easy.body_str
12
- )
13
- end
14
- end
15
-
16
- attr_reader :url, :status, :body
17
-
18
- def initialize(url, status, body)
19
- @url = url
20
- @status = status
21
- @body = body
22
- end
23
-
24
- def body_or_raise
25
- return body if status == 200
26
-
27
- raise self
28
- end
29
- end
30
- end
31
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'avmtrf1/rest_provider/instance'
4
- require 'curb'
5
- require 'json'
6
-
7
- module RedmineRemotes
8
- module RestProvider
9
- # Abstract methods
10
- # * parse_issue_id(global_issue_id)
11
- # * self.build_service_url(service_url_suffix)
12
- # * self.issue_get_url_suffix(provider_issue_id)
13
- class Instance < ::Avmtrf1::RestProvider::Instance
14
- attr_reader :remote_tracker
15
-
16
- def initialize(remote_tracker, root_url, username, password)
17
- @remote_tracker = remote_tracker
18
- super(root_url, username, password)
19
- end
20
-
21
- def request(service_url_suffix)
22
- JSON.parse(super(service_url_suffix).body_or_raise)
23
- end
24
-
25
- private
26
-
27
- # @return [RedmineRemotes::RestProvider::HttpResponse]
28
- def curl_perform(curl)
29
- return ::RedmineRemotes::RestProvider::HttpResponse.new_from_curl_easy(curl) if curl.perform
30
-
31
- raise 'Curl failed'
32
- end
33
- end
34
- end
35
- end