triannon 1.1.0 → 2.0.0

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.
@@ -24,4 +24,4 @@
24
24
  <%= @annotation.jsonld_iiif %>
25
25
  </pre>
26
26
 
27
- <%= link_to "Back to List", annotations_path %>
27
+ <%= link_to "Back to List", annotations_path(anno_root: @annotation.root_container) %>
data/config/routes.rb CHANGED
@@ -1,31 +1,82 @@
1
1
  Triannon::Engine.routes.draw do
2
2
 
3
- resources :annotations, except: [:update, :edit],
4
- # show action must explicitly forbid "new", "iiif" and "oa" as id values; couldn't
5
- # figure out how to do it with regexp constraint since beginning and end regex
6
- # matchers aren't allowed when enforcing formats for segment (e.g. :id)
7
- constraints: lambda { |request|
8
- id = request.env["action_dispatch.request.path_parameters"][:id]
9
- id !~ /^iiif$/ && id !~ /^oa$/ && id !~ /^search$/
10
- } do
11
- collection do
12
- get 'search', to: 'search#find'
13
- end
14
- end
3
+ # 1. can't use resourceful routing because of :anno_root (dynamic path segment)
15
4
 
5
+ # 2. couldn't figure out how to exclude specific values with regexp constraint since beginning and end regex matchers
6
+ # aren't allowed when enforcing formats for path segment (i.e. :anno_root, :id)
7
+
8
+ # get -> new action
9
+ get '/annotations/:anno_root/new', to: 'annotations#new'
10
+ get '/:anno_root/new', to: 'annotations#new',
11
+ constraints: lambda { |request|
12
+ anno_root = request.path_parameters[:anno_root]
13
+ id = request.path_parameters[:id]
14
+ anno_root !~ /^annotations$/ && anno_root !~ /^search$/ && anno_root !~ /^new$/ && id !~ /^search$/ && id !~ /^new$/
15
+ }
16
+
17
+ # get -> search controller find action
18
+ get '/annotations/:anno_root/search', to: 'search#find'
19
+ get '/annotations/search', to: 'search#find'
20
+ get '/:anno_root/search', to: 'search#find',
21
+ constraints: lambda { |request|
22
+ anno_root = request.path_parameters[:anno_root]
23
+ anno_root !~ /^annotations$/ && anno_root !~ /^search$/ && anno_root !~ /^new$/
24
+ }
16
25
  get '/search', to: 'search#find'
17
26
 
18
- root to: 'search#find'
27
+ # get w id -> show action
28
+ get '/annotations/:anno_root/:id(.:format)', to: 'annotations#show',
29
+ constraints: lambda { |request|
30
+ anno_root = request.path_parameters[:anno_root]
31
+ anno_root !~ /^search$/ && anno_root !~ /^new$/
32
+ }
33
+ get '/:anno_root/:id(.:format)', to: 'annotations#show',
34
+ constraints: lambda { |request|
35
+ anno_root = request.path_parameters[:anno_root]
36
+ id = request.path_parameters[:id]
37
+ anno_root !~ /^annotations$/ && anno_root !~ /^search$/ && anno_root !~ /^new$/ && id !~ /^search$/ && id !~ /^new$/
38
+ }
19
39
 
20
- # allow jsonld context in path (only allow iiif or oa as values)
21
- # must explicitly forbid "new" as id values; couldn't figure
22
- # out how to do it with regexp constraint since beginning and end regex
23
- # matchers aren't allowed when enforcing formats for segment (e.g. :id)
24
- get '/annotations/:jsonld_context/:id(.:format)', to: 'annotations#show',
40
+ # get no id -> index action
41
+ get '/annotations/:anno_root', to: 'annotations#index',
25
42
  constraints: lambda { |request|
26
- jsonld_context = request.env["action_dispatch.request.path_parameters"][:jsonld_context]
27
- id = request.env["action_dispatch.request.path_parameters"][:id]
28
- (jsonld_context =~ /^iiif$/ || jsonld_context =~ /^oa$/ ) && id !~ /^new$/
29
- }
43
+ anno_root = request.path_parameters[:anno_root]
44
+ anno_root !~ /^search$/ && anno_root !~ /^new$/
45
+ }
46
+ get '/:anno_root', to: 'annotations#index',
47
+ constraints: lambda { |request|
48
+ anno_root = request.path_parameters[:anno_root]
49
+ anno_root !~ /^annotations$/ && anno_root !~ /^search$/ && anno_root !~ /^new$/
50
+ }
51
+
52
+ # post -> create action
53
+ post '/annotations/:anno_root', to: 'annotations#create',
54
+ constraints: lambda { |request|
55
+ anno_root = request.path_parameters[:anno_root]
56
+ id = request.path_parameters[:id]
57
+ anno_root !~ /^search$/ && anno_root !~ /^new$/ && id !~ /^search$/ && id !~ /^new$/
58
+ }
59
+ post '/:anno_root', to: 'annotations#create',
60
+ constraints: lambda { |request|
61
+ anno_root = request.path_parameters[:anno_root]
62
+ anno_root !~ /^annotations$/ && anno_root !~ /^search$/ && anno_root !~ /^new$/
63
+ }
64
+
65
+ # delete -> destroy action
66
+ delete '/annotations/:anno_root/:id(.:format)', to: 'annotations#destroy',
67
+ constraints: lambda { |request|
68
+ anno_root = request.path_parameters[:anno_root]
69
+ id = request.path_parameters[:id]
70
+ anno_root !~ /^search$/ && anno_root !~ /^new$/ && id !~ /^search$/ && id !~ /^new$/
71
+ }
72
+ delete '/:anno_root/:id(.:format)', to: 'annotations#destroy',
73
+ constraints: lambda { |request|
74
+ anno_root = request.path_parameters[:anno_root]
75
+ anno_root !~ /^annotations$/ && anno_root !~ /^search$/ && anno_root !~ /^new$/
76
+ }
77
+
78
+
79
+ get '/annotations', to: 'search#find'
80
+ root to: 'search#find'
30
81
 
31
82
  end
@@ -0,0 +1,25 @@
1
+ # Logging level
2
+ solr.log=logs/
3
+ log4j.rootLogger=INFO, file, CONSOLE
4
+
5
+ # Log warnings to the console
6
+ log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
7
+ log4j.appender.CONSOLE.Threshold=WARN
8
+ log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
9
+ log4j.appender.CONSOLE.layout.ConversionPattern=%-4r [%t] %-5p %c %x \u2013 %m%n
10
+
11
+ #- size rotation with log cleanup.
12
+ log4j.appender.file=org.apache.log4j.RollingFileAppender
13
+ log4j.appender.file.MaxFileSize=4MB
14
+ log4j.appender.file.MaxBackupIndex=9
15
+
16
+ #- File to log to and log format
17
+ log4j.appender.file.File=${solr.log}/solr.log
18
+ log4j.appender.file.layout=org.apache.log4j.PatternLayout
19
+ log4j.appender.file.layout.ConversionPattern=%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS}; %C; %m\n
20
+
21
+ log4j.logger.org.apache.zookeeper=WARN
22
+ log4j.logger.org.apache.hadoop=WARN
23
+
24
+ # set to INFO to enable infostream log messages
25
+ log4j.logger.org.apache.solr.update.LoggingInfoStream=OFF
data/config/solr/solr.xml CHANGED
@@ -29,8 +29,10 @@
29
29
  If 'null' (or absent), cores will not be manageable via REST
30
30
  -->
31
31
  <cores adminPath="/admin/cores" defaultCoreName="development">
32
+ <!-- don't need development or test cores for triannon
32
33
  <core name="development" instanceDir="development-core" />
33
34
  <core name="test" instanceDir="test-core" />
35
+ -->
34
36
  <core name="triannon" instanceDir="triannon-core" />
35
37
  </cores>
36
38
  </solr>
@@ -10,6 +10,8 @@
10
10
  <field name="id" type="string" stored="true" indexed="true" multiValued="false" required="true"/>
11
11
  <field name="timestamp" type="date" stored="true" indexed="true" multiValued="false" default="NOW"/>
12
12
 
13
+ <field name="root" type="string" stored="true" indexed="true" multiValued="false"/>
14
+
13
15
  <field name="motivation" type="string" stored="true" indexed="true" multiValued="true"/>
14
16
  <!-- date field format: 1995-12-31T23:59:59Z; or w fractional seconds: 1995-12-31T23:59:59.999Z -->
15
17
  <field name="annotated_at" type="date" stored="true" indexed="true" multiValued="false"/>
@@ -4,11 +4,15 @@
4
4
  this file, see http://wiki.apache.org/solr/SolrConfigXml.
5
5
  -->
6
6
  <config>
