mpxj 5.1.9 → 5.1.10
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 +4 -4
- data/README.md +4 -1
- data/lib/mpxj/container.rb +89 -89
- data/lib/mpxj/mpxj.jar +0 -0
- data/lib/mpxj/project.rb +175 -175
- data/lib/mpxj/reader.rb +48 -48
- data/lib/mpxj/version.rb +5 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14e3c6791d8518f3cac4f787d9d4cc94b6dd76da
|
4
|
+
data.tar.gz: 3f6e8363e3a72ad46cb10739e21a315296480ae6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52a0b516a7604f65574f1dccff38de2e1ff8767e67538e2159098d8d1743a4def4bc4b85312c28141a7cd11bb29094d87f929c96bf1901d598fe93caf2d27a1d
|
7
|
+
data.tar.gz: acf7cfa6573b31342e3a95c786b163282e4ab6cea1123459201224750a0f409677187aaba75c844232ab90671bbcb40f769bda2702ad394f232b966ee3d07910
|
data/README.md
CHANGED
@@ -3,7 +3,10 @@
|
|
3
3
|
This gem allows a Ruby developer to work with a read-only view of project plans saved by a number of popular project planning applications.
|
4
4
|
The work required to read data from these files is actually carried out by a [Java library](http://mpxj.sf.net), hence you will need Java installed
|
5
5
|
and available on your path in order to work with this gem. Once the project data has been read from a file, a set of Ruby objects provides access to the
|
6
|
-
structure of the project plan and its attributes.
|
6
|
+
structure of the project plan and its attributes.
|
7
|
+
|
8
|
+
This gem only came about through the interest and support of Procore, who would love to [hear from you](https://www.procore.com/jobs/)
|
9
|
+
if you're excited about working with Ruby and Rails.
|
7
10
|
|
8
11
|
## Installation
|
9
12
|
|
data/lib/mpxj/container.rb
CHANGED
@@ -1,89 +1,89 @@
|
|
1
|
-
require 'duration'
|
2
|
-
require 'time'
|
3
|
-
|
4
|
-
module MPXJ
|
5
|
-
# Base class from which all project entities are derived
|
6
|
-
class Container
|
7
|
-
attr_reader :parent_project
|
8
|
-
def initialize(parent_project, attribute_types, attribute_values)
|
9
|
-
@parent_project = parent_project
|
10
|
-
@attribute_types = attribute_types
|
11
|
-
@attribute_values = attribute_values
|
12
|
-
end
|
13
|
-
|
14
|
-
def method_missing(name, *args, &block)
|
15
|
-
# We can probably do this more efficiently with dynamic methods... but let's get some feedback first!
|
16
|
-
attribute_name = name.to_s
|
17
|
-
attribute_type = @attribute_types[attribute_name]
|
18
|
-
attribute_value = @attribute_values[attribute_name]
|
19
|
-
|
20
|
-
if attribute_type.nil? && attribute_value.nil?
|
21
|
-
super
|
22
|
-
else
|
23
|
-
if attribute_type.nil?
|
24
|
-
attribute_type = 1
|
25
|
-
end
|
26
|
-
get_attribute_value(attribute_type, attribute_value)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
protected
|
31
|
-
|
32
|
-
attr_reader :attribute_values
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def get_attribute_value(attribute_type, attribute_value)
|
37
|
-
case attribute_type.to_i
|
38
|
-
when 12, 17, 19
|
39
|
-
get_integer_value(attribute_value)
|
40
|
-
when 8, 3, 5, 7
|
41
|
-
get_float_value(attribute_value)
|
42
|
-
when 2
|
43
|
-
get_date_value(attribute_value)
|
44
|
-
when 6, 16
|
45
|
-
get_duration_value(attribute_value)
|
46
|
-
when 4
|
47
|
-
get_boolean_value(attribute_value)
|
48
|
-
else
|
49
|
-
attribute_value
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def get_duration_value(attribute_value)
|
54
|
-
if attribute_value.nil?
|
55
|
-
Duration.new(0)
|
56
|
-
else
|
57
|
-
Duration.new(attribute_value.to_i)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def get_date_value(attribute_value)
|
62
|
-
if attribute_value.nil?
|
63
|
-
nil
|
64
|
-
else
|
65
|
-
@parent_project.zone.parse(attribute_value)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def get_float_value(attribute_value)
|
70
|
-
if attribute_value.nil?
|
71
|
-
0.0
|
72
|
-
else
|
73
|
-
attribute_value.to_f
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def get_integer_value(attribute_value)
|
78
|
-
if attribute_value.nil?
|
79
|
-
0
|
80
|
-
else
|
81
|
-
attribute_value.to_i
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def get_boolean_value(attribute_value)
|
86
|
-
attribute_value == true
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
1
|
+
require 'duration'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module MPXJ
|
5
|
+
# Base class from which all project entities are derived
|
6
|
+
class Container
|
7
|
+
attr_reader :parent_project
|
8
|
+
def initialize(parent_project, attribute_types, attribute_values)
|
9
|
+
@parent_project = parent_project
|
10
|
+
@attribute_types = attribute_types
|
11
|
+
@attribute_values = attribute_values
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(name, *args, &block)
|
15
|
+
# We can probably do this more efficiently with dynamic methods... but let's get some feedback first!
|
16
|
+
attribute_name = name.to_s
|
17
|
+
attribute_type = @attribute_types[attribute_name]
|
18
|
+
attribute_value = @attribute_values[attribute_name]
|
19
|
+
|
20
|
+
if attribute_type.nil? && attribute_value.nil?
|
21
|
+
super
|
22
|
+
else
|
23
|
+
if attribute_type.nil?
|
24
|
+
attribute_type = 1
|
25
|
+
end
|
26
|
+
get_attribute_value(attribute_type, attribute_value)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
attr_reader :attribute_values
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def get_attribute_value(attribute_type, attribute_value)
|
37
|
+
case attribute_type.to_i
|
38
|
+
when 12, 17, 19
|
39
|
+
get_integer_value(attribute_value)
|
40
|
+
when 8, 3, 5, 7
|
41
|
+
get_float_value(attribute_value)
|
42
|
+
when 2
|
43
|
+
get_date_value(attribute_value)
|
44
|
+
when 6, 16
|
45
|
+
get_duration_value(attribute_value)
|
46
|
+
when 4
|
47
|
+
get_boolean_value(attribute_value)
|
48
|
+
else
|
49
|
+
attribute_value
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_duration_value(attribute_value)
|
54
|
+
if attribute_value.nil?
|
55
|
+
Duration.new(0)
|
56
|
+
else
|
57
|
+
Duration.new(attribute_value.to_i)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_date_value(attribute_value)
|
62
|
+
if attribute_value.nil?
|
63
|
+
nil
|
64
|
+
else
|
65
|
+
@parent_project.zone.parse(attribute_value)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_float_value(attribute_value)
|
70
|
+
if attribute_value.nil?
|
71
|
+
0.0
|
72
|
+
else
|
73
|
+
attribute_value.to_f
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_integer_value(attribute_value)
|
78
|
+
if attribute_value.nil?
|
79
|
+
0
|
80
|
+
else
|
81
|
+
attribute_value.to_i
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_boolean_value(attribute_value)
|
86
|
+
attribute_value == true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/mpxj/mpxj.jar
CHANGED
Binary file
|
data/lib/mpxj/project.rb
CHANGED
@@ -1,175 +1,175 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
module MPXJ
|
4
|
-
# Represents a project plan
|
5
|
-
class Project
|
6
|
-
attr_reader :properties
|
7
|
-
attr_reader :all_resources
|
8
|
-
attr_reader :all_tasks
|
9
|
-
attr_reader :child_tasks
|
10
|
-
attr_reader :all_assignments
|
11
|
-
attr_reader :zone
|
12
|
-
|
13
|
-
def initialize(file_name, zone)
|
14
|
-
@resources_by_unique_id = {}
|
15
|
-
@tasks_by_unique_id = {}
|
16
|
-
|
17
|
-
@resources_by_id = {}
|
18
|
-
@tasks_by_id = {}
|
19
|
-
|
20
|
-
@all_resources = []
|
21
|
-
@all_tasks = []
|
22
|
-
@all_assignments = []
|
23
|
-
@child_tasks = []
|
24
|
-
|
25
|
-
@zone = zone
|
26
|
-
|
27
|
-
@field_by_alias = {}
|
28
|
-
@alias_by_field = {}
|
29
|
-
|
30
|
-
file = File.read(file_name)
|
31
|
-
json_data = JSON.parse(file)
|
32
|
-
process_custom_fields(json_data)
|
33
|
-
process_properties(json_data)
|
34
|
-
process_resources(json_data)
|
35
|
-
process_tasks(json_data)
|
36
|
-
process_assignments(json_data)
|
37
|
-
end
|
38
|
-
|
39
|
-
# Retrieves the resource with the matching unique_id attribute
|
40
|
-
#
|
41
|
-
# @param unique_id [Integer] resource unique ID
|
42
|
-
# @return [Resource] if the requested resource is found
|
43
|
-
# @return [nil] if the requested resource is not found
|
44
|
-
def get_resource_by_unique_id(unique_id)
|
45
|
-
@resources_by_unique_id[unique_id]
|
46
|
-
end
|
47
|
-
|
48
|
-
# Retrieves the task with the matching unique_id attribute
|
49
|
-
#
|
50
|
-
# @param unique_id [Integer] task unique ID
|
51
|
-
# @return [Task] if the requested task is found
|
52
|
-
# @return [nil] if the requested task is not found
|
53
|
-
def get_task_by_unique_id(unique_id)
|
54
|
-
@tasks_by_unique_id[unique_id]
|
55
|
-
end
|
56
|
-
|
57
|
-
# Retrieves the resource with the matching id attribute
|
58
|
-
#
|
59
|
-
# @param id [Integer] resource ID
|
60
|
-
# @return [Resource] if the requested resource is found
|
61
|
-
# @return [nil] if the requested resource is not found
|
62
|
-
def get_resource_by_id(id)
|
63
|
-
@resources_by_id[id]
|
64
|
-
end
|
65
|
-
|
66
|
-
# Retrieves the task with the matching id attribute
|
67
|
-
#
|
68
|
-
# @param id [Integer] task ID
|
69
|
-
# @return [Task] if the requested task is found
|
70
|
-
# @return [nil] if the requested task is not found
|
71
|
-
def get_task_by_id(id)
|
72
|
-
@tasks_by_unique_id[id]
|
73
|
-
end
|
74
|
-
|
75
|
-
# For a particular entity type (task, resource, and so on), retrieve
|
76
|
-
# the field which has the supplied alias. For example this allows the caller to
|
77
|
-
# answer the question "which task field is using the alias `Activity ID`"
|
78
|
-
#
|
79
|
-
# @param field_type_class[String] field type (possible values: task, resource, assignment, constraint, project)
|
80
|
-
# @param field_alias[String] the alias we want to look up
|
81
|
-
# @return [String] if the alias has been found return the name of the underlying field
|
82
|
-
# @return [nil] if the alias is not in use
|
83
|
-
def get_field_by_alias(field_type_class, field_alias)
|
84
|
-
hash = @field_by_alias[field_type_class]
|
85
|
-
if hash
|
86
|
-
hash[field_alias]
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
# For a particular entity type (task, resource, and so on), retrieve
|
91
|
-
# the alias used by the supplied field. For example this allows the caller to
|
92
|
-
# answer the question "does the task field Text1 have an alias?"
|
93
|
-
#
|
94
|
-
# @param field_type_class[String] field type (possible values: task, resource, assignment, constraint, project)
|
95
|
-
# @param field_type[String] the field type we want to look up
|
96
|
-
# @return [String] if the field has an alias, return the alias
|
97
|
-
# @return [nil] if the field does not have an alias
|
98
|
-
def get_alias_by_field(field_type_class, field_type)
|
99
|
-
hash = @alias_by_field[field_type_class]
|
100
|
-
if hash
|
101
|
-
hash[field_type]
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
private
|
106
|
-
|
107
|
-
def process_custom_fields(json_data)
|
108
|
-
custom_fields = json_data["custom_fields"]
|
109
|
-
custom_fields.each do |field|
|
110
|
-
process_custom_field(field)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def process_custom_field(field)
|
115
|
-
field_type_class = field["field_type_class"]
|
116
|
-
field_type = field["field_type"]
|
117
|
-
field_alias = field["field_alias"]
|
118
|
-
|
119
|
-
process_custom_field_hash(@field_by_alias, field_type_class, field_alias, field_type)
|
120
|
-
process_custom_field_hash(@alias_by_field, field_type_class, field_type, field_alias)
|
121
|
-
end
|
122
|
-
|
123
|
-
def process_custom_field_hash(hash, key1, key2, value)
|
124
|
-
key1_hash = hash[key1]
|
125
|
-
unless key1_hash
|
126
|
-
key1_hash = {}
|
127
|
-
hash[key1] = key1_hash
|
128
|
-
end
|
129
|
-
key1_hash[key2] = value
|
130
|
-
end
|
131
|
-
|
132
|
-
def process_properties(json_data)
|
133
|
-
attribute_types = json_data["property_types"]
|
134
|
-
attribute_values = json_data["property_values"]
|
135
|
-
@properties = Properties.new(self, attribute_types, attribute_values)
|
136
|
-
end
|
137
|
-
|
138
|
-
def process_resources(json_data)
|
139
|
-
attribute_types = json_data["resource_types"]
|
140
|
-
resources = json_data["resources"]
|
141
|
-
resources.each do |attribute_values|
|
142
|
-
resource = Resource.new(self, attribute_types, attribute_values)
|
143
|
-
@all_resources << resource
|
144
|
-
@resources_by_unique_id[resource.unique_id] = resource
|
145
|
-
@resources_by_id[resource.id] = resource
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def process_tasks(json_data)
|
150
|
-
attribute_types = json_data["task_types"]
|
151
|
-
tasks = json_data["tasks"]
|
152
|
-
tasks.each do |attribute_values|
|
153
|
-
task = Task.new(self, attribute_types, attribute_values)
|
154
|
-
@all_tasks << task
|
155
|
-
@tasks_by_unique_id[task.unique_id] = task
|
156
|
-
@tasks_by_id[task.id] = task
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
def process_assignments(json_data)
|
161
|
-
attribute_types = json_data["assignment_types"]
|
162
|
-
assignments = json_data["assignments"]
|
163
|
-
assignments.each do |attribute_values|
|
164
|
-
assignment = Assignment.new(self, attribute_types, attribute_values)
|
165
|
-
@all_assignments << assignment
|
166
|
-
if assignment.task
|
167
|
-
assignment.task.assignments << assignment
|
168
|
-
end
|
169
|
-
if assignment.resource
|
170
|
-
assignment.resource.assignments << assignment
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module MPXJ
|
4
|
+
# Represents a project plan
|
5
|
+
class Project
|
6
|
+
attr_reader :properties
|
7
|
+
attr_reader :all_resources
|
8
|
+
attr_reader :all_tasks
|
9
|
+
attr_reader :child_tasks
|
10
|
+
attr_reader :all_assignments
|
11
|
+
attr_reader :zone
|
12
|
+
|
13
|
+
def initialize(file_name, zone)
|
14
|
+
@resources_by_unique_id = {}
|
15
|
+
@tasks_by_unique_id = {}
|
16
|
+
|
17
|
+
@resources_by_id = {}
|
18
|
+
@tasks_by_id = {}
|
19
|
+
|
20
|
+
@all_resources = []
|
21
|
+
@all_tasks = []
|
22
|
+
@all_assignments = []
|
23
|
+
@child_tasks = []
|
24
|
+
|
25
|
+
@zone = zone
|
26
|
+
|
27
|
+
@field_by_alias = {}
|
28
|
+
@alias_by_field = {}
|
29
|
+
|
30
|
+
file = File.read(file_name)
|
31
|
+
json_data = JSON.parse(file)
|
32
|
+
process_custom_fields(json_data)
|
33
|
+
process_properties(json_data)
|
34
|
+
process_resources(json_data)
|
35
|
+
process_tasks(json_data)
|
36
|
+
process_assignments(json_data)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Retrieves the resource with the matching unique_id attribute
|
40
|
+
#
|
41
|
+
# @param unique_id [Integer] resource unique ID
|
42
|
+
# @return [Resource] if the requested resource is found
|
43
|
+
# @return [nil] if the requested resource is not found
|
44
|
+
def get_resource_by_unique_id(unique_id)
|
45
|
+
@resources_by_unique_id[unique_id]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Retrieves the task with the matching unique_id attribute
|
49
|
+
#
|
50
|
+
# @param unique_id [Integer] task unique ID
|
51
|
+
# @return [Task] if the requested task is found
|
52
|
+
# @return [nil] if the requested task is not found
|
53
|
+
def get_task_by_unique_id(unique_id)
|
54
|
+
@tasks_by_unique_id[unique_id]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Retrieves the resource with the matching id attribute
|
58
|
+
#
|
59
|
+
# @param id [Integer] resource ID
|
60
|
+
# @return [Resource] if the requested resource is found
|
61
|
+
# @return [nil] if the requested resource is not found
|
62
|
+
def get_resource_by_id(id)
|
63
|
+
@resources_by_id[id]
|
64
|
+
end
|
65
|
+
|
66
|
+
# Retrieves the task with the matching id attribute
|
67
|
+
#
|
68
|
+
# @param id [Integer] task ID
|
69
|
+
# @return [Task] if the requested task is found
|
70
|
+
# @return [nil] if the requested task is not found
|
71
|
+
def get_task_by_id(id)
|
72
|
+
@tasks_by_unique_id[id]
|
73
|
+
end
|
74
|
+
|
75
|
+
# For a particular entity type (task, resource, and so on), retrieve
|
76
|
+
# the field which has the supplied alias. For example this allows the caller to
|
77
|
+
# answer the question "which task field is using the alias `Activity ID`"
|
78
|
+
#
|
79
|
+
# @param field_type_class[String] field type (possible values: task, resource, assignment, constraint, project)
|
80
|
+
# @param field_alias[String] the alias we want to look up
|
81
|
+
# @return [String] if the alias has been found return the name of the underlying field
|
82
|
+
# @return [nil] if the alias is not in use
|
83
|
+
def get_field_by_alias(field_type_class, field_alias)
|
84
|
+
hash = @field_by_alias[field_type_class]
|
85
|
+
if hash
|
86
|
+
hash[field_alias]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# For a particular entity type (task, resource, and so on), retrieve
|
91
|
+
# the alias used by the supplied field. For example this allows the caller to
|
92
|
+
# answer the question "does the task field Text1 have an alias?"
|
93
|
+
#
|
94
|
+
# @param field_type_class[String] field type (possible values: task, resource, assignment, constraint, project)
|
95
|
+
# @param field_type[String] the field type we want to look up
|
96
|
+
# @return [String] if the field has an alias, return the alias
|
97
|
+
# @return [nil] if the field does not have an alias
|
98
|
+
def get_alias_by_field(field_type_class, field_type)
|
99
|
+
hash = @alias_by_field[field_type_class]
|
100
|
+
if hash
|
101
|
+
hash[field_type]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def process_custom_fields(json_data)
|
108
|
+
custom_fields = json_data["custom_fields"]
|
109
|
+
custom_fields.each do |field|
|
110
|
+
process_custom_field(field)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def process_custom_field(field)
|
115
|
+
field_type_class = field["field_type_class"]
|
116
|
+
field_type = field["field_type"]
|
117
|
+
field_alias = field["field_alias"]
|
118
|
+
|
119
|
+
process_custom_field_hash(@field_by_alias, field_type_class, field_alias, field_type)
|
120
|
+
process_custom_field_hash(@alias_by_field, field_type_class, field_type, field_alias)
|
121
|
+
end
|
122
|
+
|
123
|
+
def process_custom_field_hash(hash, key1, key2, value)
|
124
|
+
key1_hash = hash[key1]
|
125
|
+
unless key1_hash
|
126
|
+
key1_hash = {}
|
127
|
+
hash[key1] = key1_hash
|
128
|
+
end
|
129
|
+
key1_hash[key2] = value
|
130
|
+
end
|
131
|
+
|
132
|
+
def process_properties(json_data)
|
133
|
+
attribute_types = json_data["property_types"]
|
134
|
+
attribute_values = json_data["property_values"]
|
135
|
+
@properties = Properties.new(self, attribute_types, attribute_values)
|
136
|
+
end
|
137
|
+
|
138
|
+
def process_resources(json_data)
|
139
|
+
attribute_types = json_data["resource_types"]
|
140
|
+
resources = json_data["resources"]
|
141
|
+
resources.each do |attribute_values|
|
142
|
+
resource = Resource.new(self, attribute_types, attribute_values)
|
143
|
+
@all_resources << resource
|
144
|
+
@resources_by_unique_id[resource.unique_id] = resource
|
145
|
+
@resources_by_id[resource.id] = resource
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def process_tasks(json_data)
|
150
|
+
attribute_types = json_data["task_types"]
|
151
|
+
tasks = json_data["tasks"]
|
152
|
+
tasks.each do |attribute_values|
|
153
|
+
task = Task.new(self, attribute_types, attribute_values)
|
154
|
+
@all_tasks << task
|
155
|
+
@tasks_by_unique_id[task.unique_id] = task
|
156
|
+
@tasks_by_id[task.id] = task
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def process_assignments(json_data)
|
161
|
+
attribute_types = json_data["assignment_types"]
|
162
|
+
assignments = json_data["assignments"]
|
163
|
+
assignments.each do |attribute_values|
|
164
|
+
assignment = Assignment.new(self, attribute_types, attribute_values)
|
165
|
+
@all_assignments << assignment
|
166
|
+
if assignment.task
|
167
|
+
assignment.task.assignments << assignment
|
168
|
+
end
|
169
|
+
if assignment.resource
|
170
|
+
assignment.resource.assignments << assignment
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
data/lib/mpxj/reader.rb
CHANGED
@@ -1,48 +1,48 @@
|
|
1
|
-
require 'tempfile'
|
2
|
-
require 'active_support/core_ext/time/calculations'
|
3
|
-
|
4
|
-
module MPXJ
|
5
|
-
# Used to read a project plan from a file
|
6
|
-
class Reader
|
7
|
-
# Reads a project plan from a file, and returns a Project instance
|
8
|
-
# which provides access to the structure and attributes of the project data.
|
9
|
-
# Note that an optional timezone can be supplied to ensue that all date-time
|
10
|
-
# values returned are in the specified timezone.
|
11
|
-
#
|
12
|
-
# @param file_name [String] the name of the file to read
|
13
|
-
# @param zone [ActiveSupport::TimeZone] an optional timezone
|
14
|
-
# @return [Project] new Project instance
|
15
|
-
def self.read(file_name, zone = nil)
|
16
|
-
project = nil
|
17
|
-
json_file = Tempfile.new([File.basename(file_name, ".*"), '.json'])
|
18
|
-
tz = zone || Time.zone || ActiveSupport::TimeZone["UTC"]
|
19
|
-
|
20
|
-
begin
|
21
|
-
classpath = Dir["#{File.dirname(__FILE__)}/*.jar"].join(path_separator)
|
22
|
-
java_output = `java -cp \"#{classpath}\" net.sf.mpxj.sample.MpxjConvert \"#{file_name}\" \"#{json_file.path}\"`
|
23
|
-
if $?.exitstatus != 0
|
24
|
-
raise "Failed to read file: #{java_output}"
|
25
|
-
end
|
26
|
-
project = Project.new(json_file, tz)
|
27
|
-
ensure
|
28
|
-
json_file.close
|
29
|
-
json_file.unlink
|
30
|
-
end
|
31
|
-
project
|
32
|
-
end
|
33
|
-
|
34
|
-
# @private
|
35
|
-
def self.path_separator
|
36
|
-
if windows?
|
37
|
-
";"
|
38
|
-
else
|
39
|
-
":"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# @private
|
44
|
-
def self.windows?
|
45
|
-
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
1
|
+
require 'tempfile'
|
2
|
+
require 'active_support/core_ext/time/calculations'
|
3
|
+
|
4
|
+
module MPXJ
|
5
|
+
# Used to read a project plan from a file
|
6
|
+
class Reader
|
7
|
+
# Reads a project plan from a file, and returns a Project instance
|
8
|
+
# which provides access to the structure and attributes of the project data.
|
9
|
+
# Note that an optional timezone can be supplied to ensue that all date-time
|
10
|
+
# values returned are in the specified timezone.
|
11
|
+
#
|
12
|
+
# @param file_name [String] the name of the file to read
|
13
|
+
# @param zone [ActiveSupport::TimeZone] an optional timezone
|
14
|
+
# @return [Project] new Project instance
|
15
|
+
def self.read(file_name, zone = nil)
|
16
|
+
project = nil
|
17
|
+
json_file = Tempfile.new([File.basename(file_name, ".*"), '.json'])
|
18
|
+
tz = zone || Time.zone || ActiveSupport::TimeZone["UTC"]
|
19
|
+
|
20
|
+
begin
|
21
|
+
classpath = Dir["#{File.dirname(__FILE__)}/*.jar"].join(path_separator)
|
22
|
+
java_output = `java -cp \"#{classpath}\" net.sf.mpxj.sample.MpxjConvert \"#{file_name}\" \"#{json_file.path}\"`
|
23
|
+
if $?.exitstatus != 0
|
24
|
+
raise "Failed to read file: #{java_output}"
|
25
|
+
end
|
26
|
+
project = Project.new(json_file, tz)
|
27
|
+
ensure
|
28
|
+
json_file.close
|
29
|
+
json_file.unlink
|
30
|
+
end
|
31
|
+
project
|
32
|
+
end
|
33
|
+
|
34
|
+
# @private
|
35
|
+
def self.path_separator
|
36
|
+
if windows?
|
37
|
+
";"
|
38
|
+
else
|
39
|
+
":"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# @private
|
44
|
+
def self.windows?
|
45
|
+
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/mpxj/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# MPXJ gem module
|
2
|
-
module MPXJ
|
3
|
-
# MPXJ gem version number
|
4
|
-
VERSION = "5.1.
|
5
|
-
end
|
1
|
+
# MPXJ gem module
|
2
|
+
module MPXJ
|
3
|
+
# MPXJ gem version number
|
4
|
+
VERSION = "5.1.10"
|
5
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mpxj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.1.
|
4
|
+
version: 5.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Iles
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|