Do Quarto publish on quarto-pub (book format) images from web links? - r-markdown

I want to publish with the command
quarto::quarto_publish_site()
my book-website.
The book-website is already setup on quarto-pub. If I don't add any image as a web link, the website runs and can be uploaded.
Now I add any image as a weblink, this is a exemplary code
![](https://www.website.com/wp-content/uploads/sites/2/2022/04/picture.jpg)
When I render it locally, it works. When I launch the command to publish it
compilation failed- error Unable to load picture or PDF file 'https://www.website.com/wp-content/uploads/sites/2/2022/04/picture.jpg'.
The publishing process is interrupted after this error. This is exactly the same if I launch the command from Terminal.
Is this intended to prevent to publish on quarto-pub links from other websites?
Or I can do something to avoid to download all these pics?

Including images via URL is not supposed to work for PDF output, which is not a Quarto issue but comes from how Pandoc translates !()[] to LaTeX.
Instead, you could automatically generate a local copy of the file (if not available) and then include the image in an R code chunk like this:
```{r, echo=FALSE, fig.cap='Kid', dpi=100}
if(!file.exists("kid.jpg")) {
download.file(
url = "https://edit.co.uk/uploads/2016/12/Image-1-Alternatives-to-stock-photography-Thinkstock.jpg",
destfile = "kid.jpg",
mode = "auto")
}
knitr::include_graphics("kid.jpg")
```
(of course, including the image via !()["kid.jpg"] at different location will work too once the file exists locally.)

Related

Open a c++ application installed on computer with a custom url in browser [duplicate]

How do i set up a custom protocol handler in chrome? Something like:
myprotocol://testfile
I would need this to send a request to http://example.com?query=testfile, then send the httpresponse to my extension.
The following method registers an application to a URI Scheme. So, you can use mycustproto: in your HTML code to trigger a local application. It works on a Google Chrome Version 51.0.2704.79 m (64-bit).
I mainly used this method for printing document silently without the print dialog popping up. The result is pretty good and is a seamless solution to integrate the external application with the browser.
HTML code (simple):
Click Me
HTML code (alternative):
<input id="DealerName" />
<button id="PrintBtn"></button>
$('#PrintBtn').on('click', function(event){
event.preventDefault();
window.location.href = 'mycustproto:dealer ' + $('#DealerName').val();
});
URI Scheme will look like this:
You can create the URI Scheme manually in registry, or run the "mycustproto.reg" file (see below).
HKEY_CURRENT_USER\Software\Classes
mycustproto
(Default) = "URL:MyCustProto Protocol"
URL Protocol = ""
DefaultIcon
(Default) = "myprogram.exe,1"
shell
open
command
(Default) = "C:\Program Files\MyProgram\myprogram.exe" "%1"
mycustproto.reg example:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\mycustproto]
"URL Protocol"="\"\""
#="\"URL:MyCustProto Protocol\""
[HKEY_CURRENT_USER\Software\Classes\mycustproto\DefaultIcon]
#="\"mycustproto.exe,1\""
[HKEY_CURRENT_USER\Software\Classes\mycustproto\shell]
[HKEY_CURRENT_USER\Software\Classes\mycustproto\shell\open]
[HKEY_CURRENT_USER\Software\Classes\mycustproto\shell\open\command]
#="\"C:\\Program Files\\MyProgram\\myprogram.exe\" \"%1\""
C# console application - myprogram.exe:
using System;
using System.Collections.Generic;
using System.Text;
namespace myprogram
{
class Program
{
static string ProcessInput(string s)
{
// TODO Verify and validate the input
// string as appropriate for your application.
return s;
}
static void Main(string[] args)
{
Console.WriteLine("Raw command-line: \n\t" + Environment.CommandLine);
Console.WriteLine("\n\nArguments:\n");
foreach (string s in args)
{
Console.WriteLine("\t" + ProcessInput(s));
}
Console.WriteLine("\nPress any key to continue...");
Console.ReadKey();
}
}
}
Try to run the program first to make sure the program has been placed in the correct path:
cmd> "C:\Program Files\MyProgram\myprogram.exe" "mycustproto:Hello World"
Click the link on your HTML page:
You will see a warning window popup for the first time.
To reset the external protocol handler setting in Chrome:
If you have ever accepted the custom protocol in Chrome and would like to reset the setting, do this (currently, there is no UI in Chrome to change the setting):
Edit "Local State" this file under this path:
C:\Users\Username\AppData\Local\Google\Chrome\User Data\
or Simply go to:
%USERPROFILE%\AppData\Local\Google\Chrome\User Data\
Then, search for this string: protocol_handler
You will see the custom protocol from there.
Note: Please close your Google Chrome before editing the file. Otherwise, the change you have made will be overwritten by Chrome.
Reference:
https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
Chrome 13 now supports the navigator.registerProtocolHandler API. For example,
navigator.registerProtocolHandler(
'web+custom', 'http://example.com/rph?q=%s', 'My App');
Note that your protocol name has to start with web+, with a few exceptions for common ones (like mailto, etc). For more details, see: http://updates.html5rocks.com/2011/06/Registering-a-custom-protocol-handler
This question is old now, but there's been a recent update to Chrome (at least where packaged apps are concerned)...
http://developer.chrome.com/apps/manifest/url_handlers
and
https://github.com/GoogleChrome/chrome-extensions-samples/blob/e716678b67fd30a5876a552b9665e9f847d6d84b/apps/samples/url-handler/README.md
It allows you to register a handler for a URL (as long as you own it). Sadly no myprotocol:// but at least you can do http://myprotocol.mysite.com and can create a webpage there that points people to the app in the app store.
This is how I did it. Your app would need to install a few reg keys on installation, then in any browser you can just link to foo:\anythingHere.txt and it will open your app and pass it that value.
This is not my code, just something I found on the web when searching the same question. Just change all "foo" in the text below to the protocol name you want and change the path to your exe as well.
(put this in to a text file as save as foo.reg on your desktop, then double click it to install the keys)
-----Below this line goes into the .reg file (NOT including this line)------
REGEDIT4
[HKEY_CLASSES_ROOT\foo]
#="URL:foo Protocol"
"URL Protocol"=""
[HKEY_CLASSES_ROOT\foo\shell]
[HKEY_CLASSES_ROOT\foo\shell\open]
[HKEY_CLASSES_ROOT\foo\shell\open\command]
#="\"C:\\Program Files (x86)\\Notepad++\\notepad++.exe\" \"%1\""
Not sure whether this is the right place for my answer, but as I found very few helpful threads and this was one of them, I am posting my solution here.
Problem: I wanted Linux Mint 19.2 Cinnamon to open Evolution when clicking on mailto links in Chromium. Gmail was registered as default handler in chrome://settings/handlers and I could not choose any other handler.
Solution:
Use the xdg-settings in the console
xdg-settings set default-url-scheme-handler mailto org.gnome.Evolution.desktop
Solution was found here https://alt.os.linux.ubuntu.narkive.com/U3Gy7inF/kubuntu-mailto-links-in-chrome-doesn-t-open-evolution and adapted for my case.
I've found the solution by Jun Hsieh and MuffinMan generally works when it comes to clicking links on pages in Chrome or pasting into the URL bar, but it doesn't seem to work in a specific case of passing the string on the command line.
For example, both of the following commands open a blank Chrome window which then does nothing.
"c:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "foo://C:/test.txt"
"c:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --new-window "foo://C:/test.txt"
For comparison, feeding Chrome an http or https URL with either of these commands causes the web page to be opened.
This became apparent because one of our customers reported that clicking links for our product from a PDF being displayed within Adobe Reader fails to invoke our product when Chrome is the default browser. (It works fine with MSIE and Firefox as default, but not when either Chrome or Edge are default.)
I'm guessing that instead of just telling Windows to invoke the URL and letting Windows figure things out, the Adobe product is finding the default browser, which is Chrome in this case, and then passing the URL on the command line.
I'd be interested if anyone knows of Chrome security or other settings which might be relevant here so that Chrome will fully handle a protocol handler, even if it's provided via the command line. I've been looking but so far haven't found anything.
I've been testing this against Chrome 88.0.4324.182.
open
C:\Users\<Username>\AppData\Local\Google\Chrome\User Data\Default
open Preferences then search for excluded_schemes you will find it in 'protocol_handler' delete this excluded scheme(s) to reset chrome to open url with default application