7
- <luceneMatchVersion>4.7</luceneMatchVersion>
7
+ <luceneMatchVersion>4.10.4</luceneMatchVersion>
8
+
9
+ <!-- solr lib dirs -->
10
+ <lib dir="../lib/contrib/analysis-extras/lib" />
11
+ <lib dir="../lib/contrib/analysis-extras/lucene-libs" />
8
12
 
9
13
  <dataDir>${solr.data.dir:}</dataDir>
10
14
 
11
- <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>
15
+ <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>
12
16
  <codecFactory class="solr.SchemaCodecFactory"/>
13
17
  <schemaFactory class="ClassicIndexSchemaFactory"/>
14
18
 
@@ -24,7 +28,7 @@
24
28
  <str name="dir">${solr.data.dir:}</str>
25
29
  </updateLog>
26
30
  <autoCommit>
27
- <maxTime>15000</maxTime>
31
+ <maxTime>3000</maxTime>
28
32
  <openSearcher>false</openSearcher>
29
33
  </autoCommit>
30
34
  </updateHandler>
@@ -42,21 +46,23 @@
42
46
  It should only have the most common facets -->
43
47
  <listener event="newSearcher" class="solr.QuerySenderListener">
44
48
  <arr name="queries">
45
- <lst>
49
+ <lst>
46
50
  <!-- default query for all objects: populate facet caches -->
47
51
  <int name="rows">0</int>
48
52
  <str name="fl">score</str>
49
53
  <bool name="facet">true</bool>
50
54
  <int name="facet.mincount">1</int>
55
+ <str name="facet.field">root</str>
56
+ <str name="f.root.facet.method">enum</str>
51
57
  <str name="facet.field">motivation</str>
52
- <str name="f.motivation.facet.method">enum</str>
58
+ <str name="f.motivation.facet.method">enum</str>
53
59
  <str name="facet.field">target_type</str>
54
60
  <str name="f.target_type.facet.method">enum</str>
55
61
  <str name="facet.field">body_type</str>
56
62
  <str name="f.body_type.facet.method">enum</str>
57
63
  <str name="facet.field">annotated_at_tdate</str>
58
64
  </lst>
59
- <lst>
65
+ <lst>
60
66
  <!-- single object query: populate filter and fieldValue caches -->
61
67
  <str name="q">id:a*</str>
62
68
  <str name="defType">lucene</str>
@@ -64,11 +70,13 @@
64
70
  <str name="fl">score</str>
65
71
  <bool name="facet">true</bool>
66
72
  <int name="facet.mincount">1</int>
73
+ <str name="facet.field">root</str>
74
+ <str name="f.root.facet.method">enum</str>
67
75
  <str name="facet.field">motivation</str>
68
76
  <str name="f.motivation.facet.method">enum</str>
69
77
  <str name="facet.field">target_type</str>
70
78
  <str name="f.target_type.facet.method">enum</str>
71
- <str name="facet.field">body_type</str>
79
+ <str name="facet.field">body_type</str>
72
80
  <str name="f.body_type.facet.method">enum</str>
73
81
  <str name="facet.field">annotated_at_tdate</str>
74
82
  </lst>
@@ -78,20 +86,22 @@
78
86
  <!-- A First Searcher is opened when there is _no_ existing (current) Searcher. ("fast warmup") -->
79
87
  <listener event="firstSearcher" class="solr.QuerySenderListener">
80
88
  <arr name="queries">
81
- <lst>
89
+ <lst>
82
90
  <!-- default query for all objects: populate facet caches -->
83
91
  <int name="rows">0</int>
84
92
  <str name="fl">score</str>
85
93
  <bool name="facet">true</bool>
86
94
  <int name="facet.mincount">1</int>
95
+ <str name="facet.field">root</str>
96
+ <str name="f.root.facet.method">enum</str>
87
97
  <str name="facet.field">motivation</str>
88
98
  <str name="f.motivation.facet.method">enum</str>
89
99
  <str name="facet.field">target_type</str>
90
100
  <str name="f.target_type.facet.method">enum</str>
91
- <str name="facet.field">body_type</str>
101
+ <str name="facet.field">body_type</str>
92
102
  <str name="f.body_type.facet.method">enum</str>
93
103
  </lst>
94
- <lst>
104
+ <lst>
95
105
  <!-- single object query: populate filter and fieldValue caches -->
96
106
  <str name="q">id:a*</str>
