Using custom fonts on shinyapps.io - shiny

I would like to use a custom font in my shiny app (on plots) on shinyapps.io. I have my Roboto-Regular.ttf in the ./www/ directory. And this is the upper portion of my app.R file:
dir.create('~/.fonts')
system("chmod +x ./www/Roboto-Regular.ttf")
system("cp ./www/Roboto-Regular.ttf ~/.fonts/")
system('fc-cache -f -v ~/.fonts/')
system('fc-match Roboto')
library(ggplot2)
library(shiny)
library(shinythemes)
library(extrafont)
font_import(pattern="Roboto",prompt=FALSE)
loadfonts()
print(fonts())
Upon deploying the app, I end up with an error that looks like this:
Registering fonts with R
Scanning ttf files in /usr/share/fonts/, ~/.fonts/ ...
Extracting .afm files from .ttf files...
/home/shiny/.fonts/Roboto-Regular.ttfWarning in gzfile(dest, "w") :
cannot open compressed file '/opt/R/3.5.1/lib/R/library/extrafontdb/metrics/Roboto-Regular.afm.gz', probable reason 'Permission denied'
Error in value[[3L]](cond) : cannot open the connection
Calls: local ... tryCatch -> tryCatchList -> tryCatchOne -> <Anonymous>
Execution halted
Does anyone see what might be wrong?

After a bit of struggle I found an even simpler solution that works on shinyapps.io:
Here we go:
Place custom font in www directory: e.g. IndieFlower.ttf from here
Follow the steps from here
This leads to the following upper part of the app.R file:
dir.create('~/.fonts')
file.copy("www/IndieFlower.ttf", "~/.fonts")
system('fc-cache -f ~/.fonts')
Since Linux looks into the .fonts directory to search fonts, you don't need the extrafont package, but you can directly use those fonts like:
ggplot(mapping=aes(x=seq(1,10,.1), y=seq(1,10,.1))) +
geom_line(position="jitter", color="red", size=2) + theme_bw() +
theme(text=element_text(size = 16, family = "IndieFlower"))

This is the answer I received from RStudio regarding this. I haven't tested this out myself.
Hi,
Our developer was able to advise this is due to a possibly unfortunate design choice made when they created extrafont and the associated extrafontdb package. The extrafont font database is stored in the extrafontdb package directory -- that's essentially all that the extrafontdb package is used for.
This means that the extrafontdb directory needs to be user-writable. If the user installs the package, this will work fine, but if root installs the package (as is the case on shinyapps.io), then it won't work.
One potential workaround is to install the extrafontdb package to library that is in subdirectory of the app.
To do it: create an r-lib/ subdir, and download the extrafontdb source package there:
dir.create('r-lib')
download.file('https://cran.r-project.org/src/contrib/extrafontdb_1.0.tar.gz','r-lib/extrafontdb_1.0.tar.gz')
When deployed, the app will include this r-lib/ subdirectory and the extrafontdb source package.
Then, at the top of the app, install the extrafontdb package from the source package, into the r-lib directory.
.libPaths(c('r-lib', .libPaths()))
install.packages('r-lib/extrafontdb_1.0.tar.gz',type = 'source',repos = NULL)
They deployed an app on shinyapps.io that does the extrafontdb installation, and it works fine. The libpath is set so so that install.packages() will install from the provided source package to the r-lib/ subdirectory of the app.
Please let us know if you're able to implement the above or have any additional questions.
Thanks,

