team_hub 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/team_hub.rb +1 -0
- data/lib/team_hub/cross_referencer.rb +21 -5
- data/lib/team_hub/joiner.rb +238 -0
- data/lib/team_hub/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2b7d394b137ef8740a7d76e1aef7ed633a8071d
|
4
|
+
data.tar.gz: f7588f8b18a849a7297087f8ed843c74e5215b06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c4087b427e93c0a4dfd007f2be385ff71e0652c34e603cb2991d112f09d3822aa43541afce4eba1beac045b9d65794e809ccf4aa1cdad188284103093e20f7c
|
7
|
+
data.tar.gz: 2a39d7bab0fdcfa80e5667c262fb84b58ebf96584ba46e27147e690b60056f24b68a7935f91a9a37614f7ad8017a72f7dc88c116a97a4cb384f4fd1c38a1e770
|
data/lib/team_hub.rb
CHANGED
@@ -140,13 +140,29 @@ module TeamHub
|
|
140
140
|
@team = @site_data['team'].map {|i| [i['name'], i]}.to_h
|
141
141
|
end
|
142
142
|
|
143
|
-
# Cross-references geographic locations with team members
|
143
|
+
# Cross-references geographic locations with team members, projects, and
|
144
|
+
# working groups.
|
144
145
|
#
|
145
|
-
#
|
146
|
-
#
|
147
|
-
|
146
|
+
# xref_projects_and_team_members and xref_working_groups_and_team_members
|
147
|
+
# should be called before this method.
|
148
|
+
#
|
149
|
+
# The resulting site.data['locations'] collection will be an Array<Hash>
|
150
|
+
# of location code =>
|
151
|
+
# {'team' => Array, 'projects' => Array, 'working_groups' => Array}.
|
152
|
+
def xref_locations
|
148
153
|
locations = CrossReferencer.create_index(@site_data['team'], 'location')
|
149
|
-
|
154
|
+
locations = locations.to_a.sort!.map do |entry|
|
155
|
+
team = entry[1]
|
156
|
+
result = {'code' => entry[0], 'team' => team}
|
157
|
+
['projects', 'working_groups'].each do |category|
|
158
|
+
items = Array.new
|
159
|
+
team.each {|i| items.concat i[category] if i.member? category}
|
160
|
+
items.sort_by!{|i| i['name']}.uniq!
|
161
|
+
result[category] = items unless items.empty?
|
162
|
+
end
|
163
|
+
result
|
164
|
+
end
|
165
|
+
@site_data['locations'] = locations unless locations.empty?
|
150
166
|
end
|
151
167
|
|
152
168
|
# Cross-references projects with team members. Replaces string-based
|
@@ -0,0 +1,238 @@
|
|
1
|
+
# team_hub - Components for creating a team Hub using Jekyll
|
2
|
+
#
|
3
|
+
# Written in 2014 by Mike Bland (michael.bland@gsa.gov)
|
4
|
+
# on behalf of the 18F team, part of the US General Services Administration:
|
5
|
+
# https://18f.gsa.gov/
|
6
|
+
#
|
7
|
+
# To the extent possible under law, the author(s) have dedicated all copyright
|
8
|
+
# and related and neighboring rights to this software to the public domain
|
9
|
+
# worldwide. This software is distributed without any warranty.
|
10
|
+
#
|
11
|
+
# You should have received a copy of the CC0 Public Domain Dedication along
|
12
|
+
# with this software. If not, see
|
13
|
+
# <https://creativecommons.org/publicdomain/zero/1.0/>.
|
14
|
+
#
|
15
|
+
# @author Mike Bland (michael.bland@gsa.gov)
|
16
|
+
|
17
|
+
require 'hash-joiner'
|
18
|
+
require 'team_hub/private_assets'
|
19
|
+
require 'weekly_snippets/version'
|
20
|
+
|
21
|
+
module TeamHub
|
22
|
+
|
23
|
+
# Joins the data from +_data+, +_data/public+, and +_data/private+ into
|
24
|
+
# +site.data+, making the data look as though it came from a single source.
|
25
|
+
# Also filters out private data when +site.config[+'public'] is +true+ (aka
|
26
|
+
# "public mode").
|
27
|
+
class Joiner
|
28
|
+
attr_reader :site, :data, :public_mode, :team_by_email, :source
|
29
|
+
|
30
|
+
# Used to standardize snippet data of different versions before joining
|
31
|
+
# and publishing.
|
32
|
+
SNIPPET_VERSIONS = {
|
33
|
+
'v1' => ::WeeklySnippets::Version.new(
|
34
|
+
version_name:'v1',
|
35
|
+
field_map:{
|
36
|
+
'Username' => 'username',
|
37
|
+
'Timestamp' => 'timestamp',
|
38
|
+
'Name' => 'full_name',
|
39
|
+
'Snippets' => 'last-week',
|
40
|
+
'No This Week' => 'this-week',
|
41
|
+
}
|
42
|
+
),
|
43
|
+
'v2' => ::WeeklySnippets::Version.new(
|
44
|
+
version_name:'v2',
|
45
|
+
field_map:{
|
46
|
+
'Timestamp' => 'timestamp',
|
47
|
+
'Public vs. Private' => 'public',
|
48
|
+
'Last Week' => 'last-week',
|
49
|
+
'This Week' => 'this-week',
|
50
|
+
'Username' => 'username',
|
51
|
+
},
|
52
|
+
markdown_supported: true
|
53
|
+
),
|
54
|
+
'v3' => ::WeeklySnippets::Version.new(
|
55
|
+
version_name:'v3',
|
56
|
+
field_map:{
|
57
|
+
'Timestamp' => 'timestamp',
|
58
|
+
'Public' => 'public',
|
59
|
+
'Username' => 'username',
|
60
|
+
'Last week' => 'last-week',
|
61
|
+
'This week' => 'this-week',
|
62
|
+
},
|
63
|
+
public_field: 'public',
|
64
|
+
public_value: 'Public',
|
65
|
+
markdown_supported: true
|
66
|
+
),
|
67
|
+
}
|
68
|
+
|
69
|
+
# +site+:: Jekyll site data object
|
70
|
+
def initialize(site)
|
71
|
+
@site = site
|
72
|
+
@data = site.data
|
73
|
+
@public_mode = site.config['public']
|
74
|
+
|
75
|
+
if (site.data['private'] || {}).empty?
|
76
|
+
@source = 'public'
|
77
|
+
@join_source = @data
|
78
|
+
else
|
79
|
+
@source = 'private'
|
80
|
+
@join_source = site.data['private']
|
81
|
+
end
|
82
|
+
|
83
|
+
# We'll always need a 'team' property.
|
84
|
+
@join_source['team'] ||= []
|
85
|
+
['team', 'projects', 'departments', 'working_groups'].each do |c|
|
86
|
+
i = @join_source[c]
|
87
|
+
@join_source[c] = Joiner.flatten_index(i) if i.instance_of? Hash
|
88
|
+
end
|
89
|
+
create_team_by_email_index
|
90
|
+
end
|
91
|
+
|
92
|
+
# Takes Hash<string, Array<Hash>> collections and flattens them into an
|
93
|
+
# Array<Hash>.
|
94
|
+
def self.flatten_index(index)
|
95
|
+
private_data = index['private']
|
96
|
+
index['private'] = {'private' => private_data.values} if private_data
|
97
|
+
index.values
|
98
|
+
end
|
99
|
+
|
100
|
+
# Joins public and private project data.
|
101
|
+
def join_project_data
|
102
|
+
promote_private_data 'projects'
|
103
|
+
|
104
|
+
if @public_mode
|
105
|
+
@data['projects'].delete_if {|p| p['status'] == 'Hold'}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Creates +self.team_by_email+, a hash of email address => username to use
|
110
|
+
# as an index into +site.data[+'team'] when joining snippet data.
|
111
|
+
#
|
112
|
+
# MUST be called before remove_data, or else private email addresses will
|
113
|
+
# be inaccessible and snippets will not be joined.
|
114
|
+
def create_team_by_email_index
|
115
|
+
@team_by_email = self.class.create_team_by_email_index(
|
116
|
+
@join_source['team'])
|
117
|
+
end
|
118
|
+
|
119
|
+
# Creates an index of team member information keyed by email address.
|
120
|
+
# @param team [Array<Hash>] contains individual team member information
|
121
|
+
# @return [Hash<String, Hash>] email address => team member
|
122
|
+
def self.create_team_by_email_index(team)
|
123
|
+
team_by_email = {}
|
124
|
+
team.each do |i|
|
125
|
+
# A Hash containing only a 'private' property is a list of team
|
126
|
+
# members whose information is completely private.
|
127
|
+
if i.keys == ['private']
|
128
|
+
i['private'].each do |private_member|
|
129
|
+
email = private_member['email']
|
130
|
+
team_by_email[email] = private_member['name'] if email
|
131
|
+
end
|
132
|
+
else
|
133
|
+
email = i['email']
|
134
|
+
email = i['private']['email'] if !email and i.member? 'private'
|
135
|
+
team_by_email[email] = i['name'] if email
|
136
|
+
end
|
137
|
+
end
|
138
|
+
team_by_email
|
139
|
+
end
|
140
|
+
|
141
|
+
# Prepares +site.data[@source]+ prior to joining its data with
|
142
|
+
# +site.data+. All data nested within +'private'+ attributes will be
|
143
|
+
# stripped when @public_mode is +true+, and will be promoted to the same
|
144
|
+
# level as its parent when @public_mode is +false+.
|
145
|
+
#
|
146
|
+
# If a block is given, +site.data[@source]+ will be passed to the block
|
147
|
+
# for other initialization/setup.
|
148
|
+
def setup_join_source
|
149
|
+
if @public_mode
|
150
|
+
HashJoiner.remove_data @join_source, 'private'
|
151
|
+
else
|
152
|
+
HashJoiner.promote_data @join_source, 'private'
|
153
|
+
end
|
154
|
+
yield @join_source if block_given?
|
155
|
+
end
|
156
|
+
|
157
|
+
# Promote data from +site.data['private']+ into +site.data+, if
|
158
|
+
# +site.data['private']+ exists.
|
159
|
+
# +category+:: key into +site.data['private']+ specifying data collection
|
160
|
+
def promote_private_data(category)
|
161
|
+
@data[category] = @join_source[category] if @join_source != @data
|
162
|
+
end
|
163
|
+
|
164
|
+
# Assigns the +image+ property of each team member based on the team
|
165
|
+
# member's username and whether or not an image asset exists for that team
|
166
|
+
# member. +site.config[+'missing_team_member_img'] is used as the default
|
167
|
+
# when no image asset is available.
|
168
|
+
def assign_team_member_images
|
169
|
+
base = @site.source
|
170
|
+
img_dir = site.config['team_img_dir']
|
171
|
+
missing = File.join(img_dir, site.config['missing_team_member_img'])
|
172
|
+
|
173
|
+
site.data['team'].each do |member|
|
174
|
+
img = File.join(img_dir, "#{member['name']}.jpg")
|
175
|
+
|
176
|
+
if (File.exists? File.join(base, img) or
|
177
|
+
::TeamHub::PrivateAssets.exists?(site, img))
|
178
|
+
member['image'] = img
|
179
|
+
else
|
180
|
+
member['image'] = missing
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Joins snippet data into +site.data[+'snippets'] and filters out snippets
|
186
|
+
# from team members not appearing in +site.data[+'team'] or
|
187
|
+
# +team_by_email+.
|
188
|
+
#
|
189
|
+
# Snippet data is expected to be stored in files matching the pattern:
|
190
|
+
# +_data/+@source/snippets/[version]/[YYYYMMDD].csv
|
191
|
+
#
|
192
|
+
# resulting in the initial structure:
|
193
|
+
# +site.data[@source][snippets][version][YYYYMMDD] = Array<Hash>
|
194
|
+
#
|
195
|
+
# After this function returns, the new structure will be:
|
196
|
+
# +site.data[snippets][YYYYMMDD] = Array<Hash>
|
197
|
+
#
|
198
|
+
# and each individual snippet will have been converted to a standardized
|
199
|
+
# format defined by ::WeeklySnippets::Version.
|
200
|
+
def join_snippet_data(snippet_versions)
|
201
|
+
standardized = ::WeeklySnippets::Version.standardize_versions(
|
202
|
+
@join_source['snippets'], snippet_versions)
|
203
|
+
team = {}
|
204
|
+
@data['team'].each {|i| team[i['name']] = i}
|
205
|
+
result = {}
|
206
|
+
standardized.each do |timestamp, snippets|
|
207
|
+
joined = []
|
208
|
+
snippets.each do |snippet|
|
209
|
+
username = snippet['username']
|
210
|
+
member = team[username] || team[@team_by_email[username]]
|
211
|
+
|
212
|
+
if member
|
213
|
+
snippet['name'] = member['name']
|
214
|
+
snippet['full_name'] = member['full_name']
|
215
|
+
joined << snippet
|
216
|
+
end
|
217
|
+
end
|
218
|
+
result[timestamp] = joined unless joined.empty?
|
219
|
+
end
|
220
|
+
@data['snippets'] = result
|
221
|
+
end
|
222
|
+
|
223
|
+
# Imports the guest_users list into the top-level site.data object.
|
224
|
+
def import_guest_users
|
225
|
+
@data['guest_users'] = @join_source['hub']['guest_users']
|
226
|
+
end
|
227
|
+
|
228
|
+
# Filters out private pages when generating the public Hub.
|
229
|
+
def filter_private_pages
|
230
|
+
if @public_mode
|
231
|
+
private_pages_path = "/#{@site.config['private_pages_path']}"
|
232
|
+
@site.pages.delete_if do |p|
|
233
|
+
p.relative_path.start_with? private_pages_path
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
data/lib/team_hub/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: team_hub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Bland
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hash-joiner
|
@@ -137,6 +137,7 @@ files:
|
|
137
137
|
- lib/team_hub.rb
|
138
138
|
- lib/team_hub/canonicalizer.rb
|
139
139
|
- lib/team_hub/cross_referencer.rb
|
140
|
+
- lib/team_hub/joiner.rb
|
140
141
|
- lib/team_hub/page.rb
|
141
142
|
- lib/team_hub/private_assets.rb
|
142
143
|
- lib/team_hub/version.rb
|
@@ -160,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
161
|
version: '0'
|
161
162
|
requirements: []
|
162
163
|
rubyforge_project:
|
163
|
-
rubygems_version: 2.
|
164
|
+
rubygems_version: 2.4.5
|
164
165
|
signing_key:
|
165
166
|
specification_version: 4
|
166
167
|
summary: Components for creating a team Hub using Jekyll
|