team_hub 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 +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
|