Adding an alternative answer to symbolrush's answer which I found did not work. Here was the code I used initially:
# Add fonts to shiny linux server
if (Sys.info()[['sysname']] == 'Linux') {
dir.create('~/.fonts')
fonts = c(
"www/IBMPlexSans-Regular.ttf",
"www/IBMPlexSans-Bold.ttf",
"www/IBMPlexSans-Medium.ttf"
)
file.copy(fonts, "~/.fonts")
system('fc-cache -f ~/.fonts')
}
# Load fonts and set theme
font_paths("fonts")
font_add("IBMPlexSans", regular = "IBMPlexSans-Regular.ttf")
font_add("IBMPlexSans-Bold", regular = "IBMPlexSans-Bold.ttf")
font_add("IBMPlexSans-Medium", regular = "IBMPlexSans-Medium.ttf")
showtext_auto()
The bizarre thing is that the first instance of the app on shinyapps.io worked, including the custom fonts. However when the app went to sleep and was opened a second time, I get this error in the log:
Error in value[[3L]](cond) : font file not found for 'regular' type
I was never able to debug why this was the case, but I tried a simpler solution that has worked perfectly so far. I moved my fonts to a /font folder in the app folder (I don't think using the /www folder is necessary) and added the /font folder using path_folder():
library(showtext)
# Load fonts and set theme
font_paths("fonts")
font_add("IBMPlexSans", regular = "IBMPlexSans-Regular.ttf")
font_add("IBMPlexSans-Bold", regular = "IBMPlexSans-Bold.ttf")
font_add("IBMPlexSans-Medium", regular = "IBMPlexSans-Medium.ttf")
showtext_auto()
I hope this helps anyone who is having problems with their app not running after the first instance, as I could not find the same situation anywhere on stackoverflow.

Related

Error while building WSO2 Microgateway project on Windows 10

I’ve been trying to explore WSO2 Microgateway and set up a Microgateway project. Building the project in Windows 10 with the command “micro-gw build project-name” is giving this error: “Could not find or load main class org.wso2.apimgt.gateway.cli.cmd.Main”.
I’ve downloaded the Toolkit and Runtime from https://wso2.com/api-management/api-microgateway/. I've set the Path environment variable to the /bin directory of the Toolkit and Runtime extracted folders, but still the “micro-gw build project-name” command is giving error “Could not find or load main class org.wso2.apimgt.gateway.cli.cmd.Main”. I’ve also cloned the source code from Github (https://github.com/wso2/product-microgateway/) which has the Main.java class and tried setting environment variables to its path.
I also tried setting the environment variables to the path where Toolkit batch file is present. I also followed the steps mentioned here, https://github.com/wso2/product-microgateway/#running-the-microgateway.
I'm assuming the Toolkit batch file (micro-gw) would execute the Main.java class coming up in the error.
These steps did not resolve the error. I'm new to Java based product, and I'm sure I'm missing something here.
Problem is with the init command not the build command. Init command is suppose to setup the TOOLKIT after the first use. It should extract the platform.zip file and copy all of the required resources to relevant places for you.
I hope you get the Project ___ successfully initialized message after running the init command. Just check $TOOLKIT_HOME/logs/ directory to see if there are any information on the log file.
If the log file also doesn't help, as a workaround, copy all the .jar files inside $TOOLKIT_HOME/lib/gateway/platform and $TOOLKIT_HOME/lib/gateway/cli to $TOOLKIT_HOME/lib/platform/bre/lib and try again, that should work.
Also please report this issue at https://github.com/wso2/product-microgateway/issues

Django CompileError: File to import not found or unreadable: bootstrap-sass/assets/stylesheets/bootstrap/variables

I am currently working on the cadasta - an open source organisation's - Django project.
They require you to run their platform in a virtual machine (virtualbox) using vagrant.
As I enter their repository, and run their server using ./runserver, I am all of a sudden getting a CompileError which says:
File to import not found or unreadable: bootstrap-sass/assets/stylesheets/bootstrap/variables. Parent style sheet: /vagrant/cadasta/core/static/css/_variables.scss.
on line 74 of core/static/css/_variables.scss
#import "bootstrap-sass/assets/stylesheets/bootstrap/variables";
Following this link: https://github.com/jrief/djangocms-cascade/issues/130,
I found that libsass is already installed, and so I tried installing bootstrap-sass inside the VM, but it did no good. Everything was working fine until I renamed the cadasta-platform directory (i.e their github repo that I cloned, and so the main project is included inside this folder only.) and refreshed. I even tried running the server again, but couldn't get through this error. I suppose renaming the directory shouldn't be the cause?
I have no clue on how to proceed. Please help.
EDIT: After renaming the project folder to the same name solved this error. If anyone would ever like to answer this question, please explain why renaming the project directory produces an error like this? As I believe, I think renaming should not be an issue?

Errors I face at the final step of creating an installer for my Qt app

EDITED:
Hi all,
I used the Qt Documentations for creating an installer for my Qt app using Qt Installer Framework.
I think I'm at the final step. Please have a look at the issue:
I have a package_directory folder on my Windows Desktop with these sub-folders. The config.xml file contains this. The data subfolder contains the data.7z file. I then created a licens.txt file on my Desktop. The meta subfolder contains a package.xml file with this content.
Then I created a folder named Result on my Desktop and pasted the Cal.exe file from the Release folder onto it.
And finally Ran the following command:
C:\Qt\QtIFW2.0.3\bin\binarycreator.exe -c C:\Users\CS\Desktop\package_directory\config\config.xml -p C:\Users\CS\Desktop\package_directory\packages C:\Users\CS\Desktop\Result\Cal.exe
The installer was created in the Result folder. But I got the following message from the command line:
Warning: The <Name> tag in the 'C:/Users/CS/Desktop/package_directory/packag
es/com.vendor.product/meta/package.xml' is ignored - the installer uses the path
element right before the 'meta' ('com.vendor.product').
C:\Qt\QtIFW2.0.3\bin>
Should I ignore it? If not how to solve it, too, please?
The installer file exists in the Result folder on Desktop. When I install it and select a folder on Start Menu (say Accessories or Start Up) to have the shortcut of the program, no shortcut will be created or saved there!! :(
What is the reason for that problem and how should I solve it please?

How publish a directory with ring middleware?

I am trying to use Clojure + Compojure + Ring in combination with the qooxdoo JS library. This is actually going well, but qooxdoo runs in two modes "build" (that works for me) and "source" (not so good). In the latter case, the JS generated by qooxdoo actually hardcodes references (well, using relative addresses ../../..) back to the qooxdoo installation and at run time it asks for sth like:
http://localhost:3000/opt/qooxdoo-5.0.1-sdk/framework/source/class/qx/bom/client/OperatingSystem.js
...since I have the library installed under /opt/qooxdoo-5.0.1-sdk.
Serious sanity check: if I directly open the index.html in the browser, it works fine. So it seems I just have to figure out how to serve the static files under the /opt library install.
I have tried wrap-file from the ring.middleware.file because that sounds like what I want but no matter what path I give it I get hundreds of 404s as it tries to pick up each framework file individually from the installed library.
I can work OK under "build" (qooxdoo cobbles together a single minified .js I serve with wrap-resource) but on occasion I need to run in source mode to find JS bugs.
Am I missing something simple?
The correct way to handle this is to configure Qooxdoo to tell it what URIs you would like to use - by default the source build does just use relative paths, but you can easily override this by editing the config.json.
In your config.json you will have a "jobs" section containing a "libraries" section, containing a "library" array - your application is a library, as is Qooxdoo, as is any contribs so it will look something like this:
"jobs" : {
"libraries" : {
"=library" : [ {
"manifest" : "${QOOXDOO_PATH}/framework/Manifest.json"
}, {
"manifest" : "Manifest.json"
}
},
Each "library" object can have a "uri" property, so for your example you probably want something like this:
"jobs" : {
"libraries" : {
"=library" : [ {
"manifest" : "${QOOXDOO_PATH}/framework/Manifest.json",
"uri" : "/opt/qooxdoo-5.0.1-sdk"
}, {
"manifest" : "Manifest.json"
}
},
Simple indeed: (wrap-file "/")
In development/source mode qooxdoo works off the installation directory instead of code pulled into my local tree, and does so by hardcoding relative paths that resolve to an absolute /opt/qooxdoo-etc path.
This looks to the server like a relative "opt/qooxdoo..." file request, so I had to offer root ("/") as a search directory.
(wrap-file "/") is a serious security issue since you're offering the root directory for all.
What you can potentially do is to make a dedicate directory to server your static file, and serve your content from there.
su
mkdir -p /var/clojure/static/opt
cd /var/clojure/static/opt
ln -s /opt/qooxdoo-5.0.1-sdk qooxdoo-5.0.1-sdk
chown -r YOUR-USER-ID /var/clojure/static/opt
And use the middleware: (wrap-file "/var/clojure/static") to serve your file.
There is a section in the manual that deals with the issue of serving a source version through a web server.
I guess you found the basic insight yourself, that the web server must export a root where the relative paths used in the generated loader match URL paths under that web server. (The rational behind this is that the source version uses all the JS files from all involved libraries directly from disk.)
In the worst case that might mean you need to export the file system root ("/") from your web server. As you are doing this on a local development machine this shouldn't be much of a problem. If security is a concern you might want to collect your qooxdoo environment under some innocent path like /home/kenny/devel/qooxdoo, containing the qooxdoo SDK, your app, and all libs/contribs you might be using.
If you follow the above link you will also find some help from the qooxdoo tool chain. E.g. if you run generate.py source-httpd-config[*] it will tell you which path on your local disk is the closest parent directory that will encompass all necessary libraries, i.e. needs to be exported in your web server for the source version to work.
Alternatively, as John wrote you can export each qooxdoo lib through an individual path under your web server, and then tell your main application where to find it. You might actually need to give a proper URL like http://localhost/libs/qooxdoo-5.0.1-sdk/framework, not just a file system path as John suggests. Also remember that you have to go as far as the directory where the Manifest file resides (hence the above path ending in .../framework). See this manual section for a deep dive.

testing shiny, runApp error, can not find path

I have taken the code from http://shiny.rstudio.com/articles/build.html to test building a shiny app myself.
I have created a folder called 'Shiny' and made a project in R with this folder. Inside this project I have a folder called 'shiny_app' containing the ui.R and server.R files.
When I run runApp("/shiny_app"), I get the following error
Error in shinyAppDir(x) :
No Shiny application exists at the path "/shiny_app"
I have not changed the code from the website so I'm not sure why this is happening.
Can anyone advise? Thanks.
1) Check Working directory setwd("C:/Users/DND/Desktop/your folder")
2) Remove the forward slash, I don't think it is necessary runApp("shiny_app", launch.browser = T)