ddr-core 0.2.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.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +12 -0
  3. data/README.md +27 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/config/ddr_core_manifest.js +0 -0
  6. data/app/controllers/users/omniauth_callbacks_controller.rb +11 -0
  7. data/app/controllers/users/sessions_controller.rb +15 -0
  8. data/app/models/concerns/ddr/captionable.rb +25 -0
  9. data/app/models/concerns/ddr/describable.rb +108 -0
  10. data/app/models/concerns/ddr/governable.rb +25 -0
  11. data/app/models/concerns/ddr/has_admin_metadata.rb +141 -0
  12. data/app/models/concerns/ddr/has_attachments.rb +10 -0
  13. data/app/models/concerns/ddr/has_children.rb +10 -0
  14. data/app/models/concerns/ddr/has_content.rb +132 -0
  15. data/app/models/concerns/ddr/has_extracted_text.rb +10 -0
  16. data/app/models/concerns/ddr/has_intermediate_file.rb +25 -0
  17. data/app/models/concerns/ddr/has_multires_image.rb +14 -0
  18. data/app/models/concerns/ddr/has_parent.rb +18 -0
  19. data/app/models/concerns/ddr/has_struct_metadata.rb +21 -0
  20. data/app/models/concerns/ddr/has_thumbnail.rb +33 -0
  21. data/app/models/concerns/ddr/solr_document_behavior.rb +429 -0
  22. data/app/models/concerns/ddr/streamable.rb +25 -0
  23. data/app/models/ddr/admin_set.rb +28 -0
  24. data/app/models/ddr/attachment.rb +14 -0
  25. data/app/models/ddr/collection.rb +28 -0
  26. data/app/models/ddr/component.rb +31 -0
  27. data/app/models/ddr/contact.rb +23 -0
  28. data/app/models/ddr/digest.rb +8 -0
  29. data/app/models/ddr/file.rb +40 -0
  30. data/app/models/ddr/item.rb +36 -0
  31. data/app/models/ddr/language.rb +31 -0
  32. data/app/models/ddr/media_type.rb +22 -0
  33. data/app/models/ddr/resource.rb +94 -0
  34. data/app/models/ddr/rights_statement.rb +25 -0
  35. data/app/models/ddr/target.rb +17 -0
  36. data/config/initializers/devise.rb +262 -0
  37. data/config/locales/ddr-core.en.yml +85 -0
  38. data/config/routes.rb +3 -0
  39. data/db/migrate/20141104181418_create_users.rb +34 -0
  40. data/db/migrate/20141107124012_add_columns_to_user.rb +46 -0
  41. data/lib/ddr-core.rb +1 -0
  42. data/lib/ddr/auth.rb +80 -0
  43. data/lib/ddr/auth/ability.rb +18 -0
  44. data/lib/ddr/auth/ability_definitions.rb +26 -0
  45. data/lib/ddr/auth/ability_definitions/admin_set_ability_definitions.rb +9 -0
  46. data/lib/ddr/auth/ability_definitions/alias_ability_definitions.rb +23 -0
  47. data/lib/ddr/auth/ability_definitions/attachment_ability_definitions.rb +13 -0
  48. data/lib/ddr/auth/ability_definitions/collection_ability_definitions.rb +28 -0
  49. data/lib/ddr/auth/ability_definitions/component_ability_definitions.rb +13 -0
  50. data/lib/ddr/auth/ability_definitions/item_ability_definitions.rb +13 -0
  51. data/lib/ddr/auth/ability_definitions/lock_ability_definitions.rb +13 -0
  52. data/lib/ddr/auth/ability_definitions/publication_ability_definitions.rb +16 -0
  53. data/lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb +39 -0
  54. data/lib/ddr/auth/ability_definitions/superuser_ability_definitions.rb +9 -0
  55. data/lib/ddr/auth/ability_factory.rb +10 -0
  56. data/lib/ddr/auth/abstract_ability.rb +48 -0
  57. data/lib/ddr/auth/affiliation.rb +14 -0
  58. data/lib/ddr/auth/affiliation_groups.rb +20 -0
  59. data/lib/ddr/auth/anonymous_ability.rb +7 -0
  60. data/lib/ddr/auth/auth_context.rb +109 -0
  61. data/lib/ddr/auth/auth_context_factory.rb +13 -0
  62. data/lib/ddr/auth/detached_auth_context.rb +19 -0
  63. data/lib/ddr/auth/dynamic_groups.rb +13 -0
  64. data/lib/ddr/auth/effective_permissions.rb +12 -0
  65. data/lib/ddr/auth/effective_roles.rb +9 -0
  66. data/lib/ddr/auth/failure_app.rb +16 -0
  67. data/lib/ddr/auth/group.rb +40 -0
  68. data/lib/ddr/auth/grouper_gateway.rb +70 -0
  69. data/lib/ddr/auth/groups.rb +32 -0
  70. data/lib/ddr/auth/ldap_gateway.rb +74 -0
  71. data/lib/ddr/auth/permissions.rb +18 -0
  72. data/lib/ddr/auth/remote_groups.rb +14 -0
  73. data/lib/ddr/auth/role_based_access_controls_enforcement.rb +56 -0
  74. data/lib/ddr/auth/roles.rb +28 -0
  75. data/lib/ddr/auth/roles/role.rb +121 -0
  76. data/lib/ddr/auth/roles/role_type.rb +23 -0
  77. data/lib/ddr/auth/roles/role_types.rb +52 -0
  78. data/lib/ddr/auth/superuser_ability.rb +7 -0
  79. data/lib/ddr/auth/test_helpers.rb +22 -0
  80. data/lib/ddr/auth/user.rb +54 -0
  81. data/lib/ddr/auth/web_auth_context.rb +29 -0
  82. data/lib/ddr/core.rb +110 -0
  83. data/lib/ddr/core/engine.rb +8 -0
  84. data/lib/ddr/core/version.rb +5 -0
  85. data/lib/ddr/error.rb +16 -0
  86. data/lib/ddr/files.rb +13 -0
  87. data/lib/ddr/fits.rb +189 -0
  88. data/lib/ddr/index.rb +29 -0
  89. data/lib/ddr/index/abstract_query_result.rb +22 -0
  90. data/lib/ddr/index/connection.rb +38 -0
  91. data/lib/ddr/index/csv_query_result.rb +84 -0
  92. data/lib/ddr/index/document_builder.rb +9 -0
  93. data/lib/ddr/index/field.rb +35 -0
  94. data/lib/ddr/index/field_attribute.rb +22 -0
  95. data/lib/ddr/index/fields.rb +154 -0
  96. data/lib/ddr/index/filter.rb +139 -0
  97. data/lib/ddr/index/query.rb +82 -0
  98. data/lib/ddr/index/query_builder.rb +185 -0
  99. data/lib/ddr/index/query_clause.rb +112 -0
  100. data/lib/ddr/index/query_params.rb +40 -0
  101. data/lib/ddr/index/query_result.rb +102 -0
  102. data/lib/ddr/index/response.rb +30 -0
  103. data/lib/ddr/index/sort_order.rb +28 -0
  104. data/lib/ddr/index/unique_key_field.rb +12 -0
  105. data/lib/ddr/managers.rb +9 -0
  106. data/lib/ddr/managers/manager.rb +13 -0
  107. data/lib/ddr/managers/technical_metadata_manager.rb +141 -0
  108. data/lib/ddr/structure.rb +188 -0
  109. data/lib/ddr/structures/agent.rb +49 -0
  110. data/lib/ddr/structures/component_type_term.rb +29 -0
  111. data/lib/ddr/structures/div.rb +64 -0
  112. data/lib/ddr/structures/f_locat.rb +54 -0
  113. data/lib/ddr/structures/file.rb +52 -0
  114. data/lib/ddr/structures/file_grp.rb +35 -0
  115. data/lib/ddr/structures/file_sec.rb +22 -0
  116. data/lib/ddr/structures/fptr.rb +31 -0
  117. data/lib/ddr/structures/mets_hdr.rb +37 -0
  118. data/lib/ddr/structures/mptr.rb +49 -0
  119. data/lib/ddr/structures/struct_map.rb +40 -0
  120. data/lib/ddr/utils.rb +185 -0
  121. data/lib/ddr/vocab.rb +22 -0
  122. data/lib/ddr/vocab/asset.rb +51 -0
  123. data/lib/ddr/vocab/contact.rb +9 -0
  124. data/lib/ddr/vocab/display.rb +9 -0
  125. data/lib/ddr/vocab/duke_terms.rb +13 -0
  126. data/lib/ddr/vocab/rdf_vocabulary_parser.rb +43 -0
  127. data/lib/ddr/vocab/roles.rb +25 -0
  128. data/lib/ddr/vocab/sources/duketerms.rdf +870 -0
  129. data/lib/ddr/vocab/vocabulary.rb +37 -0
  130. data/lib/ddr/workflow.rb +8 -0
  131. data/lib/tasks/ddr/core_tasks.rake +4 -0
  132. metadata +428 -0
