My Rails app has to process and generate PDF XFA files and send to the user/browser.
Its working fine. But the issue is that before sending the file to the user, it creates 2 files in the rails tmp directory.
If 10 requests come to the pdf_controller, the number of the temp files in the tmp directory will double and it will eat up the space.
After searching around I thought that Sweeper will come to the rescue. But not much knowledge about Sweeper.
So, can anyone plz suggest which way to go?
Tempfile will delete files when the object is finalized.
Tempfile on Rdoc
Example:
def get_pdf
model = Model.find(params[:id])
file = Tempfile.new
model.to_pdf(file)
send_file file.path, ...
end
I can provide a better example if you paste your code into your question.
You could use a cron task, that deletes the files every n minutes, or, you could order the deletion from the controller itself.
Related
I am building an online translation platform. When a job is done being translated and saved, I want the user to be able to download the translated version as a text file. It is currently saved in a string in the model called "target_text".
I know in ruby I can use this method:
File.open("translation.txt", 'w') {|f| f.write("my translated string") }
I am assuming I could tack the location for the file to be saved in front of the "translation.txt", but I am not sure what folder within my app I should specify?
Furthermore I want this file to be attached to the "job" object in the same way that paperclip can attach files, the difference being it's initiated server side. How should I go about this?
I have googled all over looking for an answer to this, and I want to make sure I do it in the cleanest way possible. I would really appreciate even directions to a good place to look to understand this concept.
I don't quite understand the question, but I hope this could help...
Instead of using
File.open("translation.txt", 'w') {|f| f.write("my translated string") }
try using the following
Tempfile.open(['translation', '.txt'], Rails.root.join('tmp')) do |file|
# this will create a temp file in RAILS_ROOT/tmp/ folder
# you can replace the 'translation' text part to any auto generated text for example
# Tempfile.open([#user.id.to_s, '_translation.txt'] will create
# RAILS_ROOT/tmp/1_translation.1fe2ed.txt
# the 1fe2ed is generated by Tempfile to avoid conflicting
begin
file << "my translated string"
# this creates the file
# add all the processing you need here... cause the next ensure block
# will close and delete this temp file... so that the tmp dir doesn't get big.
# you can for example add the file to paperclip attachment
#user.translation = file
# assuming that user has paperclip attachment called translation
ensure
# close and delete file
file.close
file.unlink
end
end
also check the Tempfile docs... this is the practice i've been using... not sure if it's the best or not.. but it didn't create any issues so far
(even with paperclip s3 storage)
I am using carrierwave to handle my uploads. I have specified the store_dir following way:
def store_dir
"uploads/#{Time.now.year}/#{Time.now.month}/#{Time.now.day}"
end
Uploading files work like a charm - each time I upload a file it ends up in directory where it should end; i.e. "today's directory".
When I try to download the file, carrierwave is constructing the download path dynamically based on store_dir options. So lets say a file which was uploaded on 1.12.2012 is available on the following path on fliesystem:
/uploads/2012/12/01/file.ext
will be retrieved by carrierwave as:
/uploads/2012/12/12/file.ext
Which obviously leads to "Cannot read file" error.
I came with 2 different possible solutions:
Create a separate filed where I will be storing the actual filepath to the file upon it's creation and then will use this value to retrieve file.
Overload retrieve_from_store! method (which is part of carrierwave gem) and make it construct path based on created_at field from the file record than rather from store_dir.
I am inclining to the second possibility since it feels not that dirty. Yet both feel "not-rails-way". Which one will be better to use and why? Or maybe carrierwave provides a way to solve this issue?
Totally guessing here but by looking at the docs I think something like this should work:
def store_dir
"uploads/#{model.created_at.year}/#{model.created_at.month}/#{model.created_at.day}"
end
I'm new to rails and I'm currently trying to parse an uploaded file to rails. However, after I "read" the file once I cannot read it again. From what I've read online it appears that rails immediately deletes the uploaded file. Is there a way to make the file persistent? My code is as follows
file_param = params[:sequence]
file_param.read.each do |l|
# do stuff
end
file_param.read.each do |l|
# do stuff again. this is not being called.
end
I've thought of using paperclip or some other storage gem, but I don't need to store the files, simply read their contents. Thanks!
Read it into an array, if you really need to go over it multiple times, or just save it.
My user uploads a zip file with 3 files (A.ttf, A.svg, A.otf) and I want to store the original zip plus the 3 font files inside it. I've created the 3 versions with this code
version :ttf
process :font => :ttf
end
version :svg
process :font => :svg
end
version :otf
process :font => :otf
end
It successfully saves 4 copies of the original file, all with the proper file name. However, I don't know how to get CarrierWave to store the individual files. This code doesn't work. :(
def font(format)
new_file = nil
# Loop through the zip file and extract the files
Zip::ZipFile.open(#file.file) do |files|
files.each do |f|
next unless f.file?
filename = f.name.split("/").last
ext = filename.split('.').last
# Save the file with the proper file extension
new_file = f if ext == format
end
# Return the file to be stored by CarrierWave
new_file
end
OK, after many hours of banging my head against the wall the light finally came on. The solution is in how CarrierWave processes the upload. When you define a version, CW duplicates the file with a new name ([version name]_original_filename) and gives it to you in the current_path variable. You can do anything you want with this file reference (ie open the file and truncate it, or fill it with random date, etc.) and when you get done CW will store the file for you.
Somehow I missed the connection and when I realized what was going on it almost blinded me. I'm answering this question here so that it might help some other poor soul lost in the dark. And to show the world my ignorance. :/
I dont know about CarrierWave. But you are returnng zip file object back. Is it what you want to pass or do you want the name of the file to be passed? Or else do you want the file to be extracted and pass the extracted file path back?
I'm using paperclip for attachments in my application. I'm writing an import script for a bunch of old data, but I don't know how to create paperclip objects from files on disk. My first guess is to create mock CGI multipart objects, but that seems like a bit of a crude solution, and my initial attempt failed, I think because I didn't get the to_tempfile method right.
Is there a Right Way to do this? It seems like something that should be fairly easy.
I know that I've done the same thing, and I believe that I just created a File object from the path to each file, and assigned it to the image attribute. Paperclip will run on that file:
thing.image = File.new("/path/to/file.png")
thing.save
This works great for local files but it doesn't work as well for remote files. I have an app that uses paperclip for uploading images. Those images are getting stored on amazon s3. Anyway, I had some old data that I needed to import so I tried the following:
thing.image = open('http://www.someurl.com/path/to/image.jpg')
thing.save
If the file is small (say, less than 10K) then openuri returns a stringio object and my file would get stored on s3 as stringio.txt
If the file is larger than around 10K, then openuri returns a TempFile object. But the filename on s3 ends up being unique, but not really relating to the original filename of image.jpg
I was able to fix the problem by doing the following:
remote_photo = open('http://www.someurl.com/path/to/image.jpg')
def remote_photo.original_filename;base_uri.path.split('/').last; end
thing.image = remote_photo
thing.save