fci 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea7f77e8704e3b17cbaf20154dd8a7b3fbafddf6
4
- data.tar.gz: 6df339513937b041994330d584a5af8a42a4b943
3
+ metadata.gz: f358abc6af346556ae042946ba6677a43c17323a
4
+ data.tar.gz: 43940e9e2707254c66745a8f8b06eeeb3156452a
5
5
  SHA512:
6
- metadata.gz: 4bdfc3f81062392e6096587ab13475731c005313ad418ef0693515d9cf91bad2d0718da605f0f47c78b7bf70b597f45045c2268e8201f12da43a50f4e0c76932
7
- data.tar.gz: f7f9e629b783e2f419f042f0901e0aa5bb68690b1f3c633b1fb9fceaf4a873adeca44863de87a23d2d04de29e018a7bca886f499bb7b880072f0950fa4a45ba5
6
+ metadata.gz: 34b6e4f68cec0550dd52c3204a3f8f01cc39ff00c066fb17cb43b1e840adcba5331b7eebbd59b582c545a2f04c9ba28d7d48191eccc16a467365922bd0554689
7
+ data.tar.gz: 5e7706624f504603c0178549177f73262a92ff8d62bc183514129d9ebb0cc0fc6bfd552bc6fe07e9954fa86493fb8c7913caef51532a17e718eb55147b50aff4
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
+
4
+ # gem 'freshdesk_api', path: '../freshdesk_api_client_rb'
data/README.md CHANGED
@@ -68,24 +68,34 @@ The scaffold project that was created in ./todo comes with a `fci.yml` shell.
68
68
 
69
69
  ```
70
70
  ---
71
+ # Crowdin API credentials
71
72
  crowdin_project_id: '<%your-crowdin-project-id%>'
72
73
  crowdin_api_key: '<%your-crowdin-api-key%>'
73
74
  crowdin_base_url: 'https://api.crowdin.com'
74
75
 
76
+ # Freshdesk API credentials
75
77
  freshdesk_base_url: 'https://<%subdomain%>.freshdesk.com'
76
78
  freshdesk_username: '<%your-freshdek-username%>'
77
79
  freshdesk_password: '<%your-freshdesk-password%>'
78
80
 
79
- freshdesk_category: '<%category-id%>'
80
-
81
- translations:
82
- -
83
- crowdin_language_code: '<%crowdin-two-letters-code%>'
84
- freshdesk_category_id: '<%freshdesk-category-id%>'
85
- -
86
- crowdin_language_code: '<%crowdin-two-letters-code%>'
87
- freshdesk_category_id: '<%freshdesk-category-id%>'
88
-
81
+ # Freshdesk catogories
82
+ categories:
83
+ - freshdesk_category: '<%freshdesk-category-id%>'
84
+ translations:
85
+ -
86
+ crowdin_language_code: '<%crowdin-two-letters-code%>'
87
+ freshdesk_category_id: '<%freshdesk-category-id%>'
88
+ -
89
+ crowdin_language_code: '<%crowdin-two-letters-code%>'
90
+ freshdesk_category_id: '<%freshdesk-category-id%>'
91
+ - freshdesk_category: '<%freshdesk-category-id%>'
92
+ translations:
93
+ -
94
+ crowdin_language_code: '<%crowdin-two-letters-code%>'
95
+ freshdesk_category_id: '<%freshdesk-category-id%>'
96
+ -
97
+ crowdin_language_code: '<%crowdin-two-letters-code%>'
98
+ freshdesk_category_id: '<%freshdesk-category-id%>'
89
99
  ```
90
100
 
91
101
  ## Supported Rubies
@@ -93,6 +103,7 @@ translations:
93
103
  Tested with the following Ruby versions:
94
104
 
95
105
  - MRI 2.2.0
106
+ - JRuby 9.0.0.0.pre2
96
107
 
97
108
  ## Contributing
98
109
 
data/bin/fci CHANGED
@@ -9,6 +9,8 @@ rescue LoadError
9
9
  exit 64
10
10
  end
11
11
 
12
+ # GLI_DEBUG=true bundle exec bin/fci
13
+
12
14
  include GLI::App
13
15
  include FCI
14
16
 
@@ -47,20 +49,33 @@ pre do |global, command, options, args|
47
49
 
48
50
  # load project-specific configuration
49
51
  begin
50
- @fci_config = YAML.load(File.read(global[:config])) || {}
52
+ @cli_config = YAML.load(File.read(global[:config])) || {}
51
53
  rescue Psych::SyntaxError => err
52
54
  exit_now! <<-EOS
53
55
  Could not parse YAML: #{err.message}
54
56
  EOS
55
57
  end
56
58
 
