lib/ezid/metadata.rb in ezid-client-0.1.1 vs lib/ezid/metadata.rb in ezid-client-0.2.0

- old
+ new

@@ -10,11 +10,11 @@ include Enumerable # The metadata elements hash attr_reader :elements - def_delegators :elements, :each, :empty?, :[], :[]= + def_delegators :elements, :each, :keys, :values, :empty?, :[], :[]= # EZID metadata profiles PROFILES = %w( erc dc datacite crossref ) # Public status @@ -43,13 +43,15 @@ DATETIME_ELEMENTS = %w( _created _updated ).freeze # EZID metadata field/value separator ANVL_SEPARATOR = ": " - # Characters to escape on output to EZID - ESCAPE_RE = /[%:\r\n]/ + # Characters to escape in element values on output to EZID + ESCAPE_VALUES_RE = /[%\r\n]/ + ESCAPE_KEYS_RE = /[%:\r\n]/ + # Character sequence to unescape from EZID UNESCAPE_RE = /%\h\h/ # A comment line COMMENT_RE = /^#.*(\r?\n)?/ @@ -66,11 +68,11 @@ # Output metadata in EZID ANVL format # @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies # @return [String] the ANVL output def to_anvl - lines = map { |element| element.map { |e| escape(e) }.join(ANVL_SEPARATOR) } + lines = escape_keys.zip(escape_values).map { |e| e.join(ANVL_SEPARATOR) } lines.join("\n").force_encoding(Encoding::UTF_8) end def to_s to_anvl @@ -118,23 +120,32 @@ def stringify_keys(hsh) hsh.keys.map(&:to_s).zip(hsh.values).to_h end + def escape_keys + keys.map { |k| escape(ESCAPE_KEYS_RE, k) } + end + + def escape_values + values.map { |v| escape(ESCAPE_VALUES_RE, v) } + end + # Escape value for sending to EZID host # @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies + # @param re [Regexp] the regular expression to match for escaping # @param value [String] the value to escape # @return [String] the escaped value - def escape(value) - value.gsub(ESCAPE_RE) { |m| URI.encode(m) } + def escape(re, value) + value.gsub(re) { |m| URI.encode_www_form_component(m) } end # Unescape value from EZID host (or other source) # @see http://ezid.cdlib.org/doc/apidoc.html#request-response-bodies # @param value [String] the value to unescape # @return [String] the unescaped value def unescape(value) - value.gsub(UNESCAPE_RE) { |m| URI.decode(m) } + value.gsub(UNESCAPE_RE) { |m| URI.decode_www_form_component(m) } end # Coerce a string of metadata (e.g., from EZID host) into a Hash # @param data [String] the string to coerce # @return [Hash] the hash of coerced data