blob.rb 3,6 КБ
Newer Older
Robert Speicher's avatar
Robert Speicher включено в состав коммита
1
2
# Blob is a Rails-specific wrapper around Gitlab::Git::Blob objects
class Blob < SimpleDelegator
Jacob Vosmaer's avatar
Jacob Vosmaer включено в состав коммита
3
4
5
  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

Douwe Maan's avatar
Douwe Maan включено в состав коммита
6
7
8
  MAXIMUM_TEXT_HIGHLIGHT_SIZE = 1.megabyte

  RICH_VIEWERS = [
Douwe Maan's avatar
Douwe Maan включено в состав коммита
9
10
11
12
13
14
15
16
    BlobViewer::Image,
    BlobViewer::PDF,
    BlobViewer::Sketch,
    BlobViewer::BinarySTL,
    BlobViewer::TextSTL,
    BlobViewer::Notebook,
    BlobViewer::SVG,
    BlobViewer::Markup,
Douwe Maan's avatar
Douwe Maan включено в состав коммита
17
  ].freeze
Yorick Peterse's avatar
Yorick Peterse включено в состав коммита
18

Douwe Maan's avatar
Douwe Maan включено в состав коммита
19
20
  attr_reader :project

Robert Speicher's avatar
Robert Speicher включено в состав коммита
21
22
23
24
25
26
27
28
29
30
  # Wrap a Gitlab::Git::Blob object, or return nil when given nil
  #
  # This method prevents the decorated object from evaluating to "truthy" when
  # given a nil value. For example:
  #
  #     blob = Blob.new(nil)
  #     puts "truthy" if blob # => "truthy"
  #
  #     blob = Blob.decorate(nil)
  #     puts "truthy" if blob # No output
Douwe Maan's avatar
Douwe Maan включено в состав коммита
31
  def self.decorate(blob, project = nil)
Robert Speicher's avatar
Robert Speicher включено в состав коммита
32
33
    return if blob.nil?

Douwe Maan's avatar
Douwe Maan включено в состав коммита
34
35
36
    new(blob, project)
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
37
  def initialize(blob, project = nil)
Douwe Maan's avatar
Douwe Maan включено в состав коммита
38
39
40
    @project = project

    super(blob)
Robert Speicher's avatar
Robert Speicher включено в состав коммита
41
42
  end

Yorick Peterse's avatar
Yorick Peterse включено в состав коммита
43
44
45
46
47
48
49
50
51
52
53
54
  # 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.
  def data
    if binary?
      super
    else
      @data ||= super.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
    end
  end

Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg включено в состав коммита
55
  def no_highlighting?
Douwe Maan's avatar
Douwe Maan включено в состав коммита
56
    size && size > MAXIMUM_TEXT_HIGHLIGHT_SIZE
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg включено в состав коммита
57
58
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
59
  def too_large?
Stan Hu's avatar
Stan Hu включено в состав коммита
60
    size && truncated?
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg включено в состав коммита
61
62
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
63
64
65
  # 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.
Douwe Maan's avatar
Douwe Maan включено в состав коммита
66
67
68
69
70
71
  def raw_size
    if valid_lfs_pointer?
      lfs_size
    else
      size
    end
Douwe Maan's avatar
Douwe Maan включено в состав коммита
72
73
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
74
75
76
77
  # 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.
Douwe Maan's avatar
Douwe Maan включено в состав коммита
78
79
  def raw_binary?
    if valid_lfs_pointer?
Douwe Maan's avatar
Douwe Maan включено в состав коммита
80
81
82
83
84
      if rich_viewer
        rich_viewer.binary?
      else
        true
      end
Douwe Maan's avatar
Douwe Maan включено в состав коммита
85
86
87
    else
      binary?
    end
Robert Speicher's avatar
Robert Speicher включено в состав коммита
88
89
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
90
91
  def extension
    @extension ||= extname.downcase.delete('.')
Sam Rose's avatar
Sam Rose включено в состав коммита
92
93
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
94
95
  def video?
    UploaderHelper::VIDEO_EXT.include?(extension)
Phil Hughes's avatar
Phil Hughes включено в состав коммита
96
97
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
98
99
  def readable_text?
    text? && !valid_lfs_pointer? && !too_large?
Jacob Schatz's avatar
Jacob Schatz включено в состав коммита
100
101
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
102
  def valid_lfs_pointer?
Douwe Maan's avatar
Douwe Maan включено в состав коммита
103
    lfs_pointer? && project&.lfs_enabled?
Douwe Maan's avatar
Douwe Maan включено в состав коммита
104
105
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
106
  def invalid_lfs_pointer?
Douwe Maan's avatar
Douwe Maan включено в состав коммита
107
    lfs_pointer? && !project&.lfs_enabled?
Phil Hughes's avatar
Phil Hughes включено в состав коммита
108
109
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
110
111
112
113
114
115
116
  def simple_viewer
    @simple_viewer ||= simple_viewer_class.new(self)
  end

  def rich_viewer
    return @rich_viewer if defined?(@rich_viewer)

Douwe Maan's avatar
Douwe Maan включено в состав коммита
117
    @rich_viewer = rich_viewer_class&.new(self)
Douwe Maan's avatar
Douwe Maan включено в состав коммита
118
119
  end

Douwe Maan's avatar
Douwe Maan включено в состав коммита
120
  def rendered_as_text?(ignore_errors: true)
Douwe Maan's avatar
Douwe Maan включено в состав коммита
121
    simple_viewer.text? && (ignore_errors || simple_viewer.render_error.nil?)
Douwe Maan's avatar
Douwe Maan включено в состав коммита
122
123
124
  end

  def show_viewer_switcher?
Douwe Maan's avatar
Douwe Maan включено в состав коммита
125
126
127
128
129
130
    rendered_as_text? && rich_viewer
  end

  def override_max_size!
    simple_viewer&.override_max_size = true
    rich_viewer&.override_max_size = true
Douwe Maan's avatar
Douwe Maan включено в состав коммита
131
132
133
134
  end

  private

Douwe Maan's avatar
Douwe Maan включено в состав коммита
135
136
137
138
139
140
141
142
143
144
145
146
147
  def simple_viewer_class
    if empty?
      BlobViewer::Empty
    elsif raw_binary?
      BlobViewer::Download
    else # text
      BlobViewer::Text
    end
  end

  def rich_viewer_class
    return if invalid_lfs_pointer? || empty?

Douwe Maan's avatar
Douwe Maan включено в состав коммита
148
149
150
151
152
153
154
155
156
157
    classes =
      if valid_lfs_pointer?
        RICH_VIEWERS
      elsif binary?
        RICH_VIEWERS.select(&:binary?)
      else # text
        RICH_VIEWERS.select(&:text?)
      end

    classes.find { |viewer_class| viewer_class.can_render?(self) }
Douwe Maan's avatar
Douwe Maan включено в состав коммита
158
  end
Robert Speicher's avatar
Robert Speicher включено в состав коммита
159
end