store.rb 3.6 KB

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