static_assets.rb 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. module StaticAssets
  3. =begin
  4. file_attributes = StaticAssets.data_url_attributes(data_url)
  5. returns
  6. {
  7. mime_type: 'image/png',
  8. content: image_bin_content,
  9. file_extention: 'png',
  10. }
  11. =end
  12. def self.data_url_attributes(data_url)
  13. data = {}
  14. if data_url =~ %r{^data:(.+?);base64,(.+?)$}
  15. data[:mime_type] = $1
  16. data[:content] = Base64.decode64($2)
  17. if data[:mime_type] =~ %r{/(.+?)$}
  18. data[:file_extention] = $1
  19. end
  20. return data
  21. end
  22. raise "Unable to parse data url: #{data_url&.slice(0, 100)}"
  23. end
  24. =begin
  25. store image 1:1 in backend and return filename
  26. filename = StaticAssets.store_raw(content, content_type)
  27. returns
  28. filename # hash.png
  29. =end
  30. def self.store_raw(content, content_type)
  31. Store.remove(object: 'System::Logo', o_id: 1)
  32. file = Store.create!(
  33. object: 'System::Logo',
  34. o_id: 1,
  35. data: content,
  36. filename: 'logo_raw',
  37. preferences: {
  38. 'Content-Type' => content_type
  39. },
  40. created_by_id: 1,
  41. )
  42. filename(file)
  43. end
  44. =begin
  45. read image 1:1 size in backend and return file (Store model)
  46. store = StaticAssets.read_raw
  47. returns
  48. store # Store model, e.g. store.content or store.preferences
  49. =end
  50. def self.read_raw
  51. list = Store.list(object: 'System::Logo', o_id: 1)
  52. if list && list[0]
  53. return Store.find(list[0])
  54. end
  55. raise __('The raw logo could not be read.')
  56. end
  57. =begin
  58. store image in right size (resized) in backend and return filename
  59. filename = StaticAssets.store( content, content_type )
  60. returns
  61. filename # hash.png
  62. =end
  63. def self.store(content, content_type)
  64. Store.remove(object: 'System::Logo', o_id: 2)
  65. file = Store.create!(
  66. object: 'System::Logo',
  67. o_id: 2,
  68. data: content,
  69. filename: 'logo',
  70. preferences: {
  71. 'Content-Type' => content_type
  72. },
  73. created_by_id: 1,
  74. )
  75. StaticAssets.sync
  76. filename(file)
  77. end
  78. =begin
  79. read image size from backend (if not exists, read 1:1 size) and return file (Store model)
  80. store = StaticAssets.read
  81. returns
  82. store # Store model, e.g. store.content or store.preferences
  83. =end
  84. def self.read
  85. # use reduced dimensions
  86. list = Store.list(object: 'System::Logo', o_id: 2)
  87. # as fallback use 1:1
  88. if !list || !list[0]
  89. list = Store.list(object: 'System::Logo', o_id: 1)
  90. end
  91. # store hash in config
  92. return if !list || !list[0]
  93. file = Store.find(list[0].id)
  94. filelocation = filename(file)
  95. Setting.set('product_logo', filelocation)
  96. file
  97. end
  98. =begin
  99. generate filename based on Store model
  100. filename = StaticAssets.filename(store)
  101. =end
  102. def self.filename(file)
  103. hash = Digest::MD5.hexdigest(file.content)
  104. extension = case file.preferences['Content-Type']
  105. when %r{jpg|jpeg}i
  106. '.jpg'
  107. when %r{png}i
  108. '.png'
  109. when %r{gif}i
  110. '.gif'
  111. when %r{svg}i
  112. '.svg'
  113. else
  114. ''
  115. end
  116. "#{hash}#{extension}"
  117. end
  118. =begin
  119. sync image to fs (public/assets/images/hash.png)
  120. StaticAssets.sync
  121. =end
  122. def self.sync
  123. file = read
  124. return if !file
  125. path = Rails.public_path.join('assets', 'images', filename(file))
  126. File.open(path, 'wb') do |f|
  127. f.puts file.content
  128. end
  129. end
  130. end