Files
fizzy/app/models/account/export.rb
T
Kevin McConnell f7e2b4e0ba Don't compress attachments in export
Since they are typically images and videos, which are already
compressed.
2025-12-02 10:39:56 +00:00

74 lines
1.8 KiB
Ruby

class Account::Export < ApplicationRecord
belongs_to :account
belongs_to :user
has_one_attached :file
enum :status, %w[ pending processing completed failed ].index_by(&:itself), default: :pending
scope :current, -> { where(created_at: 24.hours.ago..) }
scope :expired, -> { where(completed_at: ...24.hours.ago) }
def self.cleanup
expired.destroy_all
end
def build_later
ExportAccountDataJob.perform_later(self)
end
def build
processing!
zipfile = generate_zip
file.attach io: File.open(zipfile.path), filename: "fizzy-export-#{id}.zip", content_type: "application/zip"
mark_completed
ExportMailer.completed(self).deliver_later
rescue => e
update!(status: :failed)
raise
ensure
zipfile&.close
zipfile&.unlink
end
def mark_completed
update!(status: :completed, completed_at: Time.current)
end
private
def generate_zip
Tempfile.new([ "export", ".zip" ]).tap do |tempfile|
Zip::File.open(tempfile.path, create: true) do |zip|
exportable_cards.find_each do |card|
add_card_to_zip(zip, card)
end
end
end
end
def exportable_cards
user.accessible_cards.includes(
:board,
creator: :identity,
comments: { creator: :identity },
rich_text_description: { embeds_attachments: :blob }
)
end
def add_card_to_zip(zip, card)
zip.get_output_stream("#{card.number}.json") do |f|
f.write(card.export_json)
end
card.export_attachments.each do |attachment|
zip.get_output_stream(attachment[:path], compression_method: Zip::Entry::STORED) do |f|
attachment[:blob].download { |chunk| f.write(chunk) }
end
rescue ActiveStorage::FileNotFoundError
# Skip attachments where the file is missing from storage
end
end
end