97
107
  <str name="defType">lucene</str>
@@ -99,11 +109,13 @@
99
109
  <str name="fl">score</str>
100
110
  <bool name="facet">true</bool>
101
111
  <int name="facet.mincount">1</int>
112
+ <str name="facet.field">root</str>
113
+ <str name="f.root.facet.method">enum</str>
102
114
  <str name="facet.field">motivation</str>
103
115
  <str name="f.motivation.facet.method">enum</str>
104
116
  <str name="facet.field">target_type</str>
105
117
  <str name="f.target_type.facet.method">enum</str>
106
- <str name="facet.field">body_type</str>
118
+ <str name="facet.field">body_type</str>
107
119
  <str name="f.body_type.facet.method">enum</str>
108
120
  </lst>
109
121
  </arr>
@@ -123,9 +135,9 @@
123
135
  <requestHandler name="/select" class="solr.SearchHandler" default="true">
124
136
  <lst name="defaults">
125
137
  <str name="echoParams">explicit</str>
126
- <str name="sort">score desc, annotated_at_tdate desc</str>
127
- <int name="rows">20</int>
128
- <str name="fl">* score</str>
138
+ <str name="sort">score desc, annotated_at_tdate desc</str>
139
+ <int name="rows">2500</int>
140
+ <str name="fl">* score</str>
129
141
  <str name="wt">ruby</str>
130
142
  <str name="indent">true</str>
131
143
 
@@ -140,46 +152,48 @@
140
152
  <str name="df">anno_jsonld</str>
141
153
  <str name="q.op">AND</str>
142
154
 
143
- <str name="qf">
155
+ <str name="qf">
144
156
  body_chars_exact^3
145
157
  body_chars_unstem^2
146
158
  body_chars_stem
147
- annotated_by_unstem^2
148
- annotated_by_stem
149
- target_url
150
- body_url
151
- motivation
152
- id
153
- </str>
154
- <str name="pf"> <!-- (phrase boost within result set) -->
155
- body_chars_exact^15
159
+ annotated_by_unstem^2
160
+ annotated_by_stem
161
+ target_url
162
+ body_url
163
+ motivation
164
+ id
165
+ </str>
166
+ <str name="pf"> <!-- (phrase boost within result set) -->
167
+ body_chars_exact^15
156
168
  body_chars_unstem^10
157
169
  body_chars_stem^5
158
170
  annotated_by_unstem^10
159
171
  annotated_by_stem^5
160
- </str>
161
- <str name="pf3"> <!-- (token trigrams boost within result set) -->
172
+ </str>
173
+ <str name="pf3"> <!-- (token trigrams boost within result set) -->
162
174
  body_chars_exact^9
163
175
  body_chars_unstem^6
164
176
  body_chars_stem^3
165
177
  annotated_by_unstem^6
166
178
  annotated_by_stem^3
167
- </str>
168
- <str name="pf2"> <!--(token bigrams boost within result set) -->
179
+ </str>
180
+ <str name="pf2"> <!--(token bigrams boost within result set) -->
169
181
  body_chars_exact^6
170
182
  body_chars_unstem^4
171
183
  body_chars_stem^2
172
184
  annotated_by_unstem^4
173
185
  annotated_by_stem^2
174
- </str>
186
+ </str>
175
187
 
176
- <bool name="facet">true</bool>
188
+ <bool name="facet">true</bool>
177
189
  <int name="facet.mincount">1</int>
190
+ <str name="facet.field">root</str>
191
+ <str name="f.root.facet.method">enum</str>
178
192
  <str name="facet.field">motivation</str>
179
193
  <str name="f.motivation.facet.method">enum</str>
180
194
  <str name="facet.field">target_type</str>
181
195
  <str name="f.target_type.facet.method">enum</str>
182
- <str name="facet.field">body_type</str>
196
+ <str name="facet.field">body_type</str>
183
197
  <str name="f.body_type.facet.method">enum</str>
184
198
  <str name="facet.field">annotated_at_tdate</str>
185
199
 
@@ -191,7 +205,7 @@
191
205
  <lst name="defaults">
192
206
  <str name="echoParams">explicit</str>
193
207
  <str name="fl">*</str>
194
- <int name="rows">1</int>
208
+ <int name="rows">10</int> <!-- just in case; expecting 1 -->
195
209
  <str name="q">{!raw f=id v=$id}</str> <!-- use id=666 instead of q=id:666 -->
