wordpress-exporter 0.0.1

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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +39 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +8 -0
  5. data/CHANGELOG.md +4 -0
  6. data/Gemfile +7 -0
  7. data/Gemfile.lock +75 -0
  8. data/LICENSE +22 -0
  9. data/README.md +71 -0
  10. data/Rakefile +8 -0
  11. data/bin/wordpress-exporter +46 -0
  12. data/lib/cli.rb +11 -0
  13. data/lib/configuration.rb +28 -0
  14. data/lib/converters/content_types_structure_creator.rb +58 -0
  15. data/lib/converters/contentful_model_to_json.rb +119 -0
  16. data/lib/converters/markup_converter.rb +35 -0
  17. data/lib/migrator.rb +30 -0
  18. data/lib/version.rb +3 -0
  19. data/lib/wordpress/blog.rb +83 -0
  20. data/lib/wordpress/category.rb +54 -0
  21. data/lib/wordpress/export.rb +30 -0
  22. data/lib/wordpress/post.rb +94 -0
  23. data/lib/wordpress/post_attachment.rb +44 -0
  24. data/lib/wordpress/post_category_domain.rb +71 -0
  25. data/lib/wordpress/tag.rb +56 -0
  26. data/spec/fixtures/blog/assets/attachment_post/attachment_post_15.json +5 -0
  27. data/spec/fixtures/blog/assets/attachment_post/attachment_post_21.json +5 -0
  28. data/spec/fixtures/blog/entries/blog/blog_1.json +62 -0
  29. data/spec/fixtures/blog/entries/category/category_11599757.json +5 -0
  30. data/spec/fixtures/blog/entries/category/category_14786.json +5 -0
  31. data/spec/fixtures/blog/entries/category/category_2214351.json +5 -0
  32. data/spec/fixtures/blog/entries/category/category_8076.json +5 -0
  33. data/spec/fixtures/blog/entries/post/post_1.json +7 -0
  34. data/spec/fixtures/blog/entries/post/post_11.json +31 -0
  35. data/spec/fixtures/blog/entries/post/post_15.json +11 -0
  36. data/spec/fixtures/blog/entries/post/post_21.json +11 -0
  37. data/spec/fixtures/blog/entries/post/post_3.json +13 -0
  38. data/spec/fixtures/blog/entries/post/post_5.json +13 -0
  39. data/spec/fixtures/blog/entries/post/post_9.json +13 -0
  40. data/spec/fixtures/blog/entries/tag/tag_2656354.json +5 -0
  41. data/spec/fixtures/blog/entries/tag/tag_306830130.json +5 -0
  42. data/spec/fixtures/default_contentful_structure.json +78 -0
  43. data/spec/fixtures/wordpress.xml +551 -0
  44. data/spec/lib/configuration_spec.rb +23 -0
  45. data/spec/lib/converters/markup_converter_spec.rb +27 -0
  46. data/spec/lib/wordpress/blog_spec.rb +64 -0
  47. data/spec/lib/wordpress/category_spec.rb +39 -0
  48. data/spec/lib/wordpress/export_spec.rb +27 -0
  49. data/spec/lib/wordpress/post_category_domain_spec.rb +41 -0
  50. data/spec/lib/wordpress/post_spec.rb +41 -0
  51. data/spec/lib/wordpress/tag_spec.rb +39 -0
  52. data/spec/spec_helper.rb +13 -0
  53. data/spec/support/db_rows_json.rb +5 -0
  54. data/spec/support/shared_configuration.rb +13 -0
  55. data/wordpress_exporter.gemspec +33 -0
  56. data/wordpress_settings/contentful_model.json +288 -0
  57. data/wordpress_settings/contentful_structure.json +78 -0
  58. data/wordpress_settings/default_contentful_structure.json +78 -0
  59. data/wordpress_settings/export_wordpress.xml +380 -0
  60. data/wordpress_settings/wordpress.xml +570 -0
  61. data/wordpress_settings/wordpress_settings.yml +13 -0
  62. metadata +288 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 680c753308782d12dfc5e7712966c05cd952836f
4
+ data.tar.gz: 3b82f2f3f1dc436ec46d2d62793337852a98cd12
5
+ SHA512:
6
+ metadata.gz: ec2f0aebefdd4117051a04363d48b013b325dd35e1e4c421d7469e8b49809de06f168ff47cc01efbb41a3fd32e8e7ad55d81eef2ea7c0fd3bf5f514a1f6eadf8
7
+ data.tar.gz: 4287679aeecca10f83554762e11850583801a42ea8de7a7f10b2db060d968f9af955bfaeaace9be877925b3e4c51a62b9ec4c6e318629d244cb828745bf978cf
data/.gitignore ADDED
@@ -0,0 +1,39 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
35
+
36
+ #RubyMine
37
+ .idea
38
+
39
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format progress
3
+ --order random
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ - 2.1.1
5
+ - 2.1
6
+ - 2.0.0
7
+ - 1.9.3
8
+ - jruby-19mode
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ # Change Log
2
+ ## 0.0.1
3
+ ### Other
4
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+ # Specify your gem's dependencies in wordpress_exporter.gemspec
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'simplecov', require: false
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,75 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ wordpress-exporter (0.0.1)
5
+ activesupport (~> 4.1)
6
+ escort (~> 0.4.0)
7
+ http (~> 0.6)
8
+ i18n (~> 0.6)
9
+ multi_json (~> 1)
10
+ nokogiri (~> 1.6.3.1)
11
+ reverse_markdown (~> 0.6.0)
12
+
13
+ GEM
14
+ remote: https://rubygems.org/
15
+ specs:
16
+ activesupport (4.2.0)
17
+ i18n (~> 0.7)
18
+ json (~> 1.7, >= 1.7.7)
19
+ minitest (~> 5.1)
20
+ thread_safe (~> 0.3, >= 0.3.4)
21
+ tzinfo (~> 1.1)
22
+ diff-lcs (1.2.5)
23
+ docile (1.1.5)
24
+ escort (0.4.0)
25
+ nesty
26
+ form_data (0.1.0)
27
+ http (0.7.1)
28
+ form_data (~> 0.1.0)
29
+ http_parser.rb (~> 0.6.0)
30
+ http_parser.rb (0.6.0)
31
+ i18n (0.7.0)
32
+ json (1.8.2)
33
+ mini_portile (0.6.0)
34
+ minitest (5.5.0)
35
+ multi_json (1.10.1)
36
+ nesty (1.0.2)
37
+ nokogiri (1.6.3.1)
38
+ mini_portile (= 0.6.0)
39
+ rake (10.4.2)
40
+ reverse_markdown (0.6.0)
41
+ nokogiri
42
+ rspec (3.1.0)
43
+ rspec-core (~> 3.1.0)
44
+ rspec-expectations (~> 3.1.0)
45
+ rspec-mocks (~> 3.1.0)
46
+ rspec-core (3.1.7)
47
+ rspec-support (~> 3.1.0)
48
+ rspec-expectations (3.1.2)
49
+ diff-lcs (>= 1.2.0, < 2.0)
50
+ rspec-support (~> 3.1.0)
51
+ rspec-its (1.1.0)
52
+ rspec-core (>= 3.0.0)
53
+ rspec-expectations (>= 3.0.0)
54
+ rspec-mocks (3.1.3)
55
+ rspec-support (~> 3.1.0)
56
+ rspec-support (3.1.2)
57
+ simplecov (0.9.1)
58
+ docile (~> 1.1.0)
59
+ multi_json (~> 1.0)
60
+ simplecov-html (~> 0.8.0)
61
+ simplecov-html (0.8.0)
62
+ thread_safe (0.3.4)
63
+ tzinfo (1.2.2)
64
+ thread_safe (~> 0.1)
65
+
66
+ PLATFORMS
67
+ ruby
68
+
69
+ DEPENDENCIES
70
+ bundler (~> 1.6)
71
+ rake
72
+ rspec (~> 3)
73
+ rspec-its (~> 1.1.0)
74
+ simplecov
75
+ wordpress-exporter!
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Contentful
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ Wordpress to Contentful Exporter
2
+ =================
3
+
4
+ ## Description
5
+ This adapter will allow you to extract content from a WordPress Blog and prepare it to be imported to [Contentful](https://wwww.contentful.com).
6
+
7
+ The following content will be extracted:
8
+
9
+ * Blog with posts
10
+ * Categories, tags and terms from custom taxonomies
11
+ * Attachments
12
+
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ gem install wordpress-exporter
18
+ ```
19
+
20
+ This will install the `wordpress-exporter` executable on your system.
21
+
22
+
23
+ ## Setup
24
+ To extract the blog content you need to [export](http://en.support.wordpress.com/export/) it from the WordPress blog and save it as a XML file.
25
+
26
+ Further you need to define where the tool can find the XML file and the destination of the transformed content.
27
+ Create a `settings.yml` file and fill in the `data_dir` and `wordpress_xml_path`:
28
+
29
+ ``` yaml
30
+ data_dir: PATH_TO_ALL_DATA
31
+ wordpress_xml_path: PATH_TO_XML/file.xml
32
+ ```
33
+
34
+ To extract the content run:
35
+
36
+ ```bash
37
+ wordpress-exporter --config-file settings.yml --extract-to-json
38
+ ```
39
+
40
+ The result will be a directory structure with the WordPress content transformed into JSON files that are ready for import.
41
+
42
+ Use the [generic-importer](https://github.com/contentful/generic-importer.rb) to import your blog then to Contentful.
43
+
44
+ ## Step by step
45
+
46
+ 1. [Export](http://en.support.wordpress.com/export/) the content of the blog from WordPress and save it as XML file.
47
+ 2. Create YAML file with settings (eg. settings.yml) and fill in the required parameters.
48
+ The generated `content types`, `entries` and `assets` will be saved to the `data_dir`.
49
+
50
+ 3. Extract the content from the XML file and generate the content model and JSON files for the import:
51
+
52
+ ```bash
53
+ wordpress-exporter --config-file settings.yml --extract-to-json
54
+ ```
55
+ If you want to create a different content model for your blog you can use `--omit-content-model`
56
+
57
+ ```bash
58
+ wordpress-exporter --config-file settings.yml --extract-to-json --omit-content-model
59
+ ```
60
+
61
+ It will only extract the content and store it as JSON, you need to take care about the content mapping yourself.
62
+ See the [Contentful-importer](https://github.com/contentful/generic-importer.rb) for details on how this needs to be done.
63
+
64
+ 4. (Optional). HTML markup can be converted to markdown:
65
+
66
+ ```bash
67
+ wordpress-exporter --config-file settings.yml --convert-markup
68
+ ```
69
+ This will only touch the content body of a blog post, other attributes will not be changed.
70
+
71
+ 5. Use the [contentful-importer](https://github.com/contentful/generic-importer.rb) to import the content to [contentful.com](https://www.contentful.com)
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'bundler/gem_tasks'
4
+
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new('spec')
7
+
8
+ task default: :spec
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'escort'
4
+ require_relative '../lib/cli'
5
+
6
+ I18n.enforce_available_locales = false
7
+
8
+ fail ArgumentError, 'Set path for configuration file and define action. More details you can find in README.' if ARGF.argv.empty?
9
+ fail ArgumentError, "Missing '--config-file' argument. The correct is form: 'wordpress-exporter --config-file PATH_TO_CONFIGURATION_FILE --action'. View README." unless ARGV.include?('--config-file')
10
+
11
+ Escort::App.create do |app|
12
+ app.summary 'Executable file of Wordpress exporter'
13
+
14
+ app.options do |opts|
15
+ opts.opt :file, '--config-file', short: '-f', long: '--config-file', type: :string
16
+
17
+ app.command '--extract-to-json' do |command|
18
+ command.summary 'Extract data from Wordpress XML dump file and save as JSON files'
19
+ command.options do |opts|
20
+ opts.opt :omit_content_model, 'omit', short: '-o', long: '--omit-content-model', type: :boolean, default: false
21
+ end
22
+ command.action do |options, arguments|
23
+ Command::CLI.new(options, arguments).execute
24
+ end
25
+ end
26
+ app.command '--create-contentful-model-from-json' do |command|
27
+ command.summary 'Create content types files, based on contentful structure json file. View README'
28
+ command.action do |options, arguments|
29
+ Command::CLI.new(options, arguments).execute
30
+ end
31
+ end
32
+ app.command '--convert-content-model-to-json' do |command|
33
+ command.summary 'Transform content_model file into contentful_structure import form. View README'
34
+ command.action do |options, arguments|
35
+ Command::CLI.new(options, arguments).execute
36
+ end
37
+ end
38
+
39
+ app.command '--convert-markup' do |command|
40
+ command.summary 'Convert markup to markdown in post content. View README'
41
+ command.action do |options, arguments|
42
+ Command::CLI.new(options, arguments).execute
43
+ end
44
+ end
45
+ end
46
+ end
data/lib/cli.rb ADDED
@@ -0,0 +1,11 @@
1
+ require_relative 'migrator'
2
+ require 'yaml'
3
+
4
+ module Command
5
+ class CLI < Escort::ActionCommand::Base
6
+ def execute
7
+ setting_file = YAML.load_file(global_options[:file])
8
+ Migrator.new(setting_file).run(command_name, command_options)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ require 'active_support/core_ext/hash'
2
+ module Contentful
3
+ class Configuration
4
+ attr_reader :space_id,
5
+ :data_dir,
6
+ :collections_dir,
7
+ :entries_dir,
8
+ :assets_dir,
9
+ :wordpress_xml,
10
+ :settings
11
+
12
+ def initialize(settings)
13
+ @settings = settings
14
+ @data_dir = settings['data_dir']
15
+ validate_required_parameters
16
+ @wordpress_xml = settings['wordpress_xml_path']
17
+ @collections_dir = "#{data_dir}/collections"
18
+ @entries_dir = "#{data_dir}/entries"
19
+ @assets_dir = "#{data_dir}/assets"
20
+ @space_id = settings['space_id']
21
+ end
22
+
23
+ def validate_required_parameters
24
+ fail ArgumentError, 'Set PATH to data_dir. Folder where all data will be stored. View README' if settings['data_dir'].nil?
25
+ fail ArgumentError, 'Set PATH to Wordpress XML file. View README' if settings['wordpress_xml_path'].nil?
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,58 @@
1
+ module Contentful
2
+ module Converter
3
+ class ContentTypesStructureCreator
4
+ attr_reader :config, :logger
5
+
6
+ def initialize(config)
7
+ @config = config
8
+ @logger = Logger.new(STDOUT)
9
+ end
10
+
11
+ def create_content_type_json_file(content_type_name, values)
12
+ collection = {
13
+ id: values[:id],
14
+ name: values[:name],
15
+ description: values[:description],
16
+ displayField: values[:displayField],
17
+ fields: create_fields(values[:fields])
18
+ }
19
+ write_json_to_file("#{config.collections_dir}/#{content_type_name}.json", collection)
20
+ logger.info "Saving #{content_type_name}.json to #{config.collections_dir}"
21
+ end
22
+
23
+ def create_fields(fields)
24
+ fields.each_with_object([]) do |(field, value), results|
25
+ results << {
26
+ name: create_field(field, value).capitalize,
27
+ id: create_field(field, value),
28
+ type: create_type_field(value),
29
+ link_type: create_link_type_field(value),
30
+ link: create_link_field(value)
31
+ }.compact
32
+ end
33
+ end
34
+
35
+ def create_field(field, value)
36
+ value.is_a?(Hash) ? value[:id] : field
37
+ end
38
+
39
+ def create_link_type_field(value)
40
+ value.is_a?(Hash) ? value[:link_type] : nil
41
+ end
42
+
43
+ def create_type_field(value)
44
+ value.is_a?(Hash) ? value[:type] : value
45
+ end
46
+
47
+ def create_link_field(value)
48
+ value.is_a?(Hash) ? value[:link] : nil
49
+ end
50
+
51
+ def write_json_to_file(path, data)
52
+ File.open(path, 'w') do |file|
53
+ file.write(JSON.pretty_generate(data))
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,119 @@
1
+ require_relative 'content_types_structure_creator'
2
+
3
+ module Contentful
4
+ module Converter
5
+ class ContentfulModelToJson
6
+ attr_reader :config, :logger, :converted_model_dir, :content_types, :omit_content_model
7
+
8
+ FIELD_TYPE = %w( Link Array )
9
+
10
+ def initialize(settings)
11
+ @config = settings
12
+ @logger = Logger.new(STDOUT)
13
+ end
14
+
15
+ def create_content_type_json(omit_content_model_flag = true)
16
+ @omit_content_model = omit_content_model_flag
17
+ contentful_structure = load_contentful_structure_file
18
+ logger.info 'Create JSON files with content types structure...'
19
+ contentful_structure.each do |content_type, values|
20
+ content_type_name = content_type_name(content_type)
21
+ create_directory(config.collections_dir)
22
+ ContentTypesStructureCreator.new(config).create_content_type_json_file(content_type_name, values)
23
+ end
24
+ logger.info 'Done!'
25
+ end
26
+
27
+ def convert_to_import_form
28
+ set_content_model_parameters
29
+ logger.info 'Converting Contentful model to Contentful import structure...'
30
+ File.open(converted_model_dir, 'w') { |file| file.write({}) }
31
+ contentful_file = JSON.parse(File.read(content_types))['items']
32
+ contentful_file.each do |content_type|
33
+ parsed_content_type = {
34
+ id: content_type['sys']['id'],
35
+ name: content_type['name'],
36
+ description: content_type['description'],
37
+ displayField: content_type['displayField'],
38
+ fields: {}.merge!(create_contentful_fields(content_type))
39
+ }
40
+ import_form = JSON.parse(File.read(converted_model_dir))
41
+ File.open(converted_model_dir, 'w') do |file|
42
+ file.write(JSON.pretty_generate(import_form.merge!(content_type['name'] => parsed_content_type)))
43
+ end
44
+ end
45
+ logger.info "Done! Contentful import structure file saved in #{converted_model_dir}"
46
+ end
47
+
48
+ def create_contentful_fields(content_type)
49
+ content_type['fields'].each_with_object({}) do |(field, _value), results|
50
+ id = link_id(field)
51
+ results[id] = case field['type']
52
+ when 'Link'
53
+ { id: field['id'], type: field['linkType'], link: 'Link' }
54
+ when 'Array'
55
+ { id: field['id'], type: field['type'], link_type: field['items']['linkType'], link: field['items']['type'] }
56
+ else
57
+ field['type']
58
+ end
59
+ end
60
+ end
61
+
62
+ def link_id(field)
63
+ if FIELD_TYPE.include? field['type']
64
+ field['name'].capitalize
65
+ else
66
+ field['id']
67
+ end
68
+ end
69
+
70
+ def content_type_name(content_type)
71
+ I18n.transliterate(content_type).underscore.tr(' ', '_')
72
+ end
73
+
74
+ def create_directory(path)
75
+ FileUtils.mkdir_p(path) unless File.directory?(path)
76
+ end
77
+
78
+ # If contentful_structure JSON file exists, it will load the file. If not, it will automatically create an empty file.
79
+ # This file is required to convert contentful model to contentful import structure.
80
+ def load_contentful_structure_file
81
+ fail ArgumentError, 'Set PATH for contentful structure JSON file. View README' if omit_content_model?
82
+ file_exists? ? load_existing_contentful_structure_file : create_empty_contentful_structure_file
83
+ end
84
+
85
+ def omit_content_model?
86
+ omit_content_model == true ? config.settings['contentful_structure_dir'].nil? : false
87
+ end
88
+
89
+ def file_exists?
90
+ omit_content_model == false ? true : File.exist?(config.settings['contentful_structure_dir'])
91
+ end
92
+
93
+ def create_empty_contentful_structure_file
94
+ File.open(config.settings['contentful_structure_dir'], 'w') { |file| file.write({}) }
95
+ load_existing_contentful_structure_file
96
+ end
97
+
98
+ def load_existing_contentful_structure_file
99
+ if omit_content_model == true
100
+ JSON.parse(File.read(config.settings['contentful_structure_dir']), symbolize_names: true).with_indifferent_access
101
+ else
102
+ spec = Gem::Specification.find_by_name('wordpress-exporter')
103
+ JSON.parse(File.read("#{spec.gem_dir}/wordpress_settings/default_contentful_structure.json"), symbolize_names: true).with_indifferent_access
104
+ end
105
+ end
106
+
107
+ def set_content_model_parameters
108
+ validate_content_model_files
109
+ @converted_model_dir = config.settings['converted_model_dir']
110
+ @content_types = config.settings['content_model_json']
111
+ end
112
+
113
+ def validate_content_model_files
114
+ fail ArgumentError, 'Set PATH for content model JSON file. View README' if config.settings['content_model_json'].nil?
115
+ fail ArgumentError, 'Set PATH where converted content model file will be saved. View README' if config.settings['converted_model_dir'].nil?
116
+ end
117
+ end
118
+ end
119
+ end