I am trying to create a temp file in my rails application. Here is the controller code:
private
def tmp_example
temp_file = TempFile.new('logo')
# save uploaded file
File.open(temp_file.path, "w") do |f|
f.write session[:user_params]["logo"].delete(:file).read
f.close
end
end
I have required the tempfile in application.rb
require 'tempfile'
But still i am getting error:
uninitialized constant UsersController::TempFile
Can anyone how to fix this issue thanks.
According to the docs, you should use Tempfile instead of TempFile:
temp_file = Tempfile.new('logo')
Related
I have created a ZIP file using ruby , now I have to add password to this file. But it is not working. Could someone help. I am using rubyzip and zip-zip gem.
Code which I tried as below :
#Create Zip File and delete if already existing
filename= 'abc.xlsx'
zip_file_path = Rails.root.join('tmp/my.zip')
file_name =filename
file_path = Rails.root.join('tmp', filename)
logger.error zip_file_path
logger.error file_path
File.delete(zip_file_path) if File.exist?(zip_file_path)
Zip::ZipFile.open(zip_file_path, Zip::ZipFile::CREATE) do |zip|
zip.add(file_name, file_path)
end
# end
Next step is to add password to ZIP file . I tried below method
Zip::File.encrypt(zip_file_path, 'password')
# Got error like : **NameError (uninitialized constant Zip::Archive):**
Also i tried to use below :
Zip::OutputStream.write_buffer(::StringIO.new(''), Zip::TraditionalEncrypter.new('password')) do |out|
out.put_next_entry("my_file.txt")
out.write my_data
end.string
#error: **NameError (uninitialized constant Zip::TraditionalEncrypter):**
I have the following code
module EmailHelper
def email_image_tag(image, **options)
attachments.inline[image] = File.read(image_path(image))
image_tag attachments[image].url, **options
end
end
In production this references the correct image with hash, because the image asset is precompiled, however in development this throws a file read exception.
Is there an elegant way to do a File.read without having to check on if Rails.env.development?
The biggest misconception here was that I thought I should point to a digested asset, forgetting that these are meant to be served and not read as a file. Therefore the file can be perfectly loaded from the asset map. I solved the above question as follows:
module MailHelper
def mail_image_tag(image, **options)
path = Rails.root.join('app', 'assets', 'images', image)
attachments.inline[image] = File.read(path)
image_tag attachments[image].url, **options
end
end
I've been knocking my head around with Heroku, while trying to download a zip file with all my receipt files data.
The files are stored on amazon s3 and it all works fine on my development machine..
I thought it had to do with Tempfile, and abandoned that previous solution, since heroku has some strict policies with their filesystem, so i used the tmp folder, but the problem doesn't seem to be there. I already tried to load directly from s3 (using openUri) to the zip file, but it doesn't seem to work either on Heroku.
What might be wrong with my code for Heroku not loading the files to the zip?
Here is my model method :
def zip_receipts(search_hash=nil)
require 'zip/zip'
require 'zip/zipfilesystem'
t=File.open("#{Rails.root}/tmp/#{Digest::MD5.hexdigest(rand(12).to_s)}_#{Process.pid}",'w')
# t = Tempfile.new(Digest::MD5.hexdigest(rand(12).to_s))
# Give the path of the temp file to the zip outputstream, it won't try to open it as an archive.
Zip::ZipOutputStream.open(t.path) do |zos|
logger.debug("search hash Zip: #{search_hash.inspect}")
self.feed(search_hash).each do |receipt|
begin
require 'open-uri'
require 'tempfile'
#configures filename
filen = File.basename(receipt.receipt_file_file_name)
ext= File.extname(filen)
filen_noext = File.basename(receipt.receipt_file_file_name, '.*')
filen=filen_noext+SecureRandom.hex(10)+ext
logger.info("Info Zip - Filename: #{filen}")
# Create a new entry on the zip file
zos.put_next_entry(filen)
# logger.info("Info Zip - Added entry: #{zos.inspect}")
# Add the contents of the file, reading directly from amazon
tfilepath= "#{Rails.root}/tmp/#{File.basename(filen,ext)}_#{Process.pid}"
open(tfilepath,"wb") do |file|
file << open(receipt.authenticated_url(:original),:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read
end
zos.print IO.binread tfilepath
# logger.info("Info Zip - Extracted from amazon: #{zos.inspect}")
rescue Exception => e
logger.info("exception #{e}")
end # closes the exception begin
end #closes receipts cycle
end #closes zip file stream cycle
# The temp file will be deleted some time...
t.close
#returns the path for send file controller to act
t.path
end
My controller:
def download_all
#user = User.find_by_id(params[:user_id])
filepath = #user.zip_receipts
# Send it using the right mime type, with a download window and some nice file name.
send_file(filepath,type: 'application/zip', disposition: 'attachment',filename:"MyReceipts.zip")
end
And I write also my view and routes, so that it might serve anyone else trying to implement a download all feature
routes.rb
resources :users do
post 'download_all'
end
my view
<%= link_to "Download receipts", user_download_all_path(user_id:user.id), method: :post %>
The problem seemed to be with the search hash, and the sql query, and not the code itself. For some reason, the receipts get listed, but aren't downloaded. So it is an all different issue
In the end i have this code for the model
def zip_receipts(search_hash=nil)
require 'zip/zip'
require 'zip/zipfilesystem'
t=File.open("#{Rails.root}/tmp/MyReceipts.zip_#{Process.pid}","w")
# t = Tempfile.new(Digest::MD5.hexdigest(rand(12).to_s))
#"#{Rails.root}/tmp/RecibosOnline#{SecureRandom.hex(10)}.zip"
puts "Zip- Receipts About to enter"
# Give the path of the temp file to the zip outputstream, it won't try to open it as an archive.
Zip::ZipOutputStream.open(t.path) do |zos|
self.feed(search_hash).each do |receipt|
begin
require 'open-uri'
require 'tempfile'
filen = File.basename(receipt.receipt_file_file_name)
ext= File.extname(filen)
filen_noext = File.basename(receipt.receipt_file_file_name, '.*')
filen=filen_noext+SecureRandom.hex(10)+ext
# puts "Info Zip - Filename: #{filen}"
# Create a new entry on the zip file
zos.put_next_entry(filen)
zos.print open(receipt.authenticated_url(:original),:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read
rescue Exception => e
puts "exception #{e}"
end # closes the exception begin
end #closes receipts cycle
end #closes zip file stream cycle
# The temp file will be deleted some time...
t.close
#returns the path for send file controller to act
t.path
end
I'm trying to move a current working task (in production and in the console) to use delayed_job in a Rails 2 app but keep getting the error:
ThermalImageJob failed with NameError: uninitialized constant Barby::Code128B
I've pored through others' code searching for an answer to no avail. Here's my code:
/lib/thermal_image_job.rb
class ThermalImageJob < Struct.new(:order_id)
def perform
order = Order.find(order_id)
order.tickets.each do |ticket|
ticket.barcodes.each do |barcode|
barcode.generate_thermal_image
end
end
end
end
/app/controllers/orders_controller.rb
Delayed::Job.enqueue(ThermalImageJob.new(#order.id))
/app/models/barcode.rb
def generate_thermal_image(format=:gif)
filename = "#{barcode}_thermal.#{format}"
temp_file_path = File.join("#{RAILS_ROOT}", 'tmp', filename)
unless FileTest.exists?(temp_file_path)
barcode_file = File.new(temp_file_path, 'w')
code = Barby::Code128B.new(barcode)
....
end
Gemfile
gem "delayed_job", "2.0.7"
gem "daemons", "1.0.10"
Well, after much head banging, I figured it out, so I'm posting this to help the next person. The problem was that it couldn't find the barby libs, so I added a require at the beginning of my class:
require "barby/outputter/rmagick_outputter"
require "barby/barcode/code_128"
I'm using CarrierWave to store files in gridfs, but having problems with opening them from my model.
Here are my configs:
/config/initialize/carrierwave.rb
CarrierWave.configure do |config|
config.grid_fs_database = Mongoid.database.name
config.grid_fs_host = Mongoid.config.master.connection.host
config.storage = :grid_fs
config.grid_fs_access_url = "/files"
end
/app/controllers/gridfs_controller.rb
/require 'mongo'
class GridfsController < ActionController::Metal
def serve
gridfs_path = env["PATH_INFO"].gsub("/files/", "")
begin
gridfs_file = Mongo::GridFileSystem.new(Mongoid.database).open(gridfs_path, 'r')
self.response_body = gridfs_file.read
self.content_type = gridfs_file.content_type
rescue
self.status = :file_not_found
self.content_type = 'text/plain'
self.response_body = ''
end
end
end
/app/uploaders/list_uploader.rb
class ListUploader < CarrierWave::Uploader::Base
storage :grid_fs
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
and in routes
match "/files/uploads/*path" => "gridfs#serve"
So, I have a model, which have a text file
class Campaign
include Mongoid::Document
mount_uploader :list, ListUploader
When I'm calling something like <%=link_to "List", #campaign.list.url %> from my view, it opens fine. But when I'm trying something like File.open("#{campaign.list.url}", "r") from campaign model, it fails. It gives me false even when I'm calling File.exists?("/files/uploads/campaign/list/4eb02c4d6b1c0f02b200000b/list.txt"), which is a proper url for that file. So, the question is how should I call it, to open the file from model? And for some reasons, it is important to open it from model. Any suggestions would help, thank you.
Carrierwave url with mongodb gridfs is not a physical path. Its merely a logical route to download the file from gridfs. Thats why you cannot access it from ruby File.open. Check out the below snippet from rails console trying to open the file from gridfs
File.open(User.first.image.pic.url,'r')
Errno::ENOENT: No such file or directory - /images/uploads/e5a1007d34.jpg
see it throw No such file or directory., So you have to download a file instead opening by
>> require 'open-uri'
>> open('image.jpg', 'wb') do |file|
?> file << open('http://0.0.0.0:3000' + (User.first.image.pic.url)).read
>> p file
>> end
#<File:image.jpg>
=> #<File:image.png (closed)>