196
210
  <str name="wt">ruby</str>
197
211
  <str name="indent">true</str>
@@ -236,4 +250,3 @@
236
250
  </admin>
237
251
 
238
252
  </config>
239
-
@@ -1,25 +1,47 @@
1
1
  require_relative '../../app/services/triannon/ldp_writer'
2
2
 
3
3
  namespace :triannon do
4
- desc "set up jetty for triannon"
5
- task :jetty_setup => [:solr_jetty_setup, :disable_fedora_auth_in_jetty]
4
+ desc "clean out then reset jetty from scratch for Triannon - starts jetty"
5
+ task :jetty_reset => ['jetty:stop', 'jetty:clean', 'jetty:environment', :jetty_config, 'jetty:start']
6
6
 
7
- desc "set up triannon Solr in jetty"
8
- task :solr_jetty_setup do
7
+ desc "configure Fedora and Solr in jetty for triannon"
8
+ task :jetty_config => [:solr_jetty_config, :disable_fedora_auth_in_jetty]
9
+
10
+ # don't display this in rake -T
11
+ #desc "set up triannon core in jetty Solr"
12
+ task :solr_jetty_config do
9
13
  `cp -r config/solr/triannon-core jetty/solr`
10
14
  `cp config/solr/solr.xml jetty/solr`
15
+ `cp config/solr/log4j.properties jetty/resources`
11
16
  end
12
17
 
13
- desc "disable fedora basic authorization in jetty"
18
+ # don't display this in rake -T
19
+ #desc "disable fedora basic authorization in jetty"
14
20
  task :disable_fedora_auth_in_jetty do
15
21
  `cp config/jetty/etc/* jetty/etc`
16
22
  end
17
23
 
18
- desc 'Create the uber root annotation container'
24
+
25
+ # ------- root container tasks ----------
26
+
27
+ # don't display this in rake -T
28
+ #desc 'ONLY WORKS WITHIN RAILS APP: Create the uber root annotation container per triannon.yml'
19
29
  task :create_uber_root_container do
20
30
  unless File.exist? Triannon.triannon_file
21
- puts "Triannon config file missing: #{Triannon.triannon_file}"
31
+ puts "ERROR: Triannon config file missing: #{Triannon.triannon_file} - are you in the rails app root directory?"
32
+ raise "Triannon config file missing: #{Triannon.triannon_file}"
22
33
  end
23
34
  Triannon::LdpWriter.create_basic_container(nil, Triannon.config[:ldp]['uber_container'])
24
35
  end
25
- end
36
+
37
+ desc "ONLY WORKS WITHIN RAILS APP: Create root anno containers per triannon.yml"
38
+ task :create_root_containers => :create_uber_root_container do
39
+ unless File.exist? Triannon.triannon_file
40
+ puts "ERROR: Triannon config file missing: #{Triannon.triannon_file} - are you in the rails app root directory?"
41
+ raise "Triannon config file missing: #{Triannon.triannon_file}"
42
+ end
43
+ Triannon.config[:ldp]['anno_containers'].each { |container_name|
44
+ Triannon::LdpWriter.create_basic_container(Triannon.config[:ldp]['uber_container'], container_name)
45
+ }
46
+ end
47
+ end # namespace triannon
data/lib/triannon.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'linkeddata'
2
2
  require 'oa/graph'
3
- require 'rdf/iiif'
4
3
  require 'rdf/triannon_vocab'
5
4
  require 'bootstrap-sass'
6
5
  require 'faraday' # for writing to LDP store
@@ -9,6 +9,20 @@ module Triannon
9
9
  end
10
10
  end
11
11
 
12
+ # general error for LDP anno root container issues
13
+ class LDPContainerError < Triannon::Error
14
+ def initialize(message = nil)
15
+ super(message)
16
+ end
17
+ end
18
+
19
+ # used when LDP anno root container doesn't exist
20
+ class MissingLDPContainerError < Triannon::LDPContainerError
21
+ def initialize(message = nil)
22
+ super(message)
23
+ end
24
+ end
25
+
12
26
  # used to keep HTTP response info from LDP
13
27
  class LDPStorageError < Triannon::Error
14
28
  attr_accessor :ldp_resp_status, :ldp_resp_body
@@ -1,3 +1,3 @@
1
1
  module Triannon
2
- VERSION = "1.1.0"
2
+ VERSION = "2.0.0"
3
3
  end