I'm trying to add a custom name to the file based on the object it's called for in WickedPDF. This worked fine as a controller action, but once it's in a Sidekiq worker, it fails saying no method name for the Issueable (polymorphic) object, which is returned as a string (and that is likely the cause of all my issues right there, but I've no idea how to get around it).
the line in question:
save_path = Rails.root.join('public', "#{#issueable.name}_checklist.pdf")
The precise error in context from the Sidekiq console output:
2019-01-15T02:36:46.194Z 10080 TID-oxwns2nmk GenerateChecklistWorker JID-cefb15a101c80e1c8727b646 INFO: start
"***************[\"/Users/jathayde/.rbenv/versions/2.5.2/bin/wkhtmltopdf\", \"-q\", \"--dpi\", \"144\", \"--margin-top\", \"30\", \"--margin-bottom\", \"20\", \"--margin-left\", \"10\", \"--margin-right\", \"10\", \"--header-spacing\", \"5\", \"--footer-spacing\", \"0\", \"file:////var/folders/1b/9267f2s126q7c_8dztswqps40000gn/T/wicked_pdf20190114-10080-40sij4.html\", \"/var/folders/1b/9267f2s126q7c_8dztswqps40000gn/T/wicked_pdf_generated_file20190114-10080-kekkfo.pdf\"]***************"
2019-01-15T02:36:58.263Z 10080 TID-oxwns2nmk GenerateChecklistWorker JID-cefb15a101c80e1c8727b646 INFO: fail: 12.069 sec
2019-01-15T02:36:58.268Z 10080 TID-oxwns2nmk WARN: {"context":"Job raised exception","job":{"class":"GenerateChecklistWorker","args":["#<Lodge:0x00007fcdb8cc86b0>",["#<Issue:0x00007fcdc267ea70>","#<Issue:0x00007fcdc26c0a88>"],"#<Issue::ActiveRecord_AssociationRelation:0x00007fcdc22e1c28>"],"retry":false,"queue":"default","jid":"cefb15a101c80e1c8727b646","created_at":1547519806.182058,"enqueued_at":1547519806.18223},"jobstr":"{\"class\":\"GenerateChecklistWorker\",\"args\":[\"#<Lodge:0x00007fcdb8cc86b0>\",[\"#<Issue:0x00007fcdc267ea70>\",\"#<Issue:0x00007fcdc26c0a88>\"],\"#<Issue::ActiveRecord_AssociationRelation:0x00007fcdc22e1c28>\"],\"retry\":false,\"queue\":\"default\",\"jid\":\"cefb15a101c80e1c8727b646\",\"created_at\":1547519806.182058,\"enqueued_at\":1547519806.18223}"}
2019-01-15T02:36:58.268Z 10080 TID-oxwns2nmk WARN: NoMethodError: undefined method `name' for "#<Lodge:0x00007fcdb8cc86b0>":String
2019-01-15T02:36:58.268Z 10080 TID-oxwns2nmk WARN: /Users/jathayde/Development/Meticulous/Products/patchvault/app/workers/generate_checklist_worker.rb:30:in `perform'
Here's the full generate_checklist_worker.rb:
class GenerateChecklistWorker
include Sidekiq::Worker
sidekiq_options retry: false
def perform(issueable, issues, event_issues)
#issueable = issueable
av = ActionView::Base.new()
av.view_paths = ActionController::Base.view_paths
av.class_eval do
include Rails.application.routes.url_helpers
include ApplicationHelper
end
pdf = av.render template: 'issues/checklist.pdf.erb',
locals: {:issueable => #issueable, :issues => #issues, :event_issues => #event_issues}
pdf = WickedPdf.new.pdf_from_string(
pdf,
disposition: 'attachment',
dpi: '144',
header: {html: {template: 'layouts/_checklist_header'}, spacing: 5 },
footer: {html: {template: 'layouts/_checklist_footer'}, spacing: 0 },
margin: {top: 30, bottom: 20, left: 10, right: 10},
locals: {:issueable => #issueable},
#cover: ApplicationController.new.render_to_string('issues/checklist_cover.pdf.erb'), locals: {:issueable => issueable}
)
save_path = Rails.root.join('public', "#{#issueable.name}_checklist.pdf")
File.open(save_path, 'wb') do |file|
file << pdf
end
end
end
Here's the method in the controller that calls this:
def checklist
#issues = #issueable.issues.kept.non_event_issues.ordered_issues
#event_issues = #issueable.issues.kept.event_issues.order(issue_number: :asc)
GenerateChecklistWorker.perform_async(#issueable, #issues, #event_issues)
redirect_to #issueable
end
You cannot serialize complex Ruby objects as Sidekiq arguments. You'll need to look up the thing (i.e. by calling find) in the job.
https://github.com/mperham/sidekiq/wiki/Best-Practices#1-make-your-job-parameters-small-and-simple
Related
With rails 5.2.4, I am trying to generate a pdf in the background (within a job) and then attach it to a model as:
pdf_contents = ApplicationController.render(
pdf: "name",
template: 'mytemplate.html.erb',
layout: 'pdf_layout.html',
disposition: 'attachment'
)
#user.attach(io: StringIO.new(pdf_contents), filename: "file.pdf", content_type: "application/pdf")
but I am getting :
WARN: ActionView::Template::Error: private method `format' called for nil:NilClass
using
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
Below solution works for my case.
# frozen_string_literal: true
class OrderPdfJob < ApplicationJob
queue_as :default
def perform(order_id)
order = Order.find(order_id)
# include helpers
action_controller = ActionController::Base.new
action_controller.view_context_class.include(ActionView::Helpers, ApplicationHelper)
pdf = WickedPdf.new.pdf_from_string(
action_controller.render_to_string(
"order_pdf/summary", layout: 'pdf', locals: { order: order }
)
)
# in your order model should have 'has_one_attached :summary'
order.summary.attach(
io: StringIO.new(pdf),
filename: "#{order.id}.pdf",
content_type: 'application/pdf'
)
order.save!
end
end
I am writing some infrastructure testing in Chef InSpec & am not sure how to go about testing that a url is not accessible publicly. I have the following code snippet which I am currently using
environments = {
:ops => "ops",
}
control "verify-not-accessible-publicly" do
impact 1.0
title "verify we are not publicly accessible"
environments.each do |_, env|
uri = "http://#{env}.internal.example.com"
begin
result = http(uri, ssl_verify: true, open_timeout: 2, read_timeout: 5, max_redirects: 0)
rescue => e
unless e.class == Faraday::ConnectionFailed
raise e
end
end
end
end
This isn't working quite like I expect. I don't think the http(uri,...) block is actually executed until it is passed into a describe function.
Thanks
you should use http resource with a describe block and matchers
describe http('url', auth: {user: 'user', pass: 'test'}, params: {params}, method: 'method', headers: {headers}, data: data, open_timeout: 60, read_timeout: 60, ssl_verify: true, max_redirects: 3) do
its('status') { should eq number }
its('body') { should eq 'body' }
its('headers.name') { should eq 'header' }
end
I just make image upload in ckeditor including carrierwave and cloudinary
I've tried once and it works well, I can browse image on my laptop and upload to cloudinary via image uploader in ckeditor. but when I try to edit or create new article and try to upload a picture, image uploader doesn't work anymore. I don't know why, I didn't edit anything after successful make the image uploader. anyone can help me? thx anyway
error that comes out like this
here's my model/ckeditor/asset.rb
class Ckeditor::Asset < ActiveRecord::Base
include Ckeditor::Orm::ActiveRecord::AssetBase
delegate :url, :current_path, :content_type, to: :data
validates :data, presence: true
end
model/ckeditor/picture.rb
class Ckeditor::Picture < Ckeditor::Asset
mount_uploader :data, CkeditorPictureUploader, mount_on: :data_file_name
def url_content
url(:content)
end
end
model/ckeditor/attachment_file.rb
class Ckeditor::AttachmentFile < Ckeditor::Asset
mount_uploader :data, CkeditorAttachmentFileUploader, mount_on: :data_file_name
def url_thumb
#url_thumb ||= Ckeditor::Utils.filethumb(filename)
end
end
uploader/ckeditor/ckeditor_picture_uploader.rb
class CkeditorPictureUploader < CarrierWave::Uploader::Base
include Ckeditor::Backend::CarrierWave
include Cloudinary::CarrierWave
include CarrierWave::MiniMagick
version :thumb do
process resize_to_fill: [118, 100]
end
version :content do
process resize_to_limit: [800, 800]
end
def extension_white_list
Ckeditor.image_file_types
end
end
config/initializers/ckeditor.rb
Ckeditor.setup do |config|
# ==> ORM configuration
# Load and configure the ORM. Supports :active_record (default), :mongo_mapper and
# :mongoid (bson_ext recommended) by default. Other ORMs may be
# available as additional gems.
require "ckeditor/orm/active_record"
config.picture_model { Ckeditor::Picture }
# config.attachment_file_model { Ckeditor::AttachmentFile }
Rails.application.config.assets.precompile += %w( ckeditor/filebrowser/images/gal_del.png )
config.cdn_url = "//cdn.ckeditor.com/4.5.6/standard/ckeditor.js"
config.js_config_url = "/assets/ckeditor/config.js"
end
EDIT
here's my ckeditor js
ckeditor/config.js
CKEDITOR.editorConfig = function( config )
{
config.enterMode = 2
config.filebrowserBrowseUrl = "/ckeditor/attachment_files";
config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";
config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";
config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";
config.filebrowserImageBrowseUrl = "/ckeditor/pictures";
config.filebrowserImageUploadUrl = "/ckeditor/pictures";
config.filebrowserUploadUrl = "/ckeditor/attachment_files";
config.toolbar_Pure = [
'/', {
name: 'basicstyles',
items: ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat']
}, {
name: 'paragraph',
items: ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl']
}, {
name: 'links',
items: ['Link', 'Unlink']
}, '/', {
name: 'styles',
items: ['Styles', 'Format', 'Font', 'FontSize']
}, {
name: 'colors',
items: ['TextColor', 'BGColor']
}, {
name: 'insert',
items: ['Image', 'Table', 'HorizontalRule', 'PageBreak']
}
];
config.allowedContent = true;
config.toolbar = 'Pure';
return true;
}
[:extract_content_type, :set_size, :read_dimensions].each do |method|
define_method :"#{method}_with_cloudinary" do
send(:"#{method}_without_cloudinary") if self.file.is_a?(CarrierWave::SanitizedFile)
{}
end
alias_method_chain method, :cloudinary
end
check CKEditor Carrierwave Cloudinary
I followed this guide to get drag and drop file uploads through AJAX: http://dannemanne.com/posts/drag-n-drop_upload_that_works_with_ror_and_paperclip
Everything was working fine on my development environment with WebBrick but if I deploy to PhusionPassenger then I get:
Paperclip::AdapterRegistry::NoHandlerError (No handler found for #<PhusionPassenger::Utils::RewindableInput:0x000000041aef38 #io=#<PhusionPassen...
I'm using this in my controller:
before_filter :parse_raw_upload, :only => :bulk_submissions
def bulk_submissions
...
#submission = Submission.create!(url: "", file: #raw_file, description: "Please edit this description", work_type: "other", date_completed: DateTime.now.to_date)
...
end
private
def parse_raw_upload
if env['HTTP_X_FILE_UPLOAD'] == 'true'
#raw_file = env['rack.input']
#raw_file.class.class_eval { attr_accessor :original_filename, :content_type }
#raw_file.original_filename = env['HTTP_X_FILE_NAME']
#raw_file.content_type = env['HTTP_X_MIME_TYPE']
end
end
Looking at the request itself all the headers are set (X_MIME_TYPE, X_FILE_NAME) etc.
Any ideas?
Thanks in advance!
The example you're cribbing from expects the file stream to be a StringIO object, but Passenger is giving you a PhusionPassenger::Utils::RewindableInput object instead.
Fortunately, a RewindableInput is duckalike to StringIO for this case, so Paperclip's StringioAdapter can be used to wrap your upload stream.
Inside the if block in your parse_raw_upload, at the end, do:
if #raw_file.class.name == 'PhusionPassenger::Utils::RewindableInput'
#raw_file = Paperclip::StringioAdapter.new(#raw_file)
end
I'm trying to upload an image to paperclip and save it to s3. However, I get the following error in my console
!! Unexpected error while processing request: invalid byte sequence in UTF-8
There are a few responses on StackOverflow about how to resolve this problem, though most point to the original solution being an update to Rack. However, I'm using Ruby 1.9.3 and Rails 3.1.3, and believe I don't have Rack (I haven't installed it as a Gem, should I??).
The filenames that I've been trying are fairly simple, so I'm assuming the issue is in the actual file, but I'm not sure how to debug which upload variable the error is coming from. Rails isn't putting any of these errors in the log files, so I can't seem to get more details.
My controller is fairly simple, just like the example on the paperclip github documentation
def create
wine_photo = WinePhoto.create(params[:wine_photo])
return render :json => wine_photo
end
though originally I used the more common
wine_photo - WinePhoto.new(params[:wine_photo])
if wine_photo.save
return render :json => wine_photo
else
return render :json => wine_photo.errors
end
My model (which I doubt is very helpful) is
class WinePhoto true
validates_with AttachmentPresenceValidator, :attributes => :photo
belongs_to :wine
belongs_to :user
def photo_url
photo.url
end
end
based on this response on stackoverflow, Ruby Invalid Byte Sequence in UTF-8, I've tried the below in my controller
def create
wine_photo = WinePhoto.new(params[:wine_photo])
wine_photo.photo = IO.read(wine_photo.photo).force_encoding("ISO-8859-1").encode("utf-8", replace: nil)
...
but still got the error.
Any suggestions on how to get past this encoding issue? Is there a way to confirm that the error is coming from the file being uploaded?
My upload code (ajax) is
save_photo: function(){
var file = document.getElementById('file_api').files[0];
console.log(file);
var xhr = new XMLHttpRequest();
if (xhr.upload && file.type == "image/jpeg" ) {
// create progress bar
var o = document.getElementById("progress");
var progress = o.appendChild(document.createElement("p"));
progress.appendChild(document.createTextNode("upload " + file.name));
// progress bar
xhr.upload.addEventListener("progress", function(e) {
var pc = parseInt(100 - (e.loaded / e.total * 100));
progress.style.backgroundPosition = pc + "% 0";
}, false);
// file received/failed
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
progress.className = (xhr.status == 200 ? "success" : "failure");
}
};
// start upload
xhr.open("POST", document.getElementById("add_photo").action, true);
xhr.setRequestHeader("X_FILENAME", file.name);
xhr.send(file);
}
}
and the params for file are
File {webkitRelativePath: "", lastModifiedDate: Thu Nov 10 2011 09:40:39 GMT+1100 (AUS Eastern Summer Time), name: "WP_000012.jpg", type: "image/jpeg", size: 1344450}
After two days of messing with this, it turns out the problem was in my ajax upload, rails wasn't getting the file field at all.
I followed this blog post to get the ajax upload working,
https://github.com/newbamboo/example-ajax-upload/blob/master/public/index.html
and changed the name in my input file to < input type="file" name="wine_photo[photo]" > where before the name was just photo.
the html form now also has
<input name="utf8" type="hidden" value="✓">