Class: Export::Packagers::Documents
- Inherits:
-
Object
- Object
- Export::Packagers::Documents
- Defined in:
- lib/export/packagers/documents.rb
Instance Attribute Summary collapse
-
#project_id ⇒ Object
readonly
Returns the value of attribute project_id.
-
#query_params ⇒ Object
readonly
Returns the value of attribute query_params.
Instance Method Summary collapse
- #add_manifest_row(entry, name, rows) ⇒ Object private
- #document_from_entry(entry) ⇒ Object private
- #documents_for_sources(sources) ⇒ Object private
- #empty_preview ⇒ Object private
- #file_available?(document) ⇒ Boolean
- #file_path(document) ⇒ Object private
- #group_entries(documents, max_bytes) ⇒ Object private
- #groups(max_bytes:) ⇒ Object
-
#initialize(query_params:, project_id:) ⇒ Documents
constructor
A new instance of Documents.
- #preview(max_bytes:) ⇒ Object
- #serialize_groups(groups) ⇒ Object private
- #serialize_sources(sources, documents, group_map) ⇒ Object private
- #source_ids ⇒ Object private
- #sources_for_query ⇒ Object private
- #stream(entries:, zip_streamer:, group_index:) ⇒ Object
- #unique_document_entries(documents) ⇒ Object private
- #write_manifest(zip, rows, written, group_index:) ⇒ Object private
Constructor Details
#initialize(query_params:, project_id:) ⇒ Documents
Returns a new instance of Documents.
10 11 12 13 14 15 |
# File 'lib/export/packagers/documents.rb', line 10 def initialize(query_params:, project_id:) @query_params = query_params @project_id = project_id @file_grouper = Export::FileGrouper.new @file_available_cache = {} end |
Instance Attribute Details
#project_id ⇒ Object (readonly)
Returns the value of attribute project_id.
8 9 10 |
# File 'lib/export/packagers/documents.rb', line 8 def project_id @project_id end |
#query_params ⇒ Object (readonly)
Returns the value of attribute query_params.
8 9 10 |
# File 'lib/export/packagers/documents.rb', line 8 def query_params @query_params end |
Instance Method Details
#add_manifest_row(entry, name, rows) ⇒ Object (private)
157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/export/packagers/documents.rb', line 157 def add_manifest_row(entry, name, rows) return unless entry.is_a?(Hash) document = entry[:document] source = entry[:source] rows << [ source&.id, document.id, name, document.document_file_file_size.to_i ] end |
#document_from_entry(entry) ⇒ Object (private)
153 154 155 |
# File 'lib/export/packagers/documents.rb', line 153 def document_from_entry(entry) entry.is_a?(Hash) ? entry[:document] : entry end |
#documents_for_sources(sources) ⇒ Object (private)
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/export/packagers/documents.rb', line 75 def documents_for_sources(sources) documents = [] index = 0 sources.each do |source| source.documents .select { |document| document.project_id == project_id } .sort_by(&:id) .each do |document| index += 1 # 1-based for UI display documents << { source:, document:, index: } end end documents end |
#empty_preview ⇒ Object (private)
185 186 187 188 189 190 |
# File 'lib/export/packagers/documents.rb', line 185 def empty_preview { sources: [], groups: [] } end |
#file_available?(document) ⇒ Boolean
42 43 44 45 46 47 48 |
# File 'lib/export/packagers/documents.rb', line 42 def file_available?(document) document = document_from_entry(document) @file_available_cache.fetch(document.id) do path = document.document_file.path @file_available_cache[document.id] = path.present? && File.exist?(path) end end |
#file_path(document) ⇒ Object (private)
146 147 148 149 150 151 |
# File 'lib/export/packagers/documents.rb', line 146 def file_path(document) document = document_from_entry(document) path = document.document_file.path return path if path.present? && File.exist?(path) nil end |
#group_entries(documents, max_bytes) ⇒ Object (private)
100 101 102 103 104 105 106 107 108 |
# File 'lib/export/packagers/documents.rb', line 100 def group_entries(documents, max_bytes) @file_grouper.group( items: documents, max_bytes: max_bytes, size_extractor: ->(entry) { file_available?(entry[:document]) ? entry[:document].document_file_file_size.to_i : 0 } ) end |
#groups(max_bytes:) ⇒ Object
35 36 37 38 39 40 |
# File 'lib/export/packagers/documents.rb', line 35 def groups(max_bytes:) return [] if source_ids.empty? documents = unique_document_entries(documents_for_sources(sources_for_query)) group_entries(documents, max_bytes) end |
#preview(max_bytes:) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/export/packagers/documents.rb', line 17 def preview(max_bytes:) return empty_preview if source_ids.empty? sources = sources_for_query table_documents = documents_for_sources(sources) unique_documents = unique_document_entries(table_documents) groups = group_entries(unique_documents, max_bytes) group_map = @file_grouper.build_group_map( groups: groups, id_extractor: ->(entry) { entry[:document].id } ) { sources: serialize_sources(sources, table_documents, group_map), groups: serialize_groups(groups) } end |
#serialize_groups(groups) ⇒ Object (private)
134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/export/packagers/documents.rb', line 134 def serialize_groups(groups) groups.map.with_index do |group, index| available_entries = group.select { |entry| file_available?(entry[:document]) } { index:, size: available_entries.sum { |entry| entry[:document].document_file_file_size.to_i }, document_ids: group.map { |entry| entry[:document].id }, available_count: available_entries.length } end end |
#serialize_sources(sources, documents, group_map) ⇒ Object (private)
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/export/packagers/documents.rb', line 110 def serialize_sources(sources, documents, group_map) documents_by_source = documents.group_by { |entry| entry[:source].id } sources.map do |source| docs = documents_by_source[source.id] || [] { id: source.id, cached: source.cached, documents: docs.map do |entry| document = entry[:document] { id: document.id, index: entry[:index], group_index: group_map[document.id], size: document.document_file_file_size.to_i, name: document.document_file_file_name, url: document.document_file.url(:original, false), available: file_available?(document) } end } end end |
#source_ids ⇒ Object (private)
181 182 183 |
# File 'lib/export/packagers/documents.rb', line 181 def source_ids Array(query_params[:source_id]).flatten.compact.map(&:to_i).uniq end |
#sources_for_query ⇒ Object (private)
67 68 69 70 71 72 73 |
# File 'lib/export/packagers/documents.rb', line 67 def sources_for_query Source.joins(:project_sources) .where(project_sources: { project_id: project_id }) .where(id: source_ids) .order(:id) .includes(:documents) end |
#stream(entries:, zip_streamer:, group_index:) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/export/packagers/documents.rb', line 50 def stream(entries:, zip_streamer:, group_index:) Export::ZipStreamer.new.stream( entries: entries, zip_streamer: zip_streamer, file_path: ->(entry) { file_path(document_from_entry(entry)) }, file_name: ->(entry) { document_from_entry(entry).document_file_file_name }, entry_id: ->(entry) { document_from_entry(entry).id }, logger_prefix: 'Documents packager', on_entry: method(:add_manifest_row), after_stream: ->(zip, rows, written) { write_manifest(zip, rows, written, group_index: group_index) } ) end |
#unique_document_entries(documents) ⇒ Object (private)
96 97 98 |
# File 'lib/export/packagers/documents.rb', line 96 def unique_document_entries(documents) documents.uniq { |entry| entry[:document].id } end |
#write_manifest(zip, rows, written, group_index:) ⇒ Object (private)
170 171 172 173 174 175 176 177 178 179 |
# File 'lib/export/packagers/documents.rb', line 170 def write_manifest(zip, rows, written, group_index:) return if !written || rows.empty? zip.write_deflated_file("documents-#{group_index + 1}.tsv") do |sink| sink.write("source_id\tdocument_id\tfilename\tfile_size_bytes\n") rows.each do |row| sink.write("#{row.join("\t")}\n") end end end |