1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
# frozen_string_literal: true
require 'uri'
module Integrations
class Irker < Integration
validates :recipients, presence: true, if: :validate_recipients?
before_validation :get_channels
field :server_host,
placeholder: 'localhost',
title: -> { s_('IrkerService|Server host (optional)') },
help: -> { s_('IrkerService|irker daemon hostname (defaults to localhost).') }
field :server_port,
placeholder: 6659,
title: -> { s_('IrkerService|Server port (optional)') },
help: -> { s_('IrkerService|irker daemon port (defaults to 6659).') }
field :default_irc_uri,
title: -> { s_('IrkerService|Default IRC URI (optional)') },
help: -> { s_('IrkerService|URI to add before each recipient.') },
placeholder: 'irc://irc.network.net:6697/'
field :recipients,
type: 'textarea',
title: -> { s_('IrkerService|Recipients') },
placeholder: 'irc[s]://irc.network.net[:port]/#channel',
required: true,
help: -> do
recipients_docs_link = ActionController::Base.helpers.link_to(
s_('IrkerService|How to enter channels or users?'),
Rails.application.routes.url_helpers.help_page_url(
'user/project/integrations/irker',
anchor: 'enter-irker-recipients'
),
target: '_blank', rel: 'noopener noreferrer'
)
ERB::Util.html_escape(
s_('IrkerService|Channels and users separated by whitespaces. %{recipients_docs_link}')
) % {
recipients_docs_link: recipients_docs_link.html_safe
}
end
field :colorize_messages,
type: 'checkbox',
title: -> { _('Colorize messages') }
# NOTE: This field is only used internally to store the parsed
# channels from the `recipients` field, it should not be exposed
# in the UI or API.
prop_accessor :channels
def title
s_('IrkerService|irker (IRC gateway)')
end
def description
s_('IrkerService|Send update messages to an irker server.')
end
def self.to_param
'irker'
end
def self.supported_events
%w[push]
end
def execute(data)
return unless supported_events.include?(data[:object_kind])
Integrations::IrkerWorker.perform_async(
project_id, channels,
colorize_messages, data, settings
)
end
def settings
{
server_host: server_host.presence || 'localhost',
server_port: server_port.presence || 6659
}
end
def help
docs_link = ActionController::Base.helpers.link_to(
_('Learn more.'),
Rails.application.routes.url_helpers.help_page_url(
'user/project/integrations/irker',
anchor: 'set-up-an-irker-daemon'
),
target: '_blank',
rel: 'noopener noreferrer'
)
format(s_(
'IrkerService|Send update messages to an irker server. ' \
'Before you can use this, you need to set up the irker daemon. %{docs_link}'
).html_safe, docs_link: docs_link.html_safe)
end
private
def get_channels
return true unless activated?
return true if recipients.nil? || recipients.empty?
map_recipients
errors.add(:recipients, 'are all invalid') if channels.empty?
true
end
def map_recipients
self.channels = recipients.split(/\s+/).map do |recipient|
format_channel(recipient)
end
channels.reject!(&:nil?)
end
def format_channel(recipient)
uri = nil
# Try to parse the chan as a full URI
begin
uri = consider_uri(URI.parse(recipient))
rescue URI::InvalidURIError
end
unless uri.present? && default_irc_uri.nil?
begin
new_recipient = URI.join(default_irc_uri, '/', recipient).to_s
uri = consider_uri(URI.parse(new_recipient))
rescue StandardError
log_error("Unable to create a valid URL", default_irc_uri: default_irc_uri, recipient: recipient)
end
end
uri
end
def consider_uri(uri)
return unless uri.is_a?(URI) && uri.scheme.present?
# Authorize both irc://domain.com/#chan and irc://domain.com/chan
return unless uri.scheme =~ /\Aircs?\z/ && !uri.path.nil?
uri.to_s
end
end
end
|