wkhtmltopdf javascript delay for output of google maps - wkhtmltopdf

I am working with WKTHMTOPDF and really enjoying it. However, the page that is being converted has google maps and the resulting PDF comes out with the map half loaded. I know there was an option to add --javascript--delay in previous versions, but it would appear it is deprecated. I am using version 0.99. Is there a different option?

There is another a better way to do this that does not require using --javascript--delay (and has the advantage of not requiring you to set a delay time before you know what the required delay will actually be).
Add a callback to the 'tileloaded' event:
google.maps.event.addListenerOnce(map, 'tilesloaded', function(){
window.status = 'ready_to_print';
});
Then call wkhtmltopdf with the --window.status option set to 'ready_to_print' e.g.
wkhtmltopdf --window-status ready_to_print map.html map.pdf
obviously you can change the string 'ready_to_print' to be whatever you want so long as window.status does not already equal that value when wkhtmltopdf is called and before the above code fires.
A similar approach can be used with google charts, though the appropriate event goes by a different name.

You can use the wkhtmltopdf version 0.12.0
I am also using in websites some highly javascript contents. Previously, It was not rendering properly with version 0.99 But when I used version 0.12 with using the option --javascript-delay, everything looks fine.
You can add other options too to load your javascript perfectly i.e. --enable-javascript , --no-stop-slow-scripts etc
Be sure that you have to use proper time delay in using --javascript-delay, it depends on your site that how much time it is taking to render. If you will use more time delay then it will take more time to execute and if you will take less time delay then javascript will not be loaded properly.
The link to latest version of wkhtmltopdf

The --javascript-delay option is not deprecated at all. Also, it would be advisable to upgrade to the latest version -- 0.9.9 is a very old version.

The --javascript-delay function works, but is suboptimal for my usage -- maybe your usage is variable as well? The PDF can sometimes contain a list of just a dozen items and their map view, or hundreds of items on the map. There is no one right msec delay for me...
I successfully used #rohit-singhal tip (Rails app using GMaps4Rails gem and haml views) inside the controller method:
def index
...
respond_to do |format|
format.pdf do
#map_data = { markers: #map_hash, zoom: 10, cluster_zoom: 10, center: center_coordinates,
fit_to_bounds: true, show_center_marker: false, map_type: 'roadmap'}
render pdf: 'Water Supplies',
disposition: 'inline',
layout: 'layouts/pdf.html.haml',
show_as_html: params.key?('debug'),
no_stop_slow_scripts: ''
end
end
end
And I used #mwag's tilesloaded callback as well. (Verbatim in the google maps generation javascript.) The controller line of interest to switch out the no_stop_slow_scripts for:
...
window_status: 'ready_to_print'
...
Both worked. Not sure if there are any advantages to one or the other.

Related

Upload to S3 with progress in plain Ruby script

This question is related to this one: Tracking Upload Progress of File to S3 Using Ruby aws-sdk,
However since there is no clear solution to this I was wondering if there's a better/easier way (if one exists) of getting file upload progress with S3 using Ruby in 2018?
In my current setup I'm basically creating a new Resource, fetch my bucket and call upload_file but I haven't yet found any options for passing blocks which would help in yielding some sort of progress.
...
#connection = Aws::S3::Resource.new
#s3_bucket = #connection.bucket(bucket)
#s3_bucket.object(path).upload_file(data, {acl: 'public-read'})
...
Is there a way to do this using the newest sdk-for-ruby v3?
Any help (or even better a small example) would be great.
The example Trevor gives in https://stackoverflow.com/a/12147709/153886 is not hacky from what I can see - just wiring things together. The SDK simply does not provide a feature for passing progress details on all operations. Plus, Trevor is the maintainer of the Ruby SDK at AWS so I trust his judgement.
Expanding on his example
bar = ProgressBar.create(:title => "Uploading action", :starting_at => 0, :total => file.size)
obj = s3.buckets['my-bucket'].objects['object-key']
obj.write(:content_length => file.size) do |writable, n_bytes|
writable.write(file.read(n_bytes))
bar.progress += n_bytes
end
If you want to have a progress block right in the upload_file method I believe you will need to open a PR to the SDK. It is not that strange that is not the case for Ruby (or for any other runtime) because, for example, there could be an optimisation in the HTTP client library that uses IO.copy_stream from your source body argument to the destination socket, which does not relay progress anywhere.

Render a view's output later via a delayed_job

