Refactor Blob and add BlobViewer::Base
This commit is contained in:
parent
7f625f06d3
commit
13891a03c7
2 changed files with 161 additions and 66 deletions
|
@ -3,8 +3,10 @@ class Blob < SimpleDelegator
|
|||
CACHE_TIME = 60 # Cache raw blobs referred to by a (mutable) ref for 1 minute
|
||||
CACHE_TIME_IMMUTABLE = 3600 # Cache blobs referred to by an immutable reference for 1 hour
|
||||
|
||||
# The maximum size of an SVG that can be displayed.
|
||||
MAXIMUM_SVG_SIZE = 2.megabytes
|
||||
MAXIMUM_TEXT_HIGHLIGHT_SIZE = 1.megabyte
|
||||
|
||||
RICH_VIEWERS = [
|
||||
].freeze
|
||||
|
||||
attr_reader :project
|
||||
|
||||
|
@ -43,82 +45,94 @@ class Blob < SimpleDelegator
|
|||
end
|
||||
|
||||
def no_highlighting?
|
||||
size && size > 1.megabyte
|
||||
size && size > MAXIMUM_TEXT_HIGHLIGHT_SIZE
|
||||
end
|
||||
|
||||
def only_display_raw?
|
||||
def too_large?
|
||||
size && truncated?
|
||||
end
|
||||
|
||||
def raw_size
|
||||
if valid_lfs_pointer?
|
||||
lfs_size
|
||||
else
|
||||
size
|
||||
end
|
||||
end
|
||||
|
||||
def raw_binary?
|
||||
if valid_lfs_pointer?
|
||||
!rich_viewer&.text_based?
|
||||
else
|
||||
binary?
|
||||
end
|
||||
end
|
||||
|
||||
def extension
|
||||
extname.downcase.delete('.')
|
||||
end
|
||||
|
||||
def svg?
|
||||
text? && language && language.name == 'SVG'
|
||||
end
|
||||
|
||||
def pdf?
|
||||
extension == 'pdf'
|
||||
end
|
||||
|
||||
def ipython_notebook?
|
||||
text? && language&.name == 'Jupyter Notebook'
|
||||
end
|
||||
|
||||
def sketch?
|
||||
binary? && extension == 'sketch'
|
||||
end
|
||||
|
||||
def stl?
|
||||
extension == 'stl'
|
||||
end
|
||||
|
||||
def markup?
|
||||
text? && Gitlab::MarkupHelper.markup?(name)
|
||||
end
|
||||
|
||||
def size_within_svg_limits?
|
||||
size <= MAXIMUM_SVG_SIZE
|
||||
@extension ||= extname.downcase.delete('.')
|
||||
end
|
||||
|
||||
def video?
|
||||
UploaderHelper::VIDEO_EXT.include?(extname.downcase.delete('.'))
|
||||
UploaderHelper::VIDEO_EXT.include?(extension)
|
||||
end
|
||||
|
||||
def to_partial_path(project)
|
||||
if lfs_pointer?
|
||||
if project.lfs_enabled?
|
||||
'download'
|
||||
else
|
||||
'text'
|
||||
end
|
||||
elsif image?
|
||||
'image'
|
||||
elsif svg?
|
||||
'svg'
|
||||
elsif pdf?
|
||||
'pdf'
|
||||
elsif ipython_notebook?
|
||||
'notebook'
|
||||
elsif sketch?
|
||||
'sketch'
|
||||
elsif stl?
|
||||
'stl'
|
||||
elsif markup?
|
||||
if only_display_raw?
|
||||
'too_large'
|
||||
else
|
||||
'markup'
|
||||
end
|
||||
elsif text?
|
||||
if only_display_raw?
|
||||
'too_large'
|
||||
else
|
||||
'text'
|
||||
end
|
||||
def readable_text?
|
||||
text? && !valid_lfs_pointer? && !too_large?
|
||||
end
|
||||
|
||||
def valid_lfs_pointer?
|
||||
lfs_pointer? && project.lfs_enabled?
|
||||
end
|
||||
|
||||
def invalid_lfs_pointer?
|
||||
lfs_pointer? && !project.lfs_enabled?
|
||||
end
|
||||
|
||||
def simple_viewer_class
|
||||
if empty?
|
||||
BlobViewer::Empty
|
||||
elsif raw_binary?
|
||||
BlobViewer::Download
|
||||
else # text
|
||||
BlobViewer::Text
|
||||
end
|
||||
end
|
||||
|
||||
def rich_viewer_class
|
||||
if invalid_lfs_pointer? || empty?
|
||||
nil
|
||||
else
|
||||
'download'
|
||||
rich_viewers_classes.find { |viewer_class| viewer_class.can_render?(self) }
|
||||
end
|
||||
end
|
||||
|
||||
def simple_viewer
|
||||
@simple_viewer ||= simple_viewer_class.new(self)
|
||||
end
|
||||
|
||||
def rich_viewer
|
||||
return @rich_viewer if defined?(@rich_viewer)
|
||||
|
||||
@rich_viewer ||= rich_viewer_class&.new(self)
|
||||
end
|
||||
|
||||
def rendered_as_text?(override_max_size: false)
|
||||
simple_viewer.is_a?(BlobViewer::Text) && !simple_viewer.render_error(override_max_size: override_max_size)
|
||||
end
|
||||
|
||||
def show_viewer_switcher?
|
||||
simple_viewer.is_a?(BlobViewer::Text) && rich_viewer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rich_viewers_classes
|
||||
if valid_lfs_pointer?
|
||||
RICH_VIEWERS
|
||||
elsif binary?
|
||||
RICH_VIEWERS.reject(&:text_based?)
|
||||
else # text
|
||||
RICH_VIEWERS.select(&:text_based?)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
81
app/models/blob_viewer/base.rb
Normal file
81
app/models/blob_viewer/base.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
module BlobViewer
|
||||
class Base
|
||||
class_attribute :partial_name, :type, :extensions, :client_side, :text_based, :switcher_icon, :switcher_title, :max_size, :absolute_max_size
|
||||
|
||||
delegate :partial_path, :rich?, :simple?, :client_side?, :text_based?, to: :class
|
||||
|
||||
attr_reader :blob
|
||||
|
||||
def initialize(blob)
|
||||
@blob = blob
|
||||
end
|
||||
|
||||
def self.partial_path
|
||||
"projects/blob/viewers/#{partial_name}"
|
||||
end
|
||||
|
||||
def self.rich?
|
||||
type == :rich
|
||||
end
|
||||
|
||||
def self.simple?
|
||||
type == :simple
|
||||
end
|
||||
|
||||
def self.client_side?
|
||||
client_side
|
||||
end
|
||||
|
||||
def server_side?
|
||||
!client_side?
|
||||
end
|
||||
|
||||
def self.text_based?
|
||||
text_based
|
||||
end
|
||||
|
||||
def self.can_render?(blob)
|
||||
!extensions || extensions.include?(blob.extension)
|
||||
end
|
||||
|
||||
def can_override_max_size?
|
||||
too_large? && !too_large?(override_max_size: true)
|
||||
end
|
||||
|
||||
def relevant_max_size
|
||||
if too_large?(override_max_size: true)
|
||||
absolute_max_size
|
||||
elsif too_large?
|
||||
max_size
|
||||
end
|
||||
end
|
||||
|
||||
def render_error(override_max_size: false)
|
||||
if too_large?(override_max_size: override_max_size)
|
||||
:too_large
|
||||
elsif server_side_but_stored_in_lfs?
|
||||
:server_side_but_stored_in_lfs
|
||||
end
|
||||
end
|
||||
|
||||
def prepare!
|
||||
if server_side? && blob.project
|
||||
blob.load_all_data!(blob.project.repository)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def too_large?(override_max_size: false)
|
||||
if override_max_size
|
||||
blob.raw_size > absolute_max_size
|
||||
else
|
||||
blob.raw_size > max_size
|
||||
end
|
||||
end
|
||||
|
||||
def server_side_but_stored_in_lfs?
|
||||
!client_side? && blob.valid_lfs_pointer?
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue