xteam_schedule 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +54 -2
- data/lib/xteam_schedule/facilitation/base.rb +15 -0
- data/lib/xteam_schedule/facilitation/composer.rb +93 -55
- data/lib/xteam_schedule/facilitation/parser.rb +35 -0
- data/lib/xteam_schedule/facilitation/qtn_patch.rb +21 -0
- data/lib/xteam_schedule/facilitation/without_nil.rb +33 -0
- data/lib/xteam_schedule/models/remote_access.rb +20 -0
- data/lib/xteam_schedule/models/schedule.rb +7 -0
- data/lib/xteam_schedule.rb +10 -0
- metadata +9 -6
data/README.md
CHANGED
@@ -13,7 +13,7 @@ You can find a blog post explaining some of the thinking behind its implementati
|
|
13
13
|
* **Read and write schedules** and interact with in-memory models through the ActiveRecord interface
|
14
14
|
* **Customise everything**; resources, assignments, groups, colours, interface settings..
|
15
15
|
* **Intuitive naming** of models, that correspond to what you see on screen
|
16
|
-
* **Full test coverage**, giving confidence to highly dynamic businesses everywhere
|
16
|
+
* **Full test coverage**, giving confidence to highly dynamic businesses everywhere [![Build Status](https://secure.travis-ci.org/cpatuzzo/xteam_schedule.png?branch=master)](http://travis-ci.org/cpatuzzo/xteam_schedule)
|
17
17
|
|
18
18
|
### Disclaimer
|
19
19
|
|
@@ -138,6 +138,8 @@ gmail_resource_names = resources.where('email like "%gmail%"').map(&:name)
|
|
138
138
|
resources.each { |r| r.update_attribute(:displayed_in_planning, true) }
|
139
139
|
```
|
140
140
|
|
141
|
+
A resource also has remote access attributes, that are explained below.
|
142
|
+
|
141
143
|
## Assignment Groups
|
142
144
|
|
143
145
|
Assignment groups are almost identical to resource groups. Typical names might be 'Training' and 'Research'.
|
@@ -334,6 +336,57 @@ finished_holidays = schedule.resources.map(&:holidays).flatten.select { |h|
|
|
334
336
|
}
|
335
337
|
```
|
336
338
|
|
339
|
+
## Remote Access
|
340
|
+
|
341
|
+
Remote access allows the xTeamView application on Mac OS X and iOS devices to view schedules remotely. A schedule has a remote_access object containing most of the setup, including the 'All' login option for the schedule.
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
schedule.remote_access.update_attributes!(
|
345
|
+
:enabled => true,
|
346
|
+
:custom_url => 'http://xteambridge.example.com',
|
347
|
+
:custom_enabled => true,
|
348
|
+
:global_login => 'username',
|
349
|
+
:global_password => 'password',
|
350
|
+
:global_login_enabled => true
|
351
|
+
)
|
352
|
+
```
|
353
|
+
|
354
|
+
When remote access is switched on in xTeam, there is a handshake process that takes place which assigns a server_id and name to the schedule. If either of these is missing or they become out of sync, the handshake will fail and you will be notified of an error in xTeam. Therefore, it is recommended that you do not change these attributes. Instead, you should enable remote in xTeam then read these attributes from that file. You can then re-use them as you please.
|
355
|
+
|
356
|
+
```ruby
|
357
|
+
schedule = XTeamSchedule.new('path/to/file/with/remote/enabled.xtps')
|
358
|
+
server_id = schedule.remote_access.server_id
|
359
|
+
name = schedule.remote_access.name
|
360
|
+
|
361
|
+
# An example of re-using the remote configuration for an entirely new schedule
|
362
|
+
schedule = XTeamSchedule.new
|
363
|
+
schedule.remote_access.update_attributes!(
|
364
|
+
:server_id => server_id,
|
365
|
+
:name => name
|
366
|
+
)
|
367
|
+
```
|
368
|
+
|
369
|
+
There are three additional attributes on each resource for configuring individual logins. It is worth noting that login details have to be plaintext, unfortunately.
|
370
|
+
|
371
|
+
```ruby
|
372
|
+
resource_group = schedule.resource_groups.create(:name => 'foo')
|
373
|
+
resource = resource_group.resources.create!(
|
374
|
+
:name => 'bar',
|
375
|
+
:remote_login => 'foo',
|
376
|
+
:remote_password => 'bar',
|
377
|
+
:remote_login_enabled => true
|
378
|
+
)
|
379
|
+
```
|
380
|
+
|
381
|
+
**Example queries:**
|
382
|
+
|
383
|
+
```ruby
|
384
|
+
global_login_details = [schedule.remote_access.global_login, schedule.remote_access.global_password]
|
385
|
+
resources_without_logins = schedule.resources.reject { |r| r.remote_login }
|
386
|
+
usernames = schedule.resources.map(&:remote_login).compact
|
387
|
+
raise 'There are duplicated logins' if usernames.count > usernames.uniq.count
|
388
|
+
```
|
389
|
+
|
337
390
|
## Under Development
|
338
391
|
|
339
392
|
This gem is far from complete. The following is a list of features that are under development:
|
@@ -341,7 +394,6 @@ This gem is far from complete. The following is a list of features that are unde
|
|
341
394
|
* Resource images
|
342
395
|
* Sort by
|
343
396
|
* Absences
|
344
|
-
* Remote access
|
345
397
|
* To assign
|
346
398
|
* Advanced colour controls
|
347
399
|
* Schedule splicing between dates
|
@@ -49,6 +49,9 @@ class XTeamSchedule::Base < ActiveRecord::Base
|
|
49
49
|
table.column :mobile, :string
|
50
50
|
table.column :name, :string
|
51
51
|
table.column :phone, :string
|
52
|
+
table.column :remote_login, :string
|
53
|
+
table.column :remote_password, :string
|
54
|
+
table.column :remote_login_enabled, :boolean
|
52
55
|
end
|
53
56
|
|
54
57
|
create_table :assignment_groups, :force => true do |table|
|
@@ -78,6 +81,18 @@ class XTeamSchedule::Base < ActiveRecord::Base
|
|
78
81
|
table.column :end_date, :date
|
79
82
|
table.column :name, :string
|
80
83
|
end
|
84
|
+
|
85
|
+
create_table :remote_accesses, :force => true do |table|
|
86
|
+
table.column :schedule_id, :integer
|
87
|
+
table.column :server_id, :integer
|
88
|
+
table.column :enabled, :boolean
|
89
|
+
table.column :name, :string
|
90
|
+
table.column :custom_url, :string
|
91
|
+
table.column :custom_enabled, :boolean
|
92
|
+
table.column :global_login, :string
|
93
|
+
table.column :global_password, :string
|
94
|
+
table.column :global_login_enabled, :boolean
|
95
|
+
end
|
81
96
|
end
|
82
97
|
end
|
83
98
|
end
|
@@ -9,7 +9,7 @@ class XTeamSchedule::Composer
|
|
9
9
|
def initialize(schedule)
|
10
10
|
schedule.save!
|
11
11
|
self.schedule = schedule
|
12
|
-
self.hash =
|
12
|
+
self.hash = HashWithoutNilValues.new
|
13
13
|
end
|
14
14
|
|
15
15
|
def compose
|
@@ -21,6 +21,7 @@ class XTeamSchedule::Composer
|
|
21
21
|
compose_interface!
|
22
22
|
compose_weekly_working_schedule!
|
23
23
|
compose_holidays!
|
24
|
+
compose_remote_access!
|
24
25
|
compose_schedule!
|
25
26
|
hash
|
26
27
|
end
|
@@ -31,10 +32,10 @@ private
|
|
31
32
|
hash['resource groups'] ||= []
|
32
33
|
resource_groups = schedule.resource_groups
|
33
34
|
resource_groups.each do |rg|
|
34
|
-
hash['resource groups'] << {
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
hash['resource groups'] << {}
|
36
|
+
current = hash['resource groups'].last
|
37
|
+
current['name'] = rg.name
|
38
|
+
current['expanded in library'] = rg.expanded_in_library
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
@@ -43,15 +44,15 @@ private
|
|
43
44
|
resources = schedule.resource_groups.map(&:resources).flatten
|
44
45
|
resources.each do |r|
|
45
46
|
image = Base64.decode64(r.image) if r.image
|
46
|
-
hash['resources'] << {
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
47
|
+
hash['resources'] << {}
|
48
|
+
current = hash['resources'].last
|
49
|
+
current['displayedInPlanning'] = r.displayed_in_planning
|
50
|
+
current['email'] = r.email
|
51
|
+
current['image'] = (StringIO.new(image) if image)
|
52
|
+
current['mobile'] = r.mobile
|
53
|
+
current['name'] = r.name
|
54
|
+
current['phone'] = r.phone
|
55
|
+
current['group'] = r.resource_group.name
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
@@ -59,10 +60,10 @@ private
|
|
59
60
|
hash['task categories'] ||= []
|
60
61
|
assignment_groups = schedule.assignment_groups
|
61
62
|
assignment_groups.each do |ag|
|
62
|
-
hash['task categories'] << {
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
hash['task categories'] << {}
|
64
|
+
current = hash['task categories'].last
|
65
|
+
current['name'] = ag.name
|
66
|
+
current['expanded in library'] = ag.expanded_in_library
|
66
67
|
end
|
67
68
|
end
|
68
69
|
|
@@ -70,12 +71,12 @@ private
|
|
70
71
|
hash['tasks'] ||= []
|
71
72
|
assignments = schedule.assignment_groups.map(&:assignments).flatten
|
72
73
|
assignments.each do |a|
|
73
|
-
hash['tasks'] << {
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
74
|
+
hash['tasks'] << {}
|
75
|
+
current = hash['tasks'].last
|
76
|
+
current['name'] = a.name
|
77
|
+
current['category'] = a.assignment_group.name
|
78
|
+
current['kind'] = 0
|
79
|
+
current['color'] = compose_colour(a.colour)
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
@@ -85,15 +86,15 @@ private
|
|
85
86
|
resources.each do |r|
|
86
87
|
working_times_with_parents = r.working_times.select { |wt| wt.resource and wt.assignment }
|
87
88
|
next unless working_times_with_parents.any?
|
88
|
-
hash['objectsForResources']
|
89
|
+
hash['objectsForResources'][r.name] = []
|
89
90
|
working_times_with_parents.each do |wt|
|
90
|
-
hash['objectsForResources'][r.name] << {
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
91
|
+
hash['objectsForResources'][r.name] << {}
|
92
|
+
current = hash['objectsForResources'][r.name].last
|
93
|
+
current['task'] = wt.assignment.name
|
94
|
+
current['begin date'] = compose_date(wt.begin_date)
|
95
|
+
current['duration'] = wt.duration
|
96
|
+
current['notes'] = wt.notes
|
97
|
+
current['title'] = ''
|
97
98
|
end
|
98
99
|
end
|
99
100
|
end
|
@@ -107,7 +108,8 @@ private
|
|
107
108
|
hash['display resource totals'] = interface.display_total_of_working_hours
|
108
109
|
hash['display task notes'] = interface.display_assignments_notes
|
109
110
|
hash['display absence cells'] = interface.display_absences
|
110
|
-
hash['interface status']
|
111
|
+
hash['interface status'] ||= {}
|
112
|
+
hash['interface status']['latest time navigation mode'] = interface.time_granularity
|
111
113
|
end
|
112
114
|
|
113
115
|
def compose_weekly_working_schedule!
|
@@ -120,23 +122,23 @@ private
|
|
120
122
|
|
121
123
|
working_days.each do |day|
|
122
124
|
day_name = day.name.downcase
|
123
|
-
hash['settings']['working schedule'][day_name] =
|
125
|
+
hash['settings']['working schedule'][day_name] = {}
|
126
|
+
current = hash['settings']['working schedule'][day_name]
|
124
127
|
if day.day_begin.present?
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
+
current['worked'] = 'yes'
|
129
|
+
current['begin'] = compose_time(day.day_begin)
|
130
|
+
current['end'] = compose_time(day.day_end)
|
128
131
|
else
|
129
|
-
|
132
|
+
current['worked'] = 'no'
|
130
133
|
end
|
131
134
|
|
132
|
-
hash['settings']['working schedule']["pause_#{day_name}"] =
|
135
|
+
hash['settings']['working schedule']["pause_#{day_name}"] = {}
|
136
|
+
current = hash['settings']['working schedule']["pause_#{day_name}"]
|
133
137
|
if day.day_begin.present? and day.break_begin.present?
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
else
|
139
|
-
{}
|
138
|
+
current['worked'] = 'yes'
|
139
|
+
current['begin'] = compose_time(day.break_begin)
|
140
|
+
current['end'] = compose_time(day.break_end)
|
141
|
+
current['duration'] = compose_time(day.break_end) - compose_time(day.break_begin)
|
140
142
|
end
|
141
143
|
end
|
142
144
|
end
|
@@ -154,11 +156,11 @@ private
|
|
154
156
|
|
155
157
|
holidays.each do |h|
|
156
158
|
h.end_date ||= h.begin_date
|
157
|
-
hash['settings']['days off'] << {
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
159
|
+
hash['settings']['days off'] << {}
|
160
|
+
current = hash['settings']['days off'].last
|
161
|
+
current['begin date'] = compose_date(h.begin_date)
|
162
|
+
current['end date'] = compose_date(h.end_date)
|
163
|
+
current['name'] = h.name
|
162
164
|
end
|
163
165
|
end
|
164
166
|
|
@@ -174,15 +176,51 @@ private
|
|
174
176
|
hash['resources'][index]['settings']['use custom days off'] = 1
|
175
177
|
r.holidays.each do |h|
|
176
178
|
h.end_date ||= h.begin_date
|
177
|
-
hash['resources'][index]['settings']['days off'] << {
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
179
|
+
hash['resources'][index]['settings']['days off'] << {}
|
180
|
+
current = hash['resources'][index]['settings']['days off'].last
|
181
|
+
current['begin date'] = compose_date(h.begin_date)
|
182
|
+
current['end date'] = compose_date(h.end_date)
|
183
|
+
current['name'] = h.name
|
182
184
|
end
|
183
185
|
end
|
184
186
|
end
|
185
187
|
|
188
|
+
def compose_remote_access!
|
189
|
+
remote_access = schedule.remote_access
|
190
|
+
hash['settings'] ||= {}
|
191
|
+
|
192
|
+
valid_setup = remote_access.server_id && remote_access.name
|
193
|
+
enable = valid_setup && remote_access.enabled
|
194
|
+
|
195
|
+
hash['settings']['remoteId'] = remote_access.server_id if valid_setup
|
196
|
+
hash['settings']['remoteEnable'] = enable
|
197
|
+
hash['settings']['remoteName'] = remote_access.name if valid_setup
|
198
|
+
hash['settings']['remoteCustomServerURL'] = remote_access.custom_url
|
199
|
+
hash['settings']['remoteUseCustomServer'] = remote_access.custom_enabled
|
200
|
+
|
201
|
+
if remote_access.global_login or remote_access.global_password
|
202
|
+
hash['settings']['remoteLoginInfo'] ||= {}
|
203
|
+
hash['settings']['remoteLoginInfo']['All'] ||= {}
|
204
|
+
hash['settings']['remoteLoginInfo']['All']['login'] = remote_access.global_login
|
205
|
+
hash['settings']['remoteLoginInfo']['All']['password'] = remote_access.global_password
|
206
|
+
hash['settings']['remoteLoginInfo']['All']['enable'] = remote_access.global_login_enabled
|
207
|
+
end
|
208
|
+
|
209
|
+
compose_remote_access_for_resources!
|
210
|
+
end
|
211
|
+
|
212
|
+
def compose_remote_access_for_resources!
|
213
|
+
hash['settings'] ||= {}
|
214
|
+
hash['settings']['remoteLoginInfo'] ||= {}
|
215
|
+
|
216
|
+
schedule.resources.each do |r|
|
217
|
+
hash['settings']['remoteLoginInfo'][r.name] = {}
|
218
|
+
hash['settings']['remoteLoginInfo'][r.name]['login'] = r.remote_login
|
219
|
+
hash['settings']['remoteLoginInfo'][r.name]['password'] = r.remote_password
|
220
|
+
hash['settings']['remoteLoginInfo'][r.name]['enable'] = r.remote_login_enabled
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
186
224
|
def compose_schedule!
|
187
225
|
hash['begin date'] = compose_date(schedule.begin_date)
|
188
226
|
hash['end date'] = compose_date(schedule.end_date)
|
@@ -20,6 +20,7 @@ class XTeamSchedule::Parser
|
|
20
20
|
parse_interface!
|
21
21
|
parse_weekly_working_schedule!
|
22
22
|
parse_holidays!
|
23
|
+
parse_remote_access!
|
23
24
|
parse_schedule!
|
24
25
|
schedule
|
25
26
|
end
|
@@ -189,6 +190,40 @@ private
|
|
189
190
|
end
|
190
191
|
end
|
191
192
|
|
193
|
+
def parse_remote_access!
|
194
|
+
settings = hash['settings']
|
195
|
+
return unless settings.present?
|
196
|
+
remote_logins = settings['remoteLoginInfo']
|
197
|
+
return unless remote_logins.present?
|
198
|
+
global_login = remote_logins['All']
|
199
|
+
global_login ||= {}
|
200
|
+
schedule.remote_access.update_attributes!(
|
201
|
+
:server_id => settings['remoteId'],
|
202
|
+
:enabled => settings['remoteEnable'],
|
203
|
+
:name => settings['remoteName'],
|
204
|
+
:custom_url => settings['remoteCustomServerURL'],
|
205
|
+
:custom_enabled => settings['remoteUseCustomServer'],
|
206
|
+
:global_login => global_login['login'],
|
207
|
+
:global_password => global_login['password'],
|
208
|
+
:global_login_enabled => global_login['enable']
|
209
|
+
)
|
210
|
+
parse_remote_access_for_resources!
|
211
|
+
end
|
212
|
+
|
213
|
+
def parse_remote_access_for_resources!
|
214
|
+
settings = hash['settings']
|
215
|
+
remote_logins = settings['remoteLoginInfo']
|
216
|
+
remote_logins.each do |name, hash|
|
217
|
+
resource = schedule.resources.find_by_name(name)
|
218
|
+
next unless resource
|
219
|
+
resource.update_attributes!(
|
220
|
+
:remote_login => hash['login'],
|
221
|
+
:remote_password => hash['password'],
|
222
|
+
:remote_login_enabled => hash['enable']
|
223
|
+
)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
192
227
|
def parse_schedule!
|
193
228
|
schedule.update_attributes!(
|
194
229
|
:begin_date => parse_date(hash['begin date']),
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Fixes dynamic find by method attempting to use the connection
|
2
|
+
# on ActiveRecord::Base in activerecord versions 3.1.0 to 3.2.2
|
3
|
+
# when it should be respecting the connection on its subclass
|
4
|
+
class QuoteTableNamePatch
|
5
|
+
def self.quote_table_name(name)
|
6
|
+
name
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ActiveRecord
|
11
|
+
module Associations
|
12
|
+
class AliasTracker
|
13
|
+
private
|
14
|
+
def connection
|
15
|
+
ActiveRecord::Base.connection
|
16
|
+
rescue ActiveRecord::ConnectionNotEstablished
|
17
|
+
QuoteTableNamePatch
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# hash = HashWithoutNilValues.new
|
2
|
+
# hash[:a] = nil
|
3
|
+
# hash # => {}
|
4
|
+
#
|
5
|
+
# hash[:a] = {}
|
6
|
+
# hash[:a].class # => HashWithoutNilValues
|
7
|
+
#
|
8
|
+
# hash[:a] = []
|
9
|
+
# hash[:a].class # => ArrayWithoutNilValues
|
10
|
+
#
|
11
|
+
# hash[:a] << nil
|
12
|
+
# hash[:a] # => []
|
13
|
+
#
|
14
|
+
# hash[:a] << {}
|
15
|
+
# hash[:a].first.class # => HashWithoutNilValues
|
16
|
+
#
|
17
|
+
class HashWithoutNilValues < Hash
|
18
|
+
def []=(key, value)
|
19
|
+
return if value.nil?
|
20
|
+
value = HashWithoutNilValues.new if value == {}
|
21
|
+
value = ArrayWithoutNilValues.new if value == []
|
22
|
+
super(key, value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class ArrayWithoutNilValues < Array
|
27
|
+
def <<(value)
|
28
|
+
return if value.nil?
|
29
|
+
value = ArrayWithoutNilValues.new if value == []
|
30
|
+
value = HashWithoutNilValues.new if value == {}
|
31
|
+
super(value)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class XTeamSchedule::RemoteAccess < XTeamSchedule::Base
|
2
|
+
belongs_to :schedule
|
3
|
+
|
4
|
+
validate :format_of_name
|
5
|
+
NAME_REGEX = /XTEAM-\d{8}-\d{4}/.freeze
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def format_of_name
|
10
|
+
return unless name
|
11
|
+
raise 'invalid' unless name =~ NAME_REGEX
|
12
|
+
xteam, date, time = name.split('-')
|
13
|
+
day, month, year = date[0..1], date[2..3], date[4..7]
|
14
|
+
hour, minute = time[0..1], time[2..3]
|
15
|
+
DateTime.new(year.to_i, month.to_i, day.to_i, hour.to_i, minute.to_i)
|
16
|
+
rescue
|
17
|
+
errors.add(:name, 'is not in the form XTEAM-DDMMYYYY-HHMM')
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -8,13 +8,16 @@ class XTeamSchedule::Schedule < XTeamSchedule::Base
|
|
8
8
|
|
9
9
|
has_one :interface
|
10
10
|
has_one :weekly_working_schedule
|
11
|
+
has_one :remote_access
|
11
12
|
|
12
13
|
ActiveSupport::Deprecation.silence do
|
13
14
|
after_initialize :set_default_interface
|
14
15
|
after_initialize :set_default_weekly_working_schedule
|
16
|
+
after_initialize :set_default_remote_access
|
15
17
|
def after_initialize
|
16
18
|
set_default_interface
|
17
19
|
set_default_weekly_working_schedule
|
20
|
+
set_default_remote_access
|
18
21
|
end
|
19
22
|
end
|
20
23
|
|
@@ -33,4 +36,8 @@ private
|
|
33
36
|
self.weekly_working_schedule ||= XTeamSchedule::WeeklyWorkingSchedule.new
|
34
37
|
end
|
35
38
|
|
39
|
+
def set_default_remote_access
|
40
|
+
self.remote_access ||= XTeamSchedule::RemoteAccess.new
|
41
|
+
end
|
42
|
+
|
36
43
|
end
|
data/lib/xteam_schedule.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
+
begin
|
2
|
+
require 'yaml'
|
3
|
+
YAML::ENGINE.yamler = 'syck'
|
4
|
+
rescue
|
5
|
+
end
|
6
|
+
|
1
7
|
require 'plist'
|
2
8
|
require 'active_record'
|
9
|
+
require 'active_support/multibyte'
|
3
10
|
require 'sqlite3'
|
4
11
|
require 'xteam_schedule/core'
|
5
12
|
|
@@ -9,10 +16,13 @@ require 'xteam_schedule/facilitation/parser'
|
|
9
16
|
require 'xteam_schedule/facilitation/composer'
|
10
17
|
require 'xteam_schedule/facilitation/io'
|
11
18
|
require 'xteam_schedule/facilitation/lmc_patch'
|
19
|
+
require 'xteam_schedule/facilitation/qtn_patch'
|
20
|
+
require 'xteam_schedule/facilitation/without_nil'
|
12
21
|
|
13
22
|
require 'xteam_schedule/models/assignment'
|
14
23
|
require 'xteam_schedule/models/assignment_group'
|
15
24
|
require 'xteam_schedule/models/interface'
|
25
|
+
require 'xteam_schedule/models/remote_access'
|
16
26
|
require 'xteam_schedule/models/resource'
|
17
27
|
require 'xteam_schedule/models/resource_group'
|
18
28
|
require 'xteam_schedule/models/schedule'
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xteam_schedule
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christopher Patuzzo
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-04-
|
18
|
+
date: 2012-04-15 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: plist
|
@@ -107,11 +107,14 @@ files:
|
|
107
107
|
- lib/xteam_schedule/facilitation/io.rb
|
108
108
|
- lib/xteam_schedule/facilitation/lmc_patch.rb
|
109
109
|
- lib/xteam_schedule/facilitation/parser.rb
|
110
|
+
- lib/xteam_schedule/facilitation/qtn_patch.rb
|
110
111
|
- lib/xteam_schedule/facilitation/schema.rb
|
112
|
+
- lib/xteam_schedule/facilitation/without_nil.rb
|
111
113
|
- lib/xteam_schedule/models/assignment.rb
|
112
114
|
- lib/xteam_schedule/models/assignment_group.rb
|
113
115
|
- lib/xteam_schedule/models/holiday.rb
|
114
116
|
- lib/xteam_schedule/models/interface.rb
|
117
|
+
- lib/xteam_schedule/models/remote_access.rb
|
115
118
|
- lib/xteam_schedule/models/resource.rb
|
116
119
|
- lib/xteam_schedule/models/resource_group.rb
|
117
120
|
- lib/xteam_schedule/models/schedule.rb
|
@@ -148,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
151
|
requirements: []
|
149
152
|
|
150
153
|
rubyforge_project:
|
151
|
-
rubygems_version: 1.8.
|
154
|
+
rubygems_version: 1.8.22
|
152
155
|
signing_key:
|
153
156
|
specification_version: 3
|
154
157
|
summary: XTeam Schedule
|