cul_scv_hydra 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,17 +1,7 @@
1
- require "active-fedora"
2
- require "active_fedora_finders"
3
- require "hydra-core"
4
- class BagAggregator < ::ActiveFedora::Base
5
- extend ActiveModel::Callbacks
6
- include ::ActiveFedora::Finders
7
- include ::ActiveFedora::DatastreamCollections
8
- include ::Hydra::ModelMethods
9
- include Cul::Scv::Hydra::Models::Common
10
- include Cul::Scv::Hydra::Models::Aggregator
11
-
12
- alias :file_objects :resources
1
+ class BagAggregator < GenericAggregator
13
2
 
14
3
  def route_as
15
4
  "collection"
16
5
  end
6
+
17
7
  end
@@ -8,9 +8,12 @@ module Hydra
8
8
  module Models
9
9
  AGGREGATOR_TYPE = (URI.parse("http://purl.oclc.org/NET/CUL/Aggregator"))
10
10
  RESOURCE_TYPE = (URI.parse("http://purl.oclc.org/NET/CUL/Resource"))
11
- MEMBER_QUERY = <<-SPARQL
11
+ MEMBER_SPARQL = <<-SPARQL
12
12
  SELECT ?pid WHERE { ?pid <http://purl.oclc.org/NET/CUL/memberOf> <info:fedora/%PID%> }
13
13
  SPARQL
14
+ MEMBER_ITQL = <<-ITQL
15
+ select $pid from <#ri> where $pid <http://purl.oclc.org/NET/CUL/memberOf> <info:fedora/%PID%>
16
+ ITQL
14
17
  end
15
18
  end
16
19
  end
@@ -3,8 +3,8 @@ module Aggregator
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
+ has_and_belongs_to_many :containers, :property=>:cul_member_of, :class_name=>'ActiveFedora::Base'
6
7
  has_metadata :name => "structMetadata", :type=>Cul::Scv::Hydra::Datastreams::StructMetadata, :versionable => true, :controlGroup => 'M'
7
- has_many :parts, :property => :cul_member_of, :class_name=>'ActiveFedora::Base'
8
8
  after_create :aggregator!
9
9
  end
10
10
 
@@ -30,7 +30,98 @@ module Aggregator
30
30
  member.save
31
31
  end
32
32
 
33
+ def solr_members(opts={})
34
+ opts = {:rows=>25,:response_format=>:solr}.merge(opts)
35
+ self.parts(opts)
36
+ #opts = {:rows=>25,:response_format=>:solr}.merge(opts)
37
+ #query = self.class.inbound_relationship_query(self.pid, "parts")
38
+ #solr_result = ::ActiveFedora::SolrService.instance.conn.query(query, :rows=>opts[:rows])
39
+ #if opts[:response_format] == :solr
40
+ # return solr_result
41
+ #else
42
+ # if opts[:response_format] == :id_array
43
+ # id_array = []
44
+ # solr_result.hits.each do |hit|
45
+ # id_array << hit[SOLR_DOCUMENT_ID]
46
+ # end
47
+ # return id_array
48
+ # elsif opts[:response_format] == :load_from_solr || self.load_from_solr
49
+ # return ::ActiveFedora::SolrService.reify_solr_results(solr_result,{:load_from_solr=>true})
50
+ # else
51
+ # return ::ActiveFedora::SolrService.reify_solr_results(solr_result)
52
+ # end
53
+ #end
54
+ end
55
+
56
+ def members(opts={})
57
+ solr_members(opts)
58
+ end
59
+
60
+ def members_ids(opts={})
61
+ opts = opts.merge({:response_format=>:id_array})
62
+ solr_members(opts)
63
+ end
64
+
65
+ def thumbnail_info
66
+ r = self.parts.reader(:response_format => :solr)
67
+ members = []
68
+ r.collect {|hit| members << SolrDocument.new(hit) } unless r.blank?
69
+ if members.length == 0
70
+ return {:asset=>"cul_scv_hydra/crystal/file.png",:mime=>'image/png'}
71
+ else
72
+ thumb = nil
73
+ unless datastreams['structMetadata'].new?
74
+ thumb = thumb_from_struct(members)
75
+ else
76
+ thumb = thumb_from_members(members)
77
+ end
78
+ end
79
+ return thumb || {:asset=>"cul_scv_hydra/crystal/file.png",:mime=>'image/png'}
80
+ end
81
+
33
82
  private
83
+ def thumb_from_struct(members)
84
+ sm = datastreams['structMetadata']
85
+ first = sm.divs_with_attribute(false,'ORDER','1').first
86
+ if first
87
+ members.each do |member|
88
+ if member["identifier_ssim"].include? first["CONTENTIDS"]
89
+ return thumb_from_solr_doc(member)
90
+ end
91
+ end
92
+ return nil
93
+ else
94
+ return nil
95
+ end
96
+ end
97
+
98
+ def thumb_from_members(members)
99
+ sorted = members.sort do |a,b|
100
+ c = a['title_si'] <=> b['title_si']
101
+ if c == 0 && a['identifier_ssim']
102
+ if b['identifier_ssim']
103
+ a['identifier_ssim'].delete(a.id) unless a['identifier_ssim'].length == 1
104
+ b['identifier_ssim'].delete(a.id) unless b['identifier_ssim'].length == 1
105
+ a['identifier_ssim'][0] <=> b['identifier_ssim'][0]
106
+ else
107
+ -1
108
+ end
109
+ else
110
+ c
111
+ end
112
+ end
113
+ thumb_from_solr_doc(sorted[0])
114
+ end
115
+
116
+ def thumb_from_solr_doc(solr_doc)
117
+ if solr_doc and (member = ActiveFedora::Base.find(solr_doc.id, :cast=>true)).respond_to? :thumbnail_info
118
+ puts "thumb: " + (thumb = member.thumbnail_info).inspect
119
+ thumb
120
+ else
121
+ return nil
122
+ end
123
+ end
124
+
34
125
  def to_uri(obj)
35
126
  if obj.respond_to? :internal_uri
36
127
  return obj.internal_uri
@@ -3,15 +3,10 @@ require 'uri'
3
3
  module Cul::Scv::Hydra::Models
4
4
  module Common
5
5
  extend ActiveSupport::Concern
6
- DC_SPEC = {
7
- :name => "DC", :type=>Cul::Scv::Hydra::Datastreams::DCMetadata,
8
- :versionable => true, :label => 'Dublin Core Record for this object'
9
- }
6
+
10
7
  included do
11
8
  define_model_callbacks :create
12
- has_and_belongs_to_many :containers, :property=>:cul_member_of, :class_name=>'ActiveFedora::Base'
13
9
  has_metadata :name => "DC", :type=>Cul::Scv::Hydra::Datastreams::DCMetadata, :versionable => true
14
- #self.ds_specs['DC'] = DC_SPEC
15
10
  has_metadata :name => "descMetadata", :type=>Cul::Scv::Hydra::Datastreams::ModsDocument, :versionable => true
16
11
  has_metadata :name => "rightsMetadata", :type=>::Hydra::Datastream::RightsMetadata, :versionable => true
17
12
 
@@ -22,30 +17,6 @@ module Common
22
17
  'ldpd'
23
18
  end
24
19
 
25
- # override a buggy impl in AF
26
- def has_datastream(args)
27
- unless args.has_key?(:name)
28
- return false
29
- end
30
- unless args.has_key?(:prefix)
31
- args.merge!({:prefix=>args[:name].to_s.upcase})
32
- end
33
- unless class_named_datastreams_desc.has_key?(args[:name])
34
- class_named_datastreams_desc[args[:name]] = {}
35
- end
36
-
37
- args.merge!({:mimeType=>args[:mime_type]}) if args.has_key?(:mime_type)
38
-
39
- unless class_named_datastreams_desc[args[:name]].has_key?(:type)
40
- #default to type ActiveFedora::Datastream
41
- args[:type] ||= ActiveFedora::Datastream
42
- end
43
- args[:type] = args[:type].constantize if args[:type].is_a? String
44
- raise args[:type] unless args[:type].name
45
- class_named_datastreams_desc[args[:name]]= args
46
- create_named_datastream_finders(args[:name],args[:prefix])
47
- create_named_datastream_update_methods(args[:name])
48
- end
49
20
  end
50
21
 
51
22
  def rdf_type
@@ -63,44 +34,6 @@ module Common
63
34
  super
64
35
  end
65
36
  end
66
-
67
- def resources(opts={})
68
- if self.respond_to? :parts # aggregator
69
- opts = {:rows=>25,:response_format=>:solr}.merge(opts)
70
- self.parts(opts)
71
- #opts = {:rows=>25,:response_format=>:solr}.merge(opts)
72
- #query = self.class.inbound_relationship_query(self.pid, "parts")
73
- #solr_result = ::ActiveFedora::SolrService.instance.conn.query(query, :rows=>opts[:rows])
74
- #if opts[:response_format] == :solr
75
- # return solr_result
76
- #else
77
- # if opts[:response_format] == :id_array
78
- # id_array = []
79
- # solr_result.hits.each do |hit|
80
- # id_array << hit[SOLR_DOCUMENT_ID]
81
- # end
82
- # return id_array
83
- # elsif opts[:response_format] == :load_from_solr || self.load_from_solr
84
- # return ::ActiveFedora::SolrService.reify_solr_results(solr_result,{:load_from_solr=>true})
85
- # else
86
- # return ::ActiveFedora::SolrService.reify_solr_results(solr_result)
87
- # end
88
- #end
89
- else
90
- logger.warn 'parts not defined; was this an Aggregator?'
91
- []
92
- end
93
- end
94
-
95
- def members(opts={})
96
- resources(opts)
97
- end
98
-
99
- def members_ids(opts={})
100
- opts = opts.merge({:response_format=>:id_array})
101
- resources(opts)
102
- end
103
-
104
37
 
105
38
  def cmodel_pid(klass)
106
39
  klass.pid_namespace + ":" + klass.name.split("::")[-1]
@@ -129,23 +62,6 @@ module Common
129
62
  "default"
130
63
  end
131
64
 
132
- def index_type_label
133
- riquery = Cul::Scv::Hydra::Models::MEMBER_QUERY.gsub(/%PID%/, self.pid)
134
- begin
135
- docs = ::ActiveFedora::Base.connection_for_pid(self.pid).find_by_sparql riquery
136
- rescue Exception=>e
137
- docs = self.parts
138
- end
139
- if docs.size == 0
140
- label = "EMPTY"
141
- elsif docs.size == 1
142
- label = "SINGLE PART"
143
- else
144
- label = "MULTIPART"
145
- end
146
- label
147
- end
148
-
149
65
  def has_desc?
150
66
  has_desc = false
151
67
  begin
@@ -159,7 +75,7 @@ module Common
159
75
  end
160
76
 
161
77
  def to_solr(solr_doc = Hash.new, opts={})
162
- super
78
+ solr_doc = super(solr_doc, opts)
163
79
  if has_desc?
164
80
  solr_doc["descriptor_ssi"] = ["mods"]
165
81
  else
@@ -0,0 +1,80 @@
1
+ module Cul::Scv::Hydra::Models
2
+ module ImageResource
3
+ IMAGE_EXT = {"image/bmp" => 'bmp', "image/gif" => 'gif', "image/jpeg" => 'jpg', "image/png" => 'png', "image/tiff" => 'tif', "image/x-windows-bmp" => 'bmp', 'image/jp2' => 'jp2'}
4
+ WIDTH = RDF::URI(ActiveFedora::Predicates.find_graph_predicate(:image_width))
5
+ LENGTH = RDF::URI(ActiveFedora::Predicates.find_graph_predicate(:image_length))
6
+ WIDTH_PREDICATE = ActiveFedora::Predicates.short_predicate("http://www.w3.org/2003/12/exif/ns#imageWidth").to_s
7
+ LENGTH_PREDICATE = ActiveFedora::Predicates.short_predicate("http://www.w3.org/2003/12/exif/ns#imageLength").to_s
8
+ EXTENT_PREDICATE = ActiveFedora::Predicates.short_predicate("http://purl.org/dc/terms/extent").to_s
9
+ FORMAT_OF_PREDICATE = ActiveFedora::Predicates.short_predicate("http://purl.org/dc/terms/isFormatOf").to_s
10
+ FORMAT_URI = RDF::URI("http://purl.org/dc/terms/format")
11
+
12
+ DJATOKA_THUMBNAIL_PARMS = {
13
+ "url_ver" => "Z39.88-2004",
14
+ "svc_id" => "info:lanl-repo/svc/getRegion",
15
+ "svc_val_fmt" => "info:ofi/fmt:kev:mtx:jpeg2000",
16
+ "svc.format" => "image/jpeg",
17
+ "svc.level" => "",
18
+ "svc.rotate" => "0",
19
+ "svc.scale" => "200",
20
+ "svc.clayers" => ""
21
+ }
22
+
23
+ DJATOKA_BASE_URL = "http://iris.cul.columbia.edu:8888/resolve"
24
+
25
+ def long
26
+ @long_side ||= max(width(), length())
27
+ end
28
+
29
+ def width
30
+ @width ||= begin
31
+ ds = datastreams["content"]
32
+ width = 0
33
+ unless ds.nil? or rels_int.relationships(ds,:exif_image_width).blank?
34
+ width = rels_int.relationships(ds,:exif_image_width).first.object.to_s.to_i
35
+ end
36
+ width = relationships(:image_width).first.to_s.to_i if width == 0
37
+ width
38
+ end
39
+ end
40
+
41
+ def length
42
+ @length ||= begin
43
+ ds = datastreams["content"]
44
+ length = 0
45
+ unless ds.nil? or rels_int.relationships(ds,:exif_image_length).blank?
46
+ length = rels_int.relationships(ds,:exif_image_length).first.object.to_s.to_i
47
+ end
48
+ length = relationships(:image_length).first.to_s.to_i if length == 0
49
+ length
50
+ end
51
+ end
52
+
53
+ def zooming?
54
+ zoom = rels_int.relationships(datastreams['content'],:foaf_zooming).first
55
+ return zoom.object.to_s if zoom
56
+ datastreams.each do |k,v|
57
+ if v.mimeType =~ /image\/jp2$/i
58
+ zoom = "info:fedora/#{k.dsid}"
59
+ end
60
+ end
61
+ return zoom
62
+ end
63
+
64
+ def thumbnail_info
65
+ thumb = rels_int.relationships(datastreams['content'],:foaf_thumbnail).first
66
+ if thumb
67
+ t_dsid = thumb.object.to_s.split('/')[-1]
68
+ t_url = "#{ActiveFedora.fedora_config.credentials[:url]}/objects/#{pid}/datastreams/#{t_dsid}/content"
69
+ return {:url=>t_url,:mime=>datastreams[t_dsid].mimeType}
70
+ elsif (zoom = self.zooming?)
71
+ t_dsid = zoom.split('/')[-1]
72
+ t_parms = DJATOKA_THUMBNAIL_PARMS.merge({"rft_id" => datastreams[t_dsid].dsLocation})
73
+ url = "#{DJATOKA_BASE_URL}?#{options.map { |key, value| "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}"}.join("&") }"
74
+ {:url => url, :mime => t_parms["svc.format"]}
75
+ else
76
+ return {:asset=>"cul_scv_hydra/crystal/file.png",:mime=>'image/png'}
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,111 @@
1
+ module Cul::Scv::Hydra::Models
2
+ module LinkableResources
3
+ include Cul::Scv::Fedora::UrlHelperBehavior
4
+ # so as to avoid including all the url hepers via:
5
+ ## include Rails.application.routes.url_helpers
6
+ # we are just going to delegate
7
+ delegate :fedora_content_path, :to => 'Rails.application.routes.url_helpers'
8
+ delegate :cache_path, :to => 'Rails.application.routes.url_helpers'
9
+
10
+ def http_client
11
+ unless @http_client
12
+ @http_client ||= HTTPClient.new
13
+ @http_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
14
+ uname = Cul::Scv::Fedora.repository.config[:user]
15
+ pwd = Cul::Scv::Fedora.repository.config[:password]
16
+ @http_client.set_auth(nil, uname, pwd)
17
+ end
18
+ @http_client
19
+ end
20
+
21
+ def linkable_resources
22
+ r = self.parts(:response_format => :solr)
23
+ return [] if r.blank?
24
+ members = r.collect {|hit|
25
+ SolrDocument.new(hit)
26
+ }
27
+ members.delete_if { |sd| (sd[:has_model_ssim] & ["info:fedora/ldpd:Resource"]).blank? }
28
+ case self.route_as
29
+ when "zoomingimage"
30
+ results = members.collect {|doc| image_resource(doc)}
31
+ base_id = self.pid
32
+ url = fedora_ds_url(base_id, 'SOURCE') + '/content'
33
+ head_req = http_client().head(url)
34
+ file_size = head_req.header["Content-Length"].first.to_i
35
+ results << {
36
+ :dimensions => "Original",
37
+ :mime_type => "image/jp2",
38
+ :uri=>base_id, :block=>"SOURCE", :filename=>base_id + "_source.jp2",
39
+ :content_models=>[]}
40
+ when "audio"
41
+ results = members.collect {|doc| audio_resource(doc)}
42
+ when "image"
43
+ results = members.collect {|doc| image_resource(doc)}
44
+ else
45
+ raise "Unknown format #{self.route_as}"
46
+ end
47
+ return results
48
+ end
49
+
50
+ def basic_resource(document)
51
+ res = {}
52
+ res[:pid] = document["id"]
53
+ res[:dsid] = "CONTENT"
54
+ res[:mime_type] = document["dc_format_ssm"] ? document["dc_format_ssm"].first : "application/octect-stream"
55
+ res[:content_models] = document["has_model_ssim"]
56
+ res[:file_size] = document["extent_ssim"].first.to_i
57
+ res[:size] = (document["extent_ssim"].first.to_i / 1024).to_s + " Kb"
58
+ res
59
+ end
60
+
61
+ def image_resource(document)
62
+ res = basic_resource(document)
63
+ if document["image_width_ssim"]
64
+ res[:dimensions] = document["image_width_ssim"].first + " x " + document["image_length_ssim"].first
65
+ res[:width] = document["image_width_ssim"].first
66
+ res[:height] = document["image_length_ssim"].first
67
+ else
68
+ res[:dimensions] = "? x ?"
69
+ res[:width] = "0"
70
+ res[:height] = "0"
71
+ end
72
+ base_id = document["id"]
73
+ base_filename = base_id.gsub(/\:/,"")
74
+ img_filename = base_filename + "." + document["dc_format_ssm"].first.gsub(/^[^\/]+\//,"")
75
+ res[:filename] = img_filename
76
+ res[:block] = "CONTENT"
77
+ res[:mime_type] = document["dc_format_ssm"] ? document["dc_format_ssm"].first : "application/octect-stream"
78
+ res[:content_models] = document["has_model_ssim"]
79
+ res[:file_size] = document["extent_ssim"].first.to_i
80
+ res[:size] = (document["extent_ssim"].first.to_i / 1024).to_s + " Kb"
81
+ res[:uri] = base_id
82
+ res
83
+ end
84
+
85
+ def audio_resource(document)
86
+ res = basic_resource(document)
87
+ base_id = document["id"]
88
+ base_filename = base_id.gsub(/\:/,"")
89
+ if res[:mime_type] =~ /wav/
90
+ ext = 'wav'
91
+ elsif res[:mime_type] =~ /mpeg/
92
+ ext = 'mp3'
93
+ else
94
+ ext = 'bin'
95
+ end
96
+ filename = base_filename + "." + ext
97
+ dc_filename = base_filename + "_dc.xml"
98
+ res[:uri] = base_id
99
+ res[:block] = "CONTENT"
100
+ res[:filename] = filename
101
+ res[:dc_path] = fedora_content_path(:download_method=>"show_pretty", :uri=>base_id, :block=>"DC", :filename=>dc_filename)
102
+ res[:mime_type] = document["dc_format_ssm"] ? document["dc_format_ssm"].first : "application/octect-stream"
103
+ res[:content_models] = document["has_model_ssim"]
104
+ res[:file_size] = document["extent_ssim"].first.to_i
105
+ res[:size] = (document["extent_ssim"].first.to_i / 1024).to_s + " Kb"
106
+ res
107
+ end
108
+
109
+ end
110
+
111
+ end
@@ -1,27 +1,13 @@
1
- require "active-fedora"
2
- require "active_fedora_finders"
3
- class ContentAggregator < ::ActiveFedora::Base
4
- extend ActiveModel::Callbacks
5
- include ::ActiveFedora::Finders
6
- include ::ActiveFedora::DatastreamCollections
7
- include ::Hydra::ModelMethods
8
- include Cul::Scv::Hydra::Models::Common
9
- include Cul::Scv::Hydra::Models::Aggregator
10
-
11
- alias :file_objects :resources
12
-
13
- def route_as
14
- "multipartitem"
15
- end
1
+ class ContentAggregator < GenericAggregator
16
2
 
17
3
  def thumbnail_info
18
- members = resources
19
- if members.length > 1
4
+ _members = member_ids()
5
+ if _members.length > 1
20
6
  return {:url=>image_url("cul_scv_hydra/crystal/kmultiple.png"),:mime=>'image/png'}
21
- elsif members.length == 0
7
+ elsif _members.length == 0
22
8
  return {:url=>image_url("cul_scv_hydra/crystal/file.png"),:mime=>'image/png'}
23
9
  else
24
- member = ActiveFedora::Base.find(members[0], :cast=>true)
10
+ member = ActiveFedora::Base.find(_members[0], :cast=>true)
25
11
  if member.respond_to? :thumbnail_info
26
12
  return member.thumbnail_info
27
13
  end
@@ -8,7 +8,7 @@ class DcDocument < ActiveFedora::Base
8
8
  include Cul::Scv::Hydra::Models::Common
9
9
  alias :file_objects :resources
10
10
 
11
- has_many :parts, :property=>:cul_member_of, :class_name=>'ActiveFedora::Base'
11
+ has_and_belongs_to_many :parts, :property => :cul_member_of, :class_name=>'ActiveFedora::Base'
12
12
 
13
13
  def self.load_instance_from_solr(pid,solr_doc=nil)
14
14
  if solr_doc.nil?
@@ -1,16 +1,35 @@
1
1
  require "active-fedora"
2
2
  require "active_fedora_finders"
3
3
  class GenericAggregator < ::ActiveFedora::Base
4
- extend ActiveModel::Callbacks
5
4
  include ::ActiveFedora::Finders
6
5
  include ::ActiveFedora::DatastreamCollections
7
6
  include ::Hydra::ModelMethods
8
7
  include Cul::Scv::Hydra::Models::Common
9
8
  include Cul::Scv::Hydra::Models::Aggregator
10
9
 
11
- alias :file_objects :resources
10
+ has_many :parts, :property => :cul_member_of, :class_name=>'ActiveFedora::Base'
12
11
 
13
12
  def route_as
14
13
  "multipartitem"
15
14
  end
15
+
16
+ def index_type_label
17
+ riquery = Cul::Scv::Hydra::Models::MEMBER_ITQL.gsub(/%PID%/, self.pid)
18
+ begin
19
+ docs = Cul::Scv::Fedora.repository.find_by_itql riquery, limit: 2, format: json
20
+ docs = JSON.parse(docs)['results']
21
+ rescue Exception=>e
22
+ Rails.logger.warn("#{self.class.name} failed to find children with TQL: #{e.message}")
23
+ docs = self.parts
24
+ end
25
+ if docs.size == 0
26
+ label = "EMPTY"
27
+ elsif docs.size == 1
28
+ label = "SINGLE PART"
29
+ else
30
+ label = "MULTIPART"
31
+ end
32
+ label
33
+ end
34
+
16
35
  end
@@ -8,6 +8,8 @@ class GenericObject < ::ActiveFedora::Base
8
8
  include Cul::Scv::Hydra::Models::Common
9
9
  include Cul::Scv::Hydra::Models::Aggregator
10
10
 
11
+ has_many :parts, :property => :cul_member_of, :class_name=>'ActiveFedora::Base'
12
+
11
13
  alias :file_objects :resources
12
14
 
13
15
  def route_as
@@ -10,8 +10,11 @@ class GenericResource < ::ActiveFedora::Base
10
10
  include ::ActiveFedora::DatastreamCollections
11
11
  include ::Hydra::ModelMethods
12
12
  include Cul::Scv::Hydra::Models::Common
13
+ include Cul::Scv::Hydra::Models::ImageResource
14
+ include Cul::Scv::Fedora::UrlHelperBehavior
13
15
  include ::ActiveFedora::RelsInt
14
- alias :file_objects :resources
16
+
17
+ has_and_belongs_to_many :containers, :property=>:cul_member_of, :class_name=>'ActiveFedora::Base'
15
18
 
16
19
  IMAGE_EXT = {"image/bmp" => 'bmp', "image/gif" => 'gif', "image/jpeg" => 'jpg', "image/png" => 'png', "image/tiff" => 'tif', "image/x-windows-bmp" => 'bmp'}
17
20
  WIDTH = RDF::URI(ActiveFedora::Predicates.find_graph_predicate(:image_width))
@@ -25,7 +28,7 @@ class GenericResource < ::ActiveFedora::Base
25
28
  end
26
29
 
27
30
  def route_as
28
- "resource"
31
+ self.zooming? ? "zoomingimage" : "resource"
29
32
  end
30
33
 
31
34
  def index_type_label
@@ -49,5 +52,97 @@ class GenericResource < ::ActiveFedora::Base
49
52
  return {:url=>image_url("cul_scv_hydra/crystal/file.png"),:mime=>'image/png'}
50
53
  end
51
54
  end
52
-
55
+
56
+ def to_solr(solr_doc = Hash.new, opts={})
57
+ solr_doc = super
58
+ unless solr_doc["extent_ssim"] || self.datastreams["content"].nil?
59
+ solr_doc["extent_ssim"] = [self.datastreams["content"].size]
60
+ end
61
+ if self.zooming?
62
+ fz = rels_int.relationships(datastreams['content'], :foaf_zooming).first.object.to_s.split('/')[-1]
63
+ ds = datastreams[fz]
64
+ rft_id = ds.controlGroup == 'E' ? datastreams[fz].dsLocation : fedora_ds_url(pid, ds.dsid) + '/content'
65
+ solr_doc['rft_id_ss'] = rft_id
66
+ end
67
+ solr_doc
68
+ end
69
+
70
+ def thumbnail_info
71
+ thumb = rels_int.relationships(datastreams['content'],:foaf_thumbnail).first
72
+ if thumb
73
+ t_dsid = thumb.object.to_s.split('/')[-1]
74
+ t_url = "#{ActiveFedora.fedora_config.credentials[:url]}/objects/#{pid}/datastreams/#{t_dsid}/content"
75
+ return {:url=>t_url,:mime=>datastreams[t_dsid].mimeType}
76
+ elsif self.zooming?
77
+ t_dsid = rels_int.relationships(dsuri, :foaf_zooming).first.object.to_s.split('/')[-1]
78
+ t_parms = DJATOKA_THUMBNAIL_PARMS.merge({"rft_id" => datastreams[t_dsid].dsLocation})
79
+ url = "#{DJATOKA_BASE_URL}?#{options.map { |key, value| "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}"}.join("&") }"
80
+ {:url => url, :mime => t_parms["svc.format"]}
81
+ else
82
+ return {:asset=>"crystal/file.png",:mime=>'image/png'}
83
+ end
84
+ end
85
+
86
+ def linkable_resources
87
+ # let's start with the known DSIDs from lindquist, then work our way back to parsing the solrized relsint
88
+ results = []
89
+ if (rels = rels_int.instance_variable_get :@solr_hash)
90
+ # this was loaded from solr
91
+ rels.each do |dsuri, props|
92
+ if dsuri =~ /\/content$/ or not props[FORMAT_OF_PREDICATE].blank?
93
+ dsid = dsuri.split('/')[-1]
94
+ res = datastream_as_resource(dsid, props)
95
+ results << res
96
+ end
97
+ end
98
+ else
99
+ content_uri = RDF::URI("info:fedora/#{self.pid}/content")
100
+ dsuris = [content_uri]
101
+ results = []
102
+ # read the graph
103
+ datastreams.each do |k, v|
104
+ rels = rels_int.relationships(v, :format_of, content_uri)
105
+ dsuris << rels[0].subject unless rels.blank?
106
+ end
107
+
108
+ dsuris.each do |dsuri|
109
+ dsid = dsuri.to_s.split('/')[-1]
110
+ width_rel = rels_int.relationships(dsuri, :exif_image_width)[0]
111
+ length_rel = rels_int.relationships(dsuri, :exif_image_length)[0]
112
+ extent_rel = rels_int.relationships(dsuri, :extent)[0]
113
+ props = {EXTENT_PREDICATE => [], WIDTH_PREDICATE => [], LENGTH_PREDICATE => []}
114
+ props[EXTENT_PREDICATE] << extent_rel.object.to_s unless extent_rel.blank?
115
+ props[WIDTH_PREDICATE] << width_rel.object.to_s unless width_rel.blank?
116
+ props[LENGTH_PREDICATE] << length_rel.object.to_s unless length_rel.blank?
117
+ results << datastream_as_resource(dsid, props)
118
+ end
119
+ end
120
+ results
121
+ end
122
+
123
+ def zooming?
124
+ !rels_int.relationships(datastreams['content'], :foaf_zooming).first.blank?
125
+ end
126
+
127
+ private
128
+ def datastream_as_resource(dsid, props={})
129
+ ds = datastreams[dsid]
130
+ raise "No resource at info:fedora/#{pid}/#{dsid}" unless ds
131
+ res = {}
132
+ res[:uri] = self.pid
133
+ res[:block] = dsid
134
+ res[:mime_type] = ds.mimeType
135
+ res[:content_models] = ["Datastream"]
136
+ res[:file_size] = ds.dsSize.to_s
137
+ if res[:file_size] == "0" and props[EXTENT_PREDICATE]
138
+ res[:file_size] = (props[EXTENT_PREDICATE].first || "0")
139
+ end
140
+ res[:size] = (res[:file_size].to_i / 1024).to_s + " Kb"
141
+ res[:width] = props[WIDTH_PREDICATE].first || "0"
142
+ res[:height] = props[LENGTH_PREDICATE].first || "0"
143
+ res[:dimensions] = "#{res[:width]} x #{res[:height]}"
144
+ base_filename = pid.gsub(/\:/,"")
145
+ res[:filename] = base_filename + "." + dsid + "." + ds.mimeType.gsub(/^[^\/]+\//,"")
146
+ res
147
+ end
53
148
  end
@@ -1,17 +1,9 @@
1
1
  require "active-fedora"
2
2
  require "active_fedora_finders"
3
- class JP2ImageAggregator < ::ActiveFedora::Base
4
- extend ActiveModel::Callbacks
5
- include ::ActiveFedora::Finders
6
- include ::ActiveFedora::DatastreamCollections
7
- include ::Hydra::ModelMethods
8
- include Cul::Scv::Hydra::Models::Common
9
- include Cul::Scv::Hydra::Models::Aggregator
3
+ class JP2ImageAggregator < ResourceAggregator
10
4
 
11
5
  has_datastream :name => "SOURCE", :type=>::ActiveFedora::Datastream, :mimeType=>"image/jp2", :controlGroup=>'E'
12
6
 
13
- alias :file_objects :resources
14
-
15
7
  def route_as
16
8
  "zoomingimage"
17
9
  end
@@ -8,6 +8,8 @@ class METSStructuredAggregator < ::ActiveFedora::Base
8
8
  include Cul::Scv::Hydra::Models::Common
9
9
  include Cul::Scv::Hydra::Models::Aggregator
10
10
 
11
+ has_many :parts, :property => :cul_member_of, :class_name=>'ActiveFedora::Base'
12
+
11
13
  alias :file_objects :resources
12
14
 
13
15
  def route_as
@@ -3,20 +3,20 @@ require "active_fedora_finders"
3
3
  require "cul_image_props"
4
4
  require "mime/types"
5
5
  require "uri"
6
- class Resource < ::ActiveFedora::Base
7
- extend ActiveModel::Callbacks
6
+ class Resource < ActiveFedora::Base
8
7
  include ::ActiveFedora::Finders
9
8
  include ::ActiveFedora::DatastreamCollections
10
- include ::Hydra::ModelMethods
9
+ # include ::Hydra::ModelMethods
11
10
  include Cul::Scv::Hydra::Models::Common
12
11
  include Cul::Scv::Hydra::Models::Resource
12
+ include Cul::Scv::Hydra::Models::ImageResource
13
13
 
14
- alias :file_objects :resources
14
+ belongs_to :container, :property=>:cul_member_of, :class_name=>'ActiveFedora::Base'
15
15
 
16
- CUL_WIDTH = "http://purl.oclc.org/NET/CUL/RESOURCE/STILLIMAGE/BASIC/imageWidth"
17
- CUL_LENGTH = "http://purl.oclc.org/NET/CUL/RESOURCE/STILLIMAGE/BASIC/imageLength"
18
- FORMAT = "http://purl.org/dc/elements/1.1/format"
19
- MEMBER_OF = "http://purl.oclc.org/NET/CUL/memberOf"
16
+ # CUL_WIDTH = "http://purl.oclc.org/NET/CUL/RESOURCE/STILLIMAGE/BASIC/imageWidth"
17
+ # CUL_LENGTH = "http://purl.oclc.org/NET/CUL/RESOURCE/STILLIMAGE/BASIC/imageLength"
18
+ # FORMAT = "http://purl.org/dc/elements/1.1/format"
19
+ # MEMBER_OF = "http://purl.oclc.org/NET/CUL/memberOf"
20
20
 
21
21
  def route_as
22
22
  "resource"
@@ -35,46 +35,44 @@ class Resource < ::ActiveFedora::Base
35
35
  end
36
36
 
37
37
  def set_title_and_label(new_title, opts={})
38
- if opts[:only_if_blank]
39
- if self.label.nil? || self.label.empty?
40
- self.label = new_title
41
- self.set_title( new_title )
42
- end
43
- else
38
+ if opts[:only_if_blank]
39
+ if self.label.nil? || self.label.empty?
44
40
  self.label = new_title
45
- set_title( new_title )
41
+ self.set_title( new_title )
46
42
  end
43
+ else
44
+ self.label = new_title
45
+ set_title( new_title )
47
46
  end
47
+ end
48
48
 
49
- # Set the title and label on the current object
50
- #
51
- # @param [String] new_title
52
- # @param [Hash] opts (optional) hash of configuration options
53
- def set_title(new_title, opts={})
54
- if has_desc?
55
- desc_metadata_ds = self.datastreams["descMetadata"]
56
- if desc_metadata_ds.respond_to?(:title_values)
57
- desc_metadata_ds.title_values = new_title
58
- else
59
- desc_metadata_ds.title = new_title
60
- end
49
+ # Set the title and label on the current object
50
+ #
51
+ # @param [String] new_title
52
+ # @param [Hash] opts (optional) hash of configuration options
53
+ def set_title(new_title, opts={})
54
+ if has_desc?
55
+ desc_metadata_ds = self.datastreams["descMetadata"]
56
+ if desc_metadata_ds.respond_to?(:title_values)
57
+ desc_metadata_ds.title_values = new_title
58
+ else
59
+ desc_metadata_ds.title = new_title
61
60
  end
62
61
  end
63
-
64
- def thumbnail_info
65
- # do the triples indicate this is a thumb? fetch
66
- width = object_relations[CUL_WIDTH].first.to_i
67
- length = object_relations[CUL_LENGTH].first.to_i
68
- if width <= 251 && length <= 251
69
- mime = object_relations[FORMAT].first
70
- url = {:url=>"#{ActiveFedora.fedora_config[:url]}/objects/#{self.pid}/datastreams/CONTENT/content", :mime=>mime}
62
+ end
63
+
64
+ def thumbnail_info
65
+ # do the triples indicate this is a thumb? fetch
66
+ if long <= 251
67
+ mime = object_relations[FORMAT].first
68
+ url = {:url=>"#{ActiveFedora.fedora_config[:url]}/objects/#{self.pid}/datastreams/CONTENT/content", :mime=>mime}
69
+ else
70
+ if object_relations[MEMBER_OF].blank?
71
+ return {:url=>image_url("cul_scv_hydra/crystal/file.png"),:mime=>'image/png'}
71
72
  else
72
- if object_relations[MEMBER_OF].blank?
73
- return {:url=>image_url("cul_scv_hydra/crystal/file.png"),:mime=>'image/png'}
74
- else
75
- url = StaticImageAggregator.find(object_relations[MEMBER_OF].first).thumbnail_info
76
- end
73
+ url = ActiveFedora::Base.find(parents.first, :cast => true).thumbnail_info
77
74
  end
78
- return url
79
75
  end
76
+ return url
77
+ end
80
78
  end
@@ -0,0 +1,22 @@
1
+ class ResourceAggregator < ::ActiveFedora::Base
2
+ include ::ActiveFedora::Finders
3
+ include ::ActiveFedora::DatastreamCollections
4
+ include ::Hydra::ModelMethods
5
+ include Cul::Scv::Hydra::Models::Common
6
+ include Cul::Scv::Hydra::Models::Aggregator
7
+ include Cul::Scv::Hydra::Models::LinkableResources
8
+
9
+ has_many :parts, :property => :cul_member_of, :class_name=>'Resource'
10
+
11
+ def route_as
12
+ "resource"
13
+ end
14
+
15
+ def index_type_label
16
+ "PART"
17
+ end
18
+
19
+ def thumbnail_info
20
+ return {:url=>image_url("cul_scv_hydra/crystal/file.png"),:mime=>'image/png'}
21
+ end
22
+ end
@@ -1,23 +1,11 @@
1
1
  require "active-fedora"
2
2
  require "active_fedora_finders"
3
- class StaticAudioAggregator < ::ActiveFedora::Base
4
- extend ActiveModel::Callbacks
5
- include ::ActiveFedora::Finders
6
- include ::ActiveFedora::DatastreamCollections
7
- include ::Hydra::ModelMethods
8
- include Cul::Scv::Hydra::Models::Common
9
- include Cul::Scv::Hydra::Models::Aggregator
10
-
11
- alias :file_objects :resources
3
+ class StaticAudioAggregator < ResourceAggregator
12
4
 
13
5
  def route_as
14
6
  "audio"
15
7
  end
16
8
 
17
- def index_type_label
18
- "PART"
19
- end
20
-
21
9
  def thumbnail_info
22
10
  return {:url=>image_url("cul_scv_hydra/crystal/mp3.png"),:mime=>'image/png'}
23
11
  end
@@ -1,14 +1,6 @@
1
1
  require "active-fedora"
2
2
  require "active_fedora_finders"
3
- class StaticImageAggregator < ::ActiveFedora::Base
4
- extend ActiveModel::Callbacks
5
- include ::ActiveFedora::Finders
6
- include ::ActiveFedora::DatastreamCollections
7
- include ::Hydra::ModelMethods
8
- include Cul::Scv::Hydra::Models::Common
9
- include Cul::Scv::Hydra::Models::Aggregator
10
-
11
- alias :file_objects :resources
3
+ class StaticImageAggregator < ResourceAggregator
12
4
 
13
5
  CUL_WIDTH = "http://purl.oclc.org/NET/CUL/RESOURCE/STILLIMAGE/BASIC/imageWidth"
14
6
  CUL_LENGTH = "http://purl.oclc.org/NET/CUL/RESOURCE/STILLIMAGE/BASIC/imageLength"
@@ -18,20 +10,17 @@ class StaticImageAggregator < ::ActiveFedora::Base
18
10
  end
19
11
 
20
12
  def index_type_label
21
- "PART"
13
+ 'PART'
22
14
  end
23
-
15
+
24
16
  def thumbnail_info
25
17
  candidate = nil
26
18
  max_dim = 251
27
19
  resources.each do |pid|
28
20
  resource = Resource.find(pid)
29
- width = resource.object_relations[CUL_WIDTH].first.to_i
30
- length = resource.object_relations[CUL_LENGTH].first.to_i
31
- max = (width > length) ? width : length
32
- if max_dim > max
21
+ if max_dim > resouce.long
33
22
  candidate = resource
34
- max_dim = max
23
+ max_dim = resource.long
35
24
  end
36
25
  end
37
26
  if candidate.nil?
data/config/fedora.yml CHANGED
@@ -1,19 +1,11 @@
1
- development:
2
- # :url: http://127.0.0.1:8983/fedora
3
- # :user: fedoraAdmin
4
- # :password: fedoraAdmin
1
+ alcott: &alcott
5
2
  :url: http://alcott.cul.columbia.edu:8080/fedora
6
3
  :user: fedoraAdmin
7
4
  :password: f+BULUS*^
8
- test:
9
- :url: http://127.0.0.1:8983/fedora
10
- :user: fedoraAdmin
11
- :password: fedoraAdmin
12
- production:
13
- :url: http://alcott.cul.columbia.edu:8080/fedora
14
- :user: fedoraAdmin
15
- :password: f+BULUS*^
16
- default:
5
+ default: &default
17
6
  :url: http://127.0.0.1:8983/fedora
18
7
  :user: fedoraAdmin
19
8
  :password: fedoraAdmin
9
+ development: *alcott
10
+ test: *default
11
+ production: *alcott
@@ -64,6 +64,8 @@
64
64
  :y_resolution: yResolution
65
65
  :resolution_unit: resolutionUnit
66
66
  http://xmlns.com/foaf/0.1/:
67
+ :foaf_image: image
67
68
  :foaf_thumbnail: thumbnail
69
+ :foaf_zooming: zoomingImage
68
70
  http://www.w3.org/1999/02/22-rdf-syntax-ns#:
69
71
  :rdf_type: type
@@ -0,0 +1,31 @@
1
+ module Cul
2
+ module Scv
3
+ module Fedora
4
+ class FakeObject
5
+ attr_accessor :pid
6
+ def initialize(pid, isNew=false)
7
+ @pid = pid
8
+ @isNew = isNew
9
+ end
10
+ def new_record?
11
+ @isNew
12
+ end
13
+ def connection
14
+ Cul::Scv::Fedora.connection
15
+ end
16
+ def repository
17
+ Cul::Scv::Fedora.repository
18
+ end
19
+ def spawn(pid)
20
+ s = FakeObject.new(pid)
21
+ s.connection= connection
22
+ s.repository= repository
23
+ s
24
+ end
25
+ protected
26
+ def connection=(connection); @connection = connection; end
27
+ def repository=(repo); @repository = repo; end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ module Cul
2
+ module Scv
3
+ module Fedora
4
+ module RubydoraPatch
5
+ def find_by_itql query, options = {}
6
+ self.risearch(query, {:lang => 'itql'}.merge(options))
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ module Cul
2
+ module Scv
3
+ module Fedora
4
+ module UrlHelperBehavior
5
+
6
+ def fedora_url
7
+ @fedora_url ||= ActiveFedora.config.credentials[:url]
8
+ end
9
+
10
+ def pid_for_url(pid)
11
+ pid.gsub(/^\//,'').gsub(/info:fedora\//,'')
12
+ end
13
+
14
+ def fedora_object_url(pid)
15
+ fedora_url + '/objects/' + pid_for_url(pid)
16
+ end
17
+
18
+ def fedora_ds_url(pid, dsid)
19
+ fedora_object_url(pid) + '/datastreams/' + dsid
20
+ end
21
+
22
+ def fedora_method_url(pid, method)
23
+ fedora_object_url(pid) + '/methods/' + method
24
+ end
25
+
26
+ def fedora_risearch_url
27
+ fedora_url + '/risearch'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
data/lib/cul_scv_hydra.rb CHANGED
@@ -1,19 +1,41 @@
1
- require "rubygems"
1
+ require 'hydra/head'
2
+ require 'active_fedora_relsint'
2
3
  module Cul
3
4
  module Scv
4
5
  module Hydra
5
6
  end
7
+ module Fedora
8
+ require 'cul_scv_fedora/url_helper_behavior'
9
+ require 'cul_scv_fedora/dummy_object'
10
+ require 'cul_scv_fedora/rubydora_patch'
11
+ def self.config_path
12
+ File.join(Rails.root.to_s, 'config', 'fedora.yml')
13
+ end
14
+ def self.config
15
+ ActiveFedora.fedora_config.credentials
16
+ end
17
+ def self.connection
18
+ @connection ||= ActiveFedora::RubydoraConnection.new(ActiveFedora.fedora_config.credentials)
19
+ end
20
+
21
+ def self.repository
22
+ @repository ||= begin
23
+ repo = connection.connection
24
+ repo.extend(RubydoraPatch)
25
+ repo
26
+ end
27
+ end
28
+
29
+ def self.ds_for_uri(fedora_uri, fake_obj=nil)
30
+ return nil unless fedora_uri =~ /info\:fedora\/.*/
31
+ p = fedora_uri.split('/')
32
+ fake_obj = fake_obj.nil? ? DummyObject.new(p[1]) : fake_obj.spawn(p[1])
33
+ ::Rubydora::Datastream.new(fake_obj, p[2])
34
+ end
35
+ end
6
36
  end
7
37
  end
8
- # this is a hack to make requiring hydra possible
9
- #module Hydra
10
- # module Datastream
11
- # module CommonModsIndexMethods
12
- # end
13
- # end
14
- #end
15
- require 'hydra/head'
16
- require 'active_fedora_relsint'
38
+
17
39
  require "cul_scv_hydra/access_controls_enforcement"
18
40
  require "cul_scv_hydra/controllers"
19
41
  require "cul_scv_hydra/om"
@@ -7,6 +7,13 @@ module Cul::Scv::Hydra
7
7
  class Engine < ::Rails::Engine
8
8
  isolate_namespace Cul::Scv::Hydra
9
9
 
10
+ config.mount_at = '/'
11
+
12
+ config.autoload_paths += %W(
13
+ #{config.root}/app/controllers/concerns
14
+ #{config.root}/app/models/concerns
15
+ )
16
+
10
17
  config.generators do |g|
11
18
  g.test_framework :rspec
12
19
  g.integration_tool :rspec
@@ -1,10 +1,10 @@
1
1
  module Cul
2
2
  module Scv
3
3
  module Hydra
4
- VERSION = '0.11.0'
4
+ VERSION = '0.12.0'
5
5
  def self.version
6
6
  VERSION
7
7
  end
8
8
  end
9
9
  end
10
- end
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cul_scv_hydra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-17 00:00:00.000000000 Z
12
+ date: 2014-04-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: blacklight
@@ -210,6 +210,9 @@ extensions: []
210
210
  extra_rdoc_files: []
211
211
  files:
212
212
  - bin/rails
213
+ - lib/cul_scv_fedora/dummy_object.rb
214
+ - lib/cul_scv_fedora/rubydora_patch.rb
215
+ - lib/cul_scv_fedora/url_helper_behavior.rb
213
216
  - lib/cul_scv_hydra/access_controls_enforcement.rb
214
217
  - lib/cul_scv_hydra/controllers/aggregates.rb
215
218
  - lib/cul_scv_hydra/controllers/aggregator_controller_helper.rb
@@ -258,6 +261,8 @@ files:
258
261
  - app/models/bag_aggregator.rb
259
262
  - app/models/concerns/cul/scv/hydra/models/aggregator.rb
260
263
  - app/models/concerns/cul/scv/hydra/models/common.rb
264
+ - app/models/concerns/cul/scv/hydra/models/image_resource.rb
265
+ - app/models/concerns/cul/scv/hydra/models/linkable_resources.rb
261
266
  - app/models/concerns/cul/scv/hydra/models/resource.rb
262
267
  - app/models/concerns/cul/scv/hydra/models.rb
263
268
  - app/models/concerns/cul.rb
@@ -272,6 +277,7 @@ files:
272
277
  - app/models/jp2_image_aggregator.rb
273
278
  - app/models/mets_structured_aggregator.rb
274
279
  - app/models/resource.rb
280
+ - app/models/resource_aggregator.rb
275
281
  - app/models/static_audio_aggregator.rb
276
282
  - app/models/static_image_aggregator.rb
277
283
  - config/fedora.yml
@@ -284,6 +290,8 @@ licenses: []
284
290
  post_install_message:
285
291
  rdoc_options: []
286
292
  require_paths:
293
+ - app
294
+ - config
287
295
  - lib
288
296
  - fixtures
289
297
  required_ruby_version: !ruby/object:Gem::Requirement