Skip to content
This repository has been archived by the owner on Sep 24, 2019. It is now read-only.

Commit

Permalink
dataset serialization to all bel.rb translators
Browse files Browse the repository at this point in the history
updated dependencies to support all bel.rb translators

refs #99
  • Loading branch information
Anthony Bargnesi committed Feb 1, 2016
1 parent b1243d8 commit e4eb5dd
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 27 deletions.
11 changes: 10 additions & 1 deletion .gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,16 @@ Gem::Specification.new do |spec|
# Dependencies

## bel.rb
spec.add_runtime_dependency 'bel', '0.4.3'
spec.add_runtime_dependency 'bel', '0.5.0'

## bel.rb translator dependencies
spec.add_runtime_dependency 'json-ld', '1.99.0'
spec.add_runtime_dependency 'rdf-json', '1.99.0'
spec.add_runtime_dependency 'rdf-rdfa', '1.99.0'
spec.add_runtime_dependency 'rdf-rdfxml', '1.99.0'
spec.add_runtime_dependency 'rdf-trig', '1.99.0.1'
spec.add_runtime_dependency 'rdf-trix', '1.99.0'
spec.add_runtime_dependency 'rdf-turtle', '1.99.0'

## bel.rb plugin - annotation/namespace search
spec.add_runtime_dependency 'bel-search-sqlite', '0.4.2'
Expand Down
71 changes: 71 additions & 0 deletions app/openbel/api/helpers/translators.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require 'bel'

module OpenBEL
module Helpers

# Helpers for translator functionality based on user's requested media
# type.
module Translators

# Patch {::Sinatra::Helpers::Stream} to respect the +puts+ and +write+
# method. This is necessary because the RDF.rb writers will call theseon
# the IO object (in this case {::Sinatra::Helpers::Stream}).
class ::Sinatra::Helpers::Stream

def puts(*args)
self << (
args.map { |string| "#{string.encode(Encoding::UTF_8)}\n" }.join
)
end

def write(string)
self << string.encode(Encoding::UTF_8)
end

# flush is a no-op; flushing is handled by sinatra/rack server
def flush; end
end

# Find a bel.rb translator plugin by value. The value is commonly the
# id, file extension, or media type associated with the translator
# plugin.
#
# @param [#to_s] value used to look up translator plugin registered
# with bel.rb
# @return [BEL::Translator] the translator instance; or +nil+ if one
# cannot be found
def self.for(value)
BEL.translator(symbolize_value(value))
end

def self.plugin_for(value)
BEL::Translator::Plugins.for(symbolize_value(value))
end

def self.requested_translator_plugin(request, params)
if params && params[:format]
self.plugin_for(params[:format])
else
request.accept.map { |accept_entry|
self.plugin_for(accept_entry)
}.compact.first
end
end

def self.requested_translator(request, params)
if params && params[:format]
self.for(params[:format])
else
request.accept.map { |accept_entry|
self.for(accept_entry)
}.compact.first
end
end

def self.symbolize_value(value)
value.to_s.to_sym
end
private_class_method :symbolize_value
end
end
end
20 changes: 15 additions & 5 deletions app/openbel/api/routes/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ class Base < Sinatra::Application
include OpenBEL::Resource::Namespaces
include OpenBEL::Schemas

DEFAULT_CONTENT_TYPE = 'application/hal+json'
SPOKEN_CONTENT_TYPES = %w[application/hal+json application/json]
DEFAULT_CONTENT_TYPE = 'application/hal+json'
DEFAULT_CONTENT_TYPE_ID = :hal
SPOKEN_CONTENT_TYPES = %w[application/hal+json application/json]
SPOKEN_CONTENT_TYPES.concat(
BEL::Translator.plugins.values.flat_map { |p| p.media_types.map(&:to_s) }
)

SCHEMA_BASE_URL = 'http://next.belframework.org/schemas/'
RESOURCE_SERIALIZERS = {
SCHEMA_BASE_URL = 'http://next.belframework.org/schemas/'
RESOURCE_SERIALIZERS = {
:annotation => AnnotationResourceSerializer,
:annotation_collection => AnnotationCollectionSerializer,
:annotation_value => AnnotationValueResourceSerializer,
Expand Down Expand Up @@ -80,6 +80,16 @@ def schema_url(name)
SCHEMA_BASE_URL + "#{name}.schema.json"
end

def wants_default?
if params[:format]
return params[:format] == DEFAULT_CONTENT_TYPE
end

request.accept.any? { |accept_entry|
accept_entry.to_s == DEFAULT_CONTENT_TYPE
}
end

def validate_media_type!(content_type, options = {})
ctype = request.content_type
valid = ctype.start_with? content_type
Expand Down
31 changes: 10 additions & 21 deletions app/openbel/api/routes/datasets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require 'openbel/api/evidence/facet_filter'
require_relative '../resources/evidence_transform'
require_relative '../helpers/pager'
require_relative '../helpers/translators'

module OpenBEL
module Routes
Expand Down Expand Up @@ -37,9 +38,6 @@ def initialize(app)
:tdb_directory => OpenBEL::Settings[:resource_rdf][:jena][:tdb_directory]
)

# Load RDF monkeypatches.
BEL::Translator.plugins[:rdf].create_translator

# Annotations using RdfRepository
annotations = BEL::Resource::Annotations.new(@rr)
@annotation_transform = AnnotationTransform.new(annotations)
Expand Down Expand Up @@ -365,18 +363,12 @@ def keys_to_symbols(obj)
filtered_total = @api.count_evidence(filters)
page_results = @api.find_dataset_evidence(dataset, filters, start, size, faceted, max_values_per_facet)

accept_type = request.accept.find { |accept_entry|
ACCEPTED_TYPES.values.include?(accept_entry.to_s)
}
accept_type ||= DEFAULT_TYPE
translator = Translators.requested_translator(request, params)
translator_plugin = Translators.requested_translator_plugin(request, params)

if params[:format]
translator = BEL::Translator.plugins[params[:format].to_sym]
halt 501 if !translator || translator.id == :rdf
accept_type = [translator.media_types].flatten.first
end

if accept_type == DEFAULT_TYPE
# Serialize to HAL if they [Accept]ed it, specified it as ?format, or
# no translator was found to match request.
if wants_default? || !translator
evidence = page_results[:cursor].map { |item|
item.delete('facets')
item
Expand Down Expand Up @@ -410,24 +402,21 @@ def keys_to_symbols(obj)

render_collection(evidence, :evidence, options)
else
out_translator = BEL.translator(accept_type)
extension = ACCEPTED_TYPES.key(accept_type.to_s)
extension = translator_plugin.file_extensions.first

response.headers['Content-Type'] = accept_type
response.headers['Content-Type'] = translator_plugin.media_types.first
status 200
attachment "#{dataset[:identifier].gsub(/[^\w]/, '_')}.#{extension}"
stream :keep_open do |response|
cursor = page_results[:cursor]
json_evidence_enum = cursor.lazy.map { |evidence|
dataset_evidence = cursor.lazy.map { |evidence|
evidence.delete('facets')
evidence.delete('_id')
evidence = keys_to_symbols(evidence)
BEL::Model::Evidence.create(evidence)
}

out_translator.write(json_evidence_enum) do |converted_evidence|
response << converted_evidence
end
translator.write(dataset_evidence, response)
end
end
end
Expand Down

0 comments on commit e4eb5dd

Please sign in to comment.