Class: Blob
- Inherits:
-
SimpleDelegator
- Object
- SimpleDelegator
- Blob
- Includes:
- BlobActiveModel, BlobLanguageFromGitAttributes, Presentable
- Defined in:
- app/models/blob.rb
Overview
Blob is a Rails-specific wrapper around Gitlab::Git::Blob, SnippetBlob and Ci::ArtifactBlob
Constant Summary collapse
- MODE_SYMLINK =
The STRING 120000 is the git-reported octal filemode for a symlink
'120000'
- CACHE_TIME =
Cache raw blobs referred to by a (mutable) ref for 1 minute
60
- CACHE_TIME_IMMUTABLE =
Cache blobs referred to by an immutable reference for 1 hour
3600
- RICH_VIEWERS =
Finding a viewer for a blob happens based only on extension and whether the blob is binary or text, which means 1 blob should only be matched by 1 viewer, and the order of these viewers doesn't really matter.
However, when the blob is an LFS pointer, we cannot know for sure whether the file being pointed to is binary or text. In this case, we match only on extension, preferring binary viewers over text ones if both exist, since the large files referred to in “Large File Storage” are much more likely to be binary than text.
`.stl` files, for example, exist in both binary and text forms, and are handled by different viewers (`BinarySTL` and `TextSTL`) depending on blob type. LFS pointers to `.stl` files are assumed to always be the binary kind, and use the `BinarySTL` viewer.
[ BlobViewer::Markup, BlobViewer::Notebook, BlobViewer::SVG, BlobViewer::OpenApi, BlobViewer::Image, BlobViewer::Sketch, BlobViewer::Balsamiq, BlobViewer::Video, BlobViewer::Audio, BlobViewer::PDF, BlobViewer::BinarySTL, BlobViewer::TextSTL ].sort_by { |v| v.binary? ? 0 : 1 }.freeze
- AUXILIARY_VIEWERS =
[ BlobViewer::GitlabCiYml, BlobViewer::RouteMap, BlobViewer::Readme, BlobViewer::License, BlobViewer::Contributing, BlobViewer::Changelog, BlobViewer::MetricsDashboardYml, BlobViewer::CargoToml, BlobViewer::Cartfile, BlobViewer::ComposerJson, BlobViewer::Gemfile, BlobViewer::Gemspec, BlobViewer::GodepsJson, BlobViewer::GoMod, BlobViewer::PackageJson, BlobViewer::Podfile, BlobViewer::Podspec, BlobViewer::PodspecJson, BlobViewer::RequirementsTxt, BlobViewer::YarnLock ].freeze
Instance Attribute Summary collapse
-
#container ⇒ Object
readonly
Returns the value of attribute container.
Class Method Summary collapse
-
.decorate(blob, container = nil) ⇒ Object
Wrap a Gitlab::Git::Blob object, or return nil when given nil.
- .lazy(repository, commit_id, path, blob_size_limit: Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE) ⇒ Object
Instance Method Summary collapse
- #audio? ⇒ Boolean
- #auxiliary_viewer ⇒ Object
-
#binary? ⇒ Boolean
Returns whether the file that this blob represents is binary.
-
#data ⇒ Object
Returns the data of the blob.
- #empty? ⇒ Boolean
- #expand! ⇒ Object
- #expanded? ⇒ Boolean
- #extension ⇒ Object
- #external_storage_error? ⇒ Boolean
- #file_type ⇒ Object
-
#initialize(blob, container = nil) ⇒ Blob
constructor
A new instance of Blob.
- #inspect ⇒ Object
- #load_all_data! ⇒ Object
-
#raw_size ⇒ Object
Returns the size of the file that this blob represents.
- #readable_text? ⇒ Boolean
- #rendered_as_text?(ignore_errors: true) ⇒ Boolean
- #rich_viewer ⇒ Object
- #show_viewer_switcher? ⇒ Boolean
- #simple_viewer ⇒ Object
- #stored_externally? ⇒ Boolean
- #video? ⇒ Boolean
Methods included from BlobActiveModel
Methods included from BlobLanguageFromGitAttributes
Methods included from Presentable
Constructor Details
#initialize(blob, container = nil) ⇒ Blob
Returns a new instance of Blob.
101 102 103 104 105 |
# File 'app/models/blob.rb', line 101 def initialize(blob, container = nil) @container = container super(blob) end |
Instance Attribute Details
#container ⇒ Object (readonly)
Returns the value of attribute container
72 73 74 |
# File 'app/models/blob.rb', line 72 def container @container end |
Class Method Details
.decorate(blob, container = nil) ⇒ Object
87 88 89 90 91 |
# File 'app/models/blob.rb', line 87 def self.decorate(blob, container = nil) return if blob.nil? new(blob, container) end |
.lazy(repository, commit_id, path, blob_size_limit: Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE) ⇒ Object
93 94 95 96 97 98 99 |
# File 'app/models/blob.rb', line 93 def self.lazy(repository, commit_id, path, blob_size_limit: Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE) BatchLoader.for([commit_id, path]).batch(key: repository) do |items, loader, args| args[:key].blobs_at(items, blob_size_limit: blob_size_limit).each do |blob| loader.call([blob.commit_id, blob.path], blob) if blob end end end |
Instance Method Details
#audio? ⇒ Boolean
193 194 195 |
# File 'app/models/blob.rb', line 193 def audio? UploaderHelper::SAFE_AUDIO_EXT.include?(extension) end |
#auxiliary_viewer ⇒ Object
211 212 213 214 215 |
# File 'app/models/blob.rb', line 211 def auxiliary_viewer return @auxiliary_viewer if defined?(@auxiliary_viewer) @auxiliary_viewer = auxiliary_viewer_class&.new(self) end |
#binary? ⇒ Boolean
Returns whether the file that this blob represents is binary. If this blob is an LFS pointer, we assume the file stored in LFS is binary, unless a text-based rich blob viewer matched on the file's extension. Otherwise, this depends on the type of the blob itself.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'app/models/blob.rb', line 163 def binary? if stored_externally? if rich_viewer rich_viewer.binary? elsif known_extension? false elsif _mime_type _mime_type.binary? else true end else binary_in_repo? end end |
#data ⇒ Object
Returns the data of the blob.
If the blob is a text based blob the content is converted to UTF-8 and any invalid byte sequences are replaced.
115 116 117 118 119 120 121 |
# File 'app/models/blob.rb', line 115 def data if binary_in_repo? super else @data ||= super.encode(Encoding::UTF_8, invalid: :replace, undef: :replace) end end |
#empty? ⇒ Boolean
130 131 132 |
# File 'app/models/blob.rb', line 130 def empty? raw_size == 0 end |
#expand! ⇒ Object
229 230 231 |
# File 'app/models/blob.rb', line 229 def @expanded = true end |
#expanded? ⇒ Boolean
225 226 227 |
# File 'app/models/blob.rb', line 225 def !!@expanded end |
#extension ⇒ Object
179 180 181 |
# File 'app/models/blob.rb', line 179 def extension @extension ||= extname.downcase.delete('.') end |
#external_storage_error? ⇒ Boolean
134 135 136 137 138 139 140 |
# File 'app/models/blob.rb', line 134 def external_storage_error? if external_storage == :lfs !repository.lfs_enabled? else false end end |
#file_type ⇒ Object
183 184 185 186 187 |
# File 'app/models/blob.rb', line 183 def file_type name = File.basename(path) Gitlab::FileDetector.type_of(path) || Gitlab::FileDetector.type_of(name) end |
#inspect ⇒ Object
107 108 109 |
# File 'app/models/blob.rb', line 107 def inspect "#<#{self.class.name} oid:#{id[0..8]} commit:#{commit_id[0..8]} path:#{path}>" end |
#load_all_data! ⇒ Object
123 124 125 126 127 128 |
# File 'app/models/blob.rb', line 123 def load_all_data! # Endpoint needed: https://gitlab.com/gitlab-org/gitaly/issues/756 Gitlab::GitalyClient.allow_n_plus_1_calls do super(repository) if container end end |
#raw_size ⇒ Object
Returns the size of the file that this blob represents. If this blob is an LFS pointer, this is the size of the file stored in LFS. Otherwise, this is the size of the blob itself.
151 152 153 154 155 156 157 |
# File 'app/models/blob.rb', line 151 def raw_size if stored_externally? external_size else size end end |
#readable_text? ⇒ Boolean
197 198 199 |
# File 'app/models/blob.rb', line 197 def readable_text? text_in_repo? && !stored_externally? && !truncated? end |
#rendered_as_text?(ignore_errors: true) ⇒ Boolean
217 218 219 |
# File 'app/models/blob.rb', line 217 def rendered_as_text?(ignore_errors: true) simple_viewer.is_a?(BlobViewer::Text) && (ignore_errors || simple_viewer.render_error.nil?) end |
#rich_viewer ⇒ Object
205 206 207 208 209 |
# File 'app/models/blob.rb', line 205 def rich_viewer return @rich_viewer if defined?(@rich_viewer) @rich_viewer = rich_viewer_class&.new(self) end |
#show_viewer_switcher? ⇒ Boolean
221 222 223 |
# File 'app/models/blob.rb', line 221 def show_viewer_switcher? rendered_as_text? && rich_viewer end |
#simple_viewer ⇒ Object
201 202 203 |
# File 'app/models/blob.rb', line 201 def simple_viewer @simple_viewer ||= simple_viewer_class.new(self) end |
#stored_externally? ⇒ Boolean
142 143 144 145 146 |
# File 'app/models/blob.rb', line 142 def stored_externally? return @stored_externally if defined?(@stored_externally) @stored_externally = external_storage && !external_storage_error? end |
#video? ⇒ Boolean
189 190 191 |
# File 'app/models/blob.rb', line 189 def video? UploaderHelper::SAFE_VIDEO_EXT.include?(extension) end |