redmine_api_helper 0.3.24

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of redmine_api_helper might be problematic. Click here for more details.

Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +2 -0
  3. data/.gitignore +11 -0
  4. data/CODE_OF_CONDUCT.md +74 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE +339 -0
  7. data/README.md +30 -0
  8. data/Rakefile +2 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/lib/date_helper/date.rb +311 -0
  12. data/lib/odf_writer/bookmark.rb +110 -0
  13. data/lib/odf_writer/bookmark_reader.rb +77 -0
  14. data/lib/odf_writer/document.rb +372 -0
  15. data/lib/odf_writer/field.rb +174 -0
  16. data/lib/odf_writer/field_reader.rb +78 -0
  17. data/lib/odf_writer/image.rb +158 -0
  18. data/lib/odf_writer/image_reader.rb +76 -0
  19. data/lib/odf_writer/images.rb +89 -0
  20. data/lib/odf_writer/list_style.rb +331 -0
  21. data/lib/odf_writer/nested.rb +156 -0
  22. data/lib/odf_writer/odf_helper.rb +56 -0
  23. data/lib/odf_writer/parser/default.rb +685 -0
  24. data/lib/odf_writer/path_finder.rb +114 -0
  25. data/lib/odf_writer/section.rb +120 -0
  26. data/lib/odf_writer/section_reader.rb +61 -0
  27. data/lib/odf_writer/style.rb +417 -0
  28. data/lib/odf_writer/table.rb +135 -0
  29. data/lib/odf_writer/table_reader.rb +61 -0
  30. data/lib/odf_writer/template.rb +222 -0
  31. data/lib/odf_writer/text.rb +97 -0
  32. data/lib/odf_writer/text_reader.rb +77 -0
  33. data/lib/odf_writer/version.rb +29 -0
  34. data/lib/redmine_api_helper/api_helper.rb +333 -0
  35. data/lib/redmine_api_helper/args_helper.rb +106 -0
  36. data/lib/redmine_api_helper/attachments_api_helper.rb +52 -0
  37. data/lib/redmine_api_helper/define_api_helpers.rb +78 -0
  38. data/lib/redmine_api_helper/document_categories_api_helper.rb +38 -0
  39. data/lib/redmine_api_helper/groups_api_helper.rb +80 -0
  40. data/lib/redmine_api_helper/helpers.rb +50 -0
  41. data/lib/redmine_api_helper/issue_priorities_api_helper.rb +38 -0
  42. data/lib/redmine_api_helper/issue_relations_api_helper.rb +66 -0
  43. data/lib/redmine_api_helper/issue_statuses_api_helper.rb +36 -0
  44. data/lib/redmine_api_helper/issues_api_helper.rb +124 -0
  45. data/lib/redmine_api_helper/my_account_api_helper.rb +45 -0
  46. data/lib/redmine_api_helper/news_api_helper.rb +73 -0
  47. data/lib/redmine_api_helper/project_memberships_api_helper.rb +77 -0
  48. data/lib/redmine_api_helper/projects_api_helper.rb +73 -0
  49. data/lib/redmine_api_helper/roles_api_helper.rb +52 -0
  50. data/lib/redmine_api_helper/scripts_api_helper.rb +87 -0
  51. data/lib/redmine_api_helper/search_api_helper.rb +38 -0
  52. data/lib/redmine_api_helper/time_entries_api_helper.rb +73 -0
  53. data/lib/redmine_api_helper/time_entry_activities_api_helper.rb +38 -0
  54. data/lib/redmine_api_helper/trackers_api_helper.rb +38 -0
  55. data/lib/redmine_api_helper/users_api_helper.rb +73 -0
  56. data/lib/redmine_api_helper/version.rb +24 -0
  57. data/lib/redmine_api_helper/wiki_pages_api_helper.rb +66 -0
  58. data/lib/redmine_api_helper.rb +88 -0
  59. data/redmine_api_helper.gemspec +35 -0
  60. metadata +148 -0
@@ -0,0 +1,135 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Ruby Gem to create a self populating Open Document Format (.odf) text file.
4
+ #
5
+ # Copyright 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ module ODFWriter
23
+
24
+ ########################################################################################
25
+ #
26
+ # Table: poulate and grow tables
27
+ #
28
+ ########################################################################################
29
+ class Table
30
+
31
+ include Nested
32
+
33
+ attr_accessor :name, :collection, :proc
34
+
35
+ ######################################################################################
36
+ #
37
+ # initialize
38
+ #
39
+ ######################################################################################
40
+ def initialize(options)
41
+ @name = options[:name]
42
+ @field = options[:field]
43
+ @collection = options[:collection]
44
+ @proc = options[:proc]
45
+ @key = @field || @name
46
+
47
+ @fields = []
48
+ @texts = []
49
+ @tables = []
50
+ @images = []
51
+ @bookmarks = []
52
+
53
+ @template_rows = []
54
+ @header = options[:header] || false
55
+ @skip_if_empty = options[:skip_if_empty] || false
56
+
57
+ end #def
58
+
59
+ ######################################################################################
60
+ #
61
+ # replace!
62
+ #
63
+ ######################################################################################
64
+ def replace!(doc, manifest, file, row = nil)
65
+
66
+ return unless table = find_table_node(doc)
67
+
68
+ @template_rows = table.xpath("table:table-row")
69
+
70
+ @header = table.xpath("table:table-header-rows").empty? ? @header : false
71
+
72
+ @collection = items(row, @key, @proc) if row
73
+
74
+ if @skip_if_empty && @collection.empty?
75
+ table.remove
76
+ return
77
+ end
78
+
79
+ @collection.each do |item|
80
+
81
+ new_node = get_next_row
82
+ #
83
+ # experimental: new node must be added to doc prior to replace!
84
+ # else new_section does not have a name space
85
+ #
86
+ table.add_child(new_node)
87
+
88
+ @tables.each { |t| t.replace!(new_node, manifest, file, item) }
89
+ @texts.each { |t| t.replace!(new_node, item) }
90
+ @fields.each { |f| f.replace!(new_node, item) }
91
+ @images.each { |f| f.replace!(new_node, manifest, file, item) }
92
+
93
+ end
94
+ Image.unique_image_names( doc) if @images.present?
95
+
96
+ @template_rows.each_with_index do |r, i|
97
+ r.remove if (get_start_node..template_length) === i
98
+ end
99
+
100
+ end #def
101
+
102
+ ######################################################################################
103
+ #
104
+ # private
105
+ #
106
+ ######################################################################################
107
+ private
108
+
109
+ def get_next_row
110
+ @row_cursor = get_start_node unless defined?(@row_cursor)
111
+
112
+ ret = @template_rows[@row_cursor]
113
+ if @template_rows.size == @row_cursor + 1
114
+ @row_cursor = get_start_node
115
+ else
116
+ @row_cursor += 1
117
+ end
118
+ return ret.dup
119
+ end #def
120
+
121
+ def get_start_node
122
+ @header ? 1 : 0
123
+ end #def
124
+
125
+ def template_length
126
+ @tl ||= @template_rows.size
127
+ end #def
128
+
129
+ def find_table_node(doc)
130
+ tables = doc.xpath(".//table:table[@table:name='#{@name}']")
131
+ tables.empty? ? nil : tables.first
132
+ end #def
133
+
134
+ end #class
135
+ end #module
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Ruby Gem to create a self populating Open Document Format (.odf) text file.
4
+ #
5
+ # Copyright 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ module ODFWriter
23
+
24
+ ########################################################################################
25
+ #
26
+ # TableReader: find all tables and set name
27
+ #
28
+ ########################################################################################
29
+ class TableReader
30
+
31
+ attr_accessor :name
32
+
33
+ ######################################################################################
34
+ #
35
+ # initialize
36
+ #
37
+ ######################################################################################
38
+ def initialize(opts)
39
+ @name = opts[:name]
40
+ end #def
41
+
42
+ ######################################################################################
43
+ #
44
+ # tables
45
+ #
46
+ ######################################################################################
47
+ def tables( doc )
48
+ nodes( doc ).keys
49
+ end #def
50
+
51
+ ######################################################################################
52
+ #
53
+ # nodes
54
+ #
55
+ ######################################################################################
56
+ def nodes( doc )
57
+ doc.xpath(".//table:table").map{|node| [node.attr("table:name"), node] }.to_h
58
+ end #def
59
+ end #class
60
+
61
+ end #module
@@ -0,0 +1,222 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Ruby Gem to create a self populating Open Document Format (.odf) text file.
4
+ #
5
+ # Copyright 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ module ODFWriter
23
+
24
+ ########################################################################################
25
+ #
26
+ # Template: handles files in .odt-package
27
+ #
28
+ ########################################################################################
29
+ class Template
30
+
31
+ ######################################################################################
32
+ #
33
+ # constants - we only work and content and styles (contains headers and footers) parts of odf
34
+ #
35
+ ######################################################################################
36
+ CONTENT_ENTRIES = {
37
+ "content.xml" => {:symbol => :content, :path => "content.xml"},
38
+ "styles.xml" => {:symbol => :styles, :path => "styles.xml" }
39
+ }.freeze
40
+
41
+ CONTENT_FILES = {
42
+ :content => {:file => "content.xml", :path => "content.xml"},
43
+ :styles => {:file => "styles.xml", :path => "styles.xml" }
44
+ }.freeze
45
+
46
+ MANIFEST = 'META-INF/manifest.xml'.freeze
47
+
48
+ ######################################################################################
49
+ #
50
+ # accessors
51
+ #
52
+ ######################################################################################
53
+ attr_accessor :output_stream
54
+
55
+ ######################################################################################
56
+ #
57
+ # initialize
58
+ #
59
+ ######################################################################################
60
+ def initialize(path = nil, zip_stream: nil)
61
+
62
+ raise "You must provide either a filename or a zip_stream: string" unless path || zip_stream
63
+ raise "Template [#{template}] not found." if path && !::File.exist?(path)
64
+
65
+ @path = path
66
+ @zip_stream = zip_stream
67
+ end #def
68
+
69
+ ######################################################################################
70
+ #
71
+ # content
72
+ #
73
+ ######################################################################################
74
+ def content(&block)
75
+
76
+ entries.each do |entry|
77
+
78
+ if entry.directory?
79
+ next
80
+
81
+ elsif CONTENT_ENTRIES.keys.include?(entry.name)
82
+ # relevant file with valid file name
83
+ entry.get_input_stream do |input_stream|
84
+ file_content = input_stream.sysread
85
+ yield CONTENT_ENTRIES[entry.name][:symbol], to_xml(file_content)
86
+ end
87
+
88
+ end #if
89
+ end #each
90
+ end #def
91
+
92
+ ######################################################################################
93
+ #
94
+ # update_content: create write buffer for zip
95
+ #
96
+ ######################################################################################
97
+ def update_content
98
+ @buffer = Zip::OutputStream.write_buffer do |out|
99
+ @output_stream = out
100
+ yield self
101
+ end
102
+ end
103
+
104
+ ######################################################################################
105
+ #
106
+ # update_files: open and traverse zip directory, pick content.xml
107
+ # and styles.xml process and eventually write contents
108
+ # to buffer
109
+ # a pointer to manifest.xml is provided
110
+ #
111
+ ######################################################################################
112
+ def update_files(&block)
113
+
114
+ # get manifest, in case a file is added
115
+ @manifest = manifest; digest = Digest::MD5.hexdigest(@manifest)
116
+
117
+ entries.each do |entry|
118
+
119
+ # search content files
120
+ if entry.directory?
121
+ next
122
+
123
+ # process content files
124
+ elsif CONTENT_ENTRIES.keys.include?(entry.name)
125
+
126
+ entry.get_input_stream do |input_stream|
127
+ file_content = input_stream.sysread
128
+ file_symbol = CONTENT_ENTRIES[entry.name][:symbol]
129
+ process_entry(file_symbol, file_content, @manifest, &block)
130
+ @output_stream.put_next_entry(entry.name)
131
+ @output_stream.write file_content
132
+ end #do
133
+
134
+ else
135
+ entry.get_input_stream do |input_stream|
136
+ @output_stream.put_next_entry(entry.name)
137
+ @output_stream.write input_stream.sysread
138
+ end
139
+ end #if
140
+ end #each
141
+
142
+ # eventually write back content file
143
+ if @manifest && digest != Digest::MD5.hexdigest(@manifest)
144
+ @output_stream.put_next_entry(MANIFEST)
145
+ @output_stream.write @manifest
146
+ end #if
147
+
148
+ end #def
149
+
150
+
151
+ ######################################################################################
152
+ #
153
+ # data: just a handle to data in buffer
154
+ #
155
+ ######################################################################################
156
+ def data
157
+ @buffer.string
158
+ end
159
+
160
+ ######################################################################################
161
+ #
162
+ # private
163
+ #
164
+ ######################################################################################
165
+ private
166
+
167
+ ######################################################################################
168
+ # entries: just open zip file or buffer
169
+ ######################################################################################
170
+ def entries
171
+ if @path
172
+ Zip::File.open(@path)
173
+ elsif @zip_stream
174
+ Zip::File.open_buffer(@zip_stream.force_encoding("ASCII-8BIT"))
175
+ end
176
+ end #def
177
+
178
+ ######################################################################################
179
+ # manifest: read manifest
180
+ ######################################################################################
181
+ def manifest
182
+ manifest = nil
183
+ entries.each do |entry|
184
+ next if entry.directory?
185
+ entry.get_input_stream do |input_stream|
186
+ if MANIFEST == entry.name
187
+ manifest = input_stream.sysread.dup
188
+ end
189
+ end
190
+ end
191
+ manifest
192
+ end #def
193
+
194
+ ######################################################################################
195
+ # to_xml
196
+ ######################################################################################
197
+ def to_xml(raw_xml)
198
+ Nokogiri::XML(raw_xml)
199
+ end #def
200
+
201
+ ######################################################################################
202
+ # process_entry: provide Nokogiri Object to caller, after having provided a file
203
+ ######################################################################################
204
+ def process_entry(file_symbol, file_content, manifest)
205
+
206
+ # create xml from file content
207
+ doc = to_xml(file_content ) # { |x| x.noblanks }
208
+ man = to_xml(manifest ) # { |x| x.noblanks }
209
+
210
+ # yield xml
211
+ yield file_symbol, doc, man
212
+
213
+ # replace file_content and manifest in place
214
+ # remove spurious whitespaces between tags "> <" becomes "><"
215
+ file_content.replace(doc.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML).squish.gsub(/(?<=>)\s+(?=<)/, ""))
216
+ # Microsoft Words complains if no trailing newline is present
217
+ manifest.replace(man.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML))
218
+
219
+ end #def
220
+
221
+ end #class
222
+ end #module
@@ -0,0 +1,97 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Ruby Gem to create a self populating Open Document Format (.odf) text file.
4
+ #
5
+ # Copyright 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ module ODFWriter
23
+
24
+ ########################################################################################
25
+ #
26
+ # Text: replace text items
27
+ #
28
+ ########################################################################################
29
+ class Text < Field
30
+
31
+ ######################################################################################
32
+ #
33
+ # constants
34
+ #
35
+ ######################################################################################
36
+ DELIMITERS = %w({ })
37
+
38
+ ######################################################################################
39
+ #
40
+ # replace!
41
+ #
42
+ ######################################################################################
43
+ def replace!(content, item = nil)
44
+
45
+ return unless node = find_text_node(content)
46
+
47
+ text = value(item)
48
+
49
+ @parser = Parser::Default.new(text, node,
50
+ :doc => content,
51
+ :remove_classes => @remove_classes,
52
+ :remove_class_prefix => @remove_class_prefix,
53
+ :remove_class_suffix => @remove_class_suffix
54
+ )
55
+
56
+ @parser.paragraphs.each do |p|
57
+ node.before(p)
58
+ end
59
+
60
+ node.remove
61
+
62
+ end #def
63
+
64
+ ######################################################################################
65
+ #
66
+ # private
67
+ #
68
+ ######################################################################################
69
+ private
70
+
71
+ ######################################################################################
72
+ # find_text_node
73
+ ######################################################################################
74
+ def find_text_node(doc)
75
+ texts = doc.xpath(".//text:p[text()='#{placeholder}']")
76
+ if texts.empty?
77
+ texts = doc.xpath(".//text:p/text:span[text()='#{placeholder}']")
78
+ if texts.empty?
79
+ texts = nil
80
+ else
81
+ texts = texts.first.parent
82
+ end
83
+ else
84
+ texts = texts.first
85
+ end
86
+
87
+ texts
88
+ end #def
89
+
90
+ ######################################################################################
91
+ # placeholder
92
+ ######################################################################################
93
+ def placeholder
94
+ "#{DELIMITERS[0]}#{@name.to_s.upcase}#{DELIMITERS[1]}"
95
+ end #def
96
+ end #class
97
+ end #module