If I render html I get html to the browser which works great. However, how can I get a route's response (the html) when being called in a module or class.
I need to do this because I'm sending documents to DocRaptor and rather than store the markup/html in a db column I would like to instead store record IDs and create the markup when the job executes.
A possible solution is using Ruby's HTTP library, Httparty or wget or something and open up the route and use the response.body. Before doing so I thought I'd ask around.
Thanks!
-- Update --
Here's something like what I ended up going with:
Quick tip - in case anyone does this and need their helper methods you need to extend AV with ApplicationHelper:
Here's something like what I ended up doing:
av = ActionView::Base.new()
av.view_paths = ActionController::Base.view_paths
av.extend ApplicationHelper #or any other helpers your template may need
body = av.render(:template => "orders/receipt.html.erb",:locals => {:order => order})
Link:
http://www.rigelgroupllc.com/blog/2011/09/22/render-rails3-views-outside-of-your-controllers/
check this question out, it contains the code probably want in an answer:
Rails 3 > Rendering views in rake task

Modernizr.load() confusion with Yepnope

I'm more than a little confused about Modernizr and it's relation to Yepnope.js. As I understand it, Modernizr comes with Yepnope.js (assuming you select the Modernizr.load() option). According to the Yepnope documentation, there are optional prefix plugins which can used. For example, you can test for versions of IE (assuming you also load the yepnope.ie-prefix.js script). However, when I attempt to run the following, I get 'undefined' alert:
Modernizr.load({
load: 'ie!my-ie-specific.js',
complete : function (url, result, key){
alert(url, result, key);
}
});
What am I doing wrong? Does Modernizr include Yepnope completely or only bits and pieces?
I got stuck on this too. Struggled for an hour.
The complete callback doesn't support tests. Change it to callback which fires when the external script is loaded.
complete runs when all scripts are loaded, OR if nothing is loaded.
I wish complete took the result variable though. I could use that.

How can I determine what's making my partials render so slowly?

I'm working on an application that has to render a very large page, composed from a bunch of partials. I can see the rendering time for each of my partials in the log, and there are several that take more than 500 milliseconds.
Obviously, this is unacceptable. How can I profile the rendering of these partials? For instance, how can I get a breakdown of the methods being called within them and say, "Oh, I'm spending X milliseconds on Y uses of link_to", etc.
I'm using Ruby 1.9.2-p290 (I can use 1.9.3 if that's helpful) and Rails 3.1.3.
I usually use the ruby_prof gem for this.
Install the gem and then setup an around_filter that looks like this
def log_profile
result =RubyProf.profile do
yield
end
File.open(Rails.root.join("profile.html"),"w") do |out|
printer = RubyProf::GraphHtmlPrinter.new(result)
printer.print(out,:min_percent=>0)
end
end
This will dump a profile of the action into profile.html, for you to examine. Ruby prof has a bunch of output formatters you can play with. Remember to do this with cache_classes on - you don't want class reloading obscuring your view

ChemDoodle Ajax Incompatibility with Pollen.js

I'm trying to use iChemLabs cloud services from a html5 web worker. Normally the cloudservices requires jQuery but I can't import that into a web worker so I'm using Pollen instead with a ChemDoodle Web Components library with which I have stripped out the document-related things.
jQuery.Hive.Pollen provides a nice ajax function very similar to jQuery, but I can't seem to get it to work at all. I know this problem will be tricky to solve considering that Access-control-headers need to be set to allow any of you to actually find the solution. However, I'm a beginning javascript programmer and I was wondering if my two weeks of frustration is actually a small difference. I am trying to invoke the following function:
var cloudmolecule;
ChemDoodle.iChemLabs.readSMILES('N1(C)C(=O)N(C)C(C(=C1N1)N(C=1)C)=O', function(mol){
cloudmolecule = mol;
});
Here is a link to the library code I am using, see the 'q.ajax' call and substitute jQuery = q for p = q (p is for pollen) in that block of code.
Right now I'm just trying to get the ajax call to work in an ordinary block of javascript with the plan to migrate to a web worker later.
If anybody could point out the problem to me I would be extremely grateful.
solved! turns out iChemLabs rejects these two extra headers that pollen creates:
_xhr.setRequestHeader("X-Requested-With", "Worker-XMLHttpRequest");
_xhr.setRequestHeader("X-Worker-Hive", "Pollen-JS" );
Simply comment them out
Also, Pollen ajax seems to return a JSON object containing the data in JSON format AND as a string, so do
o = JSON.parse(data.string)//data is the parameter to the callback function
The reduced ChemDoodle library (without document-related methods) will work like a charm with pollen ajax.

Resources