hydra-tutorial 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +93 -0
- data/README.md +15 -0
- data/Rakefile +10 -0
- data/bin/hydra-tutorial +4 -0
- data/hydra-tutorial.gemspec +16 -0
- data/open-repositories-tutorial.thor +668 -0
- data/or_templates/add_tests/records_controller_spec.rb +7 -0
- data/or_templates/adding_our_models/basic_af_model.rb +5 -0
- data/or_templates/adding_our_models/basic_mods_model.rb +13 -0
- data/or_templates/adding_our_models/basic_om_model.rb +28 -0
- data/or_templates/adding_our_models/mods_desc_metadata.rb +135 -0
- data/or_templates/building_a_basic_rails_app/fedora.yml +14 -0
- data/or_templates/building_a_basic_rails_app/solr.yml +10 -0
- data/or_templates/records_controller.rb +83 -0
- data/or_templates/wiring_it_into_rails/_form.html.erb +31 -0
- data/or_templates/wiring_it_into_rails/show.html.erb +7 -0
- data/templates/application/dataset_hydra_mods_om.rb +13 -0
- data/templates/application/dataset_hydra_om.rb +37 -0
- data/templates/application/datasets_controller.rb +82 -0
- data/templates/application/mods_desc_metadata.rb +135 -0
- data/templates/building_a_basic_rails_app/dataset_af_om.rb +34 -0
- data/templates/building_a_basic_rails_app/dataset_simple_om.rb +24 -0
- data/templates/building_a_basic_rails_app/fedora.yml +14 -0
- data/templates/building_a_basic_rails_app/om_record.rb +63 -0
- data/templates/building_a_basic_rails_app/solr.yml +10 -0
- data/tutorial.thor +493 -0
- metadata +127 -0
@@ -0,0 +1,135 @@
|
|
1
|
+
class ModsDescMetadata < ActiveFedora::NokogiriDatastream
|
2
|
+
# MODS XML constants.
|
3
|
+
|
4
|
+
MODS_NS = 'http://www.loc.gov/mods/v3'
|
5
|
+
MODS_SCHEMA = 'http://www.loc.gov/standards/mods/v3/mods-3-3.xsd'
|
6
|
+
MODS_PARAMS = {
|
7
|
+
"version" => "3.3",
|
8
|
+
"xmlns:xlink" => "http://www.w3.org/1999/xlink",
|
9
|
+
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
10
|
+
"xmlns" => MODS_NS,
|
11
|
+
"xsi:schemaLocation" => "#{MODS_NS} #{MODS_SCHEMA}",
|
12
|
+
}
|
13
|
+
|
14
|
+
# OM terminology.
|
15
|
+
|
16
|
+
set_terminology do |t|
|
17
|
+
t.root :path => 'mods', :xmlns => MODS_NS
|
18
|
+
t.originInfo do
|
19
|
+
t.dateOther
|
20
|
+
end
|
21
|
+
t.abstract
|
22
|
+
t.titleInfo do
|
23
|
+
t.title
|
24
|
+
end
|
25
|
+
|
26
|
+
t.title :ref => [:mods, :titleInfo, :title]
|
27
|
+
t.name do
|
28
|
+
t.namePart
|
29
|
+
t.role do
|
30
|
+
t.roleTerm
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
t.relatedItem do
|
35
|
+
t.titleInfo do
|
36
|
+
t.title
|
37
|
+
end
|
38
|
+
t.location do
|
39
|
+
t.url
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
t.subject do
|
44
|
+
t.topic
|
45
|
+
end
|
46
|
+
|
47
|
+
t.preferred_citation :path => 'note', :attributes => { :type => "preferred citation" }
|
48
|
+
t.related_citation :path => 'note', :attributes => { :type => "citation/reference" }
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
# Blocks to pass into Nokogiri::XML::Builder.new()
|
53
|
+
|
54
|
+
define_template :name do |xml|
|
55
|
+
xml.name {
|
56
|
+
xml.namePart
|
57
|
+
xml.role {
|
58
|
+
xml.roleTerm(:authority => "marcrelator", :type => "text")
|
59
|
+
}
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
define_template :relatedItem do |xml|
|
64
|
+
xml.relatedItem {
|
65
|
+
xml.titleInfo {
|
66
|
+
xml.title
|
67
|
+
}
|
68
|
+
xml.location {
|
69
|
+
xml.url
|
70
|
+
}
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
define_template :related_citation do |xml|
|
75
|
+
xml.note(:type => "citation/reference")
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.xml_template
|
79
|
+
Nokogiri::XML::Builder.new do |xml|
|
80
|
+
xml.mods(MODS_PARAMS) {
|
81
|
+
xml.originInfo {
|
82
|
+
xml.dateOther
|
83
|
+
}
|
84
|
+
xml.abstract
|
85
|
+
xml.titleInfo {
|
86
|
+
xml.title
|
87
|
+
}
|
88
|
+
xml.name {
|
89
|
+
xml.namePart
|
90
|
+
xml.role {
|
91
|
+
xml.roleTerm
|
92
|
+
}
|
93
|
+
}
|
94
|
+
xml.relatedItem {
|
95
|
+
xml.titleInfo {
|
96
|
+
xml.title
|
97
|
+
}
|
98
|
+
xml.location {
|
99
|
+
xml.url
|
100
|
+
}
|
101
|
+
}
|
102
|
+
xml.subject {
|
103
|
+
xml.topic
|
104
|
+
}
|
105
|
+
xml.note(:type => "preferred citation")
|
106
|
+
xml.note(:type => "citation/reference")
|
107
|
+
}
|
108
|
+
end.doc
|
109
|
+
end
|
110
|
+
|
111
|
+
def insert_person
|
112
|
+
insert_new_node(:name)
|
113
|
+
end
|
114
|
+
|
115
|
+
def insert_related_item
|
116
|
+
insert_new_node(:relatedItem)
|
117
|
+
end
|
118
|
+
|
119
|
+
def insert_related_citation
|
120
|
+
insert_new_node(:related_citation)
|
121
|
+
end
|
122
|
+
|
123
|
+
def insert_new_node(term)
|
124
|
+
add_child_node(ng_xml.root, term)
|
125
|
+
end
|
126
|
+
|
127
|
+
def remove_node(term, index)
|
128
|
+
node = self.find_by_terms(term.to_sym => index.to_i).first
|
129
|
+
unless node.nil?
|
130
|
+
node.remove
|
131
|
+
self.dirty = true
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Dataset < ActiveFedora::Base
|
2
|
+
|
3
|
+
class DatastreamMetadata < ActiveFedora::NokogiriDatastream
|
4
|
+
|
5
|
+
##
|
6
|
+
# Here's the important part. We're mapping XML into Ruby.
|
7
|
+
set_terminology do |t|
|
8
|
+
t.root :path => 'root', :xmlns => nil
|
9
|
+
t.title
|
10
|
+
t.author
|
11
|
+
t.url
|
12
|
+
t.description
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.xml_template
|
16
|
+
Nokogiri::XML::Builder.new do |xml|
|
17
|
+
xml.root do
|
18
|
+
xml.title
|
19
|
+
xml.author
|
20
|
+
xml.url
|
21
|
+
xml.description
|
22
|
+
end
|
23
|
+
end.doc
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
has_metadata :name => "descMetadata", :type => DatastreamMetadata
|
28
|
+
|
29
|
+
delegate :title, :to=>'descMetadata', :unique=>true
|
30
|
+
delegate :author, :to=>'descMetadata', :unique=>true
|
31
|
+
delegate :url, :to=>'descMetadata', :unique=>true
|
32
|
+
delegate :description, :to=>'descMetadata', :unique=>true
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Dataset < OmRecord # OmRecord contains code that lets us pretend this Dataset is a drop-in replacement for the ActiveRecord.
|
2
|
+
include OM::XML::Document
|
3
|
+
|
4
|
+
##
|
5
|
+
# Here's the important part. We're mapping XML into Ruby.
|
6
|
+
set_terminology do |t|
|
7
|
+
t.root :path => 'root', :xmlns => nil
|
8
|
+
t.title
|
9
|
+
t.author
|
10
|
+
t.url
|
11
|
+
t.description
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.xml_template
|
15
|
+
Nokogiri::XML::Builder.new do |xml|
|
16
|
+
xml.root do
|
17
|
+
xml.title
|
18
|
+
xml.author
|
19
|
+
xml.url
|
20
|
+
xml.description
|
21
|
+
end
|
22
|
+
end.doc
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
development:
|
2
|
+
user: fedoraAdmin
|
3
|
+
password: fedoraAdmin
|
4
|
+
url: http://127.0.0.1:8983/fedora
|
5
|
+
test: &TEST
|
6
|
+
user: fedoraAdmin
|
7
|
+
password: fedoraAdmin
|
8
|
+
url: <%= "http://127.0.0.1:#{ENV['TEST_JETTY_PORT'] || 8983}/fedora-test" %>
|
9
|
+
production:
|
10
|
+
user: fedoraAdmin
|
11
|
+
password: fedoraAdmin
|
12
|
+
url: http://your.production.server:8080/fedora
|
13
|
+
cucumber:
|
14
|
+
<<: *TEST
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class OmRecord
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
##
|
6
|
+
# This stuff is so we can store and retrieve data off the filesystem. Don't worry about it.
|
7
|
+
extend ActiveModel::Naming
|
8
|
+
include ActiveModel::Conversion
|
9
|
+
|
10
|
+
attr_writer :file
|
11
|
+
|
12
|
+
attr_accessor :name
|
13
|
+
attr_reader :errors
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize options={}
|
17
|
+
|
18
|
+
@errors = ActiveModel::Errors.new(self)
|
19
|
+
|
20
|
+
self.ng_xml = self.class.xml_template
|
21
|
+
|
22
|
+
options.each do |k,v|
|
23
|
+
send("#{k}=", v)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def file
|
28
|
+
@file ||= "db/datasets/#{Time.now.to_i}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def id
|
32
|
+
File.basename(file)
|
33
|
+
end
|
34
|
+
|
35
|
+
def save
|
36
|
+
File.open(file, 'w') { |f| f.puts ng_xml.to_s }
|
37
|
+
end
|
38
|
+
|
39
|
+
def persisted?
|
40
|
+
File.exists? file
|
41
|
+
end
|
42
|
+
|
43
|
+
class ClassMethods
|
44
|
+
def all
|
45
|
+
Dir.glob('db/datasets/*').map do |f|
|
46
|
+
Dataset.from_file(f)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def find id
|
51
|
+
Dataset.from_file("db/datasets/#{id}")
|
52
|
+
end
|
53
|
+
|
54
|
+
def from_file f
|
55
|
+
d = Dataset.from_xml(File.read(f))
|
56
|
+
|
57
|
+
d.file = f
|
58
|
+
|
59
|
+
d
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# This is a sample config file that does not have multiple solr instances. You will also need to be sure to
|
2
|
+
# edit the fedora.yml file to match the solr URL for active-fedora.
|
3
|
+
development:
|
4
|
+
url: http://localhost:8983/solr/development
|
5
|
+
test: &TEST
|
6
|
+
url: <%= "http://127.0.0.1:#{ENV['TEST_JETTY_PORT'] || 8983}/solr/test" %>
|
7
|
+
cucumber:
|
8
|
+
<<: *TEST
|
9
|
+
production:
|
10
|
+
url: http://your.production.server:8080/bl_solr/core0
|
data/tutorial.thor
ADDED
@@ -0,0 +1,493 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'thor'
|
5
|
+
require 'thor/group'
|
6
|
+
require 'rails/generators/actions'
|
7
|
+
require 'active_support/core_ext/array/extract_options'
|
8
|
+
|
9
|
+
$base_templates_path = File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
10
|
+
|
11
|
+
class HydraTutorialApp < Thor::Group
|
12
|
+
class_option :quick, :default => false
|
13
|
+
|
14
|
+
def welcome
|
15
|
+
$quick = options[:quick]
|
16
|
+
say %Q{
|
17
|
+
Welcome to this Hydra tutorial. We're going to go through some steps to
|
18
|
+
set up a working Hydra head. We'll build the application gradually, and give you
|
19
|
+
opportunities to stop and look around on the way.
|
20
|
+
}, Thor::Shell::Color::YELLOW
|
21
|
+
|
22
|
+
if $quick
|
23
|
+
say %Q{
|
24
|
+
We'll quickly build the application, give you some Hydra models, and send you on your way.
|
25
|
+
}, Thor::Shell::Color::YELLOW
|
26
|
+
|
27
|
+
else
|
28
|
+
say %Q{
|
29
|
+
We'll go through this tour slowly, starting by creating a pure Rails application,
|
30
|
+
and then introduce Hydra components. If you want to speed things along,
|
31
|
+
}, Thor::Shell::Color::YELLOW
|
32
|
+
|
33
|
+
exit unless yes? %Q{
|
34
|
+
If you want to speed things along, you should quit this tutorial (by saying 'no'),
|
35
|
+
and run it again with ./tutorial.thor --quick=yes.
|
36
|
+
|
37
|
+
Do you want to continue at this pace? (y/n) }, Thor::Shell::Color::GREEN
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
include Thor::Actions
|
42
|
+
include Rails::Generators::Actions
|
43
|
+
|
44
|
+
class Prerequisites < Thor::Group
|
45
|
+
class_option :quick, :default => false
|
46
|
+
include Thor::Actions
|
47
|
+
include Rails::Generators::Actions
|
48
|
+
|
49
|
+
def install_ruby
|
50
|
+
return if $quick
|
51
|
+
say %Q{
|
52
|
+
Obviously, if you can run this tutorial, you have already installed ruby.
|
53
|
+
}, Thor::Shell::Color::YELLOW
|
54
|
+
|
55
|
+
|
56
|
+
ruby_executable = run 'which ruby', :capture => true
|
57
|
+
|
58
|
+
say %Q{
|
59
|
+
You are running this using:
|
60
|
+
#{ruby_executable}
|
61
|
+
}, Thor::Shell::Color::YELLOW
|
62
|
+
|
63
|
+
if ruby_executable =~ /rvm/ or ruby_executable =~ /rbenv/ or ruby_executable =~ /home/ or ruby_Executable =~ /Users/
|
64
|
+
say %Q{
|
65
|
+
It looks like you're using rvm/rbenv/etc. (with a gemset?) We'll use this environment to build the application.
|
66
|
+
}, Thor::Shell::Color::YELLOW
|
67
|
+
|
68
|
+
else
|
69
|
+
|
70
|
+
say %Q{
|
71
|
+
We checked, and it looks like you might be using a system-wide ruby. We'd like to
|
72
|
+
suggest you use somethng like rvm [1], rbenv [2], etc to manage your ruby projects.
|
73
|
+
|
74
|
+
[1] http://rvm.io/
|
75
|
+
[2] https://github.com/sstephenson/rbenv/
|
76
|
+
}, Thor::Shell::Color::RED
|
77
|
+
|
78
|
+
exit unless yes? %Q{
|
79
|
+
You can continue and hope for the best, or go install one of these ruby managers, which may make your life easier.
|
80
|
+
|
81
|
+
Do you want to continue anyway? (y/n)
|
82
|
+
}, Thor::Shell::Color::GREEN
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def install_bundler_and_rails
|
88
|
+
say %Q{
|
89
|
+
We're going to install some prerequisite gems in order to create our skeleton Rails application.
|
90
|
+
}, Thor::Shell::Color::YELLOW
|
91
|
+
run 'gem install bundler rails'
|
92
|
+
end
|
93
|
+
|
94
|
+
def new_rails_app
|
95
|
+
say %Q{
|
96
|
+
Now we'll create the application.
|
97
|
+
}, Thor::Shell::Color::YELLOW
|
98
|
+
run 'rails new hydra_tutorial_app'
|
99
|
+
run 'cd hydra_tutorial_app'
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
def out_of_the_box
|
104
|
+
return if $quick
|
105
|
+
say %Q{
|
106
|
+
Here's a chance to look around. You can see the structure of a Rails application.
|
107
|
+
./app
|
108
|
+
./config
|
109
|
+
./lib
|
110
|
+
Gemfile
|
111
|
+
}
|
112
|
+
|
113
|
+
ask %Q{
|
114
|
+
|
115
|
+
Hit ENTER when you're ready to continue.
|
116
|
+
}, Thor::Shell::Color::GREEN
|
117
|
+
end
|
118
|
+
|
119
|
+
# and then clean up some cruft
|
120
|
+
def remove_public_index
|
121
|
+
say %Q{
|
122
|
+
We'll now remove the Rails directions from the application.
|
123
|
+
}, Thor::Shell::Color::YELLOW
|
124
|
+
inside 'hydra_tutorial_app' do
|
125
|
+
remove_file 'public/index.html'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class BuildingABasicRailsApp < Thor::Group
|
131
|
+
include Thor::Actions
|
132
|
+
include Rails::Generators::Actions
|
133
|
+
|
134
|
+
def self.source_paths
|
135
|
+
[File.join($base_templates_path, "building_a_basic_rails_app")]
|
136
|
+
end
|
137
|
+
|
138
|
+
def notes
|
139
|
+
say %Q{
|
140
|
+
We're going to build an application to track (simplified) datasets and their metadata.
|
141
|
+
}, Thor::Shell::Color::YELLOW
|
142
|
+
end
|
143
|
+
|
144
|
+
def as_if_this_was_just_a_rails_applications
|
145
|
+
say %Q{
|
146
|
+
If we wanted to build a Rails application to do this, we would add some models and controllers.
|
147
|
+
|
148
|
+
Rails can help "scaffold" the application for us.
|
149
|
+
}, Thor::Shell::Color::YELLOW
|
150
|
+
|
151
|
+
generate 'scaffold', 'dataset', 'title', 'author', 'url', 'description:text'
|
152
|
+
rake 'db:migrate'
|
153
|
+
|
154
|
+
say %Q{
|
155
|
+
This created a Dataset model (in ./app/models/dataset.rb), a controller, and some views.
|
156
|
+
}, Thor::Shell::Color::YELLOW
|
157
|
+
|
158
|
+
ask %Q{
|
159
|
+
Take a look around. Hit ENTER when you're ready to continue.
|
160
|
+
}, Thor::Shell::Color::GREEN
|
161
|
+
end
|
162
|
+
|
163
|
+
def but_maybe_we_want_to_store_our_metadata_as_xml
|
164
|
+
say %Q{
|
165
|
+
But it turns out a relational database is not a great place to store complex metadata objects,
|
166
|
+
with nesting, hierarchy, repetition, etc like we often fine in the digital library world. We'd
|
167
|
+
also like to store and manage our data in an exchangeable form rather than a custom-built database.
|
168
|
+
|
169
|
+
In our world, we often find ourselves dealing with XML-based metadata. Fortunately, we have a gem called 'om' that can help us deal with XML metadata.
|
170
|
+
To start using it, we need to add it to our Gemfile.
|
171
|
+
}, Thor::Shell::Color::YELLOW
|
172
|
+
|
173
|
+
gem 'om'
|
174
|
+
run 'bundle install'
|
175
|
+
|
176
|
+
say %Q{
|
177
|
+
Now let's adapt our Dataset model to use OM. First we'll add some code that allows us to persist our
|
178
|
+
OM Documents on the filesystem (in db/datasets) and then add a simple OM terminology as a drop-in
|
179
|
+
replacement for the ActiveRecord scaffold object.
|
180
|
+
|
181
|
+
}, Thor::Shell::Color::YELLOW
|
182
|
+
|
183
|
+
run "mkdir db/datasets"
|
184
|
+
copy_file "om_record.rb", "app/models/om_record.rb"
|
185
|
+
|
186
|
+
say %Q{
|
187
|
+
Press 'd' to see the difference between the Rails version and the OM version of Dataset.
|
188
|
+
}, Thor::Shell::Color::YELLOW
|
189
|
+
|
190
|
+
copy_file "dataset_simple_om.rb", "app/models/dataset.rb"
|
191
|
+
|
192
|
+
ask %Q{
|
193
|
+
Take a look around.
|
194
|
+
|
195
|
+
Hit ENTER when you're ready to continue.
|
196
|
+
}, Thor::Shell::Color::GREEN
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
def stop_using_the_filesystem
|
202
|
+
say %Q{
|
203
|
+
Storing the documents on the filesystem has worked so far, but what if we wanted to start
|
204
|
+
managing whole objects (instead of XML documents), version datastream, keep checksums...
|
205
|
+
|
206
|
+
We use Fedora [3], and ActiveFedora to work with data in our repository. We also use Solr to
|
207
|
+
index and provide searching, faceting, etc for our content. For now, you can just concentrate on
|
208
|
+
Fedora. We'll have a section on Solr and discovery interfaces later.
|
209
|
+
|
210
|
+
[3] http://fedora-commons.org
|
211
|
+
}, Thor::Shell::Color::YELLOW
|
212
|
+
|
213
|
+
say %Q{
|
214
|
+
Fedora runs as a java servlet inside a container like Tomcat or Jetty. Hydra provides a bundled
|
215
|
+
version of Fedora and Solr for testing and development.
|
216
|
+
}, Thor::Shell::Color::YELLOW
|
217
|
+
|
218
|
+
say %Q{
|
219
|
+
We'll download a copy now. It may take awhile.
|
220
|
+
}, Thor::Shell::Color::YELLOW
|
221
|
+
unless File.exists? '../jetty'
|
222
|
+
git :clone => 'git://github.com/projecthydra/hydra-jetty.git ../jetty'
|
223
|
+
end
|
224
|
+
run 'cp -R ../jetty jetty'
|
225
|
+
# run 'rake hydra:jetty:config'
|
226
|
+
|
227
|
+
say %Q{
|
228
|
+
Now we're configure it and start the application.
|
229
|
+
}, Thor::Shell::Color::YELLOW
|
230
|
+
rake 'hydra:jetty:config'
|
231
|
+
|
232
|
+
copy_file 'solr.yml', 'config/solr.yml'
|
233
|
+
copy_file 'fedora.yml', 'config/fedora.yml'
|
234
|
+
|
235
|
+
say %Q{
|
236
|
+
And we'll use jettywrapper to help start and stop the service.
|
237
|
+
}, Thor::Shell::Color::YELLOW
|
238
|
+
|
239
|
+
gem 'jettywrapper'
|
240
|
+
run 'bundle install'
|
241
|
+
rake 'jetty:start'
|
242
|
+
|
243
|
+
say %Q{
|
244
|
+
Take a look around. Jetty should be running on port 8983. You can see the Fedora server at
|
245
|
+
|
246
|
+
http://localhost:8983/fedora/
|
247
|
+
|
248
|
+
And a Solr index at
|
249
|
+
|
250
|
+
http://localhost:8983/solr/development/admin/
|
251
|
+
}, Thor::Shell::Color::YELLOW
|
252
|
+
|
253
|
+
ask %Q{
|
254
|
+
Hit ENTER when you're ready to continue.
|
255
|
+
}, Thor::Shell::Color::GREEN
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
def convert_our_model_to_activefedora
|
260
|
+
say %Q{
|
261
|
+
We'll update our Dataset object to use ActiveFedora.
|
262
|
+
}, Thor::Shell::Color::YELLOW
|
263
|
+
|
264
|
+
gem 'active-fedora'
|
265
|
+
run 'bundle install'
|
266
|
+
copy_file "dataset_af_om.rb", "app/models/dataset.rb"
|
267
|
+
|
268
|
+
say %Q{
|
269
|
+
You should be able to create new dataset objects and see them updated in Fedora.
|
270
|
+
}, Thor::Shell::Color::YELLOW
|
271
|
+
|
272
|
+
ask %Q{
|
273
|
+
Hit ENTER when you're ready to continue.
|
274
|
+
}, Thor::Shell::Color::GREEN
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
class Application < Thor::Group
|
279
|
+
include Thor::Actions
|
280
|
+
include Rails::Generators::Actions
|
281
|
+
|
282
|
+
def self.source_paths
|
283
|
+
[File.join($base_templates_path, "application")]
|
284
|
+
end
|
285
|
+
|
286
|
+
# here are some gems that help
|
287
|
+
def add_blacklight_and_hydra
|
288
|
+
say %Q{
|
289
|
+
Eventually, common patterns get packaged up into new gems.
|
290
|
+
}, Thor::Shell::Color::YELLOW
|
291
|
+
|
292
|
+
say %Q{
|
293
|
+
We use blacklight to provide a search interface.
|
294
|
+
}, Thor::Shell::Color::YELLOW
|
295
|
+
|
296
|
+
gem 'blacklight'
|
297
|
+
run 'bundle install'
|
298
|
+
generate 'blacklight', '--devise'
|
299
|
+
|
300
|
+
say %Q{
|
301
|
+
And hydra-head bundles OM, ActiveFedora, etc for us. It also includes things like
|
302
|
+
gated discovery and permissions (through hydra-access-controls).
|
303
|
+
}, Thor::Shell::Color::YELLOW
|
304
|
+
|
305
|
+
gem 'hydra-head', "~> 4.1"
|
306
|
+
run 'bundle install'
|
307
|
+
generate 'hydra:head', 'User'
|
308
|
+
end
|
309
|
+
|
310
|
+
def rake_db_migrate
|
311
|
+
rake 'db:migrate'
|
312
|
+
rake 'db:test:prepare'
|
313
|
+
end
|
314
|
+
|
315
|
+
def install_hydra_jetty
|
316
|
+
if $quick # if we were in quick mode, we skipped this step from before..
|
317
|
+
say %Q{
|
318
|
+
Fedora runs as a java servlet inside a container like Tomcat or Jetty. Hydra provides a bundled
|
319
|
+
version of Fedora and Solr for testing and development.
|
320
|
+
}, Thor::Shell::Color::YELLOW
|
321
|
+
|
322
|
+
say %Q{
|
323
|
+
We'll download a copy now. It may take awhile.
|
324
|
+
}, Thor::Shell::Color::YELLOW
|
325
|
+
|
326
|
+
unless File.exists? '../jetty'
|
327
|
+
git :clone => 'git://github.com/projecthydra/hydra-jetty.git ../jetty'
|
328
|
+
end
|
329
|
+
run 'cp -R ../jetty jetty'
|
330
|
+
|
331
|
+
rake 'hydra:jetty:config'
|
332
|
+
|
333
|
+
gem 'jettywrapper'
|
334
|
+
run 'bundle install'
|
335
|
+
rake 'jetty:start'
|
336
|
+
else
|
337
|
+
|
338
|
+
rake 'jetty:stop'
|
339
|
+
rake 'hydra:jetty:config'
|
340
|
+
rake 'jetty:start'
|
341
|
+
end
|
342
|
+
|
343
|
+
end
|
344
|
+
|
345
|
+
def fixup_ui
|
346
|
+
remove_file 'app/assets/stylesheets/datasets.css.scss'
|
347
|
+
remove_file 'app/assets/stylesheets/scaffolds.css.scss'
|
348
|
+
end
|
349
|
+
|
350
|
+
def fixup_datasets
|
351
|
+
return if $quick
|
352
|
+
say %Q{
|
353
|
+
We need to make a couple of tweaks to our Dataset model and controller in order
|
354
|
+
to make it a Hydra-compliant object.
|
355
|
+
|
356
|
+
Because Hydra enforces access controls in the discovery layer (and, by default, no one
|
357
|
+
has access), we need to teach our model and controller about the Hydra rightsMetadata model
|
358
|
+
and have the controller tell the object who deposited it.
|
359
|
+
}, Thor::Shell::Color::YELLOW
|
360
|
+
|
361
|
+
copy_file "dataset_hydra_om.rb", "app/models/dataset.rb"
|
362
|
+
|
363
|
+
inject_into_class "app/controllers/datasets_controller.rb", 'DatasetsController' do
|
364
|
+
" include Hydra::AssetsControllerHelper\n"
|
365
|
+
end
|
366
|
+
|
367
|
+
insert_into_file "app/controllers/datasets_controller.rb", :after => "@dataset = Dataset.new(params[:dataset])\n" do
|
368
|
+
" apply_depositor_metadata(@dataset)\n"
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
def lets_make_a_better_terminology
|
373
|
+
say %Q{
|
374
|
+
So far, we've been working with a made-up XML schema, however, in the real world, we're probably
|
375
|
+
dealing with more complex data in well-known standards like MODS.
|
376
|
+
|
377
|
+
Now we'll replace our custom schema with a basic MODS schema.
|
378
|
+
}, Thor::Shell::Color::YELLOW
|
379
|
+
copy_file "mods_desc_metadata.rb", "app/models/mods_desc_metadata.rb"
|
380
|
+
copy_file "dataset_hydra_mods_om.rb", "app/models/dataset.rb"
|
381
|
+
end
|
382
|
+
|
383
|
+
end
|
384
|
+
|
385
|
+
class MakeItNice < Thor::Group
|
386
|
+
include Thor::Actions
|
387
|
+
include Rails::Generators::Actions
|
388
|
+
|
389
|
+
def self.source_paths
|
390
|
+
[File.join($base_templates_path, "make_it_nice")]
|
391
|
+
end
|
392
|
+
|
393
|
+
# now we want our app to do stuff.. so lets enhance our old models
|
394
|
+
|
395
|
+
def some_better_views
|
396
|
+
|
397
|
+
end
|
398
|
+
|
399
|
+
def file_uploads
|
400
|
+
|
401
|
+
end
|
402
|
+
|
403
|
+
|
404
|
+
def sprinkle_some_css
|
405
|
+
|
406
|
+
end
|
407
|
+
|
408
|
+
end
|
409
|
+
|
410
|
+
class Tests < Thor::Group
|
411
|
+
include Thor::Actions
|
412
|
+
include Rails::Generators::Actions
|
413
|
+
|
414
|
+
# and write some tests
|
415
|
+
|
416
|
+
end
|
417
|
+
|
418
|
+
class InitialSteps < Thor::Group
|
419
|
+
include Thor::Actions
|
420
|
+
include Rails::Generators::Actions
|
421
|
+
|
422
|
+
# here are some steps you can do to get started
|
423
|
+
def create_a_user_account
|
424
|
+
|
425
|
+
end
|
426
|
+
|
427
|
+
def explore_the_application
|
428
|
+
run 'rails s'
|
429
|
+
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
|
434
|
+
class Cleanup < Thor::Group
|
435
|
+
include Thor::Actions
|
436
|
+
include Rails::Generators::Actions
|
437
|
+
|
438
|
+
# and write some tests
|
439
|
+
#
|
440
|
+
def stop_jetty
|
441
|
+
rake 'jetty:stop'
|
442
|
+
end
|
443
|
+
|
444
|
+
end
|
445
|
+
|
446
|
+
def prerequisites
|
447
|
+
Prerequisites.start
|
448
|
+
end
|
449
|
+
|
450
|
+
def building_a_basic_rails_app
|
451
|
+
return if $quick
|
452
|
+
|
453
|
+
inside 'hydra_tutorial_app' do
|
454
|
+
BuildingABasicRailsApp.start
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
def application
|
459
|
+
inside 'hydra_tutorial_app' do
|
460
|
+
Application.start
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
def make_it_nice
|
465
|
+
return if $quick
|
466
|
+
inside 'hydra_tutorial_app' do
|
467
|
+
MakeItNice.start
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
def tests
|
472
|
+
inside 'hydra_tutorial_app' do
|
473
|
+
Tests.start
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
def initial_steps
|
478
|
+
return if $quick
|
479
|
+
inside 'hydra_tutorial_app' do
|
480
|
+
InitialSteps.start
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
def cleanup
|
485
|
+
yes? "All Done?", Thor::Shell::Color::GREEN
|
486
|
+
inside 'hydra_tutorial_app' do
|
487
|
+
Cleanup.start
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|
492
|
+
|
493
|
+
HydraTutorialApp.start
|