RdfContext version 0.5.0 brings compliant notation-3/turtle parsing

Posted by Gregg Kellogg Mon, 22 Feb 2010 23:33:00 GMT

This version of 0.5.0 adds support for Ruby 1.9 and 1.8.6 in addition to 1.8.7. Full unicode character escapes are supported in Ruby 1.9. The N3 parser has been substantially re-written and updated to be compliant with W3C SWAP, CWM and Turtle test suites, although it is supported only to the N3-rdf level, with variables and formulae not yet supported.

See GitHub project page for more information. Available for download through Gemcutter.

Release notes for version 0.5.0

  • Support for Ruby 1.9, 1.8.7 and 1.8.6.
    • Unicode escapes and URIRefs only work properly in Ruby 1.9
    • Replaced some (&:meth) spells with {|c| c.meth} for Ruby 1.8.6 compatibility
  • Fully compliant N3 parser (n3-rdf level) with extnensive tests, including SWAP, CWM and Turtle test suites.
    • Supports paths, keywords, all semantic expressions.
    • No support yet for Formulae, variables, rules or automatic reification
    • Allow Triple#subject to be like an object, allowing literals and graphs
    • Allow Triple#predicate to be a BNode as well as a URIRef
  • Graph changes
    • Graph#properties(subject) returns properties of a subject expressed as a hash to arrays of objects.
    • Graph#seq(subject) returns ordered rdf:_n objects if subject is a rdf:Seq., or list of rdf:first/rdf:rest
    • Graph#qname(uri) as alternative to uri.qname, has namespaces available.
    • Graph#type_of(subject) array of RDF_TYPE objects.
    • Graph#allow_n3 (getter/setter and option) controls if extra N3 semantics for graphs are allowed. Otherwise, calls Triple#validate_rdf to raise exception
    • Real graph comparisons, including permutation search of triples containing BNodes (obviously, may be expensive)
    • Add QuotedGraph and AggregateGraph
  • Literal changes
    • Literal#== as alias to eql? Needed for sort and uniq.
    • Normalize valid typed literals
    • Added Literal#valid? to perform some content validations.
  • URIRef/Namespace changes
    • Fix URI generation, performing normalizations for normal URI refs, and not for Namespace URIs.
    • Fixed bug in URIRef#namespace & to_qname when namespace does not have a trailing / or #
    • URIRef#short_name may return a different value after a namespace is assigned.
  • Reduce dependency on Redland when running tests

RdfContext gem version 0.4.5 pushed

Posted by Gregg Kellogg Fri, 08 Jan 2010 22:11:00 GMT

Bug fixes and minor API changes:

  • Order includes to remove platform dependencies on load requirements.
  • Fix XML Comparison matcher
  • Add --store option to bin/rdf_context. Let Parser#detect_format intuit file type./li>
  • Add Graph#contents as alias to store
  • Add ConjunctiveGraph#triples to return all triples from store, not just default context
  • Add Graph#nsbinding to retreive Store#nsbinding<
  • Fix numerious SQLite3Store and AbstractSQLStore bugs. Add round-trip tests to Graph spec.

RdfContext gem released

Posted by Gregg Kellogg Sun, 03 Jan 2010 23:40:00 GMT

I've released version 0.4.4 of the RdfContext gem. As the name implies, RdfContext supports contextual data-stores bound to graphs, along with a ConjunctiveGraph providing the union of contexts within a given data-store.

  • Parses RDF/XML, RDFa and N3. RDF/XML and RDFa both pass all relevant W3C test cases (may be run through specs).
  • Graph and ConjunctiveGraph with pluggable data-stores. MemoryStore and SQLite3Store both support contexts as well as quoted-graphs and formulae, although no appropriate graph classes yet exist.
  • Graphs serialize to N-Triples and RDF/XML.
  • An RDF distiller runs on this site to test out different parsers. This is also useful for running automated RDFa Test Harness. 

RdfContext is based, in part on Tom Morris' Reddy gem. See the readme on GitHub for more information. MemoryStore, SQLite3Store and ConjunctiveGraph are largely ports of Python RDFLib.

RSpec soft failure for pending test cases

Posted by Gregg Kellogg Mon, 26 Oct 2009 18:40:00 GMT

 Recently, I've been playing with RSpec to run RDFa test cases. The suite has accepted and unreviewed test cases. My general way of testing is to parse the suite, and run each test through a generated spec as follows:

test_cases.each do |tc|
  specify "test #{tc.name}" do
    tc.run_test do |input|
      RdfaParser::RdfaParser.new.parse(input, tc.informationResourceInput)
    end
  end
end

The problem is, some tests are pending, so that a failure should be soft, and not hard. The way to do this is to catch Spec::Expectations::ExpectationNotMetError. This this, we can modify the above test as follows:

test_cases.each do |tc|
  specify "test #{tc.name}" do
    tc.run_test do |input|
      begin
        RdfaParser::RdfaParser.new.parse(input, tc.informationResourceInput)
      rescue Spec::Expectations::ExpectationNotMetError => e
        if tc.status == "unreviewed
          pending(e.message) {  raise }
        else
          raise
        end
      end
    end
  end
