hyrax 5.1.0.pre.beta1 → 5.2.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.
- checksums.yaml +4 -4
- data/.dassie/.env +4 -0
- data/.dassie/Gemfile +12 -7
- data/.dassie/app/controllers/application_controller.rb +4 -0
- data/.dassie/app/helpers/hyrax_helper.rb +4 -0
- data/.dassie/app/models/ability.rb +4 -0
- data/.dassie/app/models/user.rb +11 -0
- data/.dassie/app/views/shared/_footer.html.erb +17 -0
- data/.dassie/config/application.rb +1 -1
- data/.dassie/config/database.yml +18 -0
- data/.dassie/config/environments/production.rb +1 -1
- data/.dassie/config/fedora.yml +6 -6
- data/.dassie/config/initializers/devise.rb +1 -0
- data/.dassie/config/initializers/profiler.rb +5 -0
- data/.dassie/config/locales/hyrax.en.yml +1 -1
- data/.dassie/config/puma.rb +55 -5
- data/.dassie/config/routes.rb +2 -0
- data/.dassie/db/migrate/20250328100249_user_roles.rb +20 -0
- data/.dassie/db/schema.rb +123 -109
- data/.github/workflows/lint-build-test.yml +34 -5
- data/.koppie/.env +1 -1
- data/.koppie/Gemfile +10 -6
- data/.koppie/app/controllers/application_controller.rb +4 -0
- data/.koppie/app/helpers/hyrax_helper.rb +4 -0
- data/.koppie/app/models/ability.rb +4 -0
- data/.koppie/app/models/user.rb +10 -0
- data/.koppie/app/views/shared/_footer.html.erb +17 -0
- data/.koppie/config/database.yml +2 -9
- data/.koppie/config/environments/development.rb +9 -0
- data/.koppie/config/environments/production.rb +1 -1
- data/.koppie/config/initializers/1_valkyrie.rb +5 -5
- data/.koppie/config/initializers/devise.rb +1 -1
- data/.koppie/config/initializers/profiler.rb +5 -0
- data/.koppie/config/locales/hyrax.en.yml +2 -2
- data/.koppie/config/puma.rb +26 -7
- data/.koppie/config/routes.rb +2 -0
- data/.koppie/db/schema.rb +109 -110
- data/CONTAINERS.md +10 -10
- data/Dockerfile +108 -50
- data/Gemfile +2 -1
- data/app/controllers/concerns/hyrax/valkyrie_downloads_controller_behavior.rb +1 -0
- data/app/controllers/concerns/hyrax/works_controller_behavior.rb +2 -1
- data/app/controllers/hyrax/admin/analytics/work_reports_controller.rb +4 -4
- data/app/controllers/hyrax/file_sets_controller.rb +11 -0
- data/app/helpers/hyrax/hyrax_helper_behavior.rb +2 -2
- data/app/helpers/hyrax/trophy_helper.rb +1 -1
- data/app/jobs/concerns/hyrax/queued_job_behavior.rb +22 -0
- data/app/jobs/hyrax/propagate_change_depositor_job.rb +1 -1
- data/app/jobs/hyrax/queued_delete_job.rb +11 -0
- data/app/jobs/hyrax/queued_indexing_job.rb +11 -0
- data/app/jobs/migrate_files_to_valkyrie_job.rb +33 -21
- data/app/jobs/migrate_sipity_entity_job.rb +21 -0
- data/app/models/concerns/hyrax/ability.rb +4 -2
- data/app/models/concerns/hyrax/solr_document_behavior.rb +5 -2
- data/app/models/hyrax/file_metadata.rb +22 -7
- data/app/services/hyrax/analytics/ga4/base.rb +1 -1
- data/app/services/hyrax/analytics/ga4.rb +5 -1
- data/app/services/hyrax/change_depositor_service.rb +1 -1
- data/app/services/hyrax/characterization/valkyrie_characterization_service.rb +21 -13
- data/app/services/hyrax/custom_queries/find_ids_by_model.rb +31 -6
- data/app/services/hyrax/edit_permissions_service.rb +9 -8
- data/app/services/hyrax/workflow/workflow_factory.rb +3 -3
- data/app/services/migrate_resource_service.rb +1 -1
- data/app/views/_user_util_links.html.erb +2 -1
- data/app/views/hyrax/admin/analytics/collection_reports/_top_collections.html.erb +3 -7
- data/app/views/hyrax/admin/analytics/work_reports/_top_file_set_downloads.html.erb +3 -6
- data/app/views/hyrax/admin/analytics/work_reports/_top_works.html.erb +2 -3
- data/app/views/hyrax/admin/analytics/work_reports/_work_files.html.erb +1 -6
- data/app/views/hyrax/base/_social_media.html.erb +2 -0
- data/app/views/hyrax/base/iiif_viewers/_universal_viewer.html.erb +1 -1
- data/app/views/hyrax/dashboard/collections/_show_document_list_menu.html.erb +13 -12
- data/app/views/hyrax/my/_admin_set_action_menu.html.erb +31 -27
- data/app/views/hyrax/my/_collection_action_menu.html.erb +40 -35
- data/app/views/hyrax/my/_work_action_menu.html.erb +23 -22
- data/bin/db-migrate-seed.sh +1 -1
- data/bin/dev-entrypoint.sh +3 -0
- data/config/features.rb +50 -40
- data/config/initializers/indexing_adapter_initializer.rb +4 -0
- data/config/initializers/new_framework_defaults_7_2.rb +6 -4
- data/config/initializers/reform_rails_6_1_monkey_patch.rb +29 -0
- data/config/metadata/core_metadata.yaml +1 -0
- data/docker-compose-dassie.yml +6 -6
- data/docker-compose-koppie.yml +2 -2
- data/docker-compose-sirenia.yml +2 -2
- data/documentation/developing-your-hyrax-based-app.md +2 -2
- data/hyrax.gemspec +3 -3
- data/lib/freyja/persister.rb +11 -4
- data/lib/generators/hyrax/install_generator.rb +0 -5
- data/lib/generators/hyrax/templates/.env +1 -1
- data/lib/generators/hyrax/templates/config/initializers/1_valkyrie.rb +21 -19
- data/lib/generators/hyrax/templates/db/migrate/20170131142607_add_permission_template_to_sipity_workflow.rb.erb +1 -1
- data/lib/generators/hyrax/templates/db/migrate/20170810190549_update_collection_type_column_options.rb.erb +1 -1
- data/lib/generators/hyrax/templates/db/migrate/20230821153635_add_fields_to_counter_metric.rb.erb +1 -1
- data/lib/hyrax/configuration.rb +22 -7
- data/lib/hyrax/controlled_vocabulary/importer/language.rb +5 -1
- data/lib/hyrax/transactions/steps/add_file_sets.rb +2 -1
- data/lib/hyrax/version.rb +1 -1
- data/lib/hyrax.rb +1 -0
- data/lib/tasks/workflow.rake +1 -2
- data/lib/valkyrie/indexing/redis_queue/indexing_adapter.rb +144 -0
- data/lib/wings/valkyrie/query_service.rb +3 -4
- data/template.rb +1 -1
- metadata +28 -14
- data/.github/workflows/main.yml +0 -17
data/Dockerfile
CHANGED
@@ -1,50 +1,98 @@
|
|
1
|
-
ARG
|
2
|
-
ARG RUBY_VERSION=3.3
|
3
|
-
|
4
|
-
FROM ruby:$RUBY_VERSION
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
1
|
+
ARG DEBIAN_VERSION=bookworm
|
2
|
+
ARG RUBY_VERSION=3.3
|
3
|
+
|
4
|
+
FROM ruby:$RUBY_VERSION-$DEBIAN_VERSION AS hyrax-base
|
5
|
+
|
6
|
+
RUN apt-get update && \
|
7
|
+
curl -sL "https://deb.nodesource.com/setup_20.x" | bash - && \
|
8
|
+
apt-get install -y --no-install-recommends \
|
9
|
+
acl \
|
10
|
+
build-essential \
|
11
|
+
curl \
|
12
|
+
exiftool \
|
13
|
+
ffmpeg \
|
14
|
+
ghostscript \
|
15
|
+
git \
|
16
|
+
less \
|
17
|
+
libgsf-1-dev \
|
18
|
+
libimagequant-dev \
|
19
|
+
libjemalloc2 \
|
20
|
+
libjpeg62-turbo-dev \
|
21
|
+
libopenjp2-7-dev \
|
22
|
+
libopenjp2-tools \
|
23
|
+
libpng-dev \
|
24
|
+
libpoppler-cpp-dev \
|
25
|
+
libpoppler-dev \
|
26
|
+
libpoppler-glib-dev \
|
27
|
+
libpoppler-private-dev \
|
28
|
+
libpoppler-qt5-dev \
|
29
|
+
libreoffice \
|
30
|
+
libreoffice-l10n-uk \
|
31
|
+
librsvg2-dev \
|
32
|
+
libtiff-dev \
|
33
|
+
libvips-dev \
|
34
|
+
libvips-tools \
|
35
|
+
libwebp-dev \
|
36
|
+
libxml2-dev \
|
37
|
+
lsof \
|
38
|
+
mediainfo \
|
39
|
+
netcat-openbsd \
|
40
|
+
nodejs \
|
41
|
+
perl \
|
42
|
+
poppler-utils \
|
43
|
+
postgresql-client \
|
44
|
+
rsync \
|
45
|
+
ruby-grpc \
|
46
|
+
screen \
|
47
|
+
tesseract-ocr \
|
48
|
+
tzdata \
|
49
|
+
vim \
|
50
|
+
zip \
|
51
|
+
&& \
|
52
|
+
npm install --global yarn && \
|
53
|
+
apt-get clean && \
|
54
|
+
rm -rf /var/lib/apt/lists/* && \
|
55
|
+
ln -s /usr/lib/*-linux-gnu/libjemalloc.so.2 /usr/lib/libjemalloc.so.2 && \
|
56
|
+
echo "******** Packages Installed *********"
|
57
|
+
|
58
|
+
RUN bash -x -c "\
|
59
|
+
if [ $(dpkg --print-architecture) = 'amd64' ]; then \
|
60
|
+
wget https://github.com/ImageMagick/ImageMagick/releases/download/7.1.1-47/ImageMagick-82572af-gcc-x86_64.AppImage -O magick \
|
61
|
+
&& chmod a+x magick \
|
62
|
+
&& ./magick --appimage-extract \
|
63
|
+
&& mv squashfs-root/usr/etc/ImageMagick* /etc \
|
64
|
+
&& rm -rf squashfs-root/usr/share/doc \
|
65
|
+
&& cp -rv squashfs-root/usr/* /usr/local \
|
66
|
+
&& rm -rf magick squashfs-root ; \
|
67
|
+
else \
|
68
|
+
wget https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.1-47.tar.gz \
|
69
|
+
&& tar xf 7.1.1-47.tar.gz \
|
70
|
+
&& cd ImageMagick* \
|
71
|
+
&& ./configure \
|
72
|
+
&& make install \
|
73
|
+
&& ldconfig /usr/local/lib \
|
74
|
+
&& cd $OLDPWD \
|
75
|
+
&& rm -rf 7.1.1-47.tar.gz ImageMagick* ; \
|
76
|
+
fi \
|
77
|
+
&& identify -version"
|
34
78
|
|
35
79
|
RUN setfacl -d -m o::rwx /usr/local/bundle && \
|
36
|
-
|
80
|
+
gem update --silent --system
|
37
81
|
|
38
|
-
|
82
|
+
RUN useradd -m -u 1001 -U -s /bin/bash --home-dir /app app && \
|
83
|
+
mkdir -p /app/samvera/hyrax-webapp && \
|
84
|
+
chown -R app:app /app && \
|
85
|
+
echo "export PATH=/app/samvera/hyrax-webapp/bin:${PATH}" >> /etc/bash.bashrc
|
39
86
|
|
40
|
-
|
87
|
+
USER app
|
41
88
|
WORKDIR /app/samvera/hyrax-webapp
|
42
89
|
|
43
|
-
COPY --chown=1001
|
90
|
+
COPY --chown=1001 ./bin/*.sh /app/samvera/
|
44
91
|
ENV PATH="/app/samvera:$PATH" \
|
45
92
|
RAILS_ROOT="/app/samvera/hyrax-webapp" \
|
46
93
|
RAILS_SERVE_STATIC_FILES="1" \
|
47
|
-
LD_PRELOAD="/usr/
|
94
|
+
LD_PRELOAD="/usr/lib/libjemalloc.so.2" \
|
95
|
+
MALLOC_CONF="dirty_decay_ms:1000,narenas:2,background_thread:true"
|
48
96
|
|
49
97
|
ENTRYPOINT ["hyrax-entrypoint.sh"]
|
50
98
|
CMD ["bundle", "exec", "puma", "-v", "-b", "tcp://0.0.0.0:3000"]
|
@@ -55,22 +103,23 @@ FROM hyrax-base AS hyrax
|
|
55
103
|
ARG APP_PATH=.
|
56
104
|
ARG BUNDLE_WITHOUT="development test"
|
57
105
|
|
58
|
-
ONBUILD COPY --chown=1001
|
106
|
+
ONBUILD COPY --chown=1001 $APP_PATH /app/samvera/hyrax-webapp
|
59
107
|
ONBUILD RUN bundle install --jobs "$(nproc)"
|
60
108
|
ONBUILD RUN RAILS_ENV=production SECRET_KEY_BASE=`bin/rake secret` DATABASE_URL='nulldb://nulldb' bundle exec rake assets:precompile
|
109
|
+
ARG BUILD_GITSHA
|
110
|
+
ARG BUILD_TIMESTAMP
|
111
|
+
ENV BUILD_GITSHA=$BUILD_GITSHA \
|
112
|
+
BUILD_TIMESTAMP=$BUILD_TIMESTAMP
|
61
113
|
|
62
114
|
|
63
115
|
FROM hyrax-base AS hyrax-worker-base
|
64
|
-
|
65
116
|
USER root
|
66
|
-
RUN apk --no-cache add bash \
|
67
|
-
ffmpeg \
|
68
|
-
mediainfo \
|
69
|
-
openjdk17-jre \
|
70
|
-
perl
|
71
|
-
USER app
|
72
117
|
|
73
|
-
RUN
|
118
|
+
RUN apt update && \
|
119
|
+
apt install -y --no-install-recommends default-jre-headless && \
|
120
|
+
apt-get clean && \
|
121
|
+
rm -rf /var/lib/apt/lists/* && \
|
122
|
+
mkdir -p /app/fits && \
|
74
123
|
cd /app/fits && \
|
75
124
|
wget https://github.com/harvard-lts/fits/releases/download/1.6.0/fits-1.6.0.zip -O fits.zip && \
|
76
125
|
unzip fits.zip && \
|
@@ -90,6 +139,10 @@ ARG BUNDLE_WITHOUT="development test"
|
|
90
139
|
ONBUILD COPY --chown=1001:101 $APP_PATH /app/samvera/hyrax-webapp
|
91
140
|
ONBUILD RUN bundle install --jobs "$(nproc)"
|
92
141
|
ONBUILD RUN RAILS_ENV=production SECRET_KEY_BASE=`bin/rake secret` DATABASE_URL='nulldb://nulldb' bundle exec rake assets:precompile
|
142
|
+
ARG BUILD_GITSHA
|
143
|
+
ARG BUILD_TIMESTAMP
|
144
|
+
ENV BUILD_GITSHA=$BUILD_GITSHA \
|
145
|
+
BUILD_TIMESTAMP=$BUILD_TIMESTAMP
|
93
146
|
|
94
147
|
|
95
148
|
FROM hyrax-worker-base AS hyrax-engine-dev
|
@@ -98,8 +151,9 @@ USER app
|
|
98
151
|
ARG BUNDLE_WITHOUT=
|
99
152
|
ENV HYRAX_ENGINE_PATH=/app/samvera/hyrax-engine
|
100
153
|
|
101
|
-
COPY --chown=1001
|
102
|
-
COPY --chown=1001
|
154
|
+
COPY --chown=1001 .dassie /app/samvera/hyrax-webapp
|
155
|
+
COPY --chown=1001 .koppie /app/samvera/hyrax-koppie
|
156
|
+
COPY --chown=1001 . /app/samvera/hyrax-engine
|
103
157
|
|
104
158
|
RUN bundle -v && \
|
105
159
|
BUNDLE_GEMFILE=Gemfile.dassie bundle install --jobs "$(nproc)" && yarn && \
|
@@ -107,4 +161,8 @@ RUN bundle -v && \
|
|
107
161
|
yarn cache clean
|
108
162
|
|
109
163
|
ENTRYPOINT ["dev-entrypoint.sh"]
|
110
|
-
CMD ["bundle", "exec", "puma", "-v", "-b", "tcp://0.0.0.0:3000"]
|
164
|
+
CMD ["bundle", "exec", "puma", "-v", "-b", "tcp://0.0.0.0:3000"]
|
165
|
+
ARG BUILD_GITSHA
|
166
|
+
ARG BUILD_TIMESTAMP
|
167
|
+
ENV BUILD_GITSHA=$BUILD_GITSHA \
|
168
|
+
BUILD_TIMESTAMP=$BUILD_TIMESTAMP
|
data/Gemfile
CHANGED
@@ -102,6 +102,7 @@ module Hyrax
|
|
102
102
|
def find_file_metadata(file_set:, use: :original_file, mime_type: nil)
|
103
103
|
if mime_type.nil?
|
104
104
|
use = :thumbnail_file if use == :thumbnail
|
105
|
+
use = :original_file unless Hyrax::FileMetadata::Use.keys.include?(use)
|
105
106
|
use = Hyrax::FileMetadata::Use.uri_for(use: use)
|
106
107
|
results = Hyrax.custom_queries.find_many_file_metadata_by_use(resource: file_set, use: use)
|
107
108
|
else
|
@@ -359,8 +359,9 @@ module Hyrax
|
|
359
359
|
# intersection, we get the files they added via BrowseEverything
|
360
360
|
# that they have not removed from the upload widget.
|
361
361
|
uploaded_files = params.fetch(:uploaded_files, [])
|
362
|
+
params.permit(selected_files: [:expires, :file_name, :url])
|
362
363
|
selected_files = params.fetch(:selected_files, {}).values
|
363
|
-
|
364
|
+
|
364
365
|
browse_everything_urls = uploaded_files &
|
365
366
|
selected_files.map { |f| f[:url] }
|
366
367
|
|
@@ -14,9 +14,9 @@ module Hyrax
|
|
14
14
|
@works_count = @accessible_works.count
|
15
15
|
@top_works = paginate(top_works_list, rows: 10)
|
16
16
|
@top_file_set_downloads = paginate(top_files_list, rows: 10)
|
17
|
-
|
18
|
-
@pageviews = Hyrax::Analytics.daily_events('work-view'),
|
19
|
-
|
17
|
+
# rubocop:disable Style/ParallelAssignment
|
18
|
+
@pageviews, @downloads = Hyrax::Analytics.daily_events('work-view'), Hyrax::Analytics.daily_events('file-set-download') if current_user.ability.admin?
|
19
|
+
# rubocop:enable Style/ParallelAssignment
|
20
20
|
respond_to do |format|
|
21
21
|
format.html
|
22
22
|
format.csv { export_data }
|
@@ -34,7 +34,7 @@ module Hyrax
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
private
|
38
38
|
|
39
39
|
def accessible_works
|
40
40
|
models = Hyrax::ModelRegistry.work_rdf_representations.map { |m| "\"#{m}\"" }
|
@@ -9,6 +9,10 @@ module Hyrax
|
|
9
9
|
|
10
10
|
before_action :authenticate_user!, except: [:show, :citation, :stats]
|
11
11
|
load_and_authorize_resource class: Hyrax.config.file_set_class
|
12
|
+
# If Hyrax.config.file_set_class is set to ::FileSet, the load above will force-cast
|
13
|
+
# the instance as a ::FileSet, even if it is a Hyrax::FileSet. Re-cast it back to
|
14
|
+
# prevent method errors and nil objects later
|
15
|
+
before_action :cast_file_set
|
12
16
|
before_action :build_breadcrumbs, only: [:show, :edit, :stats]
|
13
17
|
before_action do
|
14
18
|
blacklight_config.track_search_session = false
|
@@ -159,6 +163,13 @@ module Hyrax
|
|
159
163
|
attrs
|
160
164
|
end
|
161
165
|
|
166
|
+
def cast_file_set
|
167
|
+
return unless @file_set.class == ::FileSet
|
168
|
+
# We can tell if a Hyrax::FileSet was improperly cast because this AF method will
|
169
|
+
# return nil since its parent is not a ActiveFedora work.
|
170
|
+
@file_set = @file_set.valkyrie_resource if @file_set.respond_to?(:parent) && @file_set.parent&.id.nil?
|
171
|
+
end
|
172
|
+
|
162
173
|
def parent(file_set: curation_concern)
|
163
174
|
@parent ||=
|
164
175
|
case file_set
|
@@ -68,10 +68,10 @@ module Hyrax
|
|
68
68
|
mailbox = UserMailbox.new(user)
|
69
69
|
unread_notifications = mailbox.unread_count
|
70
70
|
link_to(hyrax.notifications_path,
|
71
|
-
'aria-
|
71
|
+
'aria-description' => mailbox.label(params[:locale]),
|
72
72
|
class: 'notify-number nav-link') do
|
73
73
|
capture do
|
74
|
-
concat tag.span('', class: 'fa fa-bell')
|
74
|
+
concat tag.span('', class: 'fa fa-bell', 'aria-label': t('hyrax.admin.sidebar.notifications'))
|
75
75
|
concat "\n"
|
76
76
|
concat tag.span(unread_notifications,
|
77
77
|
class: count_classes_for(unread_notifications))
|
@@ -15,7 +15,7 @@ module Hyrax
|
|
15
15
|
args[:data]['remove-text'] = args[:remove_text]
|
16
16
|
|
17
17
|
args[:data][:url] = hyrax.trophy_work_path(id)
|
18
|
-
link_to '#', id: 'action-highlight-work', class: args[:class], data: args[:data] do
|
18
|
+
link_to '#', id: 'action-highlight-work', role: args[:role], class: args[:class], data: args[:data] do
|
19
19
|
yield(text)
|
20
20
|
end
|
21
21
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Hyrax
|
3
|
+
# Grants the user's edit access on the provided FileSet
|
4
|
+
module QueuedJobBehavior
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
queue_as Hyrax.config.ingest_queue_name
|
9
|
+
cattr_accessor :requeue_frequency
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def redis_queue
|
15
|
+
Valkyrie::IndexingAdapter.find(:redis_queue)
|
16
|
+
end
|
17
|
+
|
18
|
+
def requeue(**args)
|
19
|
+
self.class.set(wait_until: (self.class.requeue_frequency || 5.minutes).from_now).perform_later(**args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -26,7 +26,7 @@ module Hyrax
|
|
26
26
|
def apply_depositor_metadata(resource, depositor)
|
27
27
|
depositor_id = depositor.respond_to?(:user_key) ? depositor.user_key : depositor
|
28
28
|
resource.depositor = depositor_id if resource.respond_to? :depositor=
|
29
|
-
|
29
|
+
resource.permission_manager.acl.grant(:edit).to(::User.find_by_user_key(depositor_id)).save
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -2,6 +2,11 @@
|
|
2
2
|
# Responsible for conditionally enqueuing the file and thumbnail migration
|
3
3
|
# logic of an ActiveFedora object.
|
4
4
|
class MigrateFilesToValkyrieJob < Hyrax::ApplicationJob
|
5
|
+
# Define a logger for this job
|
6
|
+
def logger
|
7
|
+
FileUtils.mkdir_p(Hyrax.config.working_path)
|
8
|
+
@logger ||= Logger.new(Hyrax.config.working_path.join('migrate_files_to_valkyrie_job.log'))
|
9
|
+
end
|
5
10
|
##
|
6
11
|
#
|
7
12
|
# @param resource [Hyrax::FileSet]
|
@@ -33,6 +38,7 @@ class MigrateFilesToValkyrieJob < Hyrax::ApplicationJob
|
|
33
38
|
# @todo should we trigger a job if the member is a child work?
|
34
39
|
paths = Hyrax::DerivativePath.derivatives_for_reference(resource)
|
35
40
|
paths.each do |path|
|
41
|
+
next unless File.size?(path) # skip blank files
|
36
42
|
container = container_for(path)
|
37
43
|
mime_type = Marcel::MimeType.for(extension: File.extname(path))
|
38
44
|
directives = { url: path, container: container, mime_type: mime_type }
|
@@ -50,27 +56,33 @@ class MigrateFilesToValkyrieJob < Hyrax::ApplicationJob
|
|
50
56
|
|
51
57
|
files = Hyrax.custom_queries.find_many_file_metadata_by_ids(ids: resource.file_ids)
|
52
58
|
files.each do |file|
|
53
|
-
|
54
|
-
|
55
|
-
|
59
|
+
begin
|
60
|
+
# If it doesn't start with fedora, we've likely already migrated it.
|
61
|
+
next unless /^fedora:/.match?(file.file_identifier.to_s)
|
62
|
+
resource.file_ids.delete(file.id)
|
56
63
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
64
|
+
Tempfile.create do |tempfile|
|
65
|
+
tempfile.binmode
|
66
|
+
tempfile.write(URI.open(file.file_identifier.to_s.gsub("fedora:", "http:")).read)
|
67
|
+
tempfile.rewind
|
61
68
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
69
|
+
# valkyrie_file = Hyrax.storage_adapter.upload(resource: resource, file: tempfile, original_filename: file.original_filename)
|
70
|
+
valkyrie_file = Hyrax::ValkyrieUpload.file(
|
71
|
+
filename: resource.label,
|
72
|
+
file_set: resource,
|
73
|
+
io: tempfile,
|
74
|
+
use: file.pcdm_use.select {|use| Hyrax::FileMetadata::Use.use_list.include?(use)},
|
75
|
+
user: User.find_or_initialize_by(User.user_key_field => resource.depositor),
|
76
|
+
mime_type: file.mime_type,
|
77
|
+
skip_derivatives: true
|
78
|
+
)
|
79
|
+
valkyrie_file = copy_attributes(valkyrie_file:, original_file: file)
|
80
|
+
Hyrax.persister.save(resource: valkyrie_file)
|
81
|
+
end
|
82
|
+
rescue StandardError => e
|
83
|
+
# Log errors specific to file migration
|
84
|
+
logger.error("Error migrating file #{file.id} for resource #{resource.id}: #{e.message}")
|
85
|
+
logger.error(e.backtrace.join("\n"))
|
74
86
|
end
|
75
87
|
end
|
76
88
|
# reindex the file set after migrating files to include characterization info
|
@@ -93,9 +105,9 @@ class MigrateFilesToValkyrieJob < Hyrax::ApplicationJob
|
|
93
105
|
#
|
94
106
|
# @param filename [String] the name of the derivative file: i.e. 'x-thumbnail.jpg'
|
95
107
|
# @return [String]
|
96
|
-
def container_for(
|
108
|
+
def container_for(path)
|
97
109
|
# we want the portion between the '-' and the '.'
|
98
|
-
file_blob = File.basename(
|
110
|
+
file_blob = File.basename(path, '.*').split('-').last
|
99
111
|
|
100
112
|
case file_blob
|
101
113
|
when 'thumbnail'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# migrates a resource's sipity entity so it can be found
|
4
|
+
class MigrateSipityEntityJob < ApplicationJob
|
5
|
+
# input [String] id of a migrated resource
|
6
|
+
def perform(id:)
|
7
|
+
resource = Hyrax.query_service.find_by(id: id)
|
8
|
+
new_gid = Hyrax::GlobalID(resource).to_s
|
9
|
+
return if Sipity::Entity.find_by(proxy_for_global_id: new_gid)
|
10
|
+
|
11
|
+
work = resource.internal_resource.constantize.find(id)
|
12
|
+
original_gid = Hyrax::GlobalID(work).to_s
|
13
|
+
return if new_gid == original_gid
|
14
|
+
original_entity = Sipity::Entity.find_by(proxy_for_global_id: original_gid)
|
15
|
+
return if original_entity.nil?
|
16
|
+
original_entity.update(proxy_for_global_id: new_gid)
|
17
|
+
rescue ActiveFedora::ObjectNotFoundError
|
18
|
+
# this happens when the resource was never in Fedora so there is nothing to migrate.
|
19
|
+
# We don't want to retry the job so we don't raise an error.
|
20
|
+
end
|
21
|
+
end
|
@@ -404,8 +404,10 @@ module Hyrax
|
|
404
404
|
.select(:source_id)
|
405
405
|
.distinct
|
406
406
|
.pluck(:source_id)
|
407
|
-
|
408
|
-
Hyrax.
|
407
|
+
return false if ids.empty?
|
408
|
+
Hyrax::SolrQueryService.new.with_ids(ids: ids).query_result(rows: 1000)['response']['docs'].any? do |doc|
|
409
|
+
(Hyrax::ModelRegistry.admin_set_rdf_representations & doc['has_model_ssim']).present?
|
410
|
+
end
|
409
411
|
end
|
410
412
|
|
411
413
|
def registered_user?
|
@@ -82,9 +82,12 @@ module Hyrax
|
|
82
82
|
|
83
83
|
# Method to return the model
|
84
84
|
def hydra_model(classifier: nil)
|
85
|
+
# finds the model from the solr document
|
85
86
|
model = first('has_model_ssim')&.safe_constantize
|
86
|
-
|
87
|
-
|
87
|
+
# this returns nil if it isn't a valid model
|
88
|
+
resource_model = (first('has_model_ssim')&.+ 'Resource')&.safe_constantize if Hyrax.config.valkyrie_transition?
|
89
|
+
# if valkyrie_transition is enabled, we generally want to use the resource model if it exists
|
90
|
+
resource_model || model || model_classifier(classifier).classifier(self).best_model
|
88
91
|
end
|
89
92
|
|
90
93
|
def depositor(default = '')
|
@@ -44,16 +44,31 @@ module Hyrax
|
|
44
44
|
|
45
45
|
# @return [Array<RDF::URI>] list of all uses
|
46
46
|
def use_list
|
47
|
-
[
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
47
|
+
[
|
48
|
+
EXTRACTED_TEXT,
|
49
|
+
INTERMEDIATE_FILE,
|
50
|
+
ORIGINAL_FILE,
|
51
|
+
PRESERVATION_FILE,
|
52
|
+
SERVICE_FILE,
|
53
|
+
THUMBNAIL_IMAGE,
|
54
|
+
TRANSCRIPT
|
55
|
+
]
|
54
56
|
end
|
55
57
|
module_function :use_list
|
56
58
|
|
59
|
+
def keys
|
60
|
+
[
|
61
|
+
:extracted_file,
|
62
|
+
:intermediate_file,
|
63
|
+
:original_file,
|
64
|
+
:preservation_file,
|
65
|
+
:service_file,
|
66
|
+
:thumbnail_file,
|
67
|
+
:transcript_file
|
68
|
+
]
|
69
|
+
end
|
70
|
+
module_function :keys
|
71
|
+
|
57
72
|
##
|
58
73
|
# @param use [RDF::URI, Symbol]
|
59
74
|
#
|
@@ -76,7 +76,11 @@ module Hyrax
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def account_info
|
79
|
-
@account_info ||=
|
79
|
+
@account_info ||= if account_json_string.is_a? Hash
|
80
|
+
account_json_string
|
81
|
+
else
|
82
|
+
JSON.parse(account_json_string)
|
83
|
+
end
|
80
84
|
end
|
81
85
|
|
82
86
|
KEYS.each do |key|
|
@@ -63,7 +63,7 @@ module Hyrax
|
|
63
63
|
def self.apply_depositor_metadata(resource, depositor)
|
64
64
|
depositor_id = depositor.respond_to?(:user_key) ? depositor.user_key : depositor
|
65
65
|
resource.depositor = depositor_id if resource.respond_to? :depositor=
|
66
|
-
|
66
|
+
resource.permission_manager.acl.grant(:edit).to(::User.find_by_user_key(depositor_id)).save
|
67
67
|
end
|
68
68
|
private_class_method :apply_depositor_metadata
|
69
69
|
end
|
@@ -107,13 +107,19 @@ class Hyrax::Characterization::ValkyrieCharacterizationService
|
|
107
107
|
end
|
108
108
|
|
109
109
|
# Assign values of the instance properties from the metadata mapping :prop => val
|
110
|
+
# @todo push exceptional per-property behavior into the mapping somehow?
|
110
111
|
# @return [Hash]
|
111
112
|
def apply_metadata(terms)
|
112
|
-
terms.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
113
|
+
values_by_property(terms).each do |property, values|
|
114
|
+
value = if property == :mime_type
|
115
|
+
values.last
|
116
|
+
elsif [:height, :width].include?(property)
|
117
|
+
# keep only the max height or width
|
118
|
+
values.map(&:to_i).max.to_s
|
119
|
+
else
|
120
|
+
values
|
121
|
+
end
|
122
|
+
metadata.public_send("#{property}=", value)
|
117
123
|
end
|
118
124
|
end
|
119
125
|
|
@@ -127,13 +133,15 @@ class Hyrax::Characterization::ValkyrieCharacterizationService
|
|
127
133
|
end
|
128
134
|
end
|
129
135
|
|
130
|
-
|
131
|
-
#
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
136
|
+
# Map each term to the corresponding property
|
137
|
+
# (multiple terms can map to the same property),
|
138
|
+
# and gather all values for each property
|
139
|
+
# @return [Hash]
|
140
|
+
def values_by_property(terms)
|
141
|
+
terms.each_with_object({}) do |(term, value), property_values|
|
142
|
+
next unless (property = property_for(term))
|
143
|
+
|
144
|
+
(property_values[property] ||= []).concat(Array(value))
|
145
|
+
end
|
138
146
|
end
|
139
147
|
end
|