Class: DiscourseTheme::Uploader

Inherits:
Object
  • Object
show all
Defined in:
lib/discourse_theme/uploader.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dir:, client:, theme_id: nil, components: nil) ⇒ Uploader

Returns a new instance of Uploader.



18
19
20
21
22
23
# File 'lib/discourse_theme/uploader.rb', line 18

def initialize(dir:, client:, theme_id: nil, components: nil)
  @dir = dir
  @client = client
  @theme_id = theme_id
  @components = components
end

Class Method Details

.register_upload_full_theme_callback(&block) ⇒ Object

Used in the test environment to register a callback that is called with the directory of the theme being uploaded.



9
10
11
# File 'lib/discourse_theme/uploader.rb', line 9

def self.register_upload_full_theme_callback(&block)
  self.upload_full_theme_callbacks << block
end

.reset_upload_full_theme_callbacksObject

Used in the test environment to clear the registered callbacks.



14
15
16
# File 'lib/discourse_theme/uploader.rb', line 14

def self.reset_upload_full_theme_callbacks
  self.upload_full_theme_callbacks.clear
end

.upload_full_theme_callbacksObject



4
5
6
# File 'lib/discourse_theme/uploader.rb', line 4

def self.upload_full_theme_callbacks
  @upload_callbacks ||= []
end

Instance Method Details

#compress_dir(gzip, dir) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/discourse_theme/uploader.rb', line 25

def compress_dir(gzip, dir)
  sgz = Zlib::GzipWriter.new(File.open(gzip, "wb"))
  tar = Archive::Tar::Minitar::Output.new(sgz)

  Dir.chdir(dir + "/../") do
    Find.find(File.basename(dir)) do |x|
      bn = File.basename(x)
      Find.prune if bn == "node_modules" || bn == "src" || bn[0] == "."
      next if File.directory?(x)

      Minitar.pack_file(x, tar)
    end
  end
ensure
  tar.close
  sgz.close
end

#diagnose_errors(json) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/discourse_theme/uploader.rb', line 43

def diagnose_errors(json)
  count = 0
  json["theme"]["theme_fields"].each do |row|
    if (error = row["error"]) && error.length > 0
      count += 1
      UI.error ""
      UI.error "Error in #{row["target"]} #{row["name"]}: #{row["error"]}"
      UI.error ""
    end
  end
  count
end

#upload_full_theme(ignore_files: []) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/discourse_theme/uploader.rb', line 70

def upload_full_theme(ignore_files: [])
  filename = "#{Pathname.new(Dir.tmpdir).realpath}/bundle_#{SecureRandom.hex}.tar.gz"
  temp_dir = nil

  theme_dir =
    if !ignore_files.empty?
      temp_dir = Dir.mktmpdir
      FileUtils.copy_entry(@dir, temp_dir)
      dir_pathname = Pathname.new(@dir)
      ignore_files.each { |file| FileUtils.rm_f(File.join(temp_dir, file)) }
      temp_dir
    else
      @dir
    end

  self.class.upload_full_theme_callbacks.each { |cb| cb.call(theme_dir) }

  compress_dir(filename, theme_dir)

  File.open(filename) do |tgz|
    response = @client.upload_full_theme(tgz, theme_id: @theme_id, components: @components)

    json = JSON.parse(response.body)
    @theme_id = json["theme"]["id"]
    UI.error "(end of errors)" if diagnose_errors(json) != 0
    @theme_id
  end
ensure
  FileUtils.rm_rf(temp_dir) if temp_dir
  FileUtils.rm_f(filename)
end

#upload_theme_field(target:, name:, type_id:, value:) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/discourse_theme/uploader.rb', line 56

def upload_theme_field(target:, name:, type_id:, value:)
  raise "expecting theme_id to be set!" unless @theme_id

  args = {
    theme: {
      theme_fields: [{ name: name, target: target, type_id: type_id, value: value }],
    },
  }

  response = @client.update_theme(@theme_id, args)
  json = JSON.parse(response.body)
  UI.error "(end of errors)" if diagnose_errors(json) != 0
end