kithe 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9a96dd80fc482ea07bd35456a0cf8445b722354cd6fe1fda10460398a0d7846
4
- data.tar.gz: 0ccb6788a1ac0f88a47202767f1a5acb7dc12031cc4293ec27e09ded198b8daf
3
+ metadata.gz: df697bf6cd0128be5ee217fb3eb191af55994b1284e1e05f75da73667e92d8f3
4
+ data.tar.gz: f388992232e60a99f7a6f7a2743e47a1690152665b9c85adbdf34457ce822104
5
5
  SHA512:
6
- metadata.gz: 46bcc8b60dd795e4f6e063aef6c7702184d853f2266f3fb5db4636074379faf3a45a1baae83e0d0358cea6fa8c8620a43727d9ee90cffb511c28e371072fe8ad
7
- data.tar.gz: d4250716ef0b4c32c2b993a1989290a59afdb56be2159a8f814bd3b62bfe5e853845188b3200bc1c9be2f8c8f5bad950276e1286324d9f28d890e50c2ccf7a86
6
+ metadata.gz: '079a440ca120cc56e4a624b335cab990b2dc0f8a7df73821f251ecae4bf17f91000e9f57bc59c01d6a378577c871d1bc5d8a31ccee3a49a8402459edb532c7c0'
7
+ data.tar.gz: 73ba63882d5df383011c354c648b82f422891018679c8397a13143a937f9f9a12142eac18ea22d3162bb0f3f127b7ba9234a7309a18bd6329013c598ad17737d
data/README.md CHANGED
@@ -7,54 +7,32 @@ An experiment in shareable tools/components for building a digital collections a
7
7
 