Shiny downloadButton() and downloadHandler() 500 Error

I have developed a Shiny Dashboard, I have several data frames that get imported through reactive file readers, etc.. I have also added a "Generate PDF" button, using downloadButton() in my ui.R code. My server.R code implements the downloadHandler() to handle that request.
On my Windows desktop this all works perfectly. I want this to run on a Linux server I have setup. I had to modify some paths, of course, and Shiny Server runs as root on this box. When I click the "Generate PDF" button on site running on the Linux server, I get an HTTP 500 error almost instantly. I have manually compiled the pdfReport.Rmd file on the Linux server myself and it runs just fine.
I am guessing one of two things:
Somehow the data isn't getting passed the same way on the Linux box as it does on the Windows desktop. This is probably not likely, but it is a possibility.
I have something wrong with my paths so when the temp files get written to start generating the PDF, the system doesn't have the ability or a path doesn't exist to write the file. Possibly my downloadHandler() code is malformed in some way. I think this is a higher possibility than the #1.
Here is my code for the downloadHandler():
output$pdfReport <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = reactive({paste0("/srv/shiny-server/itpod/","ITPOD-",Sys.Date(),".pdf")}),
content = function(file) {
# Copy the report file to a temporary directory before processing it, in
# case we don't have write permissions to the current working dir (which
# can happen when deployed).
tempReport <- file.path("/srv/shiny-server/itpod", "pdfReport.Rmd")
file.copy("report.Rmd", tempReport, overwrite = TRUE)
params <- list(ilp=updateILP(), ico=updateICO(), sec=updateSecurity(), ppwc=updateWorkPreviousPeriodCompleted(),
pow=updateOngoingWorkCABApproved(), pwcr=updatePlannedWorkCABRequested(), epca=updateEmergencyChangesPendingCABApproval(),
fac=updateFacilities(), drs=updateDRStatus(), ov=updateOperationalEvents(), sl=updateStaffLocations(),
w = updateWeather())
# Knit the document, passing in the `params` list, and eval it in a
# child of the global environment (this isolates the code in the document
# from the code in this app).
rmarkdown::render(tempReport, output_file = file, params = params, envir = new.env(parent = globalenv())
)
}
)
I thought maybe that the path just wasn't writeable, so I tried changing that to /tmp, but that didn't work either. Poking around, I discovered that when I over the "Generate PDF" button, I get a long URL with a "session":
http://my.url.com:3838/itpod/session/d661a858f5679aba26692bc9b4442872/download/pdfReport?w=
I'm starting to wonder if this is the issue and that I'm not writing to a path of the current session or something? This is a new area to me with Shiny. Like I said, on my desktop it works fine, but once I deploy it to the Linux server, it doesn't work correctly. Any help would be much appreciated. Thanks in advance!
Ok - after much troubleshooting, I figured out that some of the files I had in the shiny webroot that were dependencies for the main pdfReport.Rmd file weren't being seen, since the code copied the report to a temp directory.
Because I didn't want to copy all of the files from my webroot over to the temp, I decided to make the report render within the webroot itself. For me, this isn't a big deal since my shiny app is running as root anyway.
I will fix this now that I have it working, basically my fix will be to do the following:
Make the service run as a normal user
Rather than copy of the files that the report depends on, I will have to statically reference them in the report code.
I apologize for all of those who may have read this and are working on it. My fix was to the code above was the following:
output$pdfReport <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = reactive({paste0("/srv/shiny-server/itpod/","ITPOD-",Sys.Date(),".pdf")}),
content = function(file) {
# Copy the report file to a temporary directory before processing it, in
# case we don't have write permissions to the current working dir (which
# can happen when deployed).
report <- file.path(getwd(), "pdfReport.Rmd")
#tempReport <- file.path(tempdir(), "pdfReport.Rmd")
#file.copy("pdfReport.Rmd", tempReport, overwrite = TRUE)
params <- list(ilp=updateILP(), ico=updateICO(), sec=updateSecurity(), ppwc=updateWorkPreviousPeriodCompleted(),
pow=updateOngoingWorkCABApproved(), pwcr=updatePlannedWorkCABRequested(), epca=updateEmergencyChangesPendingCABApproval(),
fac=updateFacilities(), drs=updateDRStatus(), ov=updateOperationalEvents(), sl=updateStaffLocations(),
w = updateWeather())
# Knit the document, passing in the `params` list, and eval it in a
# child of the global environment (this isolates the code in the document
# from the code in this app).
rmarkdown::render(report, output_file = file, params = params, envir = new.env(parent = globalenv())
)
}
)
})
Notice, that instead of copying the file to a temp directory, I just specify the file in the current working directory.

