fci 0.0.3 → 0.0.4

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.
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)