end

rdfa_parser gem released

Posted by Gregg Kellogg Sun, 18 Oct 2009 20:11:00 GMT

I just released version 0.1.0 of the rdfa_parser_gem. This parser is written in pure Ruby and uses Nokogiri XML parsing. It passes all XHTML1 test cases and most of the existing test cases for HTML4 and HTML5.

The gem is based on previous work done by Ben Adida and some libraries borrowed from the Reddy Gem.

The project is hosted on GitHub, feel free to clone. You can try out the parser through a distiller.

Restful action caching

Posted by Gregg Kellogg Sat, 29 Aug 2009 23:35:00 GMT

Caching actions without layout can be complicated when multiple request formats are used. In particular, an HTML response may use a dynamic layout, in which case you want to use the :layout => false option. However, other formats (such as XML) don't use a layout, but the :layout => false option to _caches_action_ does not properly cache the body in this case. To solve the problem, create two caches action statements:

caches_action :show,
              :if => lambda { |c| c.request.format == :html },
              :cache_path => lambda { |c| c.cache_key },
              :layout => false   caches_action :show,
              :unless => lambda{ |c| c.request.format == :html },
              :cache_path => lambda { |c| c.cache_key },
              :layout => true

Also, relying on the accept header may not cause the action caching module to detect the appropriate format. Try this in your application_controller:

before_filter :set_explicit_request_format
def set_explicit_request_format
  # Set format explicitly from accept header, unless it's already set
  request.format = :html if request.format == :any
  params[:format] ||= request.format.to_sym.to_s
end

Detecting action caching within controller

Posted by Gregg Kellogg Sat, 29 Aug 2009 23:12:00 GMT

Rails offers three forms of caching within your controller: page, action and fragment. Page caching results in the fastest access times, as the results of the first call to an action are saved in a file so that subsequent accesses never even hit rails. However, for most applications, this isn't useful, as there may be dynamic content on a page, and this does not allow for authentication. Fragment caching is the most detailed, and allows different parts of a page to be cached and allows you to check for the presence of a cached fragment within your controller (or view), but it requires the most maintenance of cache keys. Action caching is a nice compromise between the two. It allows the controller to get into the action but takes care of cache key creation. It also allows for a dynamic layout using the :layout option. However, in some actions, the amount of work done by the controller may be non-trivial, so it would be nice to check for the presence of the cache within the body of the controller action. This can be solved by borrowing some code from within ActionController::Cachine::Actions.

def index
  cache_path = ActionCachePath.new(self, cache_key)
  return if self.read_fragment(cache_path.path)
  # body of action
end

Controlling your own cache keys is also useful, particularly for actions that may take a number of parameters:

def cache_key
  key = "#{params[:controller]}/#{params[:action]}"
  params.each_pair {|k, v| key += ":#{k}=#{v.gsub(/\s/, "_")}
  key
end

ButtonLabels updated for Rails 2.3

Posted by Gregg Kellogg Mon, 09 Mar 2009 03:18:00 GMT

The ButtonLabels plugin described in another post has been updated for Rails 2.3.

HTTP Digest Authentication in Rails 2.3 2

Posted by Gregg Kellogg Sun, 08 Mar 2009 21:30:00 GMT

After a fair amount of work, I'm happy to report that HTTP Digest Authentication is now a part of Rails 2.3. Although I put the finishing touches to get this into the release, it is based on work done by Dan Manges and Xavier Shay . Also, thanks to Don Parish for bug fixes and improvements after original acceptance.

Read more about HTTP Digest Authentication in Rails 2.3 Ryan's Scraps. Relevant Lighthouse entries: 1230, 1848, and 2000. The last one includes a change, not yet approved for 2.3, which allows for using the HA1 part of the digest to store a hash of the password, rather than the cleartext of the original version. Hopefully, we'll get a version of that in soon. Also, the current implementation depends on using a session secret when computing the nonce. 2000 proposes a way to avoid this so no session is required.

Hopefully. we'll see the open issues resolved and get this into a 2.3.1 update.

Gregg

Automatically generate in_place_editor_for

Posted by Gregg Kellogg Thu, 22 Jan 2009 04:21:00 GMT

Recently, I was creating some in_place_editors for a polymorphic controller I’m working on. Although the problems not particular to polymorphic controllers, I didn’t want to embed too much model information within the controller. I came up with a way to use meathod_missing to define the in_place_editor_for on demand:

class ResourcesController &lt;&lt; ApplicationController
  def method_missing(method_id, *args)
    if method_id.to_s.match(/set_resource_(.*)$/) &amp;&amp; @resource.respond_to?($1)
      property = $1

      # Defines &quot;set_resource_#{property}&quot; on the fly
      self.class.in_place_edit_for(:resource, property)

      # Call the newly defined method
      self.send(&quot;set_resource_#{property}&quot;, args)
    else
      super
    end
  end
end