triannon 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7c88a5ccc4b645bbb52d89183ed8fa42f49eda50
4
+ data.tar.gz: eb58660e72be33aa86bc66f0feb676d9cf2ed4ea
5
+ SHA512:
6
+ metadata.gz: 54bc08d30db5e0fd1a4e1a93d70ed2da19a3359586c3f1c995b7a5713a5c30635736443193f18ec327db3a21eca3b9b3ee65deb5e59034bd57417960e1ec6710
7
+ data.tar.gz: 5f9f0fa5b0384791e765719c989996782786bcfb019e90b62c31b84d0fe39cdb42d82198dc4fe750f36f8af4c5f0e5f10a0ce928ae4a85d06335c83bea1a96f5
@@ -0,0 +1,42 @@
1
+ [![Build Status](https://travis-ci.org/sul-dlss/triannon.svg?branch=master)](https://travis-ci.org/sul-dlss/triannon) [![Dependency Status](https://gemnasium.com/sul-dlss/triannon.svg)](https://gemnasium.com/sul-dlss/triannon) [![Gem Version](https://badge.fury.io/rb/triannon.svg)](http://badge.fury.io/rb/triannon)
2
+
3
+ # Triannon
4
+
5
+ Demonstration Open Annotation to support the Linked Data for Libraries use cases.
6
+
7
+ ## Tests
8
+
9
+ Run tests:
10
+
11
+ ```console
12
+ $ rake
13
+ ```
14
+
15
+ ## Installation
16
+
17
+ Add this line to your gemfile
18
+
19
+ ```ruby
20
+ gem 'triannon'
21
+ ```
22
+
23
+ Then execute:
24
+
25
+ ```console
26
+ $ bundle
27
+ ```
28
+
29
+ Then run the triannon generator:
30
+
31
+ ```console
32
+ $ rails g triannon:install
33
+ ```
34
+
35
+ ## Running the application in development
36
+
37
+ There is a bundled rake task for running the test app:
38
+
39
+ ```console
40
+ $ rake engine_cart:generate # (first run only)
41
+ $ rake triannon:server
42
+ ```
@@ -0,0 +1,71 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ ZIP_URL = "https://github.com/projecthydra/hydra-jetty/archive/v8.0.0.rc2.zip"
8
+
9
+ require 'active_support/benchmarkable'
10
+ require 'jettywrapper'
11
+
12
+ require 'rdoc/task'
13
+
14
+ RDoc::Task.new(:rdoc) do |rdoc|
15
+ rdoc.rdoc_dir = 'rdoc'
16
+ rdoc.title = 'Triannon'
17
+ rdoc.options << '--line-numbers'
18
+ rdoc.rdoc_files.include('README.rdoc')
19
+ rdoc.rdoc_files.include('lib/**/*.rb')
20
+ end
21
+
22
+ require 'engine_cart/rake_task'
23
+ desc 'run the triannon specs'
24
+ task :ci => ['engine_cart:generate', 'jetty:clean'] do
25
+ # run the tests
26
+ RAILS_ENV = 'test'
27
+ jetty_params = Jettywrapper.load_config.merge({:jetty_home => File.expand_path(File.dirname(__FILE__) + '/jetty')})
28
+ Jettywrapper.wrap(jetty_params) do
29
+ Rake::Task['spec'].invoke
30
+ end
31
+ end
32
+
33
+ namespace :triannon do
34
+ desc 'run the test rails app w triannon'
35
+ task :server do
36
+ jetty_params = Jettywrapper.load_config.merge({:jetty_home => File.expand_path(File.dirname(__FILE__) + '/jetty')})
37
+ Jettywrapper.wrap(jetty_params) do
38
+ within_test_app do
39
+ system "rails s"
40
+ end
41
+ end
42
+ end
43
+
44
+ desc 'run the test rails console w triannon'
45
+ task :console do
46
+ jetty_params = Jettywrapper.load_config.merge({:jetty_home => File.expand_path(File.dirname(__FILE__) + '/jetty')})
47
+ Jettywrapper.wrap(jetty_params) do
48
+ within_test_app do
49
+ system "rails c"
50
+ end
51
+ end
52
+ end
53
+
54
+ desc 'run the test rails console w triannon but no jetty'
55
+ task :console_no_jetty do
56
+ within_test_app do
57
+ system "rails c"
58
+ end
59
+ end
60
+ end
61
+
62
+
63
+ load 'rails/tasks/statistics.rake'
64
+
65
+ require 'rspec/core/rake_task'
66
+
67
+ RSpec::Core::RakeTask.new(:spec)
68
+
69
+ task :default => :ci
70
+
71
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require jquery
14
+ //= require bootstrap-sprockets
15
+ //= require_tree .
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,18 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
16
+
17
+ @import "bootstrap-sprockets";
18
+ @import "bootstrap";
@@ -0,0 +1,62 @@
1
+ require_dependency "triannon/application_controller"
2
+
3
+ module Triannon
4
+ class AnnotationsController < ApplicationController
5
+ before_action :set_annotation, only: [:show, :edit, :update, :destroy]
6
+
7
+ # GET /annotations/annotations
8
+ def index
9
+ @annotations = Annotation.all
10
+ end
11
+
12
+ # GET /annotations/annotations/1
13
+ def show
14
+ end
15
+
16
+ # GET /annotations/annotations/new
17
+ def new
18
+ @annotation = Annotation.new
19
+ end
20
+
21
+ # GET /annotations/annotations/1/edit
22
+ def edit
23
+ end
24
+
25
+ # POST /annotations/annotations
26
+ def create
27
+ @annotation = Annotation.new(annotation_params)
28
+
29
+ if @annotation.save
30
+ redirect_to @annotation, notice: 'Annotation was successfully created.'
31
+ else
32
+ render :new
33
+ end
34
+ end
35
+
36
+ # PATCH/PUT /annotations/annotations/1
37
+ def update
38
+ if @annotation.update(annotation_params)
39
+ redirect_to @annotation, notice: 'Annotation was successfully updated.'
40
+ else
41
+ render :edit
42
+ end
43
+ end
44
+
45
+ # DELETE /annotations/annotations/1
46
+ def destroy
47
+ @annotation.destroy
48
+ redirect_to annotations_url, notice: 'Annotation was successfully destroyed.'
49
+ end
50
+
51
+ private
52
+ # Use callbacks to share common setup or constraints between actions.
53
+ def set_annotation
54
+ @annotation = Annotation.find(params[:id])
55
+ end
56
+
57
+ # Only allow a trusted parameter "white list" through.
58
+ def annotation_params
59
+ params.require(:annotation).permit(:data)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,4 @@
1
+ module Triannon
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Triannon
2
+ module AnnotationsHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Triannon
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,134 @@
1
+ module Triannon
2
+ class Annotation < ActiveRecord::Base
3
+
4
+ validates :data, presence: true,
5
+ length: {minimum: 30}
6
+
7
+ # full validation should be optional?
8
+ # minimal: a subject with the right type and a hasTarget? (see url)
9
+ # and perhaps modeled on this:
10
+ # https://github.com/uq-eresearch/lorestore/blob/3e9aa1c69aafd3692c69aa39c64bfdc32b757892/src/main/resources/OAConstraintsSPARQL.json
11
+
12
+ def url
13
+ if graph_exists?
14
+ solution = graph.query(self.class.basic_query)
15
+ if solution && solution.size == 1
16
+ solution.first.s.to_s
17
+ # TODO: raise exception if no URL?
18
+ end
19
+ end
20
+ end
21
+
22
+ # FIXME: this should be part of validation: RDF.type should be RDF::OpenAnnotation.Annotation
23
+ def type
24
+ if graph_exists?
25
+ query = RDF::Query.new
26
+ query << [:s, RDF::OpenAnnotation.hasTarget, nil]
27
+ query << [:s, RDF.type, :type]
28
+ solution = graph.query(query)
29
+ if solution && solution.size == 1
30
+ solution.first.type.to_s
31
+ # TODO: raise exception if no type?
32
+ end
33
+ end
34
+ end
35
+
36
+ def has_target
37
+ # FIXME: can have multiple targets per spec (example 8)
38
+ # FIXME: target might be more than a string (examples 14-17)
39
+ stmt = rdf.find_all { |s|
40
+ s.predicate.to_s == RDF::OpenAnnotation.hasTarget
41
+ }.first
42
+ stmt.object.to_str if stmt
43
+ end
44
+
45
+ def has_body
46
+ # FIXME: can have multiple bodies per spec
47
+ stmt = rdf.find_all { |s|
48
+ s.predicate.to_s == RDF::OpenAnnotation.hasBody
49
+ }.first
50
+
51
+ # FIXME: body can be other things
52
+ # if body is blank node and has character content, then return it
53
+ body = stmt.object if stmt
54
+ if body && body.is_a?(RDF::Node)
55
+ body_stmts = rdf.find_all { |s| s.subject == body }
56
+ if body_stmts &&
57
+ body_stmts.detect { |s|
58
+ s.predicate.to_s == RDF.type &&
59
+ s.object.to_s == RDF::Content.ContentAsText
60
+ }
61
+ chars_stmt = body_stmts.detect { |s| s.predicate.to_s == RDF::Content.chars}
62
+ return chars_stmt.object.to_s if chars_stmt
63
+ end
64
+ end
65
+ nil
66
+ end
67
+
68
+ def motivated_by
69
+ if graph_exists?
70
+ q = self.class.basic_query.clone
71
+ q << [:s, RDF::OpenAnnotation.motivatedBy, :motivated_by]
72
+ solution = graph.query(q)
73
+ if solution && solution.size > 0
74
+ motivations = []
75
+ solution.each {|res|
76
+ motivations << res.motivated_by.to_s
77
+ }
78
+ motivations
79
+ # TODO: raise exception if none?
80
+ end
81
+ end
82
+ end
83
+
84
+ def rdf
85
+ @rdf ||= JSON::LD::API.toRdf(json_ld) if json_ld
86
+ end
87
+
88
+ def graph
89
+ g = data_to_graph
90
+ @graph ||= g if g
91
+ end
92
+
93
+ # query for a subject with
94
+ # predicate RDF::OpenAnnotation.hasTarget
95
+ # type of RDF::OpenAnnotation.Annotation
96
+ def self.basic_query
97
+ @basic_query ||= begin
98
+ basic_query = RDF::Query.new
99
+ basic_query << [:s, RDF.type, RDF::URI("http://www.w3.org/ns/oa#Annotation")]
100
+ basic_query << [:s, RDF::OpenAnnotation.hasTarget, nil]
101
+ end
102
+ end
103
+
104
+ private
105
+
106
+ # loads RDF::Graph from data attribute. If data is in json-ld, converts it to turtle.
107
+ def data_to_graph
108
+ if data
109
+ case data
110
+ when /\{\s*\"@\w+\"/
111
+ json ||= JSON.parse(data)
112
+ g ||= RDF::Graph.new << JSON::LD::API.toRdf(json_ld) if json
113
+ self.data = g.dump(:ttl) if g
114
+ #when /http/
115
+ # g ||= RDF::Graph.load(data, :format => :ttl)
116
+ else # assume turtle
117
+ g = RDF::Graph.new
118
+ g.from_ttl(data)
119
+ g = nil if g.size == 0
120
+ end
121
+ end
122
+ g
123
+ end
124
+
125
+ def json_ld
126
+ @json_ld ||= JSON.parse(data) rescue nil
127
+ end
128
+
129
+ def graph_exists?
130
+ graph && graph.size > 0
131
+ end
132
+
133
+ end
134
+ end
@@ -0,0 +1,33 @@
1
+ module Triannon
2
+ class GraphValidator < ActiveModel::Validator
3
+
4
+ def validate(anno)
5
+ graph_exists? anno
6
+ graph = anno.graph
7
+ basic_solution = graph.query(self.basic_query)
8
+ unless basic_solution && basic_solution.size == 1
9
+ anno.errors[:data] << 'The oa:Annotation class MUST be associated with each Annotation.'
10
+ anno.errors[:data] << 'each Annotation MUST have at least one target'
11
+ end
12
+ end
13
+
14
+ def graph_exists?(anno)
15
+ graph = anno.graph
16
+ unless graph && graph.size > 0
17
+ anno.errors[:data] << 'Unable to create non-null graph'
18
+ end
19
+ end
20
+
21
+ # query for a subject with
22
+ # predicate RDF::OpenAnnotation.hasTarget
23
+ # type of RDF::OpenAnnotation.Annotation
24
+ def self.basic_query
25
+ @@basic_query ||= begin
26
+ RDF::Query.new
27
+ basic_query << [:s, RDF.type, RDF::URI("http://www.w3.org/ns/oa#Annotation")]
28
+ basic_query << [:s, RDF::OpenAnnotation.hasTarget, nil]
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,37 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <title>Cerberus</title>
8
+ <%= stylesheet_link_tag "triannon/application", media: "all" %>
9
+ <%= javascript_include_tag "triannon/application" %>
10
+ <%= csrf_meta_tags %>
11
+ </head>
12
+ <body>
13
+ <div class="container">
14
+ <!-- Static navbar -->
15
+ <div class="navbar navbar-default" role="navigation">
16
+ <div class="container-fluid">
17
+ <div class="navbar-header">
18
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
19
+ <span class="sr-only">Toggle navigation</span>
20
+ <span class="icon-bar"></span>
21
+ <span class="icon-bar"></span>
22
+ <span class="icon-bar"></span>
23
+ </button>
24
+ <%= link_to "Cerberus", root_path, class: 'navbar-brand' %>
25
+ </div>
26
+ <div class="navbar-collapse collapse">
27
+ <ul class="nav navbar-nav">
28
+ </ul>
29
+ <ul class="nav navbar-nav navbar-right">
30
+ </ul>
31
+ </div><!--/.nav-collapse -->
32
+ </div><!--/.container-fluid -->
33
+ </div>
34
+ <%= yield %>
35
+ </div>
36
+ </body>
37
+ </html>
@@ -0,0 +1,21 @@
1
+ <%= form_for(@annotation) do |f| %>
2
+ <% if @annotation.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@annotation.errors.count, "error") %> prohibited this annotation from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @annotation.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label 'data (as JSON-LD)' %><br>
16
+ <%= f.text_area :data %>
17
+ </div>
18
+ <div class="actions">
19
+ <%= f.submit %>
20
+ </div>
21
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= render 'form' %>
@@ -0,0 +1,8 @@
1
+ <h1>Annotations</h1>
2
+ <ul>
3
+ <% @annotations.each do |a| %>
4
+ <li><%= link_to a.url, annotation_path(a) %></li>
5
+ <% end %>
6
+ </ul>
7
+
8
+ <%= link_to 'New Annotation', new_annotation_path %>
@@ -0,0 +1 @@
1
+ <%= render 'form' %>
@@ -0,0 +1,32 @@
1
+ <h1>Annotation</h1>
2
+ <p>
3
+ <strong>Url (@id):</strong>
4
+ <%= @annotation.url %>
5
+ </p>
6
+ <p>
7
+ <strong>Target:</strong>
8
+ <%= link_to @annotation.has_target, @annotation.has_target %>
9
+ </p>
10
+ <p>
11
+ <strong>Body (blank node with text):</strong>
12
+ <pre>
13
+ <%= @annotation.has_body %>
14
+ </pre>
15
+ </p>
16
+ <p>
17
+ <strong>Motivated By:</strong>
18
+ <% @annotation.motivated_by { |m|%>
19
+ <%= link_to @annotation.m, @annotation.m %>
20
+ <% } %>
21
+ </p>
22
+ <p>
23
+ <strong>Type:</strong>
24
+ <%= link_to @annotation.type, @annotation.type %>
25
+ </p>
26
+
27
+ <strong>Turtle:</strong>
28
+ <pre>
29
+ <%= @annotation.graph.dump(:ttl) %>
30
+ </pre>
31
+
32
+ <%= link_to "Back to List", annotations_path %>
@@ -0,0 +1,5 @@
1
+ Triannon::Engine.routes.draw do
2
+ root to: 'annotations#index'
3
+
4
+ resources :annotations
5
+ end
@@ -0,0 +1,9 @@
1
+ class CreateTriannonAnnotations < ActiveRecord::Migration
2
+ def change
3
+ create_table :triannon_annotations do |t|
4
+ t.text :data
5
+
6
+ t.timestamps null: false
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'rails/generators'
2
+
3
+ module Triannon
4
+ class Install < Rails::Generators::Base
5
+ def inject_Triannon_routes
6
+ route "mount Triannon::Engine, at: 'annotations'"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ namespace :triannon do
2
+ # desc "Explaining what the task does"
3
+ # task :Triannon do
4
+ # # Task goes here
5
+ # end
6
+ end
@@ -0,0 +1,7 @@
1
+ require 'linkeddata'
2
+ require 'rdf/open_annotation'
3
+ require 'bootstrap-sass'
4
+
5
+ module Triannon
6
+ require "triannon/engine"
7
+ end
@@ -0,0 +1,5 @@
1
+ module Triannon
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Triannon
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Triannon
2
+ VERSION = "0.0.3"
3
+ end
metadata ADDED
@@ -0,0 +1,225 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: triannon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Chris Beer
8
+ - Naomi Dushay
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-09-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 4.2.0.beta1
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 4.2.0.beta1
28
+ - !ruby/object:Gem::Dependency
29
+ name: linkeddata
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rdf-open_annotation
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: bootstrap-sass
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: sass-rails
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 5.0.0.beta1
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 5.0.0.beta1
84
+ - !ruby/object:Gem::Dependency
85
+ name: sqlite3
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '3.0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '3.0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rspec-rails
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '3.0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '3.0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: engine_cart
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: '0.4'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '0.4'
140
+ - !ruby/object:Gem::Dependency
141
+ name: jettywrapper
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: capybara
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ description:
169
+ email:
170
+ - cabeer@stanford.edu
171
+ - ndushay@stanford.edu
172
+ executables: []
173
+ extensions: []
174
+ extra_rdoc_files: []
175
+ files:
176
+ - README.md
177
+ - Rakefile
178
+ - app/assets/javascripts/triannon/annotations.js
179
+ - app/assets/javascripts/triannon/application.js
180
+ - app/assets/stylesheets/triannon/annotations.css
181
+ - app/assets/stylesheets/triannon/application.css.scss
182
+ - app/controllers/triannon/annotations_controller.rb
183
+ - app/controllers/triannon/application_controller.rb
184
+ - app/helpers/triannon/annotations_helper.rb
185
+ - app/helpers/triannon/application_helper.rb
186
+ - app/models/triannon/annotation.rb
187
+ - app/models/triannon/graph_validator.rb
188
+ - app/views/layouts/triannon/application.html.erb
189
+ - app/views/triannon/annotations/_form.html.erb
190
+ - app/views/triannon/annotations/edit.html.erb
191
+ - app/views/triannon/annotations/index.html.erb
192
+ - app/views/triannon/annotations/new.html.erb
193
+ - app/views/triannon/annotations/show.html.erb
194
+ - config/routes.rb
195
+ - db/migrate/20140912173046_create_triannon_annotations.rb
196
+ - lib/generators/triannon/install_generator.rb
197
+ - lib/tasks/triannon_tasks.rake
198
+ - lib/triannon.rb
199
+ - lib/triannon/engine.rb
200
+ - lib/triannon/version.rb
201
+ homepage:
202
+ licenses:
203
+ - Apache 2
204
+ metadata: {}
205
+ post_install_message:
206
+ rdoc_options: []
207
+ require_paths:
208
+ - lib
209
+ required_ruby_version: !ruby/object:Gem::Requirement
210
+ requirements:
211
+ - - ">="
212
+ - !ruby/object:Gem::Version
213
+ version: '0'
214
+ required_rubygems_version: !ruby/object:Gem::Requirement
215
+ requirements:
216
+ - - ">="
217
+ - !ruby/object:Gem::Version
218
+ version: '0'
219
+ requirements: []
220
+ rubyforge_project:
221
+ rubygems_version: 2.2.0
222
+ signing_key:
223
+ specification_version: 4
224
+ summary: Rails engine for working with storage of OpenAnnotations stored in Fedora4
225
+ test_files: []