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 CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- terrimporter (0.6.4)
4
+ terrimporter (0.6.6)
5
5
  kwalify (>= 0.7.2)
6
6
 
7
7
  GEM
data/config/schema.yml CHANGED
@@ -29,7 +29,7 @@ mapping:
29
29
  type: map
30
30
  required: yes
31
31
  mapping:
32
- "relative_destination_path":
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
- "relative_destination_path":
54
+ "destination_path":
55
55
  type: str
56
56
  required: yes
57
57
  "dynamic_libraries":
58
58
  type: str
59
59
  required: no
60
- "libraries_relative_destination_path":
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
- "relative_destination_path":
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. Don't mess with indentation!
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
- relative_destination_path: public/stylesheets/
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
- relative_destination_path: public/javascripts/
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
- # libraries_relative_destination_path: public/javascripts/libraries/
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
- # relative_destination_path: public/images/ # The relative destination path
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
- module Logging
2
- require 'logger'
3
-
4
- #logformatter monkeypatch
5
- class LogFormatter < Logger::Formatter
6
- CUSTOM_FORMAT = "[%s] %5s %s: %s\n"
7
-
8
- def call(severity, time, progname, message)
9
- CUSTOM_FORMAT % [format_datetime(time), severity, progname, msg2str(message)]
10
- end
11
-
12
- def format_datetime(time)
13
- time.strftime("%Y-%m-%d %H:%M:%S")
14
- end
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
- # @param hash [:info => "message", :debug => "message", :error => "message"]
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 self.log
28
- @logger ||= Logger.new $stdout
29
- @logger.formatter = LogFormatter.new
30
- @logger
27
+ def info(message)
28
+ log(:info, message)
31
29
  end
32
30
 
33
- def verbose?
34
- !self.options.nil? && self.options[:verbose] = true
31
+ def debug(message)
32
+ log(:debug, message)
35
33
  end
36
34
 
37
- def self.initialize_logger
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
- end
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 ConfigHelper
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
- puts "Configuration file located, load from #{config_file_path}"
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
- puts "Validating configuration..."
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
- puts "Loading validator from #{schema_file_path}"
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 required_present?
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=(.*?)(&amp;|&)/)
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
- puts "No additional stylesheets defined."
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']['libraries_relative_destination_path'].nil?
96
- File.join(self['javascripts']['libraries_relative_destination_path'])
120
+ if !self['javascripts']['libraries_destination_path'].nil?
121
+ File.join(self['javascripts']['libraries_destination_path'])
97
122
  else
98
- File.join(self['javascripts']['relative_destination_path'])
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 ConfigHelper
1
+ module ConfigurationHelper
2
2
 
3
3
  def config_default_name
4
- 'terrimporter.config.yml'
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
- puts "Creating configuration file..."
28
+ LOG.info "Creating configuration file..."
29
29
  case backup_or_replace
30
30
  when :backup
31
- puts "Backing up old configuration file to #{config_working_directory_path}.bak"
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
- puts "Replacing old configuration file"
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
- puts "done! You should take a look an edit it to your needs..."
45
+ LOG.info "done! You should take a look an edit it to your needs..."
46
46
  end
47
47
 
48
48
  private
@@ -0,0 +1,8 @@
1
+ module DownloadHelper
2
+ def create_dir_path(dir)
3
+ unless File.directory?(dir) and File.file?(dir)
4
+ LOG.debug "Creating directory: #{dir}"
5
+ FileUtils.mkpath(dir)
6
+ end
7
+ end
8
+ end
@@ -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
- puts "Downloader initialized to uri: #{base_uri}"
11
+ LOG.debug "Downloader initialized to uri: #{@base_uri}"
11
12
  end
12
13
 
13
- def download(remote_path, local_path=nil)
14
- absolute_uri = absolute_path(remote_path)
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
- puts "Downloading #{absolute_uri} to local path #{local_path}"
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 #{absolute_uri}: \n #{e.message}"
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 absolute_path(relative_path)
37
- URI.join(@base_uri, relative_path)
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