@@ -0,0 +1,84 @@
1
+ require "csv"
2
+
3
+ module Ddr::Index
4
+ class CSVQueryResult < AbstractQueryResult
5
+
6
+ MAX_ROWS = 10**8 # Just set to a really high number :)
7
+ CSV_MV_SEPARATOR = ";"
8
+
9
+ delegate :headers, :to_s, :to_csv, to: :table
10
+
11
+ def delete_empty_columns!
12
+ table.by_col!.delete_if { |c, vals| vals.all?(&:nil?) }
13
+ end
14
+
15
+ def each(&block)
16
+ table.by_row!.each(&block)
17
+ end
18
+
19
+ def [](index_or_header)
20
+ table.by_col_or_row![index_or_header]
21
+ end
22
+
23
+ def table
24
+ @table ||= CSV.parse(data, csv_opts)
25
+ end
26
+
27
+ def csv_opts
28
+ { headers: csv_headers,
29
+ converters: [convert_semicolons, convert_escaped_newlines],
30
+ return_headers: false,
31
+ write_headers: true,
32
+ }
33
+ end
34
+
35
+ def solr_csv_opts
36
+ { "csv.mv.separator" => CSV_MV_SEPARATOR,
37
+ "csv.header" => solr_csv_header?,
38
+ "rows" => solr_csv_rows,
39
+ "wt" => "csv",
40
+ }
41
+ end
42
+
43
+ def query_field_headings
44
+ query.fields.map { |f| f.respond_to?(:heading) ? f.heading : f.to_s }
45
+ end
46
+
47
+ def csv_headers
48
+ :first_row
49
+ end
50
+
51
+ def solr_csv_header?
52
+ query.fields.empty?
53
+ end
54
+
55
+ def solr_csv_rows
56
+ query.rows || MAX_ROWS
57
+ end
58
+
59
+ def solr_csv_params
60
+ params.merge(solr_csv_opts)
61
+ end
62
+
63
+ def data
64
+ if solr_csv_header?
65
+ solr_data
66
+ else
67
+ [ query_field_headings.join(","), solr_data ].join("\n")
68
+ end
69
+ end
70
+
71
+ def solr_data
72
+ Connection.get("select", params: solr_csv_params)
73
+ end
74
+
75
+ def convert_semicolons
76
+ lambda { |f| f.gsub(/\\#{CSV_MV_SEPARATOR}/, CSV_MV_SEPARATOR) rescue f }
77
+ end
78
+
79
+ def convert_escaped_newlines
80
+ lambda { |f| f.gsub(/\\r/, "\r").gsub(/\\n/, "\n") rescue f }
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,9 @@
1
+ module Ddr::Index
2
+ class DocumentBuilder
3
+
4
+ def self.build(doc)
5
+ ::SolrDocument.new(doc)
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,35 @@
1
+ require 'solrizer'
2
+
3
+ module Ddr::Index
4
+ class Field < SimpleDelegator
5
+
6
+ attr_reader :base
7
+
8
+ def initialize(base, *args)
9
+ @base = base.to_s
10
+ name = if args.empty?
11
+ @base
12
+ elsif args.last.is_a?(Hash) && args.last[:solr_name]
13
+ args.last[:solr_name]
14
+ else
15
+ Solrizer.solr_name(base, *args)
16
+ end
17
+ super(name)
18
+ end
19
+
20
+ def label
21
+ I18n.t "#{i18n_base}.label", default: base.titleize
22
+ end
23
+
24
+ def heading
25
+ I18n.t "#{i18n_base}.heading", default: base
26
+ end
27
+
28
+ private
29
+
30
+ def i18n_base
31
+ "ddr.index.fields.#{base}"
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,22 @@
1
+ require "virtus"
2
+
3
+ module Ddr::Index
4
+ class FieldAttribute < Virtus::Attribute
5
+
6
+ def self.coerce(value)
7
+ case value
8
+ when Field
9
+ value
10
+ when String
11
+ Field.new(value)
12
+ when Symbol
13
+ Fields.get(value)
14
+ end
15
+ end
16
+
17
+ def coerce(value)
18
+ self.class.coerce(value)
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,154 @@
1
+ module Ddr::Index
2
+ module Fields
3
+
4
+ ID = UniqueKeyField.instance
5
+
6
+ ACCESS_ROLE = Field.new :access_role, :stored_sortable
7
+ ADMIN_POLICY_ID = Field.new :admin_policy_id, :symbol
8
+ ADMIN_SET = Field.new :admin_set, :stored_sortable
9
+ ADMIN_SET_FACET = Field.new :admin_set_facet, :facetable
10
+ ADMIN_SET_TITLE = Field.new :admin_set_title, :stored_sortable
11
+ AFFILIATION = Field.new :affiliation, :stored_searchable
12
+ AFFILIATION_FACET = Field.new :affiliation_facet, :facetable
13
+ ALEPH_ID = Field.new :aleph_id, :stored_sortable
14
+ ALL_TEXT = Field.new :all_text, solr_name: "all_text_timv"
15
+ ARRANGER_FACET = Field.new :arranger_facet, :facetable
16
+ ASPACE_ID = Field.new :aspace_id, :stored_sortable
17
+ ATTACHED_FILES_HAVING_CONTENT = Field.new :attached_files_having_content, :symbol
18
+ ATTACHED_TO_ID = Field.new :attached_to_id, :symbol
19
+ BIBLICAL_BOOK_FACET = Field.new :biblical_book_facet, :facetable
20
+ BOX_NUMBER_FACET = Field.new :box_number_facet, :facetable
21
+ CATEGORY_FACET = Field.new :category_facet, :facetable
22
+ CHAPTER_AND_VERSE_FACET = Field.new :chapter_and_verse_facet, :facetable
23
+ COLLECTION_FACET = Field.new :collection_facet, :facetable
24
+ COLLECTION_ID = Field.new :collection_id, :symbol
25
+ COLLECTION_TITLE = Field.new :collection_title, :stored_sortable
26
+ COMMON_MODEL_NAME = Field.new :common_model_name, :stored_sortable
27
+ COMPANY_FACET = Field.new :company_facet, :facetable
28
+ COMPOSER_FACET = Field.new :composer_facet, :facetable
29
+ CONTENT_CREATE_DATE = Field.new :content_create_date, :stored_sortable, type: :date
30
+ CONTENT_SIZE = Field.new :content_size, solr_name: "content_size_lsi"
31
+ CONTENT_SIZE_HUMAN = Field.new :content_size_human, :symbol
32
+ CONTRIBUTOR_FACET = Field.new :contributor_facet, :facetable
33
+ CREATOR_FACET = Field.new :creator_facet, :facetable
34
+ DATE_FACET = Field.new :date_facet, :facetable
35
+ DATE_SORT = Field.new :date_sort, :sortable
36
+ DC_IS_PART_OF = Field.new :isPartOf, :symbol
37
+ DEPOSITOR = Field.new :depositor, :stored_sortable
38
+ DISPLAY_FORMAT = Field.new :display_format, :stored_sortable
39
+ DOI = Field.new :doi, :symbol
40
+ EAD_ID = Field.new :ead_id, :stored_sortable
41
+ ENGRAVER_FACET = Field.new :engraver_facet, :facetable
42
+ EXTRACTED_TEXT = Field.new :extracted_text, solr_name: "extracted_text_tsm"
43
+ FOLDER_FACET = Field.new :folder_facet, :facetable
44
+ FOR_COLLECTION_ID = Field.new :for_collection_id, :symbol
45
+ FORMAT_FACET = Field.new :format_facet, :facetable
46
+ GENRE_FACET = Field.new :genre_facet, :facetable
47
+ IDENTIFIER_ALL = Field.new :identifier_all, :symbol
48
+ ILLUSTRATED_FACET = Field.new :illustrated_facet, :facetable
49
+ ILLUSTRATOR_FACET = Field.new :illustrator_facet, :facetable
50
+ INGESTED_BY = Field.new :ingested_by, :stored_sortable
51
+ INGESTION_DATE = Field.new :ingestion_date, :stored_sortable, type: :date
52
+ INSTRUMENTATION_FACET = Field.new :instrumentation_facet, :facetable
53
+ INTERVIEWER_NAME_FACET = Field.new :interviewer_name_facet, :facetable
54
+ IS_FORMAT_OF = Field.new :isFormatOf, :symbol
55
+ IS_LOCKED = Field.new :is_locked, :stored_sortable
56
+ # Keeping IS_MEMBER_OF_COLLECTION and IS_PART_OF for now for backwards compatibility
57
+ IS_MEMBER_OF_COLLECTION = Field.new :is_member_of_collection, :symbol
58
+ IS_PART_OF = Field.new :is_part_of, :symbol
59
+ LANGUAGE_FACET = Field.new :language_facet, :facetable
60
+ LANGUAGE_NAME = Field.new :language_name, :stored_searchable
61
+ LAST_FIXITY_CHECK_ON = Field.new :last_fixity_check_on, :stored_sortable, type: :date
62
+ LAST_FIXITY_CHECK_OUTCOME = Field.new :last_fixity_check_outcome, :symbol
63
+ LAST_VIRUS_CHECK_ON = Field.new :last_virus_check_on, :stored_sortable, type: :date
64
+ LAST_VIRUS_CHECK_OUTCOME = Field.new :last_virus_check_outcome, :symbol
65
+ LICENSE = Field.new :license, :stored_sortable
66
+ LITHOGRAPHER_FACET = Field.new :lithographer_facet, :facetable
67
+ LOCAL_ID = Field.new :local_id, :stored_sortable
68
+ LYRICIST_FACET = Field.new :lyricist_facet, :facetable
69
+ MEDIA_SUB_TYPE = Field.new :content_media_sub_type, :facetable
70
+ MEDIA_MAJOR_TYPE = Field.new :content_media_major_type, :facetable
71
+ MEDIA_TYPE = Field.new :content_media_type, :symbol
72
+ MEDIUM_FACET = Field.new :medium_facet, :facetable
73
+ MULTIRES_IMAGE_FILE_PATH = Field.new :multires_image_file_path, :stored_sortable
74
+ NESTED_PATH = Field.new :nested_path, :stored_sortable
75
+ NESTED_PATH_TEXT = Field.new :nested_path_text, :searchable
76
+ ORIGINAL_FILENAME = Field.new :original_filename, :stored_sortable
77
+ PARENT_ID = Field.new :parent_id, :symbol
78
+ PERFORMER_FACET = Field.new :performer_facet, :facetable
79
+ PERMANENT_ID = Field.new :permanent_id, :stored_sortable
80
+ PERMANENT_URL = Field.new :permanent_url, :stored_sortable
81
+ PLACEMENT_COMPANY_FACET = Field.new :placement_company_facet, :facetable
82
+ POLICY_ROLE = Field.new :policy_role, :symbol
83
+ PRODUCER_FACET = Field.new :producer_facet, :facetable
84
+ PRODUCT_FACET = Field.new :product_facet, :facetable
85
+ PUBLICATION_FACET = Field.new :publication_facet, :facetable
86
+ PUBLISHER_FACET = Field.new :publisher_facet, :facetable
87
+ RESEARCH_HELP_CONTACT = Field.new :research_help_contact, :stored_sortable
88
+ RESOURCE_CREATE_DATE = Field.new :created_at, :stored_sortable, type: :date
89
+ RESOURCE_MODEL = Field.new :resource_model, solr_name: "internal_resource_ssim"
90
+ RESOURCE_MODIFIED_DATE = Field.new :updated_at, :stored_sortable, type: :date
91
+ RESOURCE_ROLE = Field.new :resource_role, :symbol
92
+ RIGHTS_NOTE = Field.new :rights_note, :stored_searchable
93
+ ROLL_NUMBER_FACET = Field.new :roll_number_facet, :facetable
94
+ SERIES_FACET = Field.new :series_facet, :facetable
95
+ SETTING_FACET = Field.new :setting_facet, :facetable
96
+ SPATIAL_FACET = Field.new :spatial_facet, :facetable
97
+ STREAMABLE_MEDIA_TYPE = Field.new :streamable_media_type, :stored_sortable
98
+ STRUCTURE = Field.new :structure, solr_name: "structure_ss"
99
+ STRUCTURE_SOURCE = Field.new :structure_source, :stored_sortable
100
+ SUBJECT_FACET = Field.new :subject_facet, :facetable
101
+ SUBSERIES_FACET = Field.new :subseries_facet, :facetable
102
+ TARGET_ID = Field.new :target_id, :symbol
103
+ TECHMD_COLOR_SPACE = Field.new :techmd_color_space, :symbol
104
+ TECHMD_CREATING_APPLICATION = Field.new :techmd_creating_application, :symbol
105
+ TECHMD_CREATION_TIME = Field.new :techmd_creation_time, :stored_searchable, type: :date
106
+ TECHMD_FILE_SIZE = Field.new :techmd_file_size, solr_name: "techmd_file_size_lsi"
107
+ TECHMD_FITS_VERSION = Field.new :techmd_fits_version, :stored_sortable
108
+ TECHMD_FITS_DATETIME = Field.new :techmd_fits_datetime, :stored_sortable, type: :date
109
+ TECHMD_FORMAT_LABEL = Field.new :techmd_format_label, :symbol
110
+ TECHMD_FORMAT_VERSION = Field.new :techmd_format_version, :symbol
111
+ TECHMD_ICC_PROFILE_NAME = Field.new :techmd_icc_profile_name, :symbol
112
+ TECHMD_ICC_PROFILE_VERSION = Field.new :techmd_icc_profile_version, :symbol
113
+ TECHMD_IMAGE_HEIGHT = Field.new :techmd_image_height, :stored_searchable, type: :integer
114
+ TECHMD_IMAGE_WIDTH = Field.new :techmd_image_width, :stored_searchable, type: :integer
115
+ TECHMD_MD5 = Field.new :techmd_md5, :stored_sortable
116
+ TECHMD_MEDIA_TYPE = Field.new :techmd_media_type, :symbol
117
+ TECHMD_MODIFICATION_TIME = Field.new :techmd_modification_time, :stored_searchable, type: :date
118
+ TECHMD_PRONOM_IDENTIFIER = Field.new :techmd_pronom_identifier, :symbol
119
+ TECHMD_VALID = Field.new :techmd_valid, :symbol
120
+ TECHMD_WELL_FORMED = Field.new :techmd_well_formed, :symbol
121
+ TEMPORAL_FACET = Field.new :temporal_facet, :facetable
122
+ TITLE = Field.new :title, :stored_sortable
123
+ TONE_FACET = Field.new :tone_facet, :facetable
124
+ TYPE_FACET = Field.new :type_facet, :facetable
125
+ VOLUME_FACET = Field.new :volume_facet, :facetable
126
+ WORKFLOW_STATE = Field.new :workflow_state, :stored_sortable
127
+ YEAR_FACET = Field.new :year_facet, solr_name: "year_facet_iim"
128
+
129
+ def self.get(name)
130
+ const_get(name.to_s.upcase, false)
131
+ end
132
+
133
+ def self.techmd
134
+ @techmd ||= constants(false).select { |c| c =~ /\ATECHMD_/ }.map { |c| const_get(c) }.freeze
135
+ end
136
+
137
+ def self.descmd
138
+ @descmd ||= Ddr::Describable.term_names.map do |term_name|
139
+ Field.new term_name, *Ddr::Describable.indexers_for(term_name)
140
+ end.freeze
141
+ end
142
+
143
+ def self.adminmd
144
+ @adminmd ||= Ddr::HasAdminMetadata.term_names.map do |term_name|
145
+ begin
146
+ get(term_name)
147
+ rescue NameError
148
+ Field.new term_name
149
+ end
150
+ end.freeze
151
+ end
152
+
153
+ end
154
+ end
@@ -0,0 +1,139 @@
1
+ require "forwardable"
2
+ require "virtus"
3
+
4
+ module Ddr::Index
5
+ class Filter
6
+ include Virtus.model
7
+
8
+ attribute :clauses, Array, default: [ ]
9
+
10
+ def ==(other)
11
+ other.instance_of?(self.class) && (other.clauses == self.clauses)
12
+ end
13
+
14
+ module Api
15
+ def raw(*clauses)
16
+ self.clauses += clauses
17
+ self
18
+ end
19
+
20
+ def term(conditions)
21
+ self.clauses += conditions.map { |f, v| QueryClause.term(f, v) }
22
+ self
23
+ end
24
+
25
+ def where(conditions)
26
+ self.clauses += conditions.map { |f, v| QueryClause.where(f, v) }
27
+ self
28
+ end
29
+
30
+ def where_not(conditions)
31
+ self.clauses += conditions.map do |field, v|
32
+ Array(v).map { |value| QueryClause.negative(field, value) }
33
+ end.flatten
34
+ self
35
+ end
36
+
37
+ def absent(field)
38
+ self.clauses << QueryClause.absent(field)
39
+ self
40
+ end
41
+
42
+ def present(field)
43
+ self.clauses << QueryClause.present(field)
44
+ self
45
+ end
46
+
47
+ def negative(field, value)
48
+ self.clauses << QueryClause.negative(field, value)
49
+ self
50
+ end
51
+
52
+ def before(field, value)
53
+ self.clauses << QueryClause.before(field, value)
54
+ self
55
+ end
56
+
57
+ def before_days(field, value)
58
+ self.clauses << QueryClause.before_days(field, value)
59
+ self
60
+ end
61
+
62
+ def join(**args)
63
+ self.clauses << QueryClause.join(**args)
64
+ self
65
+ end
66
+
67
+ def regexp(field, value)
68
+ self.clauses << QueryClause.regexp(field, value)
69
+ self
70
+ end
71
+ end
72
+
73
+ module ClassMethods
74
+ extend Forwardable
75
+
76
+ delegate Api.public_instance_methods => :new_filter
77
+
78
+ def has_content
79
+ model "Ddr::Component", "Ddr::Attachment", "Ddr::Target"
80
+ end
81
+
82
+ def is_governed_by(arg)
83
+ term admin_policy_id: get_join_id(arg)
84
+ end
85
+
86
+ def is_member_of_collection(arg)
87
+ term is_member_of_collection: get_id(arg)
88
+ end
89
+
90
+ def is_part_of(arg)
91
+ term is_part_of: get_id(arg)
92
+ end
93
+
94
+ def model(*models)
95
+ namespaced_models = models.map{ |model| model.starts_with?("Ddr::") ? model : "Ddr::#{model}" }
96
+ where resource_model: namespaced_models
97
+ end
98
+
99
+ private
100
+
101
+ # def get_uri(arg)
102
+ # case arg
103
+ # when ActiveFedora::Base
104
+ # arg.internal_uri
105
+ # when String
106
+ # arg.start_with?("info:fedora/") ? arg : "info:fedora/#{arg}"
107
+ # else
108
+ # raise TypeError, "Argument must be a String or ActiveFedora::Base instance: #{arg.class}"
109
+ # end
110
+ # end
111
+
112
+ def get_id(arg)
113
+ case arg
114
+ when Ddr::Resource
115
+ arg.id.to_s
116
+ when Valkyrie::ID
117
+ arg.to_s
118
+ when String
119
+ arg
120
+ else
121
+ raise TypeError, "Argument must be a String or Ddr::Resource or Valkyrie::ID instance: #{arg.class}"
122
+ end
123
+ end
124
+
125
+ def get_join_id(arg)
126
+ "id-#{get_id(arg)}"
127
+ end
128
+
129
+ def new_filter
130
+ Filter.new
131
+ end
132
+
133
+ end
134
+
135
+ include Api
136
+ extend ClassMethods
137
+
138
+ end
139
+ end