redmine_remotes 0.10.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
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