Is there a way to select pictures in a pop-up using Python Selenium?

I am able to do all the basic web actions using Selenium, but I would like to do the following:
Click on a "select image" button, then there comes a pop-up, then I would like to enter some text in #1 and #2, and click #3.
Edition: What I have tried is on kijiji site, after clicking the select image button, I select two images (see picture), then I backward locate these image holder and find the Xpath, then I added the following codes (below), but it doesn't seem to do anything, it gave me some stacktrace message and no error.
imageLoc = "C:\AbsolutePath\IMG_20150620_184908_Edited_sm.jpg"
imageHolderXpath = '(//div[#class="image"])[1]'
imageHolderElement = WebDriverWait(driver, 5).until(lambda driver: driver.find_element_by_xpath(imageHolderXpath))
imageHolderElement.send_keys(imageLoc)
Output:
Message:
Stacktrace:
at FirefoxDriver.prototype.findElementInternal_ (file:///c:/users/kubik/appdata/local/temp/tmp_sthxl/extensions/fxdriver#googlecode.com/components/driver-component.js:10659)
at FirefoxDriver.prototype.findElement (file:///c:/users/kubik/appdata/local/temp/tmp_sthxl/extensions/fxdriver#googlecode.com/components/driver-component.js:10668)
at DelayedCommand.prototype.executeInternal_/h (file:///c:/users/kubik/appdata/local/temp/tmp_sthxl/extensions/fxdriver#googlecode.com/components/command-processor.js:12534)
at DelayedCommand.prototype.executeInternal_ (file:///c:/users/kubik/appdata/local/temp/tmp_sthxl/extensions/fxdriver#googlecode.com/components/command-processor.js:12539)
at DelayedCommand.prototype.execute/< (file:///c:/users/kubik/appdata/local/temp/tmp_sthxl/extensions/fxdriver#googlecode.com/components/command-processor.js:12481)
[Finished in 30.3s]
It is not possible via selenium, the Upload File dialog is out of selenium's reach.
By all means, you should avoid this popup being opened in the first place. A common solution to this problem is to find the corresponding file input element and send the absolute path to a file to be uploaded. Sample:
element = driver.find_element_by_css_selector("input[type=file]")
element.send_keys("/absolute/path/to/a/file")
Also see related topics:
How to upload file ( picture ) with selenium, python
selenium webdriver upload file
Well, there are certainly other options, like using AutoIt or Sikuli, but they would really be either unreliable, or complex, slow, platform or browser dependent (or all of it).
Here is a sample working code:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://www.kijiji.ca/p-post-ad.html?categoryId=36")
driver.find_element_by_link_text("British Columbia").click()
driver.find_element_by_link_text("Cariboo Area").click()
driver.find_element_by_link_text("100 Mile House").click()
driver.find_element_by_id("LocUpdate").click()
driver.find_element_by_css_selector("#ImageUpload [type=file]").send_keys("/Users/user/Downloads/test.jpg")
Which produces:

R Markdown with Shiny Server change host parameter

I am running RStudio on a server and I created a RMarkdown (.Rmd) file. It works fine if I create it as a static HTML but it does not work if I want it to be interactive (by adding runtime:shiny).
The issue is that when I add runtime:shiny and press the Run Document button the application will try to open at 127.0.0.1:xxxx (here xxxx is a random port). In order to make it work I would have to be able to change the host parameter to '0.0.0.0'. This is an option in the runApp function from the shiny package but I don't know how to add this option in RMarkdown.
Can anyone help me with this?
Thank you.
The ::run command from rmarkdown invokes shiny::runApp internally. You can set the option shiny.host before running the document:
options(shiny.host="0.0.0.0")
rmarkdown::run("myfile.Rmd")
You an also pass arbitrary paramters to runApp, so this should work too:
rmarkdown::run("myfile.Rmd", shiny_args=list(host="0.0.0.0"))
Neither of these will work with the Run Document button; that button starts a new R session in which to render the document. To change the shiny.host option in that session, you'll need to add the option to your .Rprofile.
Set the default values you want to initialize in (~/.Rprofile) under user directory
Sys.setenv(TZ = "UTC") # for Timezone
options(shiny.port = 9999)

Playing a mp3 file using an Embed tag where the source is ashx file and byte array from database

I currently store text to speech mp3 files as varbinary(max) in the database. what I want to do is play those audio files using the embed tag where the source is ashx file that will recieve the id of the database record and write the byte array.
My ashx file has the following code
byte[] byteArray = ttsMessage.MessageContents;
context.Response.Buffer = true;
context.Response.Clear();
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.ContentType = "audio/mpeg";
context.Response.OutputStream.Write(byteArray, 0, byteArray.Length);
context.Response.End();
The call from the aspx page is as follows
Panel5.Controls.Add(new LiteralControl(String.Format("<embed src='/TestArea/PreviewWav.ashx?source={0}' type='audio/mpeg' height='60px' width='144px'/>", ttsMessage.Id.ToString())));
I have gotten this to work with the following
Panel5.Controls.Add(new LiteralControl(String.Format("<audio controls='controls' autoplay='autoplay'><source src='/TestArea/PreviewWav.ashx?source={0}' type='audio/x-wav' /></audio>", ttsMessage.Id.ToString())));
Using the audio tag but cannot seem to get it to work with the embed tag.
I am using IE9/VS2010
Any ideas?
I think the wrong thing with embed tag is that...
Embed tag call a plugin like winmediaplayer ocx than handler firstly called from web page than media plugin get the ashx url than it started to call handler.
But web page's request and mediaplayer plugin's requests are diffent so if you check users Authentication or some other header information it fails.
You can easily see that on fiddler utility. On fiddler top-right side shows the request info. there is a user-agent part. Look it carefully.
How many requests happen from your handler,notice them. What are the differs. for each reqs.
If you have this issue,
You may use a ticket system or redirect a safety area for download without header or other request checks. Sadly web page requst cannot complately transfer media player and others.
hope helps