Last active
September 18, 2023 17:52
-
-
Save robzolkos/ce126bc8d79cdce514736b5727ac66eb to your computer and use it in GitHub Desktop.
Jump zip download refactor from service object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/jump/downloaded_photo.rb | |
class Jump::DownloadedPhoto | |
include ActiveModel::API | |
attr_accessor :file_name, :file_path | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/jump/downloaded_photos_zipper.rb | |
require 'zip' | |
class Jump::DownloadedPhotosZipper | |
def initialize(jump) | |
@jump = jump | |
end | |
def zip | |
Zip::File.open("#{folder_name}.zip", Zip::File::CREATE) do |zf| | |
temporary_downloaded_photos_paths.each do |downloaded_photo| | |
zf.add(downloaded_photo.file_name, downloaded_photo.file_path) | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/jump.rb | |
class Jump < ApplicationRecord | |
include ZippablePhotos | |
has_many :photos | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/photo.rb | |
class Photo < ApplicationRecord | |
def filename_for_zip | |
"#{stable_name}.jpg" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/jump/photos_to_temporary_folder_downloader.rb | |
class Jump::PhotosToTemporaryFolderDownloader | |
def initialize(jump) | |
@jump = jump | |
@jump.temporary_downloaded_photos = [] | |
end | |
def download | |
@jump.photos {|photo| download_photo(photo)} | |
end | |
private | |
def download_photo(photo) | |
full_download_path = File.join(folder_name, photo.filename_for_zip) | |
File.open(full_download_path, 'wb') do |file| | |
photo.image.download { |chunk| file.write(chunk) } | |
end | |
@jump.temporary_downloaded_photos << Jump::DownloadedPhoto.new(file_name: photo.filename_for_zip, file_path: full_download_path) | |
rescue => e | |
Rails.logger.error("Error downloading photo #{photo.id}: #{e.message}") | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/jump/zippable_photos.rb | |
module Jump::ZippablePhotos | |
include ActiveSupport::Concern | |
JOB_TIMEOUT = 10.minutes | |
included do | |
has_attached :photos_zip | |
attr_accessor :temporary_downloaded_photos | |
def zip_photos_later | |
return if ineligible_for_zipping? | |
update(zip_processing_started_at: Time.current) | |
ZipPhotosJob.perform_later self | |
end | |
def zip_photos | |
create_temporary_folder | |
ActsAsTenant.without_tenant do | |
Jump::PhotosToTemporaryFolderDownloader.new(self).download | |
Jump::DownloadedPhotosZipper.new(self).zip | |
attach_zipped_file | |
broadcast_download_link | |
end | |
ensure | |
delete_temporary_folder | |
end | |
private | |
def ineligible_for_zipping? | |
photos.blank? || zip_in_progress? || zip_already_attached? | |
end | |
def zip_in_progress? | |
zip_processing_started_at && zip_processing_started_at > JOB_TIMEOUT.ago | |
end | |
def zip_already_attached? | |
photos_zip.attached? | |
end | |
def sanitized_booking_name | |
"#{booking.name.gsub(/[^0-9A-Za-z.\-]/, '_')}" | |
end | |
def final_zip_file_name | |
"#{sanitized_booking_name}_tandem_photos.zip" | |
end | |
def temporary_zip_file_name | |
"#{uuid}_#{SecureRandom.hex(8)}" | |
end | |
def folder_name | |
@folder_name ||= "tmp/photos/archive_#{temporary_zip_file_name}" | |
end | |
def attach_zipped_file | |
@jump.skip_broadcast = true | |
@jump.photos_zip.attach(io: File.open("#{folder_name}.zip"), filename: final_zip_file_name, content_type: "application/zip") | |
@jump.skip_broadcast = false | |
end | |
def create_temporary_folder | |
FileUtils.mkdir_p(folder_name) unless Dir.exist?(folder_name) | |
end | |
def delete_temporary_folder | |
FileUtils.rm_rf([folder_name, "#{folder_name}.zip"]) | |
end | |
end | |
end |
Oh Nice!
Also in Jump::DownloadedPhotosZipper#zip
, I guess you meant to pass folder_name
as an argument to the initializer
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You're right @ziraqyoung - typo. I updated to module. As for why its not in app/models/concerns - I like to only put stuff in app/models/concerns that is shared by more than one model. If this module is only included in the jump.rb model than I like to keep it close to that namespaced appropriately close.