prelands_rails 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +1456 -0
- data/LICENSE.txt +21 -0
- data/Makefile +4 -0
- data/README.md +4 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/prelands_rails/concerns/abstract_interactor.rb +48 -0
- data/lib/prelands_rails/concerns/base.rb +25 -0
- data/lib/prelands_rails/concerns/can_handle_errors.rb +31 -0
- data/lib/prelands_rails/concerns/hash.rb +11 -0
- data/lib/prelands_rails/concerns/my_aws_client.rb +123 -0
- data/lib/prelands_rails/create_simple_source/check_zip_files/detect_absent_files.rb +25 -0
- data/lib/prelands_rails/create_simple_source/check_zip_files/extract_files.rb +31 -0
- data/lib/prelands_rails/create_simple_source/check_zip_files.rb +79 -0
- data/lib/prelands_rails/create_simple_source/compile/html_compiler.rb +106 -0
- data/lib/prelands_rails/create_simple_source/compile.rb +44 -0
- data/lib/prelands_rails/create_simple_source/create_record.rb +44 -0
- data/lib/prelands_rails/create_simple_source/detect_incoming_locales.rb +35 -0
- data/lib/prelands_rails/create_simple_source/upload/uploader.rb +47 -0
- data/lib/prelands_rails/create_simple_source/upload.rb +83 -0
- data/lib/prelands_rails/create_simple_source/validate_zip_content/validate_html/html.rb +115 -0
- data/lib/prelands_rails/create_simple_source/validate_zip_content/validate_html.rb +40 -0
- data/lib/prelands_rails/create_simple_source/validate_zip_content/validate_js/js.rb +62 -0
- data/lib/prelands_rails/create_simple_source/validate_zip_content/validate_js.rb +32 -0
- data/lib/prelands_rails/create_simple_source/validate_zip_content.rb +26 -0
- data/lib/prelands_rails/create_simple_source.rb +48 -0
- data/lib/prelands_rails/update_simple_source/check_zip_files.rb +39 -0
- data/lib/prelands_rails/update_simple_source/compile.rb +38 -0
- data/lib/prelands_rails/update_simple_source/update_record.rb +41 -0
- data/lib/prelands_rails/update_simple_source/upload/delete_compiled_files.rb +30 -0
- data/lib/prelands_rails/update_simple_source/upload.rb +43 -0
- data/lib/prelands_rails/update_simple_source/validate_zip_content.rb +35 -0
- data/lib/prelands_rails/update_simple_source.rb +48 -0
- data/lib/prelands_rails/validate_simple_source.rb +26 -0
- data/lib/prelands_rails/version.rb +3 -0
- data/lib/prelands_rails.rb +41 -0
- data/prelands_rails.gemspec +48 -0
- metadata +314 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class CreateSimpleSource
|
5
|
+
class Upload
|
6
|
+
#
|
7
|
+
# Загрузчик файлов на AWS.
|
8
|
+
#
|
9
|
+
class Uploader
|
10
|
+
def initialize(creds, aws_prefix, client_class = ::PrelandsRails::MyAwsClient)
|
11
|
+
@folder = aws_prefix
|
12
|
+
@client = client_class.new creds[:access_key], creds[:secret_key], creds[:region]
|
13
|
+
end
|
14
|
+
|
15
|
+
# На вход подан путь к файлу на хосте, который грузим на aws с указанным именем.
|
16
|
+
#
|
17
|
+
# @param [String] file_path
|
18
|
+
# @param [String] s3_file_name
|
19
|
+
# @param [String] bucket_name
|
20
|
+
|
21
|
+
def upload_file(s3_file_name, file_path, bucket_name)
|
22
|
+
@client.upload_file file_path, path(s3_file_name), bucket_name
|
23
|
+
end
|
24
|
+
|
25
|
+
# На вход подана строка +file_content+. Сохраняем её, как файл с указанным именем.
|
26
|
+
#
|
27
|
+
# @param [String] s3_file_name
|
28
|
+
# @param [String] file_content
|
29
|
+
# @param [String] bucket_name
|
30
|
+
|
31
|
+
def upload_content(s3_file_name, file_content, bucket_name)
|
32
|
+
Tempfile.create(SecureRandom.uuid) do |file|
|
33
|
+
file.write file_content.force_encoding('utf-8')
|
34
|
+
file.close
|
35
|
+
@client.upload_file file.path, path(s3_file_name), bucket_name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def path(file)
|
42
|
+
[@folder, file].join('/')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class CreateSimpleSource
|
5
|
+
#
|
6
|
+
# Загрузит на aws скомпилированные html, icon.ico, index.js и содержимое директории images/
|
7
|
+
#
|
8
|
+
class Upload
|
9
|
+
include ::PrelandsRails::AbstractInteractor
|
10
|
+
include ::Interactor
|
11
|
+
include ::Interactor::Contracts
|
12
|
+
include ::PrelandsRails::Base
|
13
|
+
|
14
|
+
expects do
|
15
|
+
required(:archive).filled # Входящий архив с исходниками от фрилансера. Rack::Test::UploadedFile | ActionDispatch::Http::UploadedFile
|
16
|
+
required(:compiled_htmls).value(type?: Hash) # скомпилированные исходники { file_name[String] => compiled_content[String], ... }
|
17
|
+
required(:s3_credentials).schema do
|
18
|
+
required(:access_key).filled(:str?)
|
19
|
+
required(:secret_key).filled(:str?)
|
20
|
+
required(:region).filled(:str?)
|
21
|
+
end
|
22
|
+
required(:bucket_names).value(type?: Array)
|
23
|
+
required(:aws_prefix).value(type?: String)
|
24
|
+
required(:files_content).value(type?: Hash) # { file_name => file_content, ... }
|
25
|
+
end
|
26
|
+
|
27
|
+
assures do
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
before do
|
32
|
+
@uploader = Uploader.new(context.s3_credentials, context.aws_prefix)
|
33
|
+
end
|
34
|
+
|
35
|
+
def act
|
36
|
+
context.bucket_names.each do |bucket_name|
|
37
|
+
images_files.map do |file_name, file_path|
|
38
|
+
@uploader.upload_file file_name, file_path, bucket_name
|
39
|
+
end
|
40
|
+
|
41
|
+
compiled_html_files.map do |file_name, content|
|
42
|
+
@uploader.upload_content file_name, content, bucket_name
|
43
|
+
end
|
44
|
+
|
45
|
+
@uploader.upload_content 'index.js', context.files_content['index.js'], bucket_name
|
46
|
+
end
|
47
|
+
|
48
|
+
del_tmp_files
|
49
|
+
context.uploaded_images = images_files
|
50
|
+
end
|
51
|
+
|
52
|
+
on_breach { |breaches| bad_expects breaches }
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
IMAGES = /\A(images\/.+|icon\.ico)\z/
|
57
|
+
|
58
|
+
def images_files
|
59
|
+
return @images_files if defined?(@images_files)
|
60
|
+
|
61
|
+
@tmp_paths = []
|
62
|
+
|
63
|
+
@images_files ||= Zip::File.open(context.archive.tempfile) do |zipfile|
|
64
|
+
zipfile.map do |entry|
|
65
|
+
next if entry.name.index(IMAGES) != 0
|
66
|
+
|
67
|
+
tmp_path = Rails.root.join make_tmp_path
|
68
|
+
entry.extract tmp_path
|
69
|
+
@tmp_paths << tmp_path
|
70
|
+
|
71
|
+
[entry.name, tmp_path]
|
72
|
+
end.compact.to_h
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def del_tmp_files
|
77
|
+
@tmp_paths.each do |path|
|
78
|
+
File.delete(path) if File.exists?(path)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class CreateSimpleSource
|
5
|
+
class ValidateZipContent
|
6
|
+
class ValidateHtml
|
7
|
+
#
|
8
|
+
# Принимает строку с html разметкой и валидирует её.
|
9
|
+
#
|
10
|
+
class Html
|
11
|
+
attr_reader :errors
|
12
|
+
|
13
|
+
# @param [String] string Содержимое html файла.
|
14
|
+
def initialize(string, continue_id)
|
15
|
+
@errors = []
|
16
|
+
@continue_id = continue_id
|
17
|
+
@string = string.gsub(/(\r\n?|\n)/, '') # убираем переносы, мешающие регуляркам
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid?
|
21
|
+
@errors = [
|
22
|
+
check_internal_scripts,
|
23
|
+
check_internal_styles,
|
24
|
+
check_continue_element,
|
25
|
+
check_js_plug,
|
26
|
+
check_css_plug,
|
27
|
+
check_title_presence,
|
28
|
+
check_a_hrefs,
|
29
|
+
check_favicon
|
30
|
+
].compact
|
31
|
+
|
32
|
+
!@errors.any?
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @return [nil] Если внутри html НЕ содержится JavaScript код в виде <script>...</script>
|
38
|
+
# @return [String] Иначе - вернёт сообщение об ошибке
|
39
|
+
def check_internal_scripts
|
40
|
+
rx = /<script[^>]*>([^<]+)<\/script>/
|
41
|
+
return unless any(rx)
|
42
|
+
|
43
|
+
'A JavaScript code is detected inside html-file. Please, move it to index.js.'
|
44
|
+
end
|
45
|
+
|
46
|
+
def check_internal_styles
|
47
|
+
rx = /<style[^>]*>([^<]+)<\/style>/
|
48
|
+
return unless any(rx)
|
49
|
+
|
50
|
+
'An internal CSS is detected inside html-file. Please, move it to index.css.'
|
51
|
+
end
|
52
|
+
|
53
|
+
def check_continue_element
|
54
|
+
rx = Regexp.new('id="%s"' % @continue_id)
|
55
|
+
res = @string.scan(rx).flatten
|
56
|
+
return if res.size == 1
|
57
|
+
|
58
|
+
return 'The continue element with id="%s" must be uniq. Found %s matches.' % [@continue_id, res.size] if res.size > 1
|
59
|
+
|
60
|
+
'Not found continue element with id="%s"' % @continue_id
|
61
|
+
end
|
62
|
+
|
63
|
+
def check_js_plug
|
64
|
+
body_rx = /<body[^>]*>(.+)<\/body>/
|
65
|
+
js_rx = '<script src="index.js"'
|
66
|
+
|
67
|
+
@string[body_rx]
|
68
|
+
res = $1&.[](js_rx)
|
69
|
+
return if res.present?
|
70
|
+
|
71
|
+
'Plug index.js script before closing tag of body.'
|
72
|
+
end
|
73
|
+
|
74
|
+
def check_css_plug
|
75
|
+
head_rx = /(?<=<head)(.+)(?=<\/head>)/
|
76
|
+
css_rx = 'href="index.css"'
|
77
|
+
|
78
|
+
@string[head_rx]
|
79
|
+
res = $1&.[](css_rx)
|
80
|
+
return if res.present?
|
81
|
+
|
82
|
+
'Plug index.css before closing tag of head.'
|
83
|
+
end
|
84
|
+
|
85
|
+
def check_title_presence
|
86
|
+
title_rx = /<title>[^<]+<\/title>/
|
87
|
+
return if @string[title_rx]
|
88
|
+
|
89
|
+
'Tag <title> not found.'
|
90
|
+
end
|
91
|
+
|
92
|
+
def check_a_hrefs
|
93
|
+
ahref_rx = /<a[^>]+href="[^"]+"/
|
94
|
+
return unless @string[ahref_rx]
|
95
|
+
|
96
|
+
'Links with href attribute found.'
|
97
|
+
end
|
98
|
+
|
99
|
+
def check_favicon
|
100
|
+
favicon_rx = '<link rel="shortcut icon" href="icon.ico">'
|
101
|
+
return if @string[favicon_rx]
|
102
|
+
|
103
|
+
'<link rel="shortcut icon" href="icon.ico"> not found.'
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
|
108
|
+
def any(regex)
|
109
|
+
@string.scan(regex).flatten.map(&:strip).map(&:present?).any?
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class CreateSimpleSource
|
5
|
+
class ValidateZipContent
|
6
|
+
#
|
7
|
+
# Валидирует все html файлы.
|
8
|
+
#
|
9
|
+
class ValidateHtml
|
10
|
+
include ::PrelandsRails::AbstractInteractor
|
11
|
+
include ::Interactor
|
12
|
+
include ::Interactor::Contracts
|
13
|
+
include ::PrelandsRails::Base
|
14
|
+
|
15
|
+
CONTINUE_ID = 'continue'
|
16
|
+
|
17
|
+
expects do
|
18
|
+
required(:files_content).value(type?: Hash) # { file_name => file_content, ... }
|
19
|
+
end
|
20
|
+
|
21
|
+
assures do
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def act
|
26
|
+
errors =
|
27
|
+
incoming_html_files.map do |key, content|
|
28
|
+
content = Html.new(content, CONTINUE_ID)
|
29
|
+
next if content.valid?
|
30
|
+
[key, content.errors]
|
31
|
+
end.compact.to_h
|
32
|
+
|
33
|
+
fail! errors: errors if errors.any?
|
34
|
+
end
|
35
|
+
|
36
|
+
on_breach { |breaches| bad_expects breaches }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class CreateSimpleSource
|
5
|
+
class ValidateZipContent
|
6
|
+
class ValidateJs
|
7
|
+
#
|
8
|
+
# Принимает строку с JavaScript кодом разметкой и валидирует её.
|
9
|
+
#
|
10
|
+
class Js
|
11
|
+
attr_reader :errors
|
12
|
+
|
13
|
+
# @param [String] string Содержимое JavaScript файла.
|
14
|
+
def initialize(string)
|
15
|
+
@errors = []
|
16
|
+
@string = string.gsub(/(\r\n?|\n)/, '') # убираем переносы, мешающие регуляркам
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?
|
20
|
+
@errors = [
|
21
|
+
check_location_changes,
|
22
|
+
check_framework_calls
|
23
|
+
].compact
|
24
|
+
|
25
|
+
!@errors.any?
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def check_location_changes
|
31
|
+
match_data = @string.match LOCATION_RX
|
32
|
+
is_loc_assign = ->(matched) { matched =~ /^('|")$/ || @string.match(/(;|\s*)#{matched}\s*=\s*('|")/) }
|
33
|
+
return unless match_data && is_loc_assign[match_data[3]]
|
34
|
+
|
35
|
+
'Location statement has found'
|
36
|
+
end
|
37
|
+
|
38
|
+
def check_framework_calls
|
39
|
+
res = FUNCS_RX.map do |key, func|
|
40
|
+
[ key, !!@string[func] ]
|
41
|
+
end
|
42
|
+
|
43
|
+
return if res.map { |kf| kf[1] }.all?
|
44
|
+
|
45
|
+
res.to_h.map do |key, result|
|
46
|
+
'Call of %s() not found' % key if !result
|
47
|
+
end.compact.join('; ')
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
LOCATION_RX = /(;|\s*)location(\.href\s*=|\.replace\(|\.assign\(|\s*=)\s*(\w+|"|')/
|
53
|
+
FUNCS_RX = {
|
54
|
+
post_email: /post_email\([^)]+\)/,
|
55
|
+
post_gender: /post_gender\([^)]+\)/,
|
56
|
+
post_age: /post_age\([^)]+\)/
|
57
|
+
}.freeze
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class CreateSimpleSource
|
5
|
+
class ValidateZipContent
|
6
|
+
#
|
7
|
+
# Валидирует JavaScript код.
|
8
|
+
#
|
9
|
+
class ValidateJs
|
10
|
+
include ::PrelandsRails::AbstractInteractor
|
11
|
+
include ::Interactor
|
12
|
+
include ::Interactor::Contracts
|
13
|
+
|
14
|
+
expects do
|
15
|
+
required(:files_content).value(type?: Hash) # { file_name => file_content, ... }
|
16
|
+
end
|
17
|
+
|
18
|
+
assures do
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
def act
|
23
|
+
content = context[:files_content]['index.js']
|
24
|
+
content = Js.new(content)
|
25
|
+
fail! errors: {'index.js' => content.errors} unless content.valid?
|
26
|
+
end
|
27
|
+
|
28
|
+
on_breach { |breaches| bad_expects breaches }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class CreateSimpleSource
|
5
|
+
#
|
6
|
+
# Примет содержимое файлов и валидирует их контент.
|
7
|
+
#
|
8
|
+
class ValidateZipContent
|
9
|
+
include ::PrelandsRails::AbstractInteractor
|
10
|
+
include ::Interactor::Organizer
|
11
|
+
include ::Interactor::Contracts
|
12
|
+
|
13
|
+
expects do
|
14
|
+
required(:files_content).value(type?: Hash) # { file_name[String] => file_content[String], ... }
|
15
|
+
end
|
16
|
+
|
17
|
+
assures do
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
organize ValidateHtml, ValidateJs#, ValidateCss
|
22
|
+
|
23
|
+
on_breach { |breaches| bad_expects breaches }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
#
|
5
|
+
# Примет zip-файл с исходниками преленда и опубликует этот преленд.
|
6
|
+
#
|
7
|
+
class CreateSimpleSource
|
8
|
+
include ::PrelandsRails::AbstractInteractor
|
9
|
+
include ::Interactor::Organizer
|
10
|
+
include ::Interactor::Contracts
|
11
|
+
|
12
|
+
expects do
|
13
|
+
required(:archive).filled # Входящий архив с исходниками от фрилансера. Rack::Test::UploadedFile | ActionDispatch::Http::UploadedFile
|
14
|
+
required(:preland_domain_ids).filled(type?: Array)
|
15
|
+
required(:expected_locales).filled(type?: Array) # Список локалей, для которых must were all index_<locale>.html files in the zip archive
|
16
|
+
required(:s3_credentials).schema do
|
17
|
+
required(:access_key).filled(:str?)
|
18
|
+
required(:secret_key).filled(:str?)
|
19
|
+
required(:region).filled(:str?)
|
20
|
+
end
|
21
|
+
required(:bucket_names).filled(type?: Array)
|
22
|
+
required(:aws_prefix).value(type?: String) # имя директории в букете
|
23
|
+
required(:preland_id).filled
|
24
|
+
required(:static_js_path).value(type?: String) # путь к размещённым в интернете нашим js скриптам
|
25
|
+
required(:model_preland_simple_source).filled
|
26
|
+
end
|
27
|
+
|
28
|
+
before do
|
29
|
+
fail!(errors: 'Preland domains missing') if context.preland_domain_ids.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
assures do
|
33
|
+
required(:incoming_locales).filled(type?: Array)
|
34
|
+
required(:files_content).value(type?: Hash) # распакованные файлы из архива { file_name[String] => file_content[String], ... }
|
35
|
+
required(:compiled_htmls).value(type?: Hash) # скомпилированные исходники { file_name[String] => compiled_content[String], ... }
|
36
|
+
required(:preland_simple_source).filled
|
37
|
+
end
|
38
|
+
|
39
|
+
organize DetectIncomingLocales,
|
40
|
+
CheckZipFiles,
|
41
|
+
ValidateZipContent,
|
42
|
+
Compile,
|
43
|
+
Upload,
|
44
|
+
CreateRecord
|
45
|
+
|
46
|
+
on_breach { |breaches| bad_expects breaches }
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class UpdateSimpleSource
|
5
|
+
|
6
|
+
class CheckZipFiles
|
7
|
+
include ::PrelandsRails::AbstractInteractor
|
8
|
+
include ::Interactor
|
9
|
+
include ::Interactor::Contracts
|
10
|
+
|
11
|
+
expects do
|
12
|
+
required(:archive) # Rack::Test::UploadedFile | ActionDispatch::Http::UploadedFile
|
13
|
+
required(:expected_locales).value(type?: Array)
|
14
|
+
required(:incoming_locales).filled(type?: Array)
|
15
|
+
end
|
16
|
+
|
17
|
+
assures do
|
18
|
+
optional(:files_content).maybe(type?: Hash) # js,html,css: { file_name => file_content, ... }
|
19
|
+
end
|
20
|
+
|
21
|
+
before do
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def act
|
26
|
+
if context.archive
|
27
|
+
result = ::PrelandsRails::CreateSimpleSource::CheckZipFiles.call context
|
28
|
+
if result.success?
|
29
|
+
context.files_content = result.files_content
|
30
|
+
else
|
31
|
+
fail!(errors: result.errors)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
on_breach { |breaches| bad_expects breaches }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class UpdateSimpleSource
|
5
|
+
|
6
|
+
class Compile
|
7
|
+
include ::PrelandsRails::AbstractInteractor
|
8
|
+
include ::Interactor
|
9
|
+
include ::Interactor::Contracts
|
10
|
+
|
11
|
+
expects do
|
12
|
+
optional(:files_content).maybe(type?: Hash) # js,html,css: { file_name => file_content, ... }
|
13
|
+
required(:static_js_path).value(type?: String)
|
14
|
+
end
|
15
|
+
|
16
|
+
assures do
|
17
|
+
optional(:compiled_htmls).value(type?: Hash) # { file_name[String] => compiled_content[String], ... }
|
18
|
+
end
|
19
|
+
|
20
|
+
before do
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def act
|
25
|
+
if context.files_content
|
26
|
+
result = ::PrelandsRails::CreateSimpleSource::Compile.call context
|
27
|
+
if result.success?
|
28
|
+
context.compiled_htmls = result.compiled_htmls
|
29
|
+
else
|
30
|
+
fail!(errors: result.errors)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
on_breach { |breaches| bad_expects breaches }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module PrelandsRails
|
2
|
+
class UpdateSimpleSource
|
3
|
+
#
|
4
|
+
# обновит запись ::Preland::SimpleSource
|
5
|
+
#
|
6
|
+
class UpdateRecord
|
7
|
+
include ::PrelandsRails::AbstractInteractor
|
8
|
+
include ::Interactor
|
9
|
+
include ::Interactor::Contracts
|
10
|
+
include ::PrelandsRails::Base
|
11
|
+
|
12
|
+
expects do
|
13
|
+
required(:archive) # Входящий архив с исходниками от фрилансера. Rack::Test::UploadedFile | ActionDispatch::Http::UploadedFile
|
14
|
+
required(:aws_prefix).value(type?: String) # имя директории в букете
|
15
|
+
required(:preland_id).filled
|
16
|
+
required(:preland_domain_ids).value(type?: Array)
|
17
|
+
required(:incoming_locales).filled(type?: Array)
|
18
|
+
required(:model_preland_simple_source).filled
|
19
|
+
end
|
20
|
+
|
21
|
+
assures do
|
22
|
+
required(:preland_simple_source).filled
|
23
|
+
end
|
24
|
+
|
25
|
+
before do
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def act
|
30
|
+
source = context.model_preland_simple_source.find_by aws_prefix: context.aws_prefix
|
31
|
+
source.archive = context.archive if context.archive
|
32
|
+
source.preland_domain_ids = context.preland_domain_ids
|
33
|
+
source.locales = context.incoming_locales
|
34
|
+
source.save!
|
35
|
+
context.preland_simple_source = source
|
36
|
+
end
|
37
|
+
|
38
|
+
on_breach { |breaches| bad_expects breaches }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class UpdateSimpleSource
|
5
|
+
class Upload
|
6
|
+
#
|
7
|
+
# Удалить из +bucket_names+ файлы преленда из директории +aws_prefix+.
|
8
|
+
#
|
9
|
+
module DeleteCompiledFiles
|
10
|
+
def delete_compiled_files
|
11
|
+
creds = context.s3_credentials
|
12
|
+
client = ::PrelandsRails::MyAwsClient.new creds[:access_key], creds[:secret_key], creds[:region]
|
13
|
+
|
14
|
+
context.bucket_names.each do |bucket_name|
|
15
|
+
files = client.list_objects bucket_name
|
16
|
+
next unless files
|
17
|
+
|
18
|
+
files = files.map do |file_name|
|
19
|
+
{ key: file_name } if file_name.index(context.aws_prefix) == 0
|
20
|
+
end.compact
|
21
|
+
|
22
|
+
next if files.empty?
|
23
|
+
|
24
|
+
client.delete_objects bucket_name, files
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class UpdateSimpleSource
|
5
|
+
|
6
|
+
class Upload
|
7
|
+
include ::PrelandsRails::AbstractInteractor
|
8
|
+
include ::Interactor
|
9
|
+
include ::Interactor::Contracts
|
10
|
+
include DeleteCompiledFiles
|
11
|
+
|
12
|
+
expects do
|
13
|
+
required(:archive) # Входящий архив с исходниками от фрилансера. Rack::Test::UploadedFile | ActionDispatch::Http::UploadedFile
|
14
|
+
optional(:compiled_htmls).maybe(type?: Hash) # скомпилированные исходники { file_name[String] => compiled_content[String], ... }
|
15
|
+
required(:s3_credentials).schema do
|
16
|
+
required(:access_key).filled(:str?)
|
17
|
+
required(:secret_key).filled(:str?)
|
18
|
+
required(:region).filled(:str?)
|
19
|
+
end
|
20
|
+
required(:bucket_names).value(type?: Array)
|
21
|
+
required(:aws_prefix).value(type?: String)
|
22
|
+
optional(:files_content).maybe(type?: Hash) # js,html,css: { file_name => file_content, ... }
|
23
|
+
end
|
24
|
+
|
25
|
+
assures do
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
before do
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
def act
|
34
|
+
if context.archive && context.compiled_htmls && context.files_content
|
35
|
+
delete_compiled_files
|
36
|
+
::PrelandsRails::CreateSimpleSource::Upload.call context
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
on_breach { |breaches| bad_expects breaches }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PrelandsRails
|
4
|
+
class UpdateSimpleSource
|
5
|
+
|
6
|
+
class ValidateZipContent
|
7
|
+
include ::PrelandsRails::AbstractInteractor
|
8
|
+
include ::Interactor
|
9
|
+
include ::Interactor::Contracts
|
10
|
+
|
11
|
+
expects do
|
12
|
+
optional(:files_content).maybe(type?: Hash) # js,html,css: { file_name => file_content, ... }
|
13
|
+
end
|
14
|
+
|
15
|
+
assures do
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
before do
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def act
|
24
|
+
if context.files_content
|
25
|
+
result = ::PrelandsRails::CreateSimpleSource::ValidateZipContent.call context
|
26
|
+
unless result.success?
|
27
|
+
fail!(errors: result.errors)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
on_breach { |breaches| bad_expects breaches }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|