store.rb 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. class Store < ApplicationModel
  3. load 'store/object.rb'
  4. load 'store/file.rb'
  5. # rubocop:disable Rails/InverseOf
  6. belongs_to :store_object, class_name: 'Store::Object'
  7. belongs_to :store_file, class_name: 'Store::File'
  8. # rubocop:enable Rails/InverseOf
  9. validates :filename, presence: true
  10. store :preferences
  11. =begin
  12. add an attachment to storage
  13. result = Store.add(
  14. object: 'Ticket::Article',
  15. o_id: 4711,
  16. data: binary_string,
  17. preferences: {
  18. content_type: 'image/png',
  19. content_id: 234,
  20. }
  21. )
  22. returns
  23. result = true
  24. =end
  25. def self.add(data)
  26. data = data.stringify_keys
  27. # lookup store_object.id
  28. store_object = Store::Object.create_if_not_exists(name: data['object'])
  29. data['store_object_id'] = store_object.id
  30. # add to real store
  31. file = Store::File.add(data['data'])
  32. data['size'] = data['data'].to_s.bytesize
  33. data['store_file_id'] = file.id
  34. # not needed attributes
  35. data.delete('data')
  36. data.delete('object')
  37. # store meta data
  38. store = Store.create!(data)
  39. store
  40. end
  41. =begin
  42. get attachment of object
  43. list = Store.list(
  44. object: 'Ticket::Article',
  45. o_id: 4711,
  46. )
  47. returns
  48. result = [store1, store2]
  49. store1 = {
  50. size: 94123,
  51. filename: 'image.png',
  52. preferences: {
  53. content_type: 'image/png',
  54. content_id: 234,
  55. }
  56. }
  57. store1.content # binary_string
  58. =end
  59. def self.list(data)
  60. # search
  61. store_object_id = Store::Object.lookup(name: data[:object])
  62. stores = Store.where(store_object_id: store_object_id, o_id: data[:o_id].to_i)
  63. .order('created_at ASC, id ASC')
  64. stores
  65. end
  66. =begin
  67. remove attachments of object from storage
  68. result = Store.remove(
  69. object: 'Ticket::Article',
  70. o_id: 4711,
  71. )
  72. returns
  73. result = true
  74. =end
  75. def self.remove(data)
  76. # search
  77. store_object_id = Store::Object.lookup(name: data[:object])
  78. stores = Store.where(store_object_id: store_object_id)
  79. .where(o_id: data[:o_id])
  80. .order('created_at ASC, id ASC')
  81. stores.each do |store|
  82. # check backend for references
  83. Store.remove_item(store.id)
  84. end
  85. true
  86. end
  87. =begin
  88. remove one attachment from storage
  89. Store.remove_item(store_id)
  90. =end
  91. def self.remove_item(store_id)
  92. store = Store.find(store_id)
  93. file_id = store.store_file_id
  94. # check backend for references
  95. files = Store.where(store_file_id: file_id)
  96. if files.count > 1 || files.first.id != store.id
  97. store.destroy!
  98. return true
  99. end
  100. store.destroy!
  101. Store::File.find(file_id).destroy!
  102. end
  103. =begin
  104. get content of file
  105. store = Store.find(store_id)
  106. content_as_string = store.content
  107. returns
  108. content_as_string
  109. =end
  110. def content
  111. file = Store::File.find_by(id: store_file_id)
  112. if !file
  113. raise "No such file #{store_file_id}!"
  114. end
  115. file.content
  116. end
  117. =begin
  118. get content of file
  119. store = Store.find(store_id)
  120. location_of_file = store.save_to_file
  121. returns
  122. location_of_file
  123. =end
  124. def save_to_file(path = nil)
  125. content
  126. file = Store::File.find_by(id: store_file_id)
  127. if !file
  128. raise "No such file #{store_file_id}!"
  129. end
  130. if !path
  131. path = Rails.root.join('tmp', filename)
  132. end
  133. ::File.open(path, 'wb') do |handle|
  134. handle.write file.content
  135. end
  136. path
  137. end
  138. def provider
  139. file = Store::File.find_by(id: store_file_id)
  140. if !file
  141. raise "No such file #{store_file_id}!"
  142. end
  143. file.provider
  144. end
  145. end