store.rb 3.6 KB

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