store.rb 3.5 KB

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