57
- @freshdesk = FreshdeskAPI::Client.new do |c|
58
- c.base_url = @fci_config['freshdesk_base_url']
59
- c.username = @fci_config['freshdesk_username']
60
- c.password = @fci_config['freshdesk_password']
59
+ if global[:verbose]
60
+ ENV['GLI_DEBUG'] = 'true'
61
+ end
62
+
63
+ @freshdesk = FreshdeskAPI::Client.new do |config|
64
+ config.base_url = @cli_config['freshdesk_base_url']
65
+ config.username = @cli_config['freshdesk_username']
66
+ config.password = @cli_config['freshdesk_password']
67
+
68
+ if global[:verbose]
69
+ require 'logger'
70
+ config.logger = Logger.new(STDOUT)
71
+ end
72
+ end
73
+
74
+ if global[:verbose]
75
+ Crowdin::API.log = Logger.new(STDOUT)
61
76
  end
62
77
 
63
- @crowdin = Crowdin::API.new(api_key: @fci_config['crowdin_api_key'], project_id: @fci_config['crowdin_project_id'], base_url: @fci_config['crowdin_base_url'])
78
+ @crowdin = Crowdin::API.new(api_key: @cli_config['crowdin_api_key'], project_id: @cli_config['crowdin_project_id'], base_url: @cli_config['crowdin_base_url'])
64
79
 
65
80
  true
66
81
  end
data/fci.gemspec CHANGED
@@ -18,7 +18,7 @@ spec = Gem::Specification.new do |s|
18
18
  s.add_runtime_dependency('nokogiri')
19
19
  s.add_runtime_dependency('rubyzip')
20
20
  s.add_runtime_dependency('crowdin-api')
21
- s.add_runtime_dependency('freshdesk_api')
21
+ s.add_runtime_dependency('freshdesk_api','>=0.1.1')
22
22
  s.add_runtime_dependency('gli','2.13.0')
23
23
  s.add_development_dependency('rake')
24
24
  s.add_development_dependency('rdoc')
data/fci.yml.example CHANGED
@@ -9,12 +9,21 @@ freshdesk_base_url: 'https://<%subdomain%>.freshdesk.com'
9
9
  freshdesk_username: '<%your-freshdek-username%>'
10
10
  freshdesk_password: '<%your-freshdesk-password%>'
11
11
 
12
- freshdesk_category: '<%freshdesk-category-id%>'
13
-
14
- translations:
15
- -
16
- crowdin_language_code: '<%crowdin-two-letters-code%>'
17
- freshdesk_category_id: '<%freshdesk-category-id%>'
18
- -
19
- crowdin_language_code: '<%crowdin-two-letters-code%>'
20
- freshdesk_category_id: '<%freshdesk-category-id%>'
12
+ # Freshdesk catogories
13
+ categories:
14
+ - freshdesk_category: '<%freshdesk-category-id%>'
15
+ translations:
16
+ -
17
+ crowdin_language_code: '<%crowdin-two-letters-code%>'
18
+ freshdesk_category_id: '<%freshdesk-category-id%>'
19
+ -
20
+ crowdin_language_code: '<%crowdin-two-letters-code%>'
21
+ freshdesk_category_id: '<%freshdesk-category-id%>'
22
+ - freshdesk_category: '<%freshdesk-category-id%>'
23
+ translations:
24
+ -
25
+ crowdin_language_code: '<%crowdin-two-letters-code%>'
26
+ freshdesk_category_id: '<%freshdesk-category-id%>'
27
+ -
28
+ crowdin_language_code: '<%crowdin-two-letters-code%>'
29
+ freshdesk_category_id: '<%freshdesk-category-id%>'
@@ -33,139 +33,145 @@ command :'import:sources' do |c|
33
33
  end
34
34
  end
35
35
 
36
- # for store information about folders/articles ids
36
+ # for store information about categories/folders/articles ids
37
37
  resources_config = YAML.load(File.open(resources_config_file))
38
38
 
39
- # Source Category
40
- source_category_id = @fci_config['freshdesk_category'].to_i
39
+ @cli_config['categories'].each do |category|
40
+ # Source Category
41
+ source_category_id = category['freshdesk_category'].to_i
41
42
 
42
- # Check if Category exists in Freshdesk
43
- source_category = FreshdeskAPI::SolutionCategory.find!(@freshdesk, id: source_category_id)
44
- raise('No such category') unless source_category.id == source_category_id
43
+ # Check if Category exists in Freshdesk
44
+ source_category = FreshdeskAPI::SolutionCategory.find!(@freshdesk, id: source_category_id)
45
+ raise('No such category') unless source_category.id == source_category_id
45
46
 
