We have a content type that uses a number of image styles to re-purpose images for a variety of different sections of our website, and have a large number of derivatives that need to be generated.
I want to use a script to pre-generate the necessary image derivatives before we go live after a major upgrade.
My thought was to write a script that uses Curl to call the URLs for which image derivatives will be created.
If in a browser I go to a specific URL that will cause generation of a derivative the image gets generated as expected. This is default Drupal behavior.
However, if I make a call to Curl on the command line for another URL that will cause generation of a derivative, the image does not get generated as expected.
I suspect it's because Curl is not actually downloading images. I also tried with Lynx and the result was the same.
Can anyone advise if there is a way to force Curl or Lynx to automatically download images so that the derivatives get created?
Thanks,
Pablo
you want to download all <img src="url" /> 's ?
easy, parse out the src attributes with DOMDocument and make an individual curl request for each image, kinda like this:
function downloadAllImagesFromUrl(string $url):int{
$imagesDownloaded=0;
$ch=curl_init();
if(!curl_setopt_array($ch,array(
CURLOPT_AUTOREFERER => true,
CURLOPT_BINARYTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTPGET => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_CONNECTTIMEOUT => 4,
CURLOPT_TIMEOUT => 8,
CURLOPT_COOKIEFILE => "", // <<makes curl save/load cookies across requests..
CURLOPT_ENCODING => "", // << makes curl post all supported encodings, gzip/deflate/etc, makes transfers faster
CURLOPT_URL=>$url,
CURLOPT_RETURNTRANSFER=>true
))){
throw new Exception(curl_error($ch));
}
$html=curl_exec($ch);
$domd=#DOMDocument::loadHTML($html);
foreach($domd->getElementsByTagName("img") as $img){
$src=$img->getAttribute("src");
if(!$src){
continue;
}
//Warning: you might want to parse_url PHP_URL_HOST / PHP_URL_PORT / PHP_URL_PATH
// if the urls are not absolute but relative.
curl_setopt($ch,CURLOPT_URL,$src);
curl_exec($ch);
++$imagesDownloaded;
}
curl_close($ch);
return $imagesDownloaded;
}
It is probably much faster to use get_headers() instead of curl_exec, but since PHP by default use ignore_user_abort, drupal may abort image generation if you dont actually download them but only get their headers. warning, the code above assumes all image src's are absolute. you need additional coding with parse_url & PHP_URL_HOST / PHP_URL_PORT / PHP_URL_PATH if you want to handle relative urls.. and note: this can be made much faster by using multithreading with curl_multi interface, but that requires much more complex coding..
Related
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.
I am having issues with translating client-side text in CKAN. My site is in french, so here is the problem:
- if I click on the green button "S'abonner" from the left, it should change the button to a red one and show the text "Se désabonner", but instead, it shows me "Unfollow", like in the photos:
And if I click it again it shows me "Follow" (instead of "S'abonner"). So this is a problem on the client side. Normally, when you generate text on the server side you write in the templates _('msgid present in pofile'), but, on the client side, it uses the result from the AJAX call to "/api/i18n/{language}".
I did some digging and it seems that the client-side translation uses the result from the AJAX call to "/api/i18n/fr", but all I get is a json object:
{
"": {
"domain": "ckan",
"lang": "fr",
"plural-forms": "nplurals=2; plural=(n > 1)"
}
}
But, if I look at the ckan demo website, (http://demo.ckan.org/api/i18n/fr), I get a long JSON file, that contains all the translations.
I managed to discover from where this Ajax call is done, apparently it comes from : "src/ckan/ckan/public/base/javascript/client.js", at the function:
getLocaleData: function (locale, success, error) {
var url = this.url('/api/i18n/' + (locale || ''));
return jQuery.getJSON(url).then(success, error);
}
If I replace
var url = this.url('/api/i18n/' + (locale || ''));
with
var url = this.url('http://demo.ckan.org/api/i18n/fr')
the problem is solved, because I get the translations in the json object.
My question is how I can get the right data to be generated, is there a parameter to put in production.ini? Unfortunately, the documentation in CKAN is really poor so I have no leads on this. Does anybody have a clue?
Thanks!
I suspect that you might be running an unreleased branch of CKAN (eg master), so the Javascript translations have not been built.
This is done with the following command:
paster front-end-build -c config_file.ini
Just run this command and the translations should come up fine.
On the main repository this is only done just before releases to avoid complicating the git history.
Check for instance this site running the latest master branch, but on which the front end is built every night:
http://master.ckan.org/fr/dataset/world-countries
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.
I'm trying to debug my program by logging information from an ajax call. This is something that doesn't render a view, just runs asynchronously. The log will only display arrays to a depth of 3, and the documentation doesn't seem to have any notion that someone might want more information than that.
Please, how do I increase this depth so I can have access to this information without finding weird ways to render my ajax call? Or, if doing this isn't the "Cake" way, is there a better way to output info to a log or console for debugging?
I think this is not the case of CakePHP but an issue with XDebug or PHP configuration itself. You can try to add this line to your php.ini
xdebug.var_display_max_depth = 5
It works if you debug with var_dump(). You should write how do you try to debug, bacause different methods depends on different mechanisms.
If it doesn't work you can try to make the Cake to display original PHP error messages instead of its own error handler messages. In your core.php find code like this:
Configure::write('Error', array(
'handler' => 'displayErrorWithoutCrap',
'level' => E_ALL & ~E_DEPRECATED,
'trace' => true
));
And change it into this:
Configure::write('Error', array(
//'handler' => 'ErrorHandler::handleError',
'handler' => 'displayErrorWithoutCrap',
'level' => E_ALL & ~E_DEPRECATED,
'trace' => true
));
and add this line at the end of bootstrap.php :
function displayErrorWithoutCrap() {
return false;
}
I ended up submitting a ticket to the Git project for CakePHP and it was confirmed that the debug depth for arrays is hard-coded for log files. The response indicated that it would be considered for a change in the next version.
I ended up finding the number in the Debug class and changed it to a larger number which gave me more depth. Not the best fix, but it works for now until support is added to the next version.
I'm trying to figure out what the purpose of the file /var/resource_config.json is in Magento. It appears to perhaps be a caching of a configuration, but can't see where in the source code it is being created and/or updated.
I'm in the process of setting up local/dev/staging/prod environments for an EE1.12 build and want to figure out if I can safely exclude it from my repo or whether I need to script some updates to it for deploys.
Maybe the flash image uploader in admin creates it?
Any ideas or directions to look?
This is a configuration cache file for the "alternative media store" system. This is a system where requests for media files are routed through get.php, and allows you to store media in the database instead of the file system. (That may be a gross over simplification, as I've never used the feature myself)
You can safely, (and should) exclude this file from deployments/source control, as it's a cache file and will be auto generated as needed. See the following codeblock in the root level get.php for more information.
if (!$mediaDirectory) {
$config = Mage_Core_Model_File_Storage::getScriptConfig();
$mediaDirectory = str_replace($bp . $ds, '', $config['media_directory']);
$allowedResources = array_merge($allowedResources, $config['allowed_resources']);
$relativeFilename = str_replace($mediaDirectory . '/', '', $pathInfo);
$fp = fopen($configCacheFile, 'w');
if (flock($fp, LOCK_EX | LOCK_NB)) {
ftruncate($fp, 0);
fwrite($fp, json_encode($config));
}
flock($fp, LOCK_UN);
fclose($fp);
checkResource($relativeFilename, $allowedResources);
}
Speaking in general terms, Magento's var folder serves the same purpose as the *nix var folder
Variable files—files whose content is expected to continually change during normal operation of the system—such as logs, spool files, and temporary e-mail files. Sometimes a separate partition
and should be isolated to particular systems (i.e. not a part of deployments)