8
8
  Kithe is a toolkit for building digital collections/repository applications in Rails. It comes out of experience in the [samvera](https://samvera.org/) community of open source library-archives-museums digital collections/preservation work (but is not a samvera project).
9
9
 
10
- Kithe does not use fedora or valkyrie, but stores all metadata using ActiveRecord. Kithe requires you use postgres 9.5+ as your db. While kithe provides some additional architecture and support on top of "ordinary" ActiveRecord, it tries to mostly let you develop as you would any Rails app, inclduing all choices and you'd normally have, and taking advantage of standard ActiveRecord-based functionality. Kithe bases it's file handling framework on [shrine](https://shrinerb.com), supporting cloud or local file storage.
10
+ Kithe does not use fedora or valkyrie, but stores all metadata using ActiveRecord. Kithe requires you use postgres 9.5+ as your db. It uses [shrine](https://shrinerb.com) for file-handling/asset-storing and tries to support developing your app as a normal Rails/ActiveRecord app. It will not give you a working turnkey application, but is a collection of tools for building an app with certain patterns.
11
11
 
12
- Kithe will not give you a working "turnkey" application. It is a collection of tools to help you write a Rails app. You may end up using some but not all of kithe's tools. The range of tools provided and areas of an app given some support in kithe will probably grow over time, in hopefully a careful and cautious way.
12
+ Kithe provides tools to supports these architectural patterns:
13
13
 
14
- In that it provides tools and not a turnkey app, develping an app based on kythe in some ways similar to developing an app based on [valkyrie](https://github.com/samvera-labs/valkyrie). They both provide basic architecture for modelling/persistence, although in quite different ways. Kithe also provides tools in addition to modelling/persistence, but does _not_ provide the data-mapper/repository pattern valkyrie does, or any built-in abstraction for persisting anywhere but a postgres DB.
14
+ * [Modelling and Persistence](./guides/modelling.md):
15
+ * A Collection/Work/Asset model based on Samvera/PCDM, using rails Single-Table Inheritance to support hetereogenous associations with efficient rdbms lookup.
16
+ * Using Postgres JSONB for "schema-less" flexible storage, via [attr_json](https://github.com/jrochkind/attr_json), supporting complex structured nested repeatable data values.
17
+ * [Work representatives](./guides/work_representative.md) via ActiveRecord association, using postgres recursive CTE's to compute the "leaf" representative, designed to support efficient use of the DB including pre-loading leaf representatives.
18
+ * UUIDv4's as internal primary keys, but also provide a "friendlier_id" with a shorter unique alphanumeric identifier for URLs and other UI. By default they are supplied by a postgres stored procedure, but your code can set them to whatever you like.
15
19
 
16
- If you are comparing it to a "solution bundle" digital collections platform, kithe may seem like more work. But experience has shown me that in our domain, historically "solution bundles" can be less of a "turnkey" approach than they seem, and can have greater development cost over total app lifecycle than anticipated. If you have similar experience that leads you to consider a more 'bespoke' app approach -- you may want to consider kithe. We hope to provide architecturally simple support and standardization for your custom app, taking care of some of the common "hard parts" and leaving you with flexibility to build out the app that meets your needs.
17
-
18
- Kithe has beeen developed in tandem with the Science History Institute's in-development [replacement digital collections](https://github.com/sciencehistory/scihist_digicoll) app, and you can look there for a model/canonical/demo kithe use.
19
-
20
- The Science History Institute app is live and working, so kithe is 1.0. We are serious about [semantic verisioning](https://semver.org/) and will endeavor to release backwards breaking changes only with a major release, and minimize major releases.
21
-
22
- While it is working well for us, since it hasn't had wide use, it could still be considered somewhat of an experiment. But you are invited to try it out and see how it works. You are welcome to use it, but also welcome to copy any code or just ideas from kithe.
23
-
24
- Any questions or feedback of any kind are very welcome and encouraged, in the github project issues, samvera slack, or wherever is convenient.
25
-
26
-
27
- # Kithe parts
28
-
29
- Some guide documentation is available to explain each of kithe's major functionality areas. Definitely start with the modelling guide.
30
-
31
- * [Modelling and Persistence](./guides/modelling.md): It can be somewhwat challenging to figure out a good way to model our data in an rdbms. We give you a hopefully flexible and understandable architecture that is designed to support efficient performance. It's influenced by PCDM and traditional samvera modelling. It's based on [attr_json](https://github.com/jrochkind/attr_json) to let you model arbitrary and complex object-oriented data that gets persisted as a serialized json hash. It uses rails Single Table Inheritance to support hetereogenous associations and collections. The modelling classes in some places use postgres-specific features for efficiency.
32
-
33
- * [Work representatives](./guides/work_representative.md). Built in associations to support "representative", using postgres recursive CTE's to compute the "leaf" representative, designed to support efficient use of the DB including pre-loading leaf representatives.
34
-
35
- * Kithe objects use UUIDv4's as internal primary keys, but also provide a "friendlier_id" with a shorter unique alphanumeric identifier for URLs and other UI. By default they are supplied by a postgres stored procedure, but your code can set them to whatever you like.
36
-
37
- * [Form support](./guides/forms.md): Dealing with complex and _repeatable_ data, as our modelling layer allows, can be tricky in an HTML form. We supply javascript-backed Rails form input help for repeatable and compound/nested data.
20
+ * [Form support](./guides/forms.md): Easy Rails-like forms for that complex nested and repeatable form data, leaning on simple_form.
38
21
  * An extension to Rails "strong parameters" that make some common patterns for
39
- embedded JSON attributes more convenient, [Kithe::Parameters](./app/models/kithe/parameters.rb).
40
-
41
- * [File handling](./guides/file_handling.md): Handling files is at the core of digital repository use cases. We need a file handling framework that is flexible, predictable and reliable, and architected for performance. We try to give you one based on the [shrine](https://shrinerb.com) file attachment toolkit for ruby.
22
+ embedded JSON attributes more convenient, [Kithe::Parameters](./app/models/kithe/parameters.rb)
42
23
 
43
- * [Derivatives](./guides/derivatives.md) A flexible and reliable derivatives architecture, designed to ensure data consistency without race conditions, and support efficient DB usage patterns.
24
+ * [File handling](./guides/file_handling.md): A framework that let's you easily plug in your own custom characterization and derivatives handling, to be handled in an efficient and flexible way, ordinarily using background jobs. Implemented on top of [shrine](https://shrinerb.com).
25
+ * [Derivatives](./guides/derivatives.md) handling ensures data consistency without race conditions, and efficient querying patterns, letting you plugin custom derivatives creation, with some standard routines included.
44
26
 
45
- * [Solr Indexing](./guides/solr_indexing.md): Uses [traject](https://github.com/traject/traject) for defining mappings from your model objects to what you want in a Solr index. Uses ActiveRecord callbacks to automatically sync saves to solr, with many opportunities for customization.
27
+ * [Solr Indexing](./guides/solr_indexing.md): Built-in Solr indexing using [traject](https://github.com/traject/traject) for defining mappings from your model objects to what you want in a Solr index. Uses ActiveRecord callbacks to automatically sync saves to solr, with many opportunities for customization.
46
28
  * Not coupled to any other kithe components, could be used independently, hypothetically on any ActiveRecord model.
47
- * Written after review of "prior art" in [sunspot](https://github.com/sunspot/sunspot) and [searchkick](https://github.com/ankane/searchkick) (which both used AR callback-based indexing), and others.
48
-
49
- * A [recommended approach for using Blacklight](./guides/blacklight_approach.md) with search result view templates based on actual ActiveRecord models. It is totally optional to use Blacklight at all with kithe, or to use this approach if you do.
50
29
 
51
- ### Also
30
+ * A [recommended approach for using Blacklight](./guides/blacklight_approach.md) with search result view templates based on actual ActiveRecord models. Blacklight use is optional with kithe, but kithe works well with blacklight.
52
31
 
53
- * [Kithe::Parameters](./app/models/kithe/parameters.rb) provides some shortcuts around Rails "strong params" for attr_json serialized attributes.
32
+ * Assorted optional utilities
33
+ * [Kithe::ConfigBase](./app/models/kithe/config_base.rb) A totally optional solution for managing environmental config variables.
54
34
 
55
- * [Kithe::ConfigBase](./app/models/kithe/config_base.rb) A totally optional solution for managing environmental config variables.
56
-
57
- * [ArrayInclusionValdaitor](./app/validators/array_inclusion_validator.rb) Useful for validating on attr_json arrays of primitives.
35
+ * [ArrayInclusionValdaitor](./app/validators/array_inclusion_validator.rb) Useful for validating on attr_json arrays of primitives.
58
36
 
59
37
  ## Setting up your app to use kithe
60
38
 
@@ -70,11 +48,28 @@ So you want to start an app that uses kithe. We should later provide better 'get
70
48
 
71
49
  * Specific additional pre-requisites/requirements can sometimes be found in individual feature docs. And include the Javascript from [cocoon](https://github.com/nathanvda/cocoon), for form support for repeatable-field editing forms. We haven't quite figured out our preferred sane approach for sharing Javascript via kithe.
72
50
 
73
- Note that at present kithe will end up forcing your app to use `:sql` [style schema dumps](https://guides.rubyonrails.org/v3.2.8/migrations.html#types-of-schema-dumps). We may try to fix this.
51
+
52
+ ## Why kithe?
53
+
54
+ Kithe tries to let you develop your app like "an ordinary Rails app" (in all it's possible variations), while handling some of the rough spots common to the kinds of modelling and administration common to digital collections domains. But developers should be able to use standard Rails patterns and skills to develop an app to your specific local needs, familiar, no more complicated than building any other Rails app. You add features to a kithe app just like building Rails, using whatever patterns you like. We support modern Rails versions, 5.2+.
55
+
56
+ In that kithe provides tools and not a turnkey app, develping an app based on kythe in some ways similar to developing an app based on [valkyrie](https://github.com/samvera-labs/valkyrie) (but not hyrax). They both provide basic architecture for modelling/persistence, although in quite different ways. Kithe also provides tools in addition to modelling/persistence, but does _not_ provide the data-mapper/repository pattern valkyrie does, or any built-in abstraction for persisting anywhere but a postgres DB.
57
+
58
+ If you are comparing it to a "solution bundle" digital collections platform like hyrax, kithe may seem like more work. But experience has shown us that in our domain, "solution bundles" can turn out less of a "turnkey" approach than they seem, and can have greater development cost over total app lifecycle than anticipated. If you have similar experience that leads you to consider a more 'bespoke' app approach -- you may want to consider kithe. We hope to provide architecturally simple support and standardization for your custom app, taking care of some of the common "hard parts" and leaving you with flexibility to build out the app that meets your needs.
59
+
60
+ Kithe has beeen developed in tandem with the Science History Institute's in-development [replacement digital collections](https://github.com/sciencehistory/scihist_digicoll) app, which has been in production for several years using kithe.
61
+
62
+ [The University of Minnesota found kithe](https://docs.google.com/presentation/d/1Z4AoIDOaxbY4pt3mDhNt6MfUs6VIMjysKKmaYQpjuk8/edit?usp=sharing) to pair well with GeoBlacklight, an easy way to provide the persistence layer and metadata editing UI that blacklight on it's own lacks.
63
+
64
+ We are serious about [semantic verisioning](https://semver.org/) and will endeavor to release backwards breaking changes only with a major release, and minimize major releases.
65
+
66
+ Kithe is working well for us, but has had limited (but non-zero) adoption from other institutions. It's still somewhat of an experiment, but one we think is going well. If you would consider developing a digital collections/repository app in "just Rails", we think it's worth investigating if kithe can save you some trouble in some rough common use cases. You are invited to try it out and see how it works, using kithe directly, or copying any code or just ideas from kithe.
67
+
68
+ Any questions or feedback of any kind are very welcome and encouraged! In the github project issues, samvera slack, or wherever is convenient.
74
69
 
75
70
  ## To be done
76
71
 
77
- Considering some blacklight integration support.
72
+ Considering some additional blacklight integration support, is any needed?
78
73
 
79
74
  Other components/features may become more clear as we continue to develop. It's possible that kithe won't (at least for a long time) contain controllers themselves (it may contain some helper methods for controllers), or generalized permissions architecture. Both of these are some of the things most particular to specific apps, that are hard to generalize without creating monsters.
80
75
 
@@ -85,8 +80,6 @@ This is a Rails 'engine' whose template was created with: `rails plugin new kith
85
80
 
86
81
  * Note we have chosen not to make it 'mountable' or 'isolated', I think that would be inappropriate for this kind of gem. It _is_ an engine so it can hook into Rails load paths and config as needed.
87
82
 
88
-
89
-
90
83
  * Note we are currently using the standard rails-generated dummy app in spec/dummy for testing, rather than [engine_cart](https://github.com/cbeer/engine_cart) or [combustion](https://github.com/pat/combustion).
91
84
  * Before you run the tests for the first time, create the database by running: `rails db:setup`. This will create two databases, kithe_development and kithe_test.
92
85
  * Some of the rspec tests depend on [FFmpeg](https://ffmpeg.org/) for testing file derivative transformations. Mac users can install [ffmpeg via homebrew](https://formulae.brew.sh/formula/ffmpeg): `brew install ffmpeg`
@@ -97,6 +97,8 @@ module Kithe
97
97
  # only call on-finish if we have a writer, batch writers are lazily
98
98
  # created and maybe we never created one
99
99
  if @writer
100
+ # if we created the writer ourselves locally and nobody
101
+ # specified an on_finish, close our locally-created writer.
100
102
  on_finish = if @local_writer && @on_finish.nil?
101
103
  proc {|writer| writer.close }
102
104
  else
@@ -105,7 +107,7 @@ module Kithe
105
107
  on_finish.call(@writer) if on_finish
106
108
  end
107
109
 
108
- Thread.current[THREAD_CURRENT_KEY] = @original_thread_current_settings
110
+ Thread.current[THREAD_CURRENT_KEY] = @original_settings
109
111
  end
110
112
 
111
113
  private
@@ -120,6 +120,9 @@ module Kithe
120
120
  #
121
121
  # By default will use a per-update writer, or thread/block-specific writer configured with `self.index_with`,
122
122
  # or you can pass one in.
123
+ #
124
+ # This method is part of Kithe API, including allowing local apps to override! Backwards
125
+ # compatibilty matters for semver with any change to method signature.
123
126
  def update_index(mapper: kithe_indexable_mapper, writer:nil)
124
127
  RecordIndexUpdater.new(self, mapper: mapper, writer: writer).update_index
125
128
  end
@@ -81,31 +81,11 @@ class Kithe::Asset < Kithe::Model
81
81
  source = file
82
82
  return false unless source
83
83
 
84
- #local_files = file_attacher.process_derivatives(:kithe_derivatives, only: only, except: except, lazy: lazy)
85
- local_files = _process_kithe_derivatives_without_download(source, only: only, except: except, lazy: lazy)
84
+ local_files = file_attacher.process_derivatives(:kithe_derivatives, only: only, except: except, lazy: lazy)
86
85
 
87
86
  file_attacher.add_persisted_derivatives(local_files)
88
87
  end
89
88
 
90
- # Working around Shrine's insistence on pre-downloading original before calling derivative processor.
91
- # We want to avoid that, so when our `lazy` argument is in use, original does not get eagerly downloaded,
92
- # but only gets downloaded if needed to make derivatives.
93
- #
94
- # This is a somewhat hacky way to do that, loking at the internals of shrine `process_derivatives`,
95
- # and pulling them out to skip the parts we don't want. We also lose shrine instrumentation
96
- # around this action.
97
- #
98
- # See: https://github.com/shrinerb/shrine/issues/470
99
- #
100
- # If that were resolved, the 'ordinary' shrine thing would be to replace calls
101
- # to this local private method with:
102
- #
103
- # file_attacher.process_derivatives(:kithe_derivatives, only: only, except: except, lazy: lazy)
104
- #
105
- private def _process_kithe_derivatives_without_download(source, **options)
106
- processor = file_attacher.class.derivatives_processor(:kithe_derivatives)
107
- local_files = file_attacher.instance_exec(source, **options, &processor)
108
- end
109
89
 
110
90
  # Just a convennience for file_attacher.add_persisted_derivatives (from :kithe_derivatives),
111
91
  # feel free to use that if you want to add more than one etc. By default stores to
@@ -144,6 +124,14 @@ class Kithe::Asset < Kithe::Model
144
124
  result && result.values.first
145
125
  end
146
126
 
127
+ # Like #update_derivative, but can update multiple at once.
128
+ #
129
+ # asset.update_derivatives({ "big_thumb" => big_thumb_io, "small_thumb" => small_thumb_io })
130
+ #
131
+ # Options from kithe `add_persisted_derivatives`/shrine `add_derivative` supported.
132
+ #
133
+ # asset.update_derivatives({ "big_thumb" => big_thumb_io, "small_thumb" => small_thumb_io }, delete_false)
134
+ #
147
135
  def update_derivatives(deriv_hash, **options)
148
136
  file_attacher.add_persisted_derivatives(deriv_hash, **options)
149
137
  end
@@ -42,7 +42,7 @@ class ArrayInclusionValidator < ActiveModel::EachValidator
42
42
 
43
43
  unless not_allowed_values.blank?
44
44
  formatted_rejected = not_allowed_values.uniq.collect(&:inspect).join(",")
45
- record.errors.add(attribute, :inclusion, options.except(:in).merge!(rejected_values: formatted_rejected, value: value))
45
+ record.errors.add(attribute, :inclusion, **options.except(:in).merge!(rejected_values: formatted_rejected, value: value))
46
46
  end
47
47
  end
48
48
  end
data/lib/kithe/version.rb CHANGED
@@ -1,6 +1,3 @@
1
1
  module Kithe
2
- # not sure why rubygems turned our alphas into 2.0.0.pre.alpha1, inserting
3
- # "pre". We need to do same thing with betas to get version orderings
4
- # appropriate.
5
- VERSION = '2.1.0'
2
+ VERSION = '2.2.0'
6
3
  end
@@ -10,7 +10,11 @@ class Shrine
10
10
 
11
11
  # Register our derivative processor, that will create our registered derivatives,
12
12
  # with our custom options.
13
- uploader::Attacher.derivatives(:kithe_derivatives) do |original, **options|
13
+ #
14
+ # We do download: false, so when our `lazy` argument is in use, original does not get eagerly downloaded,
15
+ # but only gets downloaded if needed to make derivatives. This is great for performance, especially
16
+ # when running batch job to add just missing derivatives.
17
+ uploader::Attacher.derivatives(:kithe_derivatives, download: false) do |original, **options|
14
18
  Kithe::Asset::DerivativeCreator.new(self.class.kithe_derivative_definitions,
15
19
  source_io: original,
16
20
  shrine_attacher: self,
@@ -44,10 +48,12 @@ class Shrine
44
48
  # Tempfile and Dir.mktmpdir may be useful.
45
49
  #
46
50
  # If in order to do your transformation you need additional information about the original,
47
- # just add a `record:` keyword argument to your block, and the Asset object will be passed in:
51
+ # just add a `attacher:` keyword argument to your block, and a `Shrine::Attacher` subclass
52
+ # will be passed in. You can then get the model object from `attacher.record`, or the
53
+ # original file as a `Shrine::UploadedFile` object with `attacher.file`.
48
54
  #
49
- # define_derivative :thumbnail do |original_file, record:|
50
- # record.width, record.height, record.content_type # etc
55
+ # define_derivative :thumbnail do |original_file, attacher:|
56
+ # attacher.record.title, attacher.file.width, attacher.file.content_type # etc
51
57
  # end
52
58
  #
53
59
  # Derivatives are normally uploaded to the Shrine storage labeled :kithe_derivatives,
@@ -26,6 +26,11 @@ class Shrine
26
26
  # Like the shrine `add_derivatives` method, but also *persists* the
27
27
  # derivatives (saves to db), in a realiably concurrency-safe way.
28
28
  #
29
+ # For ruby 3 compatibility, make sure you supply local_files as a hash
30
+ # literal with curly braces:
31
+ #
32
+ # attacher.add_persisted_derivatives({ derivative_name1: io_obj1, deriv2: io2 })
33
+ #
29
34
  # Generally can take any options that shrine `add_derivatives`
30
35
  # can take, including custom `storage` or `metadata` arguments.
31
36
  #
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.1.0
4
+ version: 2.2.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: 2021-04-13 00:00:00.000000000 Z
11
+ date: 2021-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -70,14 +70,14 @@ dependencies:
70
70
  requirements:
71
71
  - - "~>"
72
72
  - !ruby/object:Gem::Version
73
- version: '3.2'
73
+ version: '3.3'
74
74
  type: :runtime
75
75
  prerelease: false
76
76
  version_requirements: !ruby/object:Gem::Requirement
77
77
  requirements:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
- version: '3.2'
80
+ version: '3.3'
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: shrine-url
83
83
  requirement: !ruby/object:Gem::Requirement
@@ -410,7 +410,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
410
410
  - !ruby/object:Gem::Version
411
411
  version: '0'
412
412
  requirements: []
413
- rubygems_version: 3.0.3
413
+ rubygems_version: 3.1.6
414
414
  signing_key:
415
415
  specification_version: 4
416
416
  summary: Shareable tools/components for building a digital collections app in Rails.