terrimporter 0.6.4 → 0.7.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.
- data/Gemfile.lock +1 -1
- data/config/schema.yml +28 -5
- data/config/{terrimporter.config.yml → terrimporter.yml} +24 -6
- data/lib/terrimporter/app_logger.rb +39 -30
- data/lib/terrimporter/configuration.rb +39 -10
- data/lib/terrimporter/{config_helper.rb → configuration_helper.rb} +6 -6
- data/lib/terrimporter/download_helper.rb +8 -0
- data/lib/terrimporter/downloader.rb +42 -15
- data/lib/terrimporter/importer.rb +64 -139
- data/lib/terrimporter/importer_helper.rb +9 -0
- data/lib/terrimporter/options.rb +13 -30
- data/lib/terrimporter/version.rb +2 -2
- data/lib/terrimporter.rb +17 -2
- data/test/fixtures/html/application_root.html +1 -0
- data/test/fixtures/html/application_root_css_error.html +13 -0
- data/test/fixtures/html/application_root_js_error.html +14 -0
- data/test/fixtures/html/module.html +9 -0
- data/test/fixtures/html/modulecontent.html +7 -0
- data/test/fixtures/invalid.config.yml +3 -1
- data/test/fixtures/minimal.test.config.yml +3 -2
- data/test/fixtures/test.config.yml +14 -5
- data/test/test_helper.rb +24 -1
- data/test/test_terrimporter.rb +21 -4
- data/test/unit/test_app_logger.rb +19 -36
- data/test/unit/test_config_helper.rb +1 -1
- data/test/unit/test_configuration.rb +45 -3
- data/test/unit/test_downloader.rb +68 -3
- data/test/unit/test_importer.rb +38 -78
- data/test/unit/test_options.rb +23 -3
- metadata +18 -9
- data/terrimporter.config.yml.bak +0 -47
data/Gemfile.lock
CHANGED
data/config/schema.yml
CHANGED
@@ -29,7 +29,7 @@ mapping:
|
|
29
29
|
type: map
|
30
30
|
required: yes
|
31
31
|
mapping:
|
32
|
-
"
|
32
|
+
"destination_path":
|
33
33
|
type: str
|
34
34
|
required: yes
|
35
35
|
"styles":
|
@@ -51,13 +51,13 @@ mapping:
|
|
51
51
|
type: map
|
52
52
|
required: yes
|
53
53
|
mapping:
|
54
|
-
"
|
54
|
+
"destination_path":
|
55
55
|
type: str
|
56
56
|
required: yes
|
57
57
|
"dynamic_libraries":
|
58
58
|
type: str
|
59
59
|
required: no
|
60
|
-
"
|
60
|
+
"libraries_destination_path":
|
61
61
|
type: str
|
62
62
|
required: no
|
63
63
|
"images":
|
@@ -69,9 +69,32 @@ mapping:
|
|
69
69
|
"server_path":
|
70
70
|
type: str
|
71
71
|
required: yes
|
72
|
-
"
|
72
|
+
"destination_path":
|
73
73
|
type: str
|
74
74
|
required: yes
|
75
75
|
"file_types":
|
76
76
|
type: str
|
77
|
-
required: no
|
77
|
+
required: no
|
78
|
+
"modules":
|
79
|
+
type: seq
|
80
|
+
required: no
|
81
|
+
sequence:
|
82
|
+
- type: map
|
83
|
+
mapping:
|
84
|
+
"name":
|
85
|
+
type: str
|
86
|
+
required: yes
|
87
|
+
"skin":
|
88
|
+
type: str
|
89
|
+
required: no
|
90
|
+
default: ""
|
91
|
+
"destination_path":
|
92
|
+
type: str
|
93
|
+
required: yes
|
94
|
+
"module_template":
|
95
|
+
type: str
|
96
|
+
required: yes
|
97
|
+
"template_only":
|
98
|
+
type: bool
|
99
|
+
default: false
|
100
|
+
required: no
|
@@ -1,13 +1,23 @@
|
|
1
1
|
#-------------------------------------------------------------------------------
|
2
|
-
# terrimporter configuration, adjust as needed.
|
2
|
+
# terrimporter configuration, adjust as needed.
|
3
3
|
#-------------------------------------------------------------------------------
|
4
|
+
# Important notes READ THEM:
|
5
|
+
# * Don't mess with indentation!
|
6
|
+
# * All local paths are relative to the running directory
|
7
|
+
# * multiple entries have the following format (stylesheet replacement example):
|
8
|
+
# - what: /replacethis/
|
9
|
+
# with: /withthis/
|
10
|
+
# - what: /another/
|
11
|
+
# with: /replacement/
|
12
|
+
|
13
|
+
# APPLICATION
|
4
14
|
# url: Terrific base url
|
5
15
|
application_url: http://terrific.project.url
|
6
16
|
|
7
17
|
# STYLESHEETS
|
8
18
|
stylesheets:
|
9
19
|
# The destination directory, relative from the current running directory
|
10
|
-
|
20
|
+
destination_path: public/stylesheets/
|
11
21
|
# Additional stylesheets, you can but don't have to add the .css extension
|
12
22
|
# styles: ie, ie6, ie7.css
|
13
23
|
# replace_strings: Define string replacements in css files
|
@@ -19,18 +29,26 @@ stylesheets:
|
|
19
29
|
# JAVASCRIPTS
|
20
30
|
javascripts:
|
21
31
|
# Destination path of the javascript base.js file
|
22
|
-
|
32
|
+
destination_path: public/javascripts/
|
23
33
|
# Dynamic libraries definition, you can but don't have to add the .js extension
|
24
34
|
# dynamic_libraries: foo_lib.js bar_lib.js
|
25
|
-
# Destination path of the dynamic libraries relative
|
26
|
-
#
|
35
|
+
# Destination path of the dynamic libraries (relative)
|
36
|
+
# libraries_destination_path: public/javascripts/libraries/
|
27
37
|
|
28
38
|
# IMAGES - multiple entries allowed
|
29
39
|
images:
|
30
40
|
# - server_path: / # The server path is appended to the image_server_path
|
31
|
-
#
|
41
|
+
# destination_path: public/images/ # The relative destination path
|
32
42
|
# file_types: jpg, png, gif # Image file endings to be downloaded
|
33
43
|
|
44
|
+
# MODULES - multiple entries allowed
|
45
|
+
modules:
|
46
|
+
# - name: #Module name
|
47
|
+
# skin: #Skin name, if used
|
48
|
+
# module_template: #The module template used, required
|
49
|
+
# template_only: false #Only import template without surrounding divs, default: false
|
50
|
+
# destination_path: #Destination path of
|
51
|
+
|
34
52
|
#-------------------------------------------------------------------------------
|
35
53
|
# ADVANCED EDITING - Only edit the following if you know what you're doing...
|
36
54
|
# ------------------------------------------------------------------------------
|
@@ -1,43 +1,52 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
1
|
+
class Logger
|
2
|
+
attr_accessor :level
|
3
|
+
|
4
|
+
LOG_LEVELS = {:debug => 0, :info => 1, :warn => 2, :error=> 3, :fatal => 4}
|
5
|
+
LOG_COLORS = {:debug =>'33', :info =>'32', :warn =>'33', :error=>'31', :fatal =>'31'}
|
6
|
+
|
7
|
+
# more infos: https://wiki.archlinux.org/index.php/Color_Bash_Prompt
|
8
|
+
#\033[0m Text reset
|
9
|
+
#\033[0;37m White
|
10
|
+
#\033[032m Green
|
11
|
+
#\033[033m Yellow
|
12
|
+
#\033[031m Red
|
13
|
+
#\033[037m White
|
14
|
+
|
15
|
+
# %s => [datetime], %s => color, %-5s => severity, %s => message
|
16
|
+
LOG_FORMAT = "\033[0;37m %s \033[0m[\033[%sm%-5s\033[0m]: %s \n"
|
17
|
+
TIME_FORMAT = "%H:%M:%S"
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
self.level = :debug
|
15
21
|
end
|
16
22
|
|
17
|
-
|
18
|
-
|
19
|
-
def log(hash)
|
20
|
-
Logging.log.debug hash[:debug] unless hash[:debug].nil?
|
21
|
-
Logging.log.info hash[:info] unless hash[:info].nil?
|
22
|
-
Logging.log.warn hash[:warn] unless hash[:warn].nil?
|
23
|
-
Logging.log.error hash[:error] unless hash[:error].nil?
|
24
|
-
Logging.log.fatal hash[:fatal] unless hash[:fatal].nil?
|
23
|
+
def error(message)
|
24
|
+
log(:error, message)
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
29
|
-
@logger.formatter = LogFormatter.new
|
30
|
-
@logger
|
27
|
+
def info(message)
|
28
|
+
log(:info, message)
|
31
29
|
end
|
32
30
|
|
33
|
-
def
|
34
|
-
|
31
|
+
def debug(message)
|
32
|
+
log(:debug, message)
|
35
33
|
end
|
36
34
|
|
37
|
-
def
|
35
|
+
def log(severity, message)
|
36
|
+
return if LOG_LEVELS[severity] < LOG_LEVELS[self.level]
|
38
37
|
|
38
|
+
color = LOG_COLORS[severity]
|
39
|
+
if LOG_LEVELS[severity] >= LOG_LEVELS[:error]
|
40
|
+
$stderr.puts(LOG_FORMAT % [format_datetime(Time.now), color, severity.to_s.upcase, message])
|
41
|
+
else
|
42
|
+
$stdout.puts(LOG_FORMAT % [format_datetime(Time.now), color, severity.to_s.upcase, message])
|
43
|
+
end
|
39
44
|
end
|
40
45
|
|
41
|
-
|
46
|
+
def format_datetime(time)
|
47
|
+
time.strftime(TIME_FORMAT)
|
48
|
+
end
|
42
49
|
|
50
|
+
end
|
43
51
|
|
52
|
+
LOG = Logger.new
|
@@ -4,7 +4,7 @@
|
|
4
4
|
module TerrImporter
|
5
5
|
class Application
|
6
6
|
class Configuration < Hash
|
7
|
-
include
|
7
|
+
include ConfigurationHelper
|
8
8
|
|
9
9
|
attr_accessor :validations, :config_file
|
10
10
|
|
@@ -15,7 +15,7 @@ module TerrImporter
|
|
15
15
|
|
16
16
|
def load_configuration
|
17
17
|
config_file_path = determine_config_file_path
|
18
|
-
|
18
|
+
LOG.debug "Configuration file located, load from #{config_file_path}"
|
19
19
|
validate_and_load_config(config_file_path)
|
20
20
|
end
|
21
21
|
|
@@ -42,9 +42,8 @@ module TerrImporter
|
|
42
42
|
]
|
43
43
|
end
|
44
44
|
|
45
|
-
#todo split!
|
46
45
|
def validate_and_load_config(file)
|
47
|
-
|
46
|
+
LOG.debug "Validating configuration..."
|
48
47
|
|
49
48
|
parser = Kwalify::Yaml::Parser.new(load_validator)
|
50
49
|
document = parser.parse_file(file)
|
@@ -59,12 +58,12 @@ module TerrImporter
|
|
59
58
|
end
|
60
59
|
|
61
60
|
def load_validator
|
62
|
-
|
61
|
+
LOG.debug "Loading validator from #{schema_file_path}"
|
63
62
|
schema = Kwalify::Yaml.load_file(schema_file_path)
|
64
63
|
Kwalify::Validator.new(schema)
|
65
64
|
end
|
66
65
|
|
67
|
-
def
|
66
|
+
def mandatory_present?
|
68
67
|
if self['export_path'].nil? or self['export_settings']['application'].nil? or self['application_url'].nil?
|
69
68
|
false
|
70
69
|
else
|
@@ -72,12 +71,38 @@ module TerrImporter
|
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
74
|
+
def determine_configuration_values_from_html(raw_html)
|
75
|
+
css_result, js_result = raw_html.scan(/(\/terrific\/base\/(.*?)\/public\/.*base.(css|js).php)\?.*application=(.*?)(&|&)/)
|
76
|
+
|
77
|
+
raise ConfigurationError, "Unable to extract css information from application url, content is: #{raw_html}" if css_result.nil? or css_result.size < 5
|
78
|
+
raise ConfigurationError, "Unable to extract javascript information from application url, content is: #{raw_html}" if js_result.nil? or js_result.size < 5
|
79
|
+
|
80
|
+
css_export_path = css_result[0]
|
81
|
+
js_export_path = js_result[0]
|
82
|
+
terrific_version = css_result[1]
|
83
|
+
application = css_result[3]
|
84
|
+
|
85
|
+
raise ConfigurationError, "Unable to determine css export path" if css_export_path.nil?
|
86
|
+
raise ConfigurationError, "Unable to determine js export path " if js_export_path.nil?
|
87
|
+
raise ConfigurationError, "Unable to determine terrific version" if terrific_version.nil?
|
88
|
+
raise ConfigurationError, "Unable to determine application path" if application.nil?
|
89
|
+
|
90
|
+
LOG.info "Determined the following configuration values from #{self['application_url']}:\n" +
|
91
|
+
"terrific version: #{terrific_version} \n" +
|
92
|
+
"application path: #{application}"
|
93
|
+
|
94
|
+
self['version'] = terrific_version
|
95
|
+
self['export_settings'] ||= {}
|
96
|
+
self['export_settings']['application'] = application
|
97
|
+
self['export_path'] = {'css' => css_export_path, 'js' => js_export_path}
|
98
|
+
end
|
99
|
+
|
75
100
|
def stylesheets
|
76
101
|
stylesheets = ["base.css"]
|
77
102
|
if additional_stylesheets?
|
78
103
|
stylesheets = stylesheets + self['stylesheets']['styles'].to_s.robust_split
|
79
104
|
else
|
80
|
-
|
105
|
+
LOG.debug "No additional stylesheets defined."
|
81
106
|
end
|
82
107
|
stylesheets.add_if_missing!('.css')
|
83
108
|
end
|
@@ -92,10 +117,10 @@ module TerrImporter
|
|
92
117
|
end
|
93
118
|
|
94
119
|
def libraries_destination_path
|
95
|
-
if !self['javascripts']['
|
96
|
-
File.join(self['javascripts']['
|
120
|
+
if !self['javascripts']['libraries_destination_path'].nil?
|
121
|
+
File.join(self['javascripts']['libraries_destination_path'])
|
97
122
|
else
|
98
|
-
File.join(self['javascripts']['
|
123
|
+
File.join(self['javascripts']['destination_path'])
|
99
124
|
end
|
100
125
|
end
|
101
126
|
|
@@ -111,6 +136,10 @@ module TerrImporter
|
|
111
136
|
!self['images'].nil?
|
112
137
|
end
|
113
138
|
|
139
|
+
def modules?
|
140
|
+
!self['modules'].nil?
|
141
|
+
end
|
142
|
+
|
114
143
|
end
|
115
144
|
end
|
116
145
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
module
|
1
|
+
module ConfigurationHelper
|
2
2
|
|
3
3
|
def config_default_name
|
4
|
-
'terrimporter.
|
4
|
+
'terrimporter.yml'
|
5
5
|
end
|
6
6
|
|
7
7
|
def schema_default_name
|
@@ -25,13 +25,13 @@ module ConfigHelper
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def create_config_file(backup_or_replace = nil, application_url = nil)
|
28
|
-
|
28
|
+
LOG.info "Creating configuration file..."
|
29
29
|
case backup_or_replace
|
30
30
|
when :backup
|
31
|
-
|
31
|
+
LOG.debug "Backing up old configuration file to #{config_working_directory_path}.bak"
|
32
32
|
FileUtils.mv(config_working_directory_path, config_working_directory_path + '.bak')
|
33
33
|
when :replace
|
34
|
-
|
34
|
+
LOG.debug "Replacing old configuration file"
|
35
35
|
FileUtils.rm_f(config_working_directory_path) if File.exists? config_working_directory_path
|
36
36
|
end
|
37
37
|
FileUtils.cp(config_example_path, config_working_directory_path)
|
@@ -42,7 +42,7 @@ module ConfigHelper
|
|
42
42
|
File.open(config_working_directory_path, 'w') { |f| f.write(configuration) }
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
LOG.info "done! You should take a look an edit it to your needs..."
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
@@ -4,39 +4,66 @@ require 'uri'
|
|
4
4
|
module TerrImporter
|
5
5
|
class Application
|
6
6
|
class Downloader
|
7
|
+
include DownloadHelper
|
7
8
|
|
8
9
|
def initialize(base_uri)
|
9
10
|
@base_uri = base_uri
|
10
|
-
|
11
|
+
LOG.debug "Downloader initialized to uri: #{@base_uri}"
|
11
12
|
end
|
12
13
|
|
13
|
-
def download(remote_path, local_path=nil)
|
14
|
-
|
14
|
+
def download(remote_path, local_path = nil)
|
15
|
+
remote_url = url(remote_path)
|
15
16
|
begin
|
16
17
|
if local_path.nil? #download to buffer
|
18
|
+
LOG.debug "Download #{remote_url} to buffer"
|
17
19
|
data = StringIO.new
|
18
|
-
|
19
|
-
puts "Downloading #{absolute_uri} to buffer"
|
20
|
-
|
21
|
-
absolute_uri.open { |io| data = io.read }
|
20
|
+
remote_url.open { |io| data = io.read }
|
22
21
|
data.to_s
|
23
22
|
else
|
24
|
-
|
25
|
-
|
26
|
-
open(local_path, "wb") { |file|
|
27
|
-
file.write(absolute_uri.open.read)
|
28
|
-
}
|
23
|
+
LOG.info "Download #{remote_url} to local path #{local_path}"
|
24
|
+
create_dir_path File.dirname(local_path)
|
25
|
+
open(local_path, "wb") { |file| file.write(remote_url.open.read) }
|
29
26
|
end
|
30
27
|
rescue SocketError => e
|
31
|
-
raise DefaultError, "Error opening url #{
|
28
|
+
raise DefaultError, "Error opening url #{remote_url}: \n #{e.message}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def batch_download(remote_path, local_path, type_filter = "")
|
33
|
+
source_path = url(remote_path)
|
34
|
+
create_dir_path local_path
|
35
|
+
LOG.debug "Download multiple files from #{source_path} to #{local_path} #{"allowed extensions: " + type_filter unless type_filter.empty?}"
|
36
|
+
|
37
|
+
files = html_directory_list(source_path)
|
38
|
+
|
39
|
+
unless type_filter.empty?
|
40
|
+
LOG.debug "Apply type filter: #{type_filter}"
|
41
|
+
files = files.find_all { |file| file =~ Regexp.new(".*" + type_filter.robust_split.join("|") + "$") }
|
42
|
+
end
|
43
|
+
|
44
|
+
LOG.info "Download #{files.size} files..."
|
45
|
+
files.each do |file|
|
46
|
+
local_file_path = File.join(local_path.to_s, file)
|
47
|
+
self.download(File.join(source_path.to_s, file), local_file_path)
|
32
48
|
end
|
33
49
|
end
|
34
50
|
|
35
51
|
private
|
36
|
-
def
|
37
|
-
|
52
|
+
def html_directory_list(remote_path)
|
53
|
+
LOG.debug "Get html directory list"
|
54
|
+
output = self.download(remote_path)
|
55
|
+
files = []
|
56
|
+
|
57
|
+
output.scan(/<a\shref=\"([^\"]+)\"/) do |res|
|
58
|
+
files << res[0] if not res[0] =~ /^\?/ and not res[0] =~ /.*\/$/ and res[0].size > 1
|
59
|
+
end
|
60
|
+
LOG.debug "Found #{files.size} files"
|
61
|
+
files
|
38
62
|
end
|
39
63
|
|
64
|
+
def url(relative_path)
|
65
|
+
URI.join(@base_uri, relative_path)
|
66
|
+
end
|
40
67
|
end
|
41
68
|
end
|
42
69
|
end
|