46
- # Get category's folders in Freshdesk
47
- puts "[Freshdesk] Get folders for Category with id #{source_category_id}"
48
- folders = @freshdesk.solution_folders(category_id: source_category_id).all!
47
+ # Check if Category exists in resources config
48
+ unless resources_config[source_category_id]
49
+ category_config = resources_config.merge!(source_category_id => {})[source_category_id]
50
+ else
51
+ category_config = resources_config[source_category_id]
52
+ end
49
53
 
50
- folders_builder = []
51
- folders.each do |folder|
52
- folder_xml = build_folder_xml(folder)
54
+ # Get category's folders in Freshdesk
55
+ puts "[Freshdesk] Get folders for Category with id #{source_category_id}"
56
+ folders = @freshdesk.solution_folders(category_id: source_category_id).all!
53
57
 
54
- # write to resources config file
55
- unless folder_xml.nil?
56
- resources_config[:folders] = [] unless resources_config[:folders]
57
- unless resources_config[:folders].detect { |f| f[:id] == folder.id }
58
- resources_config[:folders] << { id: folder.id }
58
+ folders_builder = []
59
+ folders.each do |folder|
60
+ folder_xml = build_folder_xml(folder)
61
+
62
+ # write to resources config file
63
+ unless folder_xml.nil?
64
+ category_config[:folders] = [] unless category_config[:folders]
65
+ unless category_config[:folders].detect { |f| f[:id] == folder.id }
66
+ category_config[:folders] << { id: folder.id }
67
+ end
68
+ end
69
+
70
+ unless folder_xml.nil?
71
+ folders_builder << build_folder_hash(folder).merge({ xml: folder_xml })
59
72
  end
60
73
  end
61
74
 
62
- unless folder_xml.nil?
63
- folders_builder << build_folder_hash(folder).merge({ xml: folder_xml })
75
+ folders_config = resources_config[source_category_id][:folders]
76
+ # Get articles for each folder
77
+ articles_builder = []
78
+ folders.each do |folder|
79
+ puts "[Freshdesk] Get articles for Folder with id #{folder.id}"
80
+ articles = @freshdesk.solution_articles(category_id: source_category_id, folder_id: folder.id).all!
81
+
82
+ articles.each do |article|
83
+ article_xml = build_article_xml(article)
84
+
85
+ # write to resources config file
86
+ if folder_config = folders_config.detect { |f| f[:id] == folder.id }
87
+ folder_config[:articles] = [] unless folder_config[:articles]
88
+ unless folder_config[:articles].detect { |a| a[:id] == article.id }
89
+ folder_config[:articles] << { id: article.id }
90
+ end
91
+ else
92
+ abort 'No such folder!'
93
+ end
94
+
95
+ unless article_xml.nil?
96
+ articles_builder << build_article_hash(article).merge({ xml: article_xml })
97
+ end
98
+ end
64
99
  end
65
- end
66
100
 
67
- # Get folders articles
68
- articles_builder = []
69
- folders.each do |folder|
70
- puts "[Freshdesk] Get articles for Folder with id #{folder.id}"
71
- articles = @freshdesk.solution_articles(category_id: source_category_id, folder_id: folder.id).all!
101
+ crowdin_project_info = @crowdin.project_info
102
+ remote_project_tree = get_remote_files_hierarchy(crowdin_project_info['files'])
72
103
 
73
- articles.each do |article|
74
- article_xml = build_article_xml(article)
104
+ resources_category_dir = File.join(resources_dir, source_category_id.to_s)
105
+ unless File.exists?(resources_category_dir)
106
+ FileUtils.mkdir(resources_category_dir)
107
+ end
75
108
 
76
- # write to resources config file
77
- if config_folder = resources_config[:folders].detect { |f| f[:id] == folder.id }
78
- (config_folder[:articles] ||= []) << { id: article.id }
79
- else
80
- abort 'No such folder!'
81
- end
109
+ # Create directory for Category on Crowdin if it does not exist yet
110
+ unless remote_project_tree[:dirs].include?("/#{source_category_id}")
111
+ puts "[Crowdin] Create directory `#{source_category_id}`"
112
+ @crowdin.add_directory(source_category_id.to_s)
113
+ @crowdin.change_directory(source_category_id.to_s, title: source_category.attributes[:name])
114
+ end
82
115
 
