contentful-importer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +38 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +87 -0
- data/LICENSE +22 -0
- data/README.md +327 -0
- data/Rakefile +7 -0
- data/bin/contentful-importer +85 -0
- data/contentful_importer.gemspec +38 -0
- data/example_settings/contentful_model.json +288 -0
- data/example_settings/contentful_structure.json +78 -0
- data/example_settings/files_meaning.txt +15 -0
- data/example_settings/settings.yml +16 -0
- data/lib/cli.rb +13 -0
- data/lib/configuration.rb +36 -0
- data/lib/converters/content_types_structure_creator.rb +60 -0
- data/lib/converters/contentful_model_to_json.rb +109 -0
- data/lib/importer/data_organizer.rb +117 -0
- data/lib/importer/mime_content_type.rb +564 -0
- data/lib/importer/parallel_importer.rb +429 -0
- data/lib/json_schema_validator.rb +64 -0
- data/lib/migrator.rb +39 -0
- data/lib/version.rb +3 -0
- data/spec/fixtures/import_files/assets/image/image_1.json +9 -0
- data/spec/fixtures/import_files/assets/image/image_2.json +9 -0
- data/spec/fixtures/import_files/assets/image/image_3.json +9 -0
- data/spec/fixtures/import_files/assets/image/image_4.json +9 -0
- data/spec/fixtures/import_files/collections/job_skills.json +13 -0
- data/spec/fixtures/import_files/collections/jobs.json +37 -0
- data/spec/fixtures/import_files/collections/profile.json +19 -0
- data/spec/fixtures/import_files/collections/user.json +36 -0
- data/spec/fixtures/import_files/entries/job_skills/job_skills_1.json +7 -0
- data/spec/fixtures/import_files/entries/job_skills/job_skills_10.json +7 -0
- data/spec/fixtures/import_files/entries/job_skills/job_skills_2.json +7 -0
- data/spec/fixtures/import_files/entries/job_skills/job_skills_3.json +7 -0
- data/spec/fixtures/import_files/entries/job_skills/job_skills_4.json +7 -0
- data/spec/fixtures/import_files/entries/job_skills/job_skills_5.json +7 -0
- data/spec/fixtures/import_files/entries/job_skills/job_skills_6.json +7 -0
- data/spec/fixtures/import_files/entries/job_skills/job_skills_7.json +7 -0
- data/spec/fixtures/import_files/entries/job_skills/job_skills_8.json +7 -0
- data/spec/fixtures/import_files/entries/job_skills/job_skills_9.json +7 -0
- data/spec/fixtures/import_files/entries/jobs/jobs_1.json +56 -0
- data/spec/fixtures/import_files/entries/jobs/jobs_2.json +55 -0
- data/spec/fixtures/import_files/entries/jobs/jobs_4.json +49 -0
- data/spec/fixtures/import_files/entries/profile/profile_1.json +12 -0
- data/spec/fixtures/import_files/entries/profile/profile_2.json +12 -0
- data/spec/fixtures/import_files/entries/user/user_1.json +24 -0
- data/spec/fixtures/import_files/entries/user/user_2.json +20 -0
- data/spec/fixtures/import_files/logs/log_published_assets.csv +4 -0
- data/spec/fixtures/import_files/logs/log_published_entries.csv +23 -0
- data/spec/fixtures/import_files/logs/success_assets.csv +4 -0
- data/spec/fixtures/import_files/logs/success_published_assets.csv +0 -0
- data/spec/fixtures/import_files/logs/success_published_entries.csv +22 -0
- data/spec/fixtures/import_files/logs/success_thread_0.csv +12 -0
- data/spec/fixtures/import_files/logs/success_thread_1.csv +11 -0
- data/spec/fixtures/import_files/threads/0/1TVvxCqoRq0qUYAOQuOqys_2.json +20 -0
- data/spec/fixtures/import_files/threads/0/2soCP557HGKoOOK0SqmMOm_1.json +7 -0
- data/spec/fixtures/import_files/threads/0/2soCP557HGKoOOK0SqmMOm_10.json +7 -0
- data/spec/fixtures/import_files/threads/0/2soCP557HGKoOOK0SqmMOm_2.json +7 -0
- data/spec/fixtures/import_files/threads/0/2soCP557HGKoOOK0SqmMOm_3.json +7 -0
- data/spec/fixtures/import_files/threads/0/2soCP557HGKoOOK0SqmMOm_4.json +7 -0
- data/spec/fixtures/import_files/threads/0/2soCP557HGKoOOK0SqmMOm_5.json +7 -0
- data/spec/fixtures/import_files/threads/0/2soCP557HGKoOOK0SqmMOm_6.json +7 -0
- data/spec/fixtures/import_files/threads/0/2soCP557HGKoOOK0SqmMOm_7.json +7 -0
- data/spec/fixtures/import_files/threads/0/6H6pGAV1PUsuoAW26Iu48W_1.json +9 -0
- data/spec/fixtures/import_files/threads/0/6H6pGAV1PUsuoAW26Iu48W_2.json +9 -0
- data/spec/fixtures/import_files/threads/0/6H6pGAV1PUsuoAW26Iu48W_3.json +9 -0
- data/spec/fixtures/import_files/threads/0/6H6pGAV1PUsuoAW26Iu48W_4.json +9 -0
- data/spec/fixtures/import_files/threads/0/6H6pGAV1PUsuoAW26Iu48W_5.json +9 -0
- data/spec/fixtures/import_files/threads/1/1TVvxCqoRq0qUYAOQuOqys_1.json +24 -0
- data/spec/fixtures/import_files/threads/1/1TVvxCqoRq0qUYAOQuOqys_2.json +20 -0
- data/spec/fixtures/import_files/threads/1/2soCP557HGKoOOK0SqmMOm_6.json +7 -0
- data/spec/fixtures/import_files/threads/1/2soCP557HGKoOOK0SqmMOm_7.json +7 -0
- data/spec/fixtures/import_files/threads/1/2soCP557HGKoOOK0SqmMOm_8.json +7 -0
- data/spec/fixtures/import_files/threads/1/2soCP557HGKoOOK0SqmMOm_9.json +7 -0
- data/spec/fixtures/import_files/threads/1/4L1bg4WQ5aWQMiE82ouag_1.json +56 -0
- data/spec/fixtures/import_files/threads/1/4L1bg4WQ5aWQMiE82ouag_2.json +55 -0
- data/spec/fixtures/import_files/threads/1/4L1bg4WQ5aWQMiE82ouag_4.json +49 -0
- data/spec/fixtures/import_files/threads/1/4WFZh4MwC4Mc0EQWAeOY8A_1.json +12 -0
- data/spec/fixtures/import_files/threads/1/4WFZh4MwC4Mc0EQWAeOY8A_2.json +12 -0
- data/spec/fixtures/import_files/threads/assets/0/image_1.json +9 -0
- data/spec/fixtures/import_files/threads/assets/0/image_2.json +9 -0
- data/spec/fixtures/import_files/threads/assets/0/image_3.json +9 -0
- data/spec/fixtures/import_files/threads/assets/0/image_4.json +9 -0
- data/spec/fixtures/settings/contentful_model.json +252 -0
- data/spec/fixtures/settings/contentful_structure.json +73 -0
- data/spec/fixtures/settings/contentful_structure_test.json +66 -0
- data/spec/fixtures/settings/settings.yml +12 -0
- data/spec/fixtures/vcr_cassettes/create_asset.yml +621 -0
- data/spec/fixtures/vcr_cassettes/create_entry.yml +122 -0
- data/spec/fixtures/vcr_cassettes/create_space.yml +87 -0
- data/spec/fixtures/vcr_cassettes/import_assets.yml +2822 -0
- data/spec/fixtures/vcr_cassettes/import_content_types.yml +1915 -0
- data/spec/fixtures/vcr_cassettes/import_entries.yml +5066 -0
- data/spec/fixtures/vcr_cassettes/import_entry.yml +363 -0
- data/spec/fixtures/vcr_cassettes/invalid_credentials.yml +69 -0
- data/spec/fixtures/vcr_cassettes/publish_an_entry.yml +214 -0
- data/spec/fixtures/vcr_cassettes/publish_asset.yml +895 -0
- data/spec/fixtures/vcr_cassettes/publish_entries.yml +5121 -0
- data/spec/fixtures/vcr_cassettes/valid_credentials.yml +7360 -0
- data/spec/lib/configuration_spec.rb +22 -0
- data/spec/lib/importer/parallel_importer_spec.rb +161 -0
- data/spec/lib/json_schema_validator_spec.rb +63 -0
- data/spec/lib/migrator_spec.rb +99 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/db_rows_json.rb +9 -0
- data/spec/support/shared_configuration.rb +22 -0
- data/spec/support/vcr.rb +16 -0
- metadata +436 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
1. contentful_model.json
|
2
|
+
|
3
|
+
File which contains downloaded the entire structure of the Space.
|
4
|
+
To get this file use:
|
5
|
+
curl -X GET \
|
6
|
+
-H 'Authorization: Bearer ACCESS_TOKEN' \
|
7
|
+
'https://api.contentful.com/spaces/SPACE_ID/content_types' > contentful_model.json
|
8
|
+
|
9
|
+
2. contentful_structure.json
|
10
|
+
|
11
|
+
Contentful model structure converted to a form that importer supports.Contains models of content types with attributes and their types.
|
12
|
+
|
13
|
+
3. settings.yml
|
14
|
+
|
15
|
+
Configuration file which contains defined paths to the files needed to export data.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#PATH to all data
|
2
|
+
data_dir: PATH_TO_ALL_DATA
|
3
|
+
|
4
|
+
########## IMPORT DATA TO CONTENTFUL ##########
|
5
|
+
|
6
|
+
#Contentful credentials - Define before import data to Contentful.
|
7
|
+
access_token: ACCESS_TOKEN
|
8
|
+
organization_id: ORGANIZATION_ID
|
9
|
+
space_id: DEFINE_SPACE_ID_BEFORE_IMPORT
|
10
|
+
default_locale: LOCALE_CODE
|
11
|
+
|
12
|
+
## CONVERT CONTENTFUL MODEL TO CONTENTFUL IMPORT STRUCTURE
|
13
|
+
content_model_json: example_settings/contentful_model.json
|
14
|
+
converted_model_dir: example_settings/contentful_structure.json
|
15
|
+
|
16
|
+
contentful_structure_dir: example_settings/contentful_structure.json
|
data/lib/cli.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'migrator'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Command
|
5
|
+
class CLI < Escort::ActionCommand::Base
|
6
|
+
|
7
|
+
def execute
|
8
|
+
setting_file = YAML.load_file(global_options[:file])
|
9
|
+
Migrator.new(setting_file).run(command_name, command_options)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'active_support/core_ext/hash'
|
2
|
+
module Contentful
|
3
|
+
class Configuration
|
4
|
+
attr_reader :space_id,
|
5
|
+
:config,
|
6
|
+
:data_dir,
|
7
|
+
:collections_dir,
|
8
|
+
:entries_dir,
|
9
|
+
:assets_dir,
|
10
|
+
:log_files_dir,
|
11
|
+
:threads_dir,
|
12
|
+
:imported_entries,
|
13
|
+
:published_entries,
|
14
|
+
:published_assets,
|
15
|
+
:space_id
|
16
|
+
|
17
|
+
def initialize(settings)
|
18
|
+
@config = settings
|
19
|
+
validate_required_parameters
|
20
|
+
@data_dir = settings['data_dir']
|
21
|
+
@collections_dir = "#{data_dir}/collections"
|
22
|
+
@entries_dir = "#{data_dir}/entries"
|
23
|
+
@assets_dir = "#{data_dir}/assets"
|
24
|
+
@log_files_dir = "#{data_dir}/logs"
|
25
|
+
@threads_dir = "#{data_dir}/threads"
|
26
|
+
@imported_entries = []
|
27
|
+
@published_entries = []
|
28
|
+
@published_assets = []
|
29
|
+
@space_id = settings['space_id']
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate_required_parameters
|
33
|
+
fail ArgumentError, 'Set PATH to data_dir. Folder where all data will be stored. View README' if config['data_dir'].nil?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Contentful
|
2
|
+
module Converter
|
3
|
+
class ContentTypesStructureCreator
|
4
|
+
|
5
|
+
attr_reader :config, :logger
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
@logger = Logger.new(STDOUT)
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_content_type_json_file(content_type_name, values)
|
13
|
+
collection = {
|
14
|
+
id: values[:id],
|
15
|
+
name: values[:name],
|
16
|
+
description: values[:description],
|
17
|
+
displayField: values[:displayField],
|
18
|
+
fields: create_fields(values[:fields])
|
19
|
+
}
|
20
|
+
write_json_to_file("#{config.collections_dir}/#{content_type_name}.json", collection)
|
21
|
+
logger.info "Saving #{content_type_name}.json to #{config.collections_dir}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_fields(fields)
|
25
|
+
fields.each_with_object([]) do |(field, value), results|
|
26
|
+
results << {
|
27
|
+
name: create_field(field, value).capitalize,
|
28
|
+
id: create_field(field, value),
|
29
|
+
type: create_type_field(value),
|
30
|
+
link_type: create_link_type_field(value),
|
31
|
+
link: create_link_field(value)
|
32
|
+
}.compact
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_field(field, value)
|
37
|
+
value.is_a?(Hash) ? value[:id] : field
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_link_type_field(value)
|
41
|
+
value.is_a?(Hash) ? value[:link_type] : nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_type_field(value)
|
45
|
+
value.is_a?(Hash) ? value[:type] : value
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_link_field(value)
|
49
|
+
value.is_a?(Hash) ? value[:link] : nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def write_json_to_file(path, data)
|
53
|
+
File.open(path, 'w') do |file|
|
54
|
+
file.write(JSON.pretty_generate(data))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,109 @@
|
|
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
|
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
|
16
|
+
contentful_structure = load_contentful_structure_file
|
17
|
+
logger.info 'Create JSON files with content types structure...'
|
18
|
+
contentful_structure.each do |content_type, values|
|
19
|
+
content_type_name = content_type_name(content_type)
|
20
|
+
create_directory(config.collections_dir)
|
21
|
+
ContentTypesStructureCreator.new(config).create_content_type_json_file(content_type_name, values)
|
22
|
+
end
|
23
|
+
logger.info 'Done!'
|
24
|
+
end
|
25
|
+
|
26
|
+
def convert_to_import_form
|
27
|
+
set_content_model_parameters
|
28
|
+
logger.info 'Converting Contentful model to Contentful import structure...'
|
29
|
+
File.open(converted_model_dir, 'w') { |file| file.write({}) }
|
30
|
+
content_type_file = JSON.parse(File.read(content_types))['items']
|
31
|
+
content_type_file.each do |content_type|
|
32
|
+
parsed_content_type = {
|
33
|
+
id: content_type['sys']['id'],
|
34
|
+
name: content_type['name'],
|
35
|
+
description: content_type['description'],
|
36
|
+
displayField: content_type['displayField'],
|
37
|
+
fields: create_content_type_fields(content_type)
|
38
|
+
}
|
39
|
+
import_form = JSON.parse(File.read(converted_model_dir))
|
40
|
+
File.open(converted_model_dir, 'w') do |file|
|
41
|
+
file.write(JSON.pretty_generate(import_form.merge!(content_type['name'] => parsed_content_type)))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
logger.info "Done! Contentful import structure file saved in #{converted_model_dir}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_content_type_fields(content_type)
|
48
|
+
content_type['fields'].each_with_object({}) do |(field, _value), results|
|
49
|
+
id = link_id(field)
|
50
|
+
results[id] = case field['type']
|
51
|
+
when 'Link'
|
52
|
+
{id: field['id'], type: field['linkType'], link: 'Link'}
|
53
|
+
when 'Array'
|
54
|
+
{id: field['id'], type: field['type'], link_type: field['items']['linkType'], link: field['items']['type']}
|
55
|
+
else
|
56
|
+
field['type']
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def link_id(field)
|
62
|
+
if FIELD_TYPE.include? field['type']
|
63
|
+
field['name'].capitalize
|
64
|
+
else
|
65
|
+
field['id']
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def content_type_name(content_type)
|
70
|
+
I18n.transliterate(content_type).underscore.tr(' ', '_')
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_directory(path)
|
74
|
+
FileUtils.mkdir_p(path) unless File.directory?(path)
|
75
|
+
end
|
76
|
+
|
77
|
+
# If contentful_structure JSON file exists, it will load the file. If not, it will automatically create an empty file.
|
78
|
+
# This file is required to convert contentful model to contentful import structure.
|
79
|
+
def load_contentful_structure_file
|
80
|
+
fail ArgumentError, 'Set PATH for contentful structure JSON file. View README' if config.config['contentful_structure_dir'].nil?
|
81
|
+
file_exists? ? load_existing_contentful_structure_file : create_empty_contentful_structure_file
|
82
|
+
end
|
83
|
+
|
84
|
+
def file_exists?
|
85
|
+
File.exists?(config.config['contentful_structure_dir'])
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_empty_contentful_structure_file
|
89
|
+
File.open(config.config['contentful_structure_dir'], 'w') { |file| file.write({}) }
|
90
|
+
load_existing_contentful_structure_file
|
91
|
+
end
|
92
|
+
|
93
|
+
def load_existing_contentful_structure_file
|
94
|
+
JSON.parse(File.read(config.config['contentful_structure_dir']), symbolize_names: true).with_indifferent_access
|
95
|
+
end
|
96
|
+
|
97
|
+
def set_content_model_parameters
|
98
|
+
validate_content_model_files
|
99
|
+
@converted_model_dir = config.config['converted_model_dir']
|
100
|
+
@content_types = config.config['content_model_json']
|
101
|
+
end
|
102
|
+
|
103
|
+
def validate_content_model_files
|
104
|
+
fail ArgumentError, 'Set PATH for content model JSON file. View README' if config.config['content_model_json'].nil?
|
105
|
+
fail ArgumentError, 'Set PATH where converted content model file will be saved. View README' if config.config['converted_model_dir'].nil?
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'thread'
|
3
|
+
require_relative 'parallel_importer'
|
4
|
+
|
5
|
+
module Contentful
|
6
|
+
class DataOrganizer
|
7
|
+
|
8
|
+
attr_reader :config, :split_params, :logger
|
9
|
+
|
10
|
+
def initialize(settings)
|
11
|
+
@config = settings
|
12
|
+
@split_params = {object_index: 0, current_thread: 0}
|
13
|
+
@logger = Logger.new(STDOUT)
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute(threads_count)
|
17
|
+
create_threads_subdirectories(threads_count, true)
|
18
|
+
split_entries(threads_count)
|
19
|
+
end
|
20
|
+
|
21
|
+
def split_assets_to_threads(threads_count)
|
22
|
+
create_threads_subdirectories(threads_count, false, {assets: 'assets/'})
|
23
|
+
split_assets(threads_count)
|
24
|
+
end
|
25
|
+
|
26
|
+
def split_entries(threads_count)
|
27
|
+
entries_per_thread_count = total_entries_count / threads_count
|
28
|
+
Dir.glob("#{config.entries_dir}/*") do |dir_path|
|
29
|
+
collection_name = File.basename(dir_path)
|
30
|
+
if has_contentful_structure?(collection_name)
|
31
|
+
content_type_id = content_type_id_from_file(collection_name)
|
32
|
+
process_collection_files(content_type_id, dir_path, entries_per_thread_count, threads_count)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def split_assets(threads_count)
|
38
|
+
asset_per_thread = total_assets_count / threads_count
|
39
|
+
Dir.glob("#{config.assets_dir}/**/*json") do |asset_path|
|
40
|
+
copy_asset(asset_path)
|
41
|
+
split_params[:object_index] += 1
|
42
|
+
count_index_files(asset_per_thread, threads_count)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def process_collection_files(content_type_id, dir_path, entries_per_thread_count, threads_count)
|
47
|
+
logger.info "Processing collection: #{content_type_id}"
|
48
|
+
Dir.glob("#{dir_path}/*.json") do |entry_path|
|
49
|
+
copy_entry(entry_path, split_params[:current_thread], content_type_id)
|
50
|
+
split_params[:object_index] += 1
|
51
|
+
count_index_files(entries_per_thread_count, threads_count)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def count_index_files(objects_per_thread_count, threads_count)
|
56
|
+
if split_params[:object_index] == objects_per_thread_count
|
57
|
+
split_params[:object_index] = 0
|
58
|
+
set_current_thread(threads_count)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_current_thread(threads_count)
|
63
|
+
split_params[:current_thread] += 1
|
64
|
+
split_params[:current_thread] = 0 if split_params[:current_thread] == threads_count
|
65
|
+
end
|
66
|
+
|
67
|
+
def has_contentful_structure?(collection_file)
|
68
|
+
File.exist?("#{config.collections_dir}/#{collection_file}.json")
|
69
|
+
end
|
70
|
+
|
71
|
+
def content_type_id_from_file(collection_file)
|
72
|
+
JSON.parse(File.read("#{config.collections_dir}/#{collection_file}.json"))['id']
|
73
|
+
end
|
74
|
+
|
75
|
+
def new_entry_name(content_type_id, entry_path)
|
76
|
+
"#{content_type_id}_#{File.basename(entry_path, '.*').match(/(\d+)/)[0]}.json"
|
77
|
+
end
|
78
|
+
|
79
|
+
def copy_entry(entry_path, current_thread, content_type_id)
|
80
|
+
FileUtils.cp entry_path, "#{config.threads_dir}/#{current_thread}/#{new_entry_name(content_type_id, entry_path)}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def copy_asset(asset_path)
|
84
|
+
FileUtils.cp asset_path, "#{config.threads_dir}/assets/#{split_params[:current_thread]}/#{File.basename(asset_path)}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_threads_subdirectories(threads_count, validate, dir = {})
|
88
|
+
validate_collections_files if validate
|
89
|
+
create_directory(config.threads_dir)
|
90
|
+
threads_count.times do |thread_id|
|
91
|
+
create_directory("#{config.threads_dir}/#{dir[:assets]}#{thread_id}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def create_directory(path)
|
96
|
+
FileUtils.mkdir_p(path) unless File.directory?(path)
|
97
|
+
end
|
98
|
+
|
99
|
+
def total_entries_count
|
100
|
+
total_number = 0
|
101
|
+
Dir.glob("#{config.entries_dir}/*") do |dir_path|
|
102
|
+
collection_name = File.basename(dir_path)
|
103
|
+
total_number += Dir.glob("#{config.entries_dir}/#{collection_name}/*").count if has_contentful_structure?(collection_name)
|
104
|
+
end
|
105
|
+
total_number
|
106
|
+
end
|
107
|
+
|
108
|
+
def total_assets_count
|
109
|
+
Dir.glob("#{config.assets_dir}/**/*json").count
|
110
|
+
end
|
111
|
+
|
112
|
+
def validate_collections_files
|
113
|
+
fail ArgumentError, "Make sure the #{config.collections_dir} directory exists and the content structure resides within it. View README" unless Dir.exist?(config.collections_dir)
|
114
|
+
fail ArgumentError, 'Collections directory is empty! Create content types JSON files. View README' if Dir.glob("#{config.collections_dir}/*").empty?
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,564 @@
|
|
1
|
+
module Contentful
|
2
|
+
class MimeContentType
|
3
|
+
EXTENSION_LIST = {'.323' => 'text/h323',
|
4
|
+
'.3g2' => 'video/3gpp2',
|
5
|
+
'.3gp' => 'video/3gpp',
|
6
|
+
'.3gp2' => 'video/3gpp2',
|
7
|
+
'.3gpp' => 'video/3gpp',
|
8
|
+
'.7z' => 'application/x-7z-compressed',
|
9
|
+
'.aa' => 'audio/audible',
|
10
|
+
'.AAC' => 'audio/aac',
|
11
|
+
'.aaf' => 'application/octet-stream',
|
12
|
+
'.aax' => 'audio/vnd.audible.aax',
|
13
|
+
'.ac3' => 'audio/ac3',
|
14
|
+
'.aca' => 'application/octet-stream',
|
15
|
+
'.accda' => 'application/msaccess.addin',
|
16
|
+
'.accdb' => 'application/msaccess',
|
17
|
+
'.accdc' => 'application/msaccess.cab',
|
18
|
+
'.accde' => 'application/msaccess',
|
19
|
+
'.accdr' => 'application/msaccess.runtime',
|
20
|
+
'.accdt' => 'application/msaccess',
|
21
|
+
'.accdw' => 'application/msaccess.webapplication',
|
22
|
+
'.accft' => 'application/msaccess.ftemplate',
|
23
|
+
'.acx' => 'application/internet-property-stream',
|
24
|
+
'.AddIn' => 'text/xml',
|
25
|
+
'.ade' => 'application/msaccess',
|
26
|
+
'.adobebridge' => 'application/x-bridge-url',
|
27
|
+
'.adp' => 'application/msaccess',
|
28
|
+
'.ADT' => 'audio/vnd.dlna.adts',
|
29
|
+
'.ADTS' => 'audio/aac',
|
30
|
+
'.afm' => 'application/octet-stream',
|
31
|
+
'.ai' => 'application/postscript',
|
32
|
+
'.aif' => 'audio/x-aiff',
|
33
|
+
'.aifc' => 'audio/aiff',
|
34
|
+
'.aiff' => 'audio/aiff',
|
35
|
+
'.air' => 'application/vnd.adobe.air-application-installer-package+zip',
|
36
|
+
'.amc' => 'application/x-mpeg',
|
37
|
+
'.application' => 'application/x-ms-application',
|
38
|
+
'.art' => 'image/x-jg',
|
39
|
+
'.asa' => 'application/xml',
|
40
|
+
'.asax' => 'application/xml',
|
41
|
+
'.ascx' => 'application/xml',
|
42
|
+
'.asd' => 'application/octet-stream',
|
43
|
+
'.asf' => 'video/x-ms-asf',
|
44
|
+
'.ashx' => 'application/xml',
|
45
|
+
'.asi' => 'application/octet-stream',
|
46
|
+
'.asm' => 'text/plain',
|
47
|
+
'.asmx' => 'application/xml',
|
48
|
+
'.aspx' => 'application/xml',
|
49
|
+
'.asr' => 'video/x-ms-asf',
|
50
|
+
'.asx' => 'video/x-ms-asf',
|
51
|
+
'.atom' => 'application/atom+xml',
|
52
|
+
'.au' => 'audio/basic',
|
53
|
+
'.avi' => 'video/x-msvideo',
|
54
|
+
'.axs' => 'application/olescript',
|
55
|
+
'.bas' => 'text/plain',
|
56
|
+
'.bcpio' => 'application/x-bcpio',
|
57
|
+
'.bin' => 'application/octet-stream',
|
58
|
+
'.bmp' => 'image/bmp',
|
59
|
+
'.c' => 'text/plain',
|
60
|
+
'.cab' => 'application/octet-stream',
|
61
|
+
'.caf' => 'audio/x-caf',
|
62
|
+
'.calx' => 'application/vnd.ms-office.calx',
|
63
|
+
'.cat' => 'application/vnd.ms-pki.seccat',
|
64
|
+
'.cc' => 'text/plain',
|
65
|
+
'.cd' => 'text/plain',
|
66
|
+
'.cdda' => 'audio/aiff',
|
67
|
+
'.cdf' => 'application/x-cdf',
|
68
|
+
'.cer' => 'application/x-x509-ca-cert',
|
69
|
+
'.chm' => 'application/octet-stream',
|
70
|
+
'.class' => 'application/x-java-applet',
|
71
|
+
'.clp' => 'application/x-msclip',
|
72
|
+
'.cmx' => 'image/x-cmx',
|
73
|
+
'.cnf' => 'text/plain',
|
74
|
+
'.cod' => 'image/cis-cod',
|
75
|
+
'.config' => 'application/xml',
|
76
|
+
'.contact' => 'text/x-ms-contact',
|
77
|
+
'.coverage' => 'application/xml',
|
78
|
+
'.cpio' => 'application/x-cpio',
|
79
|
+
'.cpp' => 'text/plain',
|
80
|
+
'.crd' => 'application/x-mscardfile',
|
81
|
+
'.crl' => 'application/pkix-crl',
|
82
|
+
'.crt' => 'application/x-x509-ca-cert',
|
83
|
+
'.cs' => 'text/plain',
|
84
|
+
'.csdproj' => 'text/plain',
|
85
|
+
'.csh' => 'application/x-csh',
|
86
|
+
'.csproj' => 'text/plain',
|
87
|
+
'.css' => 'text/css',
|
88
|
+
'.csv' => 'text/csv',
|
89
|
+
'.cur' => 'application/octet-stream',
|
90
|
+
'.cxx' => 'text/plain',
|
91
|
+
'.dat' => 'application/octet-stream',
|
92
|
+
'.datasource' => 'application/xml',
|
93
|
+
'.dbproj' => 'text/plain',
|
94
|
+
'.dcr' => 'application/x-director',
|
95
|
+
'.def' => 'text/plain',
|
96
|
+
'.deploy' => 'application/octet-stream',
|
97
|
+
'.der' => 'application/x-x509-ca-cert',
|
98
|
+
'.dgml' => 'application/xml',
|
99
|
+
'.dib' => 'image/bmp',
|
100
|
+
'.dif' => 'video/x-dv',
|
101
|
+
'.dir' => 'application/x-director',
|
102
|
+
'.disco' => 'text/xml',
|
103
|
+
'.dll' => 'application/x-msdownload',
|
104
|
+
'.dll.config' => 'text/xml',
|
105
|
+
'.dlm' => 'text/dlm',
|
106
|
+
'.doc' => 'application/msword',
|
107
|
+
'.docm' => 'application/vnd.ms-word.document.macroEnabled.12',
|
108
|
+
'.docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
109
|
+
'.dot' => 'application/msword',
|
110
|
+
'.dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
|
111
|
+
'.dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
112
|
+
'.dsp' => 'application/octet-stream',
|
113
|
+
'.dsw' => 'text/plain',
|
114
|
+
'.dtd' => 'text/xml',
|
115
|
+
'.dtsConfig' => 'text/xml',
|
116
|
+
'.dv' => 'video/x-dv',
|
117
|
+
'.dvi' => 'application/x-dvi',
|
118
|
+
'.dwf' => 'drawing/x-dwf',
|
119
|
+
'.dwp' => 'application/octet-stream',
|
120
|
+
'.dxr' => 'application/x-director',
|
121
|
+
'.eml' => 'message/rfc822',
|
122
|
+
'.emz' => 'application/octet-stream',
|
123
|
+
'.eot' => 'application/octet-stream',
|
124
|
+
'.eps' => 'application/postscript',
|
125
|
+
'.etl' => 'application/etl',
|
126
|
+
'.etx' => 'text/x-setext',
|
127
|
+
'.evy' => 'application/envoy',
|
128
|
+
'.exe' => 'application/octet-stream',
|
129
|
+
'.exe.config' => 'text/xml',
|
130
|
+
'.fdf' => 'application/vnd.fdf',
|
131
|
+
'.fif' => 'application/fractals',
|
132
|
+
'.filters' => 'Application/xml',
|
133
|
+
'.fla' => 'application/octet-stream',
|
134
|
+
'.flr' => 'x-world/x-vrml',
|
135
|
+
'.flv' => 'video/x-flv',
|
136
|
+
'.fsscript' => 'application/fsharp-script',
|
137
|
+
'.fsx' => 'application/fsharp-script',
|
138
|
+
'.generictest' => 'application/xml',
|
139
|
+
'.gif' => 'image/gif',
|
140
|
+
'.group' => 'text/x-ms-group',
|
141
|
+
'.gsm' => 'audio/x-gsm',
|
142
|
+
'.gtar' => 'application/x-gtar',
|
143
|
+
'.gz' => 'application/x-gzip',
|
144
|
+
'.h' => 'text/plain',
|
145
|
+
'.hdf' => 'application/x-hdf',
|
146
|
+
'.hdml' => 'text/x-hdml',
|
147
|
+
'.hhc' => 'application/x-oleobject',
|
148
|
+
'.hhk' => 'application/octet-stream',
|
149
|
+
'.hhp' => 'application/octet-stream',
|
150
|
+
'.hlp' => 'application/winhlp',
|
151
|
+
'.hpp' => 'text/plain',
|
152
|
+
'.hqx' => 'application/mac-binhex40',
|
153
|
+
'.hta' => 'application/hta',
|
154
|
+
'.htc' => 'text/x-component',
|
155
|
+
'.htm' => 'text/html',
|
156
|
+
'.html' => 'text/html',
|
157
|
+
'.htt' => 'text/webviewhtml',
|
158
|
+
'.hxa' => 'application/xml',
|
159
|
+
'.hxc' => 'application/xml',
|
160
|
+
'.hxd' => 'application/octet-stream',
|
161
|
+
'.hxe' => 'application/xml',
|
162
|
+
'.hxf' => 'application/xml',
|
163
|
+
'.hxh' => 'application/octet-stream',
|
164
|
+
'.hxi' => 'application/octet-stream',
|
165
|
+
'.hxk' => 'application/xml',
|
166
|
+
'.hxq' => 'application/octet-stream',
|
167
|
+
'.hxr' => 'application/octet-stream',
|
168
|
+
'.hxs' => 'application/octet-stream',
|
169
|
+
'.hxt' => 'text/html',
|
170
|
+
'.hxv' => 'application/xml',
|
171
|
+
'.hxw' => 'application/octet-stream',
|
172
|
+
'.hxx' => 'text/plain',
|
173
|
+
'.i' => 'text/plain',
|
174
|
+
'.ico' => 'image/x-icon',
|
175
|
+
'.ics' => 'application/octet-stream',
|
176
|
+
'.idl' => 'text/plain',
|
177
|
+
'.ief' => 'image/ief',
|
178
|
+
'.iii' => 'application/x-iphone',
|
179
|
+
'.inc' => 'text/plain',
|
180
|
+
'.inf' => 'application/octet-stream',
|
181
|
+
'.inl' => 'text/plain',
|
182
|
+
'.ins' => 'application/x-internet-signup',
|
183
|
+
'.ipa' => 'application/x-itunes-ipa',
|
184
|
+
'.ipg' => 'application/x-itunes-ipg',
|
185
|
+
'.ipproj' => 'text/plain',
|
186
|
+
'.ipsw' => 'application/x-itunes-ipsw',
|
187
|
+
'.iqy' => 'text/x-ms-iqy',
|
188
|
+
'.isp' => 'application/x-internet-signup',
|
189
|
+
'.ite' => 'application/x-itunes-ite',
|
190
|
+
'.itlp' => 'application/x-itunes-itlp',
|
191
|
+
'.itms' => 'application/x-itunes-itms',
|
192
|
+
'.itpc' => 'application/x-itunes-itpc',
|
193
|
+
'.IVF' => 'video/x-ivf',
|
194
|
+
'.jar' => 'application/java-archive',
|
195
|
+
'.java' => 'application/octet-stream',
|
196
|
+
'.jck' => 'application/liquidmotion',
|
197
|
+
'.jcz' => 'application/liquidmotion',
|
198
|
+
'.jfif' => 'image/pjpeg',
|
199
|
+
'.jnlp' => 'application/x-java-jnlp-file',
|
200
|
+
'.jpb' => 'application/octet-stream',
|
201
|
+
'.jpe' => 'image/jpeg',
|
202
|
+
'.jpeg' => 'image/jpeg',
|
203
|
+
'.jpg' => 'image/jpeg',
|
204
|
+
'.js' => 'application/x-javascript',
|
205
|
+
'.jsx' => 'text/jscript',
|
206
|
+
'.jsxbin' => 'text/plain',
|
207
|
+
'.latex' => 'application/x-latex',
|
208
|
+
'.library-ms' => 'application/windows-library+xml',
|
209
|
+
'.lit' => 'application/x-ms-reader',
|
210
|
+
'.loadtest' => 'application/xml',
|
211
|
+
'.lpk' => 'application/octet-stream',
|
212
|
+
'.lsf' => 'video/x-la-asf',
|
213
|
+
'.lst' => 'text/plain',
|
214
|
+
'.lsx' => 'video/x-la-asf',
|
215
|
+
'.lzh' => 'application/octet-stream',
|
216
|
+
'.m13' => 'application/x-msmediaview',
|
217
|
+
'.m14' => 'application/x-msmediaview',
|
218
|
+
'.m1v' => 'video/mpeg',
|
219
|
+
'.m2t' => 'video/vnd.dlna.mpeg-tts',
|
220
|
+
'.m2ts' => 'video/vnd.dlna.mpeg-tts',
|
221
|
+
'.m2v' => 'video/mpeg',
|
222
|
+
'.m3u' => 'audio/x-mpegurl',
|
223
|
+
'.m3u8' => 'audio/x-mpegurl',
|
224
|
+
'.m4a' => 'audio/m4a',
|
225
|
+
'.m4b' => 'audio/m4b',
|
226
|
+
'.m4p' => 'audio/m4p',
|
227
|
+
'.m4r' => 'audio/x-m4r',
|
228
|
+
'.m4v' => 'video/x-m4v',
|
229
|
+
'.mac' => 'image/x-macpaint',
|
230
|
+
'.mak' => 'text/plain',
|
231
|
+
'.man' => 'application/x-troff-man',
|
232
|
+
'.manifest' => 'application/x-ms-manifest',
|
233
|
+
'.map' => 'text/plain',
|
234
|
+
'.master' => 'application/xml',
|
235
|
+
'.mda' => 'application/msaccess',
|
236
|
+
'.mdb' => 'application/x-msaccess',
|
237
|
+
'.mde' => 'application/msaccess',
|
238
|
+
'.mdp' => 'application/octet-stream',
|
239
|
+
'.me' => 'application/x-troff-me',
|
240
|
+
'.mfp' => 'application/x-shockwave-flash',
|
241
|
+
'.mht' => 'message/rfc822',
|
242
|
+
'.mhtml' => 'message/rfc822',
|
243
|
+
'.mid' => 'audio/mid',
|
244
|
+
'.midi' => 'audio/mid',
|
245
|
+
'.mix' => 'application/octet-stream',
|
246
|
+
'.mk' => 'text/plain',
|
247
|
+
'.mmf' => 'application/x-smaf',
|
248
|
+
'.mno' => 'text/xml',
|
249
|
+
'.mny' => 'application/x-msmoney',
|
250
|
+
'.mod' => 'video/mpeg',
|
251
|
+
'.mov' => 'video/quicktime',
|
252
|
+
'.movie' => 'video/x-sgi-movie',
|
253
|
+
'.mp2' => 'video/mpeg',
|
254
|
+
'.mp2v' => 'video/mpeg',
|
255
|
+
'.mp3' => 'audio/mpeg',
|
256
|
+
'.mp4' => 'video/mp4',
|
257
|
+
'.mp4v' => 'video/mp4',
|
258
|
+
'.mpa' => 'video/mpeg',
|
259
|
+
'.mpe' => 'video/mpeg',
|
260
|
+
'.mpeg' => 'video/mpeg',
|
261
|
+
'.mpf' => 'application/vnd.ms-mediapackage',
|
262
|
+
'.mpg' => 'video/mpeg',
|
263
|
+
'.mpp' => 'application/vnd.ms-project',
|
264
|
+
'.mpv2' => 'video/mpeg',
|
265
|
+
'.mqv' => 'video/quicktime',
|
266
|
+
'.ms' => 'application/x-troff-ms',
|
267
|
+
'.msi' => 'application/octet-stream',
|
268
|
+
'.mso' => 'application/octet-stream',
|
269
|
+
'.mts' => 'video/vnd.dlna.mpeg-tts',
|
270
|
+
'.mtx' => 'application/xml',
|
271
|
+
'.mvb' => 'application/x-msmediaview',
|
272
|
+
'.mvc' => 'application/x-miva-compiled',
|
273
|
+
'.mxp' => 'application/x-mmxp',
|
274
|
+
'.nc' => 'application/x-netcdf',
|
275
|
+
'.nsc' => 'video/x-ms-asf',
|
276
|
+
'.nws' => 'message/rfc822',
|
277
|
+
'.ocx' => 'application/octet-stream',
|
278
|
+
'.oda' => 'application/oda',
|
279
|
+
'.odc' => 'text/x-ms-odc',
|
280
|
+
'.odh' => 'text/plain',
|
281
|
+
'.odl' => 'text/plain',
|
282
|
+
'.odp' => 'application/vnd.oasis.opendocument.presentation',
|
283
|
+
'.ods' => 'application/oleobject',
|
284
|
+
'.odt' => 'application/vnd.oasis.opendocument.text',
|
285
|
+
'.one' => 'application/onenote',
|
286
|
+
'.onea' => 'application/onenote',
|
287
|
+
'.onepkg' => 'application/onenote',
|
288
|
+
'.onetmp' => 'application/onenote',
|
289
|
+
'.onetoc' => 'application/onenote',
|
290
|
+
'.onetoc2' => 'application/onenote',
|
291
|
+
'.orderedtest' => 'application/xml',
|
292
|
+
'.osdx' => 'application/opensearchdescription+xml',
|
293
|
+
'.p10' => 'application/pkcs10',
|
294
|
+
'.p12' => 'application/x-pkcs12',
|
295
|
+
'.p7b' => 'application/x-pkcs7-certificates',
|
296
|
+
'.p7c' => 'application/pkcs7-mime',
|
297
|
+
'.p7m' => 'application/pkcs7-mime',
|
298
|
+
'.p7r' => 'application/x-pkcs7-certreqresp',
|
299
|
+
'.p7s' => 'application/pkcs7-signature',
|
300
|
+
'.pbm' => 'image/x-portable-bitmap',
|
301
|
+
'.pcast' => 'application/x-podcast',
|
302
|
+
'.pct' => 'image/pict',
|
303
|
+
'.pcx' => 'application/octet-stream',
|
304
|
+
'.pcz' => 'application/octet-stream',
|
305
|
+
'.pdf' => 'application/pdf',
|
306
|
+
'.pfb' => 'application/octet-stream',
|
307
|
+
'.pfm' => 'application/octet-stream',
|
308
|
+
'.pfx' => 'application/x-pkcs12',
|
309
|
+
'.pgm' => 'image/x-portable-graymap',
|
310
|
+
'.pic' => 'image/pict',
|
311
|
+
'.pict' => 'image/pict',
|
312
|
+
'.pkgdef' => 'text/plain',
|
313
|
+
'.pkgundef' => 'text/plain',
|
314
|
+
'.pko' => 'application/vnd.ms-pki.pko',
|
315
|
+
'.pls' => 'audio/scpls',
|
316
|
+
'.pma' => 'application/x-perfmon',
|
317
|
+
'.pmc' => 'application/x-perfmon',
|
318
|
+
'.pml' => 'application/x-perfmon',
|
319
|
+
'.pmr' => 'application/x-perfmon',
|
320
|
+
'.pmw' => 'application/x-perfmon',
|
321
|
+
'.png' => 'image/png',
|
322
|
+
'.pnm' => 'image/x-portable-anymap',
|
323
|
+
'.pnt' => 'image/x-macpaint',
|
324
|
+
'.pntg' => 'image/x-macpaint',
|
325
|
+
'.pnz' => 'image/png',
|
326
|
+
'.pot' => 'application/vnd.ms-powerpoint',
|
327
|
+
'.potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
|
328
|
+
'.potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
|
329
|
+
'.ppa' => 'application/vnd.ms-powerpoint',
|
330
|
+
'.ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
|
331
|
+
'.ppm' => 'image/x-portable-pixmap',
|
332
|
+
'.pps' => 'application/vnd.ms-powerpoint',
|
333
|
+
'.ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
|
334
|
+
'.ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
|
335
|
+
'.ppt' => 'application/vnd.ms-powerpoint',
|
336
|
+
'.pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
|
337
|
+
'.pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
338
|
+
'.prf' => 'application/pics-rules',
|
339
|
+
'.prm' => 'application/octet-stream',
|
340
|
+
'.prx' => 'application/octet-stream',
|
341
|
+
'.ps' => 'application/postscript',
|
342
|
+
'.psc1' => 'application/PowerShell',
|
343
|
+
'.psd' => 'application/octet-stream',
|
344
|
+
'.psess' => 'application/xml',
|
345
|
+
'.psm' => 'application/octet-stream',
|
346
|
+
'.psp' => 'application/octet-stream',
|
347
|
+
'.pub' => 'application/x-mspublisher',
|
348
|
+
'.pwz' => 'application/vnd.ms-powerpoint',
|
349
|
+
'.qht' => 'text/x-html-insertion',
|
350
|
+
'.qhtm' => 'text/x-html-insertion',
|
351
|
+
'.qt' => 'video/quicktime',
|
352
|
+
'.qti' => 'image/x-quicktime',
|
353
|
+
'.qtif' => 'image/x-quicktime',
|
354
|
+
'.qtl' => 'application/x-quicktimeplayer',
|
355
|
+
'.qxd' => 'application/octet-stream',
|
356
|
+
'.ra' => 'audio/x-pn-realaudio',
|
357
|
+
'.ram' => 'audio/x-pn-realaudio',
|
358
|
+
'.rar' => 'application/octet-stream',
|
359
|
+
'.ras' => 'image/x-cmu-raster',
|
360
|
+
'.rat' => 'application/rat-file',
|
361
|
+
'.rc' => 'text/plain',
|
362
|
+
'.rc2' => 'text/plain',
|
363
|
+
'.rct' => 'text/plain',
|
364
|
+
'.rdlc' => 'application/xml',
|
365
|
+
'.resx' => 'application/xml',
|
366
|
+
'.rf' => 'image/vnd.rn-realflash',
|
367
|
+
'.rgb' => 'image/x-rgb',
|
368
|
+
'.rgs' => 'text/plain',
|
369
|
+
'.rm' => 'application/vnd.rn-realmedia',
|
370
|
+
'.rmi' => 'audio/mid',
|
371
|
+
'.rmp' => 'application/vnd.rn-rn_music_package',
|
372
|
+
'.roff' => 'application/x-troff',
|
373
|
+
'.rpm' => 'audio/x-pn-realaudio-plugin',
|
374
|
+
'.rqy' => 'text/x-ms-rqy',
|
375
|
+
'.rtf' => 'application/rtf',
|
376
|
+
'.rtx' => 'text/richtext',
|
377
|
+
'.ruleset' => 'application/xml',
|
378
|
+
'.s' => 'text/plain',
|
379
|
+
'.safariextz' => 'application/x-safari-safariextz',
|
380
|
+
'.scd' => 'application/x-msschedule',
|
381
|
+
'.sct' => 'text/scriptlet',
|
382
|
+
'.sd2' => 'audio/x-sd2',
|
383
|
+
'.sdp' => 'application/sdp',
|
384
|
+
'.sea' => 'application/octet-stream',
|
385
|
+
'.searchConnector-ms' => 'application/windows-search-connector+xml',
|
386
|
+
'.setpay' => 'application/set-payment-initiation',
|
387
|
+
'.setreg' => 'application/set-registration-initiation',
|
388
|
+
'.settings' => 'application/xml',
|
389
|
+
'.sgimb' => 'application/x-sgimb',
|
390
|
+
'.sgml' => 'text/sgml',
|
391
|
+
'.sh' => 'application/x-sh',
|
392
|
+
'.shar' => 'application/x-shar',
|
393
|
+
'.shtml' => 'text/html',
|
394
|
+
'.sit' => 'application/x-stuffit',
|
395
|
+
'.sitemap' => 'application/xml',
|
396
|
+
'.skin' => 'application/xml',
|
397
|
+
'.sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',
|
398
|
+
'.sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
|
399
|
+
'.slk' => 'application/vnd.ms-excel',
|
400
|
+
'.sln' => 'text/plain',
|
401
|
+
'.slupkg-ms' => 'application/x-ms-license',
|
402
|
+
'.smd' => 'audio/x-smd',
|
403
|
+
'.smi' => 'application/octet-stream',
|
404
|
+
'.smx' => 'audio/x-smd',
|
405
|
+
'.smz' => 'audio/x-smd',
|
406
|
+
'.snd' => 'audio/basic',
|
407
|
+
'.snippet' => 'application/xml',
|
408
|
+
'.snp' => 'application/octet-stream',
|
409
|
+
'.sol' => 'text/plain',
|
410
|
+
'.sor' => 'text/plain',
|
411
|
+
'.spc' => 'application/x-pkcs7-certificates',
|
412
|
+
'.spl' => 'application/futuresplash',
|
413
|
+
'.src' => 'application/x-wais-source',
|
414
|
+
'.srf' => 'text/plain',
|
415
|
+
'.SSISDeploymentManifest' => 'text/xml',
|
416
|
+
'.ssm' => 'application/streamingmedia',
|
417
|
+
'.sst' => 'application/vnd.ms-pki.certstore',
|
418
|
+
'.stl' => 'application/vnd.ms-pki.stl',
|
419
|
+
'.sv4cpio' => 'application/x-sv4cpio',
|
420
|
+
'.sv4crc' => 'application/x-sv4crc',
|
421
|
+
'.svc' => 'application/xml',
|
422
|
+
'.swf' => 'application/x-shockwave-flash',
|
423
|
+
'.t' => 'application/x-troff',
|
424
|
+
'.tar' => 'application/x-tar',
|
425
|
+
'.tcl' => 'application/x-tcl',
|
426
|
+
'.testrunconfig' => 'application/xml',
|
427
|
+
'.testsettings' => 'application/xml',
|
428
|
+
'.tex' => 'application/x-tex',
|
429
|
+
'.texi' => 'application/x-texinfo',
|
430
|
+
'.texinfo' => 'application/x-texinfo',
|
431
|
+
'.tgz' => 'application/x-compressed',
|
432
|
+
'.thmx' => 'application/vnd.ms-officetheme',
|
433
|
+
'.thn' => 'application/octet-stream',
|
434
|
+
'.tif' => 'image/tiff',
|
435
|
+
'.tiff' => 'image/tiff',
|
436
|
+
'.tlh' => 'text/plain',
|
437
|
+
'.tli' => 'text/plain',
|
438
|
+
'.toc' => 'application/octet-stream',
|
439
|
+
'.tr' => 'application/x-troff',
|
440
|
+
'.trm' => 'application/x-msterminal',
|
441
|
+
'.trx' => 'application/xml',
|
442
|
+
'.ts' => 'video/vnd.dlna.mpeg-tts',
|
443
|
+
'.tsv' => 'text/tab-separated-values',
|
444
|
+
'.ttf' => 'application/octet-stream',
|
445
|
+
'.tts' => 'video/vnd.dlna.mpeg-tts',
|
446
|
+
'.txt' => 'text/plain',
|
447
|
+
'.u32' => 'application/octet-stream',
|
448
|
+
'.uls' => 'text/iuls',
|
449
|
+
'.user' => 'text/plain',
|
450
|
+
'.ustar' => 'application/x-ustar',
|
451
|
+
'.vb' => 'text/plain',
|
452
|
+
'.vbdproj' => 'text/plain',
|
453
|
+
'.vbk' => 'video/mpeg',
|
454
|
+
'.vbproj' => 'text/plain',
|
455
|
+
'.vbs' => 'text/vbscript',
|
456
|
+
'.vcf' => 'text/x-vcard',
|
457
|
+
'.vcproj' => 'Application/xml',
|
458
|
+
'.vcs' => 'text/plain',
|
459
|
+
'.vcxproj' => 'Application/xml',
|
460
|
+
'.vddproj' => 'text/plain',
|
461
|
+
'.vdp' => 'text/plain',
|
462
|
+
'.vdproj' => 'text/plain',
|
463
|
+
'.vdx' => 'application/vnd.ms-visio.viewer',
|
464
|
+
'.vml' => 'text/xml',
|
465
|
+
'.vscontent' => 'application/xml',
|
466
|
+
'.vsct' => 'text/xml',
|
467
|
+
'.vsd' => 'application/vnd.visio',
|
468
|
+
'.vsi' => 'application/ms-vsi',
|
469
|
+
'.vsix' => 'application/vsix',
|
470
|
+
'.vsixlangpack' => 'text/xml',
|
471
|
+
'.vsixmanifest' => 'text/xml',
|
472
|
+
'.vsmdi' => 'application/xml',
|
473
|
+
'.vspscc' => 'text/plain',
|
474
|
+
'.vss' => 'application/vnd.visio',
|
475
|
+
'.vsscc' => 'text/plain',
|
476
|
+
'.vssettings' => 'text/xml',
|
477
|
+
'.vssscc' => 'text/plain',
|
478
|
+
'.vst' => 'application/vnd.visio',
|
479
|
+
'.vstemplate' => 'text/xml',
|
480
|
+
'.vsto' => 'application/x-ms-vsto',
|
481
|
+
'.vsw' => 'application/vnd.visio',
|
482
|
+
'.vsx' => 'application/vnd.visio',
|
483
|
+
'.vtx' => 'application/vnd.visio',
|
484
|
+
'.wav' => 'audio/wav',
|
485
|
+
'.wave' => 'audio/wav',
|
486
|
+
'.wax' => 'audio/x-ms-wax',
|
487
|
+
'.wbk' => 'application/msword',
|
488
|
+
'.wbmp' => 'image/vnd.wap.wbmp',
|
489
|
+
'.wcm' => 'application/vnd.ms-works',
|
490
|
+
'.wdb' => 'application/vnd.ms-works',
|
491
|
+
'.wdp' => 'image/vnd.ms-photo',
|
492
|
+
'.webarchive' => 'application/x-safari-webarchive',
|
493
|
+
'.webtest' => 'application/xml',
|
494
|
+
'.wiq' => 'application/xml',
|
495
|
+
'.wiz' => 'application/msword',
|
496
|
+
'.wks' => 'application/vnd.ms-works',
|
497
|
+
'.WLMP' => 'application/wlmoviemaker',
|
498
|
+
'.wlpginstall' => 'application/x-wlpg-detect',
|
499
|
+
'.wlpginstall3' => 'application/x-wlpg3-detect',
|
500
|
+
'.wm' => 'video/x-ms-wm',
|
501
|
+
'.wma' => 'audio/x-ms-wma',
|
502
|
+
'.wmd' => 'application/x-ms-wmd',
|
503
|
+
'.wmf' => 'application/x-msmetafile',
|
504
|
+
'.wml' => 'text/vnd.wap.wml',
|
505
|
+
'.wmlc' => 'application/vnd.wap.wmlc',
|
506
|
+
'.wmls' => 'text/vnd.wap.wmlscript',
|
507
|
+
'.wmlsc' => 'application/vnd.wap.wmlscriptc',
|
508
|
+
'.wmp' => 'video/x-ms-wmp',
|
509
|
+
'.wmv' => 'video/x-ms-wmv',
|
510
|
+
'.wmx' => 'video/x-ms-wmx',
|
511
|
+
'.wmz' => 'application/x-ms-wmz',
|
512
|
+
'.wpl' => 'application/vnd.ms-wpl',
|
513
|
+
'.wps' => 'application/vnd.ms-works',
|
514
|
+
'.wri' => 'application/x-mswrite',
|
515
|
+
'.wrl' => 'x-world/x-vrml',
|
516
|
+
'.wrz' => 'x-world/x-vrml',
|
517
|
+
'.wsc' => 'text/scriptlet',
|
518
|
+
'.wsdl' => 'text/xml',
|
519
|
+
'.wvx' => 'video/x-ms-wvx',
|
520
|
+
'.x' => 'application/directx',
|
521
|
+
'.xaf' => 'x-world/x-vrml',
|
522
|
+
'.xaml' => 'application/xaml+xml',
|
523
|
+
'.xap' => 'application/x-silverlight-app',
|
524
|
+
'.xbap' => 'application/x-ms-xbap',
|
525
|
+
'.xbm' => 'image/x-xbitmap',
|
526
|
+
'.xdr' => 'text/plain',
|
527
|
+
'.xht' => 'application/xhtml+xml',
|
528
|
+
'.xhtml' => 'application/xhtml+xml',
|
529
|
+
'.xla' => 'application/vnd.ms-excel',
|
530
|
+
'.xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
|
531
|
+
'.xlc' => 'application/vnd.ms-excel',
|
532
|
+
'.xld' => 'application/vnd.ms-excel',
|
533
|
+
'.xlk' => 'application/vnd.ms-excel',
|
534
|
+
'.xll' => 'application/vnd.ms-excel',
|
535
|
+
'.xlm' => 'application/vnd.ms-excel',
|
536
|
+
'.xls' => 'application/vnd.ms-excel',
|
537
|
+
'.xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
|
538
|
+
'.xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
|
539
|
+
'.xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
540
|
+
'.xlt' => 'application/vnd.ms-excel',
|
541
|
+
'.xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
|
542
|
+
'.xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
543
|
+
'.xlw' => 'application/vnd.ms-excel',
|
544
|
+
'.xml' => 'text/xml',
|
545
|
+
'.xmta' => 'application/xml',
|
546
|
+
'.xof' => 'x-world/x-vrml',
|
547
|
+
'.XOML' => 'text/plain',
|
548
|
+
'.xpm' => 'image/x-xpixmap',
|
549
|
+
'.xps' => 'application/vnd.ms-xpsdocument',
|
550
|
+
'.xrm-ms' => 'text/xml',
|
551
|
+
'.xsc' => 'application/xml',
|
552
|
+
'.xsd' => 'text/xml',
|
553
|
+
'.xsf' => 'text/xml',
|
554
|
+
'.xsl' => 'text/xml',
|
555
|
+
'.xslt' => 'text/xml',
|
556
|
+
'.xsn' => 'application/octet-stream',
|
557
|
+
'.xss' => 'application/xml',
|
558
|
+
'.xtp' => 'application/octet-stream',
|
559
|
+
'.xwd' => 'image/x-xwindowdump',
|
560
|
+
'.z' => 'application/x-compress',
|
561
|
+
'.zip' => 'application/x-zip-compressed'
|
562
|
+
}
|
563
|
+
end
|
564
|
+
end
|