Class: WeeklySnippets::Version

Inherits:
Object
  • Object
show all
Defined in:
lib/weekly_snippets/version.rb

Overview

Encapsulates the mapping from actual snippet data fields to a standardized set of data fields for each version of snippets.

Since 18F experimented with a handful of different snippet formats, with slightly different field names and semantics, we needed a way to transform each batch into a common format before generating Hub pages, to streamline the logic and possibly allow for even more formats in the future without requiring version-specific hacks.

The common format fields are:

  • username: identifies the snippet author

  • last-week: summary of last week’s activity

  • this-week: summary of this week’s anticipated activity

  • timestamp: identifies when the snippet was reported; might not necessarily match the timestamp of the batch in which it appears

  • public: true if the snippet may be published publicly

  • markdown: true if the snippet version supports Markdown syntax

When using Jekyll, snippet data should be stored in the _data directory with versioned subdirectories containing timestamped Comma Separated Value (CSV) files, e.g.:

  • _data/snippets/v1/20141110.csv

  • _data/snippets/v2/20141201.csv

  • _data/snippets/v3/20141208.csv

Jekyll imports this data into a Hash structure (site.data) resembling:

  • version => { timestamp => [ snippets ] }

Version.standardize_versions will convert this structure into a Hash resembling:

  • timestamp => [ snippets ]

Defined Under Namespace

Classes: InitError, UnknownFieldError, UnknownVersionError

Constant Summary collapse

FIELD_NAMES =

Set of field name values that the field_map argument of initialize must map to.

['username', 'last-week', 'this-week', 'timestamp']

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(version_name:, field_map:, public_field: nil, public_value: nil, markdown_supported: false) ⇒ Version

Returns a new instance of Version.

Parameters:

  • version_name (String)

    identifies the version, e.g. “v3”

  • field_map (Hash<String, String>)

    contains the mapping from the field name in the original data file to the standardized internal field name

  • public_field (String) (defaults to: nil)

    if present, the field that indicates whether or not a snippet can be published in public mode; if not present, no snippets matching this version should be published publicly

  • public_value (String) (defaults to: nil)

    if present, the value for public_field that indicates whether or not a snippet should be published in public mode

  • markdown_supported (true, false) (defaults to: false)

    indicates whether or not the snippet version supports Markdown syntax

Raises:

  • (InitError)

    if field_map does not contain mappings for every element of FIELD_NAMES

  • (InitError)

    if one of public_field or public_value is set, but not the other



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/weekly_snippets/version.rb', line 80

def initialize(version_name:, field_map:, public_field:nil,
  public_value:nil, markdown_supported: false)

  expected = FIELD_NAMES.sort
  actual = field_map.values.sort
  intersection = expected & actual

  unless intersection == expected
    raise InitError.new("Snippet version \"#{version_name}\" " +
      "missing mappings for fields: #{expected - intersection}")
  end

  unless (public_field == nil and public_value == nil) or (
    public_field != nil and public_value != nil)
    raise InitError.new("Snippet version \"#{version_name}\" has " +
      "public_field and public_value mismatched: " +
      "public_field == #{public_field ? "\"#{public_field}\"" : 'nil'}; " +
      "public_value == #{public_value ? "\"#{public_value}\"" : 'nil'}")
  end

  @version_name = version_name
  @field_map = field_map
  @public_field = public_field
  @public_value = public_value
  @markdown_supported = markdown_supported
end

Instance Attribute Details

#field_mapObject (readonly)

Returns the value of attribute field_map.



61
62
63
# File 'lib/weekly_snippets/version.rb', line 61

def field_map
  @field_map
end

#markdown_supportedObject (readonly)

Returns the value of attribute markdown_supported.



61
62
63
# File 'lib/weekly_snippets/version.rb', line 61

def markdown_supported
  @markdown_supported
end

#public_fieldObject (readonly)

Returns the value of attribute public_field.



61
62
63
# File 'lib/weekly_snippets/version.rb', line 61

def public_field
  @public_field
end

#public_valueObject (readonly)

Returns the value of attribute public_value.



61
62
63
# File 'lib/weekly_snippets/version.rb', line 61

def public_value
  @public_value
end

#version_nameObject (readonly)

Returns the value of attribute version_name.



61
62
63
# File 'lib/weekly_snippets/version.rb', line 61

def version_name
  @version_name
end

Class Method Details

.standardize_versions(snippets_by_version, snippet_versions) ⇒ Hash<String, Array<Hash>>

Transforms snippets of different versions into a standard format.

The keys of snippets_by_version should indicate the version of the corresponding batch of snippets, and also match the keys of snippet_versions. Each batch of snippets for each version should be a Hash from a timestamp string (typically YYYYMMDD) to an Array of Hashes representing individual snippet entries.

The resulting Hash will map from timestamp string to an Array of standardized snippet Hashes, eliminating the now unnecessary version information.

Parameters:

  • snippets_by_version (Hash<String, Hash<String, Array<Hash>>>)

    contains: version => { timestamp => [ snippets ] }

  • snippet_versions (Hash<String,Snippets::Version>)

    mapping from snippet version name to the corresponding Snippets::Version object

Returns:

  • (Hash<String, Array<Hash>>)

    a mapping from a (weekly) timestamp to a corresponding set of standardized snippets

Raises:



158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/weekly_snippets/version.rb', line 158

def self.standardize_versions(snippets_by_version, snippet_versions)
  result = {}
  snippets_by_version.each do |version, batch|
    v = snippet_versions[version]
    unless v
      raise UnknownVersionError.new("Unknown snippet version: #{version}")
    end
    batch.each do |timestamp, snippets|
      result[timestamp] = snippets.each {|s| v.standardize s}
    end
  end
  result
end

Instance Method Details

#standardize(snippet) ⇒ Hash<String,String>

Converts the field names within snippet to standardized names using field_map, and sets snippet and snippet.

Parameters:

  • snippet (Hash<String, String>)

    snippet data to evaluate

Returns:

  • (Hash<String,String>)

    snippet

Raises:



119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/weekly_snippets/version.rb', line 119

def standardize(snippet)
  snippet.keys.each do |k|
    unless @field_map.member? k
      raise UnknownFieldError.new("Snippet field not recognized by " +
        "version \"#{@version_name}\": #{k}")
    end
    snippet[@field_map[k]] = snippet.delete k
  end
  snippet['public'] = (@public_field and
    snippet[@public_field] == @public_value) ? true : false
  snippet['markdown'] = @markdown_supported
  snippet
end