How generate pdf in rake task using cron job rails 3 - ruby-on-rails

Hi i am using rails 3 and wicked pdf gem to generate pdf in my controllers.But now i want to
generate pdf in rake task which will run through cron jobs.After creating this PDF i will send
it in email.
this is my normal controller method to generate pdf
def generate_invoice_pdf
begin
#trunk_groups_orig = TrunkGroupSubscriber.all
render :pdf => "GenerateInvoice", :layout => false, :template => "/accountings/generate_invoice_pdf"
rescue => client
puts client.inspect
end
end
But how i can generate pdf in rake task
Many many thanks for any help

If you are using pdfkit or wicked_pdf then you can try this,see if it works.
Updating code
class PdfInvoice
def generate_invoice
#trunk_groups_orig = TrunkGroupSubscriber.all
content = File.read('#{Rails.root}/app/views/accountings/generate_invoice_pdf.erb')
template = ERB.new(content)
# THis will generate html content
html_content = template.result(binding)
# now you have html content
pdf= WickedPdf.new.pdf_from_string(html_content)
# then save to a file
save_path = Rails.root.join('pdfs','filename.pdf')
File.open(save_path, 'wb') do |file|
file << pdf
end
end
end
PdfInvoice.new.generate_pdf
#You can customize method based on your requirement,

Related

Wicked pdf, failed to load PDF document

I am trying to implement the gem wicked_pdf . After initial difficulties (fatal error (exception reentered)), I managed to start the server. I set up a pdf with the content "Hello world" for the test, but every time I want to open it, I get a "failed to load PDF document" notification
Controller
def index
respond_to do |format|
format.html
format.pdf do
render pdf: "index.pdf.haml",
layout: 'pdf.html.haml',
page_size: 'A4',
disposition: 'inline'
end
end
end
index.pdf.haml
Hello world
config/initializers/wicked_pdf.rb
# WickedPDF Global Configuration
#
# Use this to set up shared configuration options for your entire application.
# Any of the configuration options shown here can also be applied to single
# models by passing arguments to the `render :pdf` call.
#
# To learn more, check out the README:
#
# https://github.com/mileszs/wicked_pdf/blob/master/README.md
class WickedPdf
module PdfHelper
remove_method(:render)
end
end
WickedPdf.config = {
# Path to the wkhtmltopdf executable: This usually isn't needed if using
# one of the wkhtmltopdf-binary family of gems.
# exe_path: '/usr/local/bin/wkhtmltopdf',
# or
# exe_path: Gem.bin_path('wkhtmltopdf-binary', 'wkhtmltopdf')
# Layout file to be used for all PDFs
# (but can be overridden in `render :pdf` calls)
# layout: 'pdf.haml',
# Using wkhtmltopdf without an X server can be achieved by enabling the
# 'use_xvfb' flag. This will wrap all wkhtmltopdf commands around the
# 'xvfb-run' #command, in order to simulate an X server.
# use_xvfb: true,
}
config/initializers/mime_types.rb
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
Mime::Type.register "application/pdf", :pdf
Link to Screenshot: https://drive.google.com/file/d/1ujt8ANq16SrmSHJk45APMXXxm1l5q5ic/view?usp=sharing
Ok, so I downgraded wicked_pdf to version 1.4.0 and I removed:
class WickedPdf
module PdfHelper
remove_method(:render)
end
end
From config/initializers/wicked_pdf.rb, and now it works.

Files in public directory in Rails - Errno::ENOENT (No such file or directory # rb_sysopen

I'm currently working on a Rails 5.2 application using the combine pdf gem. I'm trying to merge two PDF files but somehow I'm unable to load files from the public directory.
In the controller I have the following method:
def pdf_download
pdf = CombinePDF.new
pdf << CombinePDF.load("#{Rails.root}/public/pdfs/1.pdf")
pdf << CombinePDF.load("#{Rails.root}/public/pdfs/1.pdf")
pdf.save "combined.pdf"
send_data combined_file.to_pdf, filename: "combined.pdf", type: "application/pdf"
end
I have tried many posts on StackOverflow without success such as using Rails.root. But I still get the same error:
Errno::ENOENT (No such file or directory # rb_sysopen - app/public/pdfs/1.pdf):
Is there any additional configuration I have to do to load files from public? and if these PDF shouldn't be in public where should I store them?
This fixed it for me:
def pdf_download
pdf = CombinePDF.new
pdf << CombinePDF.load(Rails.root.join("public", "pdfs/1.pdf").to_s)
pdf << CombinePDF.load(Rails.root.join("public", "pdfs/2.pdf").to_s)
# pdf.save "combined.pdf"
send_data pdf.to_pdf, filename: "combined.pdf", type: "application/pdf"
end
This fixed it for me:
pdf << CombinePDF.load("./public/pdfs/1.pdf")

Save xlsx file to disk in Sidekiq as background

I am trying to generate excel file in background by using axlsx and save it (Rails4.2). In GitHub page of axlsx, it says As of Rails 4.1 you must use render_to_string to render a mail attachment. However, it throws me a error NoMethodError: undefined method 'render_to_string' for #<CreateExcelSheetWorker:0x007fbccf51db30>
My worker class:
class CreateExcelSheetWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { daily }
def perform()
model = SomeModel.where(wanted: true).order(started_at: :desc)
xlsx = render_to_string handlers: [:axlsx], formats: [:xlsx], template: "template/file", locals: {model: model}
path = "/tmp/a.xlsx"
File.open(path, "w+") do |f|
f.write(xlsx)
end
end
end
I cannot figure out how to fix this, any help appreciated.
That render_to_string comment is for usage of the gem in actionmailers. Outside of any kind of view context, you'll have to use xlsx builder api directly. Something like this:
package = Axlsx::Package.new do |p|
p.workbook.add_worksheet(name: "Summary") do |sheet|
sheet.add_row ["foo", 1]
end
end
File.write(filename, package.to_stream.read)
Sergio's answer is fine. But, if you are wanting to use the axlsx_rails template, you can use this example, which builds a fake view context to render the template:
require 'abstract_controller'
require 'action_controller'
require 'action_view'
require 'active_record'
# require any helpers
require './app/helpers/application_helper'
# active record only if data is here
require './app/models/widget'
ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: 'db/development.sqlite3'
)
ActionController::Base.prepend_view_path "./app/views/"
# place data in view_assigns
view_assigns = {widgets: Widget.all}
av = ActionView::Base.new(ActionController::Base.view_paths, view_assigns)
av.class_eval do
# include any needed helpers (for the view)
include ApplicationHelper
end
# normal render statement
content = av.render template: 'widgets/index.xlsx.axlsx'
# do something with content, such as:
File.open("/tmp/with_runner.xlsx","w+b") {|f| f.puts content }
https://gist.github.com/straydogstudio/dceb775ead81470cea70

Download all files to a zip within Heroku

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

How to open file that is stored by CarrierWave in GridFs from a rails model? (File.open issue)

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)>

Resources