kithe 2.5.0 → 2.6.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/app/derivative_transformers/kithe/ffmpeg_extract_jpg.rb +23 -14
- data/app/indexing/kithe/indexable/record_index_updater.rb +3 -0
- data/app/models/kithe/model.rb +11 -4
- data/app/models/kithe/parameters.rb +17 -4
- data/lib/kithe/indexable_settings.rb +8 -9
- data/lib/kithe/version.rb +1 -1
- data/lib/shrine/plugins/kithe_persisted_derivatives.rb +4 -0
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0ca2d6002aec0accb7264e06f3abcb71f33cf5673fa3ef27bfa035cbca67195
|
4
|
+
data.tar.gz: 9c5ffce36b1ff7a318059babe307627e23ccc00f6997f22a1fdc0d547cfd8a0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42129dea71f6944d2a70ca69cde8c5f1802c8915ce32cf1b237dbc6223edfcd9cefe776255cb2321c1978da8906a322e88ca443240915b6b2ee1eee53063cd42
|
7
|
+
data.tar.gz: 44478b610e5eb8abda0b385932fb8528c3f6b962f77be9168391d940dac26b739c4c9ec81f1b0912123f178c19b2e2837b1cc6e68483b7c8c59d67e40f1bb8dc
|
@@ -15,18 +15,21 @@ module Kithe
|
|
15
15
|
# @param start_seconds [Integer] seek to this point to find thumbnail. If it's
|
16
16
|
# after the end of the video, you won't get a thumb back though! [Default 0]
|
17
17
|
#
|
18
|
-
# @param frame_sample_size [Integer] argument passed to ffmpeg thumbnail filter,
|
18
|
+
# @param frame_sample_size [Integer,false,nil] argument passed to ffmpeg thumbnail filter,
|
19
19
|
# how many frames to sample, starting at start_seconds, to choose representative
|
20
20
|
# thumbnail. If set to false, thumbnail filter won't be used. If this one
|
21
21
|
# goes past the end of the video, ffmpeg is fine with it. Set to `false` to
|
22
22
|
# disable use of ffmpeg sample feature, and just use exact frame at start_seconds.
|
23
|
-
#
|
23
|
+
#
|
24
|
+
# NOTE: This can consume significant RAM depending on value and video resolution.
|
25
|
+
#
|
26
|
+
# [Default false, not operative]
|
24
27
|
#
|
25
28
|
# @width_pixels [Integer] output thumb at this width. aspect ratio will be
|
26
29
|
# maintained. Warning, if it's larger than video original, ffmpeg will
|
27
30
|
# upscale! If set to nil, thumb will be output at original video
|
28
31
|
# resolution. [Default nil]
|
29
|
-
def initialize(start_seconds: 0, frame_sample_size:
|
32
|
+
def initialize(start_seconds: 0, frame_sample_size: false, width_pixels: nil)
|
30
33
|
@start_seconds = start_seconds
|
31
34
|
@frame_sample_size = frame_sample_size
|
32
35
|
@width_pixels = width_pixels
|
@@ -68,30 +71,36 @@ module Kithe
|
|
68
71
|
def _call(ffmpeg_source_arg)
|
69
72
|
tempfile = Tempfile.new(['temp_deriv', ".jpg"])
|
70
73
|
|
74
|
+
ffmpeg_args = produce_ffmpeg_args(input_arg: ffmpeg_source_arg, output_path: tempfile.path)
|
75
|
+
|
76
|
+
TTY::Command.new(printer: :null).run(*ffmpeg_args)
|
77
|
+
|
78
|
+
return tempfile
|
79
|
+
rescue StandardError => e
|
80
|
+
tempfile.unlink if tempfile
|
81
|
+
raise e
|
82
|
+
end
|
83
|
+
|
84
|
+
def produce_ffmpeg_args(input_arg:, output_path:)
|
71
85
|
ffmpeg_args = [ffmpeg_command, "-y"]
|
86
|
+
|
72
87
|
if start_seconds && start_seconds > 0
|
73
88
|
ffmpeg_args.concat ["-ss", start_seconds.to_i]
|
74
89
|
end
|
75
90
|
|
76
|
-
ffmpeg_args.concat ["-i",
|
91
|
+
ffmpeg_args.concat ["-i", input_arg]
|
77
92
|
|
78
93
|
video_filter_parts = []
|
79
|
-
video_filter_parts << "thumbnail=#{frame_sample_size}" if frame_sample_size
|
94
|
+
video_filter_parts << "thumbnail=#{frame_sample_size}" if (frame_sample_size || 0) > 1
|
80
95
|
video_filter_parts << "scale=#{width_pixels}:-1" if width_pixels
|
81
|
-
|
96
|
+
|
97
|
+
if video_filter_parts.present?
|
82
98
|
ffmpeg_args.concat ["-vf", video_filter_parts.join(',')]
|
83
99
|
end
|
84
100
|
|
85
101
|
ffmpeg_args.concat ["-frames:v", "1"]
|
86
102
|
|
87
|
-
ffmpeg_args <<
|
88
|
-
|
89
|
-
TTY::Command.new(printer: :null).run(*ffmpeg_args)
|
90
|
-
|
91
|
-
return tempfile
|
92
|
-
rescue StandardError => e
|
93
|
-
tempfile.unlink if tempfile
|
94
|
-
raise e
|
103
|
+
ffmpeg_args << output_path
|
95
104
|
end
|
96
105
|
end
|
97
106
|
end
|
@@ -24,6 +24,9 @@ module Kithe
|
|
24
24
|
# it's nil, meaning we'll find the indexer to use from current thread settings,
|
25
25
|
# or global settings.
|
26
26
|
#
|
27
|
+
# (note: this design means we can't currently use traject processing_thread_pool for
|
28
|
+
# concurrency, sorry.)
|
29
|
+
#
|
27
30
|
# @param writer [Traject::Writer] Can pass i a custom Traject::Writer which the
|
28
31
|
# index representation will be sent to. By default it's nil, meaning we'll find
|
29
32
|
# the writer to use from current thread settings or global settings.
|
data/app/models/kithe/model.rb
CHANGED
@@ -32,8 +32,11 @@ class Kithe::Model < ActiveRecord::Base
|
|
32
32
|
# this should only apply to Works, but we define it here so we can preload it
|
33
33
|
# when fetching all Kithe::Model. And it's to Kithe::Model so it can include
|
34
34
|
# both Works and Assets. We do some app-level validation to try and make it used
|
35
|
-
# as intended.
|
36
|
-
has_many :members,
|
35
|
+
# as intended. Members are by default ordered by position, then created_at.
|
36
|
+
has_many :members, -> { order(position: :asc, created_at: :asc) },
|
37
|
+
class_name: "Kithe::Model", foreign_key: :parent_id,
|
38
|
+
inverse_of: :parent, dependent: :destroy
|
39
|
+
|
37
40
|
belongs_to :parent, class_name: "Kithe::Model", inverse_of: :members, optional: true
|
38
41
|
|
39
42
|
# a self-referential many-to-many is a bit confusing, but our "contains" relation
|
@@ -130,11 +133,15 @@ class Kithe::Model < ActiveRecord::Base
|
|
130
133
|
LIMIT 1;
|
131
134
|
EOS
|
132
135
|
|
133
|
-
# trying to use a prepared statement, hoping it means performance advantage
|
136
|
+
# trying to use a prepared statement, hoping it means performance advantage,
|
137
|
+
# this is super undocumented
|
138
|
+
|
139
|
+
bind = ActiveRecord::Relation::QueryAttribute.new("m.id", self.representative_id, ActiveRecord::Type::Value.new)
|
140
|
+
|
134
141
|
result = self.class.connection.select_all(
|
135
142
|
recursive_cte,
|
136
143
|
"set_leaf_representative",
|
137
|
-
[
|
144
|
+
[bind],
|
138
145
|
preparable: true
|
139
146
|
).first.try(:dig, "id")
|
140
147
|
|
@@ -63,11 +63,24 @@
|
|
63
63
|
class Kithe::Parameters < ActionController::Parameters
|
64
64
|
attr_reader :auto_allowed_keys
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
|
67
|
+
# Rails 7 adds another initializer method, annoyingly
|
68
|
+
if Rails.version.split.first.to_i >= 7
|
69
|
+
def initialize(hash = {}, logging_context = {})
|
70
|
+
if hash.respond_to?(:to_unsafe_h)
|
71
|
+
hash = hash.to_unsafe_h
|
72
|
+
end
|
73
|
+
|
74
|
+
super(hash, logging_context)
|
75
|
+
end
|
76
|
+
else
|
77
|
+
def initialize(hash = {})
|
78
|
+
if hash.respond_to?(:to_unsafe_h)
|
79
|
+
hash = hash.to_unsafe_h
|
80
|
+
end
|
81
|
+
|
82
|
+
super(hash)
|
69
83
|
end
|
70
|
-
super(hash)
|
71
84
|
end
|
72
85
|
|
73
86
|
def permit_attr_json(klass, except:nil)
|
@@ -6,22 +6,21 @@ module Kithe
|
|
6
6
|
def initialize(solr_url:, writer_class_name:, writer_settings:,
|
7
7
|
model_name_solr_field:, solr_id_value_attribute:, disable_callbacks: false,
|
8
8
|
batching_mode_batch_size: 100)
|
9
|
-
@solr_url = solr_url
|
10
9
|
@writer_class_name = writer_class_name
|
11
10
|
@writer_settings = writer_settings
|
12
11
|
@model_name_solr_field = model_name_solr_field
|
13
12
|
@solr_id_value_attribute = solr_id_value_attribute || 'id'
|
14
13
|
@batching_mode_batch_size = batching_mode_batch_size
|
14
|
+
|
15
|
+
# use our local setter to set solr_url also in writer_settings
|
16
|
+
solr_url = solr_url
|
15
17
|
end
|
16
18
|
|
17
|
-
|
18
|
-
# writer_settings
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
else
|
23
|
-
@writer_settings
|
24
|
-
end
|
19
|
+
|
20
|
+
# set solr_url also in writer_settings, cause it's expected there.
|
21
|
+
def solr_url=(v)
|
22
|
+
@solr_url = v
|
23
|
+
writer_settings["solr.url"] = v if writer_settings
|
25
24
|
end
|
26
25
|
|
27
26
|
# Turn writer_class_name into an actual Class object.
|
data/lib/kithe/version.rb
CHANGED
@@ -134,6 +134,10 @@ class Shrine
|
|
134
134
|
def remove_persisted_derivatives(*paths, **options)
|
135
135
|
return if paths.empty?
|
136
136
|
|
137
|
+
# Shrine does weird things if we pass in Strings, let's save ourselves
|
138
|
+
# the terrible debugging on that mistake, and noramlize to symbols
|
139
|
+
paths = paths.collect(&:to_sym)
|
140
|
+
|
137
141
|
other_changes_allowed = !!options.delete(:allow_other_changes)
|
138
142
|
if record && !other_changes_allowed && record.changed?
|
139
143
|
raise TypeError.new("Can't safely add_persisted_derivatives on model with unsaved changes. Pass `allow_other_changes: true` to force.")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kithe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Rochkind
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: 5.2.1
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '7.1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: 5.2.1
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '7.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: attr_json
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -426,7 +426,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
426
426
|
- !ruby/object:Gem::Version
|
427
427
|
version: '0'
|
428
428
|
requirements: []
|
429
|
-
rubygems_version: 3.2.
|
429
|
+
rubygems_version: 3.2.33
|
430
430
|
signing_key:
|
431
431
|
specification_version: 4
|
432
432
|
summary: Shareable tools/components for building a digital collections app in Rails.
|