terrimporter 0.6.4 → 0.7.0

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