83
- unless article_xml.nil?
84
- articles_builder << build_article_hash(article).merge({ xml: article_xml })
116
+ # Creates xml files for folders and upload to Crowdin
117
+ folders_builder.each do |folder|
118
+ file_name = "folder_#{folder[:id]}.xml"
119
+
120
+ o = File.new(File.join(resources_category_dir, file_name), 'w')
121
+ o.write folder[:xml].to_xml
122
+ o.close
123
+
124
+ files = [
125
+ {
126
+ source: File.join(resources_category_dir, file_name),
127
+ dest: File.join(source_category_id.to_s, file_name),
128
+ export_pattert: '/%two_letters_code%/%original_path%/%original_file_name%',
129
+ title: folder[:name]
130
+ }
131
+ ]
132
+
133
+ if remote_project_tree[:files].include?("/#{source_category_id}/#{file_name}")
134
+ puts "[Crowdin] Update file `#{file_name}`"
135
+ @crowdin.update_file(files, type: 'webxml')
136
+ else
137
+ puts "[Crowdin] Add file `#{file_name}`"
138
+ @crowdin.add_file(files, type: 'webxml')
85
139
  end
86
140
  end
87
- end
88
141
 
142
+ # Creates xml files for articles and upload to Crowdin
143
+ articles_builder.each do |article|
144
+ file_name = "article_#{article[:id]}.xml"
145
+
146
+ o = File.new(File.join(resources_category_dir, file_name), 'w')
147
+ o.write article[:xml].to_xml
148
+ o.close
149
+
150
+ files = [
151
+ {
152
+ source: File.join(resources_category_dir, file_name),
153
+ dest: File.join(source_category_id.to_s, file_name),
154
+ export_pattert: '/%two_letters_code%/%original_path%/%original_file_name%',
155
+ title: article[:title]
156
+ }
157
+ ]
158
+
159
+ if remote_project_tree[:files].include?("/#{source_category_id}/#{file_name}")
160
+ puts "[Crowdin] Update file `#{file_name}`"
161
+ @crowdin.update_file(files, type: 'webxml')
162
+ else
163
+ puts "[Crowdin] Add file `#{file_name}`"
164
+ @crowdin.add_file(files, type: 'webxml')
89
165
 
90
- crowdin_project_info = @crowdin.project_info
91
-
92
- # Creates xml files for folders and upload to Crowdin
93
- folders_builder.each do |folder|
94
- file_name = "folder_#{folder[:id]}.xml"
95
-
96
- o = File.new(File.join(resources_dir, file_name), 'w')
97
- o.write folder[:xml].to_xml
98
- o.close
99
-
100
- if crowdin_project_info['files'].detect { |file| file['name'] == file_name }
101
- puts "[Crowdin] Update file `#{file_name}`"
102
- @crowdin.update_file(
103
- files = [
104
- {
105
- source: File.join(resources_dir, file_name),
106
- dest: file_name,
107
- export_pattert: '/%two_letters_code%/%original_file_name%',
108
- title: folder[:name]
109
- }
110
- ], type: 'webxml'
111
- )
112
- else
113
- puts "[Crowdin] Add file `#{file_name}`"
114
- @crowdin.add_file(
115
- files = [
116
- {
117
- source: File.join(resources_dir, file_name),
118
- dest: file_name,
119
- export_pattert: '/%two_letters_code%/%original_file_name%',
120
- title: folder[:name]
121
- }
122
- ], type: 'webxml'
123
- )
166
+ end
124
167
  end
125
- end
126
-
127
- # Creates xml files for articles and upload to Crowdin
128
- articles_builder.each do |article|
129
- file_name = "article_#{article[:id]}.xml"
130
-
131
- o = File.new(File.join(resources_dir, file_name), 'w')
132
- o.write article[:xml].to_xml
133
- o.close
134
-
135
- if crowdin_project_info['files'].detect { |file| file['name'] == file_name }
136
- puts "[Crowdin] Update file `#{file_name}`"
137
- @crowdin.update_file(
138
- files = [
139
- {
140
- source: File.join(resources_dir, file_name),
141
- dest: file_name,
142
- export_pattert: '/%two_letters_code%/%original_file_name%',
143
- title: article[:title]
144
- }
145
- ], type: 'webxml'
146
- )
147
- else
148
- puts "[Crowdin] Add file `#{file_name}`"
149
- @crowdin.add_file(
150
- files = [
151
- {
152
- source: File.join(resources_dir, file_name),
153
- dest: file_name,
154
- export_pattert: '/%two_letters_code%/%original_file_name%',
155
- title: article[:title]
156
- }
157
- ], type: 'webxml'
158
- )
159
168
 
169
+ # Write resources config file
170
+ puts "Write config file for Category with id `#{source_category_id}`"
171
+ File.open(resources_config_file, 'w') do |f|
172
+ f.write resources_config.to_yaml
160
173
  end
161
- end
162
-
163
- # Write resources config file
164
- puts "Write config file"
165
- File.open(resources_config_file, 'w') do |f|
166
- f.write resources_config.to_yaml
167
- end
168
174
 
175
+ end # @cli_config['categories'].each
169
176
  end
170
177
  end
171
-
@@ -22,67 +22,89 @@ command :'export:translations' do |c|
22
22
 
23
23
  # for store information about folders/articles ids
24
24
  unless File.exists?(resources_config_file)
25
- raise "Error! Config file does not exist. First run `push` command"
25
+ raise "Error! Config file does not exist. First run `push` command."
26
26
  end
27
27
 
28
28
  resources_config = YAML.load(File.open(resources_config_file))
29
29
 
30
30
  if !resources_config || resources_config.nil? || resources_config.empty?
31
- raise "Error! Resources config empty. First run `push` command"
31
+ raise "Error! Resources config empty. First run `push` command."
32
32
  end
33
33
 
34
- @fci_config['translations'].each do |lang|
35
- folder_xml_files = Dir["#{resources_dir}/#{lang['crowdin_language_code']}/folder_*.xml"]
36
- article_xml_files = Dir["#{resources_dir}/#{lang['crowdin_language_code']}/article_*.xml"]
34
+ @cli_config['categories'].each do |category|
35
+ category['translations'].each do |lang|
36
+ folder_xml_files = Dir["#{resources_dir}/#{lang['crowdin_language_code']}/#{category['freshdesk_category']}/folder_*.xml"]
37
+ article_xml_files = Dir["#{resources_dir}/#{lang['crowdin_language_code']}/#{category['freshdesk_category']}/article_*.xml"]
37
38
 
38
- unless freshdesk_category = FreshdeskAPI::SolutionCategory.find(@freshdesk, id: lang['freshdesk_category_id'].to_i)
39
- raise "Not such Category ID for language `#{lang['crowdin_language_code']}`in Freshdesk. Please create new one and set ID in config file."
40
- end
39
+ unless freshdesk_category = FreshdeskAPI::SolutionCategory.find(@freshdesk, id: lang['freshdesk_category_id'].to_i)
40
+ raise "Not such Category\##{lang['freshdesk_category_id']} for language `#{lang['crowdin_language_code']}` in Freshdesk. Please create new one and set `:freshdesk_category_id` in config file."
41
+ end
42
+
43
+ all_folders = []
44
+ all_articles = []
45
+
46
+ # Read folders from XML files
47
+ folder_xml_files.each do |file|
48
+ folder_xml_file = File.read(file)
41
49
 
42
- all_folders = []
43
- all_articles = []
50
+ folder = parse_folder_xml(folder_xml_file)
44
51
 
45
- # Read folders from XML files
46
- folder_xml_files.each do |file|
47
- # Load the xml file into a String
48
- folder_xml_file = File.read(file)
52
+ all_folders << folder
53
+ end
49
54
 
50
- folder = parse_folder_xml(folder_xml_file)
55
+ # Read articles from XML filse
56
+ article_xml_files.each do |file|
57
+ article_xml_file = File.read(file)
51
58
 
52
- all_folders << folder
53
- end
59
+ article = parse_article_xml(article_xml_file)
54
60
 
55
- # Read articles from XML filse
56
- article_xml_files.each do |file|
57
- article_xml_file = File.read(file)
61
+ all_articles << article
62
+ end
58
63
 
59
- article = parse_article_xml(article_xml_file)
64
+ ### Folders ###
65
+ #
66
+ all_folders.each do |folder|
67
+ category_config = resources_config[category['freshdesk_category'].to_i]
60
68
 
61
- all_articles << article
62
- end
69
+ if folder_config = category_config[:folders].detect { |f| f[:id].to_s == folder[:id].to_s }
63
70
 
64
- ### Folders ###
65
- #
66
- all_folders.each do |folder|
67
- if config_folder = resources_config[:folders].detect { |f| f[:id].to_s == folder[:id].to_s }
71
+ folder_config[:translations] = [] unless folder_config[:translations]
68
72
 
69
- config_folder[:translations] = [] unless config_folder[:translations]
73
+ # if Folder translation ID exists in config
74
+ if folder_translation = folder_config[:translations].detect { |tr| tr[:lang] == lang['crowdin_language_code'] }
75
+ # Get folder from Freshdesk and update it
76
+ freshdesk_folder = FreshdeskAPI::SolutionFolder.find(
77
+ @freshdesk,
78
+ category_id: lang['freshdesk_category_id'].to_i,
79
+ id: folder_translation[:id]
80
+ )
70
81
 
71
- # if Folder translation ID exists in config
72
- if folder_translation = config_folder[:translations].detect { |t| t[:lang] == lang['crowdin_language_code'] }
73
- # Get folder from Freshdesk and update it
74
- freshdesk_folder = FreshdeskAPI::SolutionFolder.find(
75
- @freshdesk,
76
- category_id: lang['freshdesk_category_id'].to_i,
77
- id: folder_translation[:id]
78
- )
82
+ # Remove Folder translation from config it it not found in Freshdesk
83
+ if freshdesk_folder.nil?
84
+ puts "Remove undefined Folder from config."
85
+ folder_config[:translations].delete_if { |tr| tr[:lang] == lang['crowdin_language_code'] }
86
+
87
+ puts "[Freshdesk] Create new Folder."
88
+ freshdesk_folder = FreshdeskAPI::SolutionFolder.create!(
89
+ @freshdesk,
90
+ category_id: lang['freshdesk_category_id'].to_i,
91
+ name: folder[:name],
92
+ description: folder[:description],
93
+ visibility: 1
94
+ )
79
95
 
80
- # Remove Folder translation from config it it not found in Freshdesk
81
- if freshdesk_folder.nil?
82
- puts "Remove undefined Folder from config"
83
- config_folder[:translations].delete_if { |tr| tr[:lang] == lang['crowdin_language_code'] }
96
+ folder_config[:translations] << { lang: lang['crowdin_language_code'], id: freshdesk_folder.id }
97
+ end
84
98
 
85
- puts "[Freshdesk] Create new Folder"
99
+ if freshdesk_folder.attributes[:name] != folder[:name] || freshdesk_folder.attributes[:description] != folder[:description]
100
+ puts "[Freshdesk] Update existing Folder."
101
+ freshdesk_folder.update!(name: folder[:name], description: folder[:description])
102
+ else
103
+ puts "[Freshdesk] Nothing to update. An existing Folder still the same."
104
+ end
105
+ else
106
+ # create new folder in Freshdesk and save id to config file
107
+ puts "[Freshdesk] Create new Folder."
86
108
  freshdesk_folder = FreshdeskAPI::SolutionFolder.create!(
87
109
  @freshdesk,
88
110
  category_id: lang['freshdesk_category_id'].to_i,
@@ -91,116 +113,100 @@ command :'export:translations' do |c|
91
113
  visibility: 1
92
114
  )
93
115
 
94
- config_folder[:translations] << { lang: lang['crowdin_language_code'], id: freshdesk_folder.id }
95
-
96
- end
97
-
98
- if freshdesk_folder.attributes[:name] != folder[:name] || freshdesk_folder.attributes[:description] != folder[:description]
99
- puts "[Freshdesk] Update existing Folder"
100
- freshdesk_folder.update!(name: folder[:name], description: folder[:description])
101
- else
102
- puts "[Freshdesk] Nothing to update. An existing Folder still the same."
116
+ folder_config[:translations] << { lang: lang['crowdin_language_code'], id: freshdesk_folder.id }
103
117
  end
104
-
105
118
  else
106
- # create new folder in Freshdesk and save id to config file
107
- puts "[Freshdesk] Create new Folder"
108
- freshdesk_folder = FreshdeskAPI::SolutionFolder.create!(
109
- @freshdesk,
110
- category_id: lang['freshdesk_category_id'].to_i,
111
- name: folder[:name],
112
- description: folder[:description],
113
- visibility: 1
114
- )
115
-
116
- config_folder[:translations] << { lang: lang['crowdin_language_code'], id: freshdesk_folder.id }
119
+ abort "No such folder!"
117
120
  end
118
- else
119
- abort "No such folder!"
121
+ end # all_folders.each
122
+
123
+ puts "Write info about Folders localization for Category `#{freshdesk_category.id}` to config."
124
+ File.open(resources_config_file, 'w') do |f|
125
+ f.write resources_config.to_yaml
120
126
  end
121
- end # all_folders
122
-
123
- ### Articles ###
124
- #
125
- all_articles.each do |article|
126
- if config_folder = resources_config[:folders].detect { |f| f[:id].to_s == article[:folder_id].to_s }
127
- unless folder_translation = config_folder[:translations].detect { |t| t[:lang] == lang['crowdin_language_code'] }
128
- abort "No `#{lang['crowdin_language_code']}` translations for folder"
129
- end
130
127
 
131
- if config_article = config_folder[:articles].detect { |f| f[:id].to_s == article[:id].to_s }
132
- config_article[:translations] = [] unless config_article[:translations]
128
+ ### Articles ###
129
+ #
130
+ all_articles.each do |article|
131
+ category_config = resources_config[category['freshdesk_category'].to_i]
132
+ if folder_config = category_config[:folders].detect { |f| f[:id].to_s == article[:folder_id].to_s }
133
+ unless folder_translation = folder_config[:translations].detect { |t| t[:lang] == lang['crowdin_language_code'] }
134
+ abort "No `#{lang['crowdin_language_code']}` translations for folder."
135
+ end
133
136
 
134
- # if Article translation ID exists in config - update article on Freshdesk
135
- if article_translation = config_article[:translations].detect { |t| t[:lang] == lang['crowdin_language_code'] }
136
- freshdesk_article = FreshdeskAPI::SolutionArticle.find(
137
- @freshdesk,
138
- category_id: lang['freshdesk_category_id'].to_i,
139
- folder_id: folder_translation[:id],
140
- id: article_translation[:id]
141
- )
137
+ if article_config = folder_config[:articles].detect { |f| f[:id].to_s == article[:id].to_s }
138
+ article_config[:translations] = [] unless article_config[:translations]
142
139
 
143
- # Remove Article translation from config if it not found in Freshdesk
144
- if freshdesk_article.nil?
145
- puts "Remove undefined Article from config"
146
- config_article[:translations].delete_if { |tr| tr[:lang] == lang['crowdin_language_code'] }
140
+ # if Article translation ID exists in config - update article on Freshdesk
141
+ if article_translation = article_config[:translations].detect { |t| t[:lang] == lang['crowdin_language_code'] }
142
+ freshdesk_article = FreshdeskAPI::SolutionArticle.find(
143
+ @freshdesk,
144
+ category_id: lang['freshdesk_category_id'].to_i,
145
+ folder_id: folder_translation[:id],
146
+ id: article_translation[:id]
147
+ )
147
148
 
148
- puts "[Freshdesk] Create new Article"
149
- freshdesk_article = FreshdeskAPI::SolutionArticle.create!(
149
+ # Remove Article translation from config if it not found in Freshdesk
150
+ if freshdesk_article.nil?
151
+ puts "Remove undefined Article from config."
152
+ article_config[:translations].delete_if { |tr| tr[:lang] == lang['crowdin_language_code'] }
153
+
154
+ puts "[Freshdesk] Create new Article."
155
+ freshdesk_article = FreshdeskAPI::SolutionArticle.create!(
150
156
  @freshdesk,
151
157
  category_id: lang['freshdesk_category_id'].to_i,
152
158
  folder_id: folder_translation[:id],
153
159
  title: article[:title],
154
160
  description: article[:description]
155
- )
156
- config_article[:translations] << { lang: lang['crowdin_language_code'], id: freshdesk_article.id }
157
- next
158
- end
161
+ )
162
+ article_config[:translations] << { lang: lang['crowdin_language_code'], id: freshdesk_article.id }
163
+ next
164
+ end
159
165
 
160
- if freshdesk_article.attributes[:title] != article[:title] || freshdesk_article.attributes[:description] != article[:description]
161
- puts "[Freshdesk] Update existing Article"
166
+ if freshdesk_article.attributes[:title] != article[:title] || freshdesk_article.attributes[:description] != article[:description]
167
+ puts "[Freshdesk] Update existing Article."
162
168
 
163
- freshdesk_article.update!(
169
+ freshdesk_article.update!(
170
+ title: article[:title],
171
+ description: article[:description]
172
+ )
173
+ else
174
+ puts "[Freshdesk] Nothing to update. An existing Article still the same."
175
+ end
176
+
177
+ else
178
+ # creates new article on Freshdesk and save ID to config file
179
+ if folder_translation = folder_config[:translations].detect { |t| t[:lang] == lang['crowdin_language_code'] }
180
+ # do nothing for now
181
+ else
182
+ abort "No translation for this folder."
183
+ end
184
+
185
+ puts "[Freshdesk] Create new Article."
186
+ freshdesk_article = FreshdeskAPI::SolutionArticle.create!(
187
+ @freshdesk,
188
+ category_id: lang['freshdesk_category_id'].to_i,
189
+ folder_id: folder_translation[:id],
164
190
  title: article[:title],
165
191
  description: article[:description]
166
192
  )
167
- else
168
- puts "[Freshdesk] Nothing to update. An existing Article still the same."
193
+ article_config[:translations] << { lang: lang['crowdin_language_code'], id: freshdesk_article.id }
169
194
  end
170
-
171
195
  else
172
- # creates new article on Freshdesk and save ID to config file
173
- if folder_translation = config_folder[:translations].detect { |t| t[:lang] == lang['crowdin_language_code'] }
174
- # do nothing for now
175
- else
176
- abort "No translation for this folder"
177
- end
178
-
179
- puts "[Freshdesk] Create new Article"
180
- freshdesk_article = FreshdeskAPI::SolutionArticle.create!(
181
- @freshdesk,
182
- category_id: lang['freshdesk_category_id'].to_i,
183
- folder_id: folder_translation[:id],
184
- title: article[:title],
185
- description: article[:description]
186
- )
187
- config_article[:translations] << { lang: lang['crowdin_language_code'], id: freshdesk_article.id }
196
+ abort "No such article!"
188
197
  end
189
198
  else
190
- abort "No such article!"
199
+ abort "No such folder!"
191
200
  end
192
- else
193
- abort "No such folder!"
194
- end
195
- end # all_articles
201
+ end # all_articles.each
196
202
 
197
- puts "Write info about localization to config"
198
- File.open(resources_config_file, 'w') do |f|
199
- f.write resources_config.to_yaml
200
- end
203
+ puts "Write info about Articles localization for Category `#{freshdesk_category.id}` to config."
204
+ File.open(resources_config_file, 'w') do |f|
205
+ f.write resources_config.to_yaml
206
+ end
201
207
 
202
- end # @fci_config['translations']
208
+ end # category['translations'].each
209
+ end # @cli_config['categories'].each
203
210
 
204
211
  end
205
212
  end
206
-
data/lib/fci/export.rb CHANGED
@@ -6,7 +6,7 @@ module FCI
6
6
  folder = {
7
7
  id: folder_xml[:id],
8
8
  name: folder_xml.xpath('name').text,
9
- description: folder_xml.xpath('name').text,
9
+ description: folder_xml.xpath('description').text,
10
10
  position: folder_xml[:position],
11
11
  }
12
12
 
data/lib/fci/helpers.rb CHANGED
@@ -4,3 +4,21 @@ class String
4
4
  gsub(/^[ \t]{#{indent}}/, '')
5
5
  end
6
6
  end
7
+
8
+ # Return +hierarchy+ of directories and files in Crowdin project
9
+ #
10
+ # +files+ - basically, it's project files details from API method `project_info`
11
+ #
12
+ def get_remote_files_hierarchy(files, root = '/', hierarchy = { dirs: [], files: [] })
13
+ files.each do |node|
14
+ case node['node_type']
15
+ when 'directory'
16
+ hierarchy[:dirs] << "#{root}#{node['name']}"
17
+ get_remote_files_hierarchy(node['files'], root + node['name'] + '/', hierarchy)
18
+ when 'file'
19
+ hierarchy[:files] << "#{root}#{node['name']}"
20
+ end
21
+ end
22
+
23
+ return hierarchy
24
+ end
data/lib/fci/init.rb CHANGED
@@ -31,19 +31,28 @@ module FCI
31
31
 
32
32
  def mk_config(root_dir, project_name)
33
33
  config = <<-EOS.strip_heredoc
34
- ---
35
- # Crowdin API credentials
36
- crowdin_project_id: '<%your-crowdin-project-id%>'
37
- crowdin_api_key: '<%your-crowdin-api-key%>'
38
- crowdin_base_url: 'https://api.crowdin.com'
34
+ ---
35
+ # Crowdin API credentials
36
+ crowdin_project_id: '<%your-crowdin-project-id%>'
37
+ crowdin_api_key: '<%your-crowdin-api-key%>'
38
+ crowdin_base_url: 'https://api.crowdin.com'
39
39
 
40
- # Freshdesk API credentials
41
- freshdesk_base_url: 'https://<%subdomain%>.freshdesk.com'
42
- freshdesk_username: '<%your-freshdek-username%>'
43
- freshdesk_password: '<%your-freshdesk-password%>'
44
-
45
- freshdesk_category: '<%freshdesk-category-id%>'
40
+ # Freshdesk API credentials
41
+ freshdesk_base_url: 'https://<%subdomain%>.freshdesk.com'
42
+ freshdesk_username: '<%your-freshdesk-username%>'
43
+ freshdesk_password: '<%your-freshdesk-password%>'
46
44
 
45
+ # Freshdesk catogories
46
+ categories:
47
+ - freshdesk_category: '<%freshdesk-category-id%>'
48
+ translations:
49
+ -
50
+ crowdin_language_code: '<%crowdin-two-letters-code%>'
51
+ freshdesk_category_id: '<%freshdesk-category-id%>'
52
+ -
53
+ crowdin_language_code: '<%crowdin-two-letters-code%>'
54
+ freshdesk_category_id: '<%freshdesk-category-id%>'
55
+ - freshdesk_category: '<%freshdesk-category-id%>'
47
56
  translations:
48
57
  -
49
58
  crowdin_language_code: '<%crowdin-two-letters-code%>'
data/lib/fci/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module FCI
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fci
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Maminov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-19 00:00:00.000000000 Z
11
+ date: 2015-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 0.1.1
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: 0.1.1
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: gli
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -189,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
189
  version: '0'
190
190
  requirements: []
191
191
  rubyforge_project:
192
- rubygems_version: 2.4.6
192
+ rubygems_version: 2.4.7
193
193
  signing_key:
194
194
  specification_version: 4
195
195
  summary: Freshdesk and Crowdin integration Command Line Interface (CLI)