I'd like to download a webgl graphic from plotly in R. Plotly supports this by providing an "export" which allows a (R)Selenium argument. Everything works as expected when using chrome as browser (see example 1 below)
library(plotly)
library(magrittr)
library(RSelenium)
p <- plot_ly(z = ~volcano) %>% add_surface()
### Example 1: Chrome (working as expecteded) ###
eCaps <- list(
chromeOptions =
list(prefs = list(
"profile.default_content_settings.popups" = 0L,
"download.prompt_for_download" = FALSE,
"download.default_directory" = getwd()
)
)
)
chrome <- rsDriver(port = 4590L, browser = "chrome",
geckover = NULL, iedrver = NULL, phantomver = NULL,
extraCapabilities = eCaps)
export(p, file = "test1.svg", selenium = chrome)
chrome[["server"]]$stop()
But, since I'm interested in a "silent" download in the background (without opening a browser-window) I tried the same with phantomjs. This seems to work as well but downloads the plot to my default download directory (see example 2 below). During my investigation I came across several old posts saying downloading files in phantomjs isn't possible. But since it seems possible (but uses the default directory) I thought there might be a way to set the download directory in the meantime as well.
library(plotly)
library(magrittr)
library(RSelenium)
p <- plot_ly(z = ~volcano) %>% add_surface()
### Example 2: Phantom JS (Download path not settable) ###
phjs <- rsDriver(port = 4595L, browser = "phantomjs",
chromever = NULL, geckover = NULL, iedrver = NULL)
export(p, file = "test2.svg", selenium = phjs)
phjs[["server"]]$stop()
In short: How do I change the download folder in phantomjs (when using with (R)selenium)?
Related
I am having trouble getting this code to work. I am trying to download documents from the FAO website in the URL. Please can someone help me? I use MAC OS and my chrome version is Version 106.0.5249.103 (Official Build) (x86_64)
library(rvest)
library(httr2)
library(RSelenium)
library(stringr)
url <- "https://www.fao.org/faolex/country-profiles/general-profile/en/?iso3=NAM"
base_url <- "https://www.fao.org"
ids <- read_html(url) %>%
html_elements(".doclink > a") %>%
html_attr("href") %>%
paste0(base_url, .)
grab_link <- function(page_url, s_ctl) {
# load the target url
s_ctl$navigate(page_url)
# wait for the page load to complete
Sys.sleep(4)
# getPageSource returns a list with html as the first element
page <- s_ctl$getPageSource()[[1]]
# Using rvest
read_html(page) %>%
html_elements(".item-title > a") %>%
html_attr("href") %>%
url_parse() %>%
purrr::pluck("query", "url")
}
selenium_driver <- rsDriver(
browser = "chrome",
chromever = "106.0.5249.61",
port = 4444L, #4545L,
verbose = FALSE,
check = FALSE
)
# control the client browser
ctl_browser <- selenium_driver[["client"]]
links <- purrr::map_chr(ids, grab_link, ctl_browser)
# Stop selenium server and quit browser
selenium_driver[["server"]]$stop()
When I change the file path to C drive, Chrome just save the pdf in the default download path.
options = webdriver.ChromeOptions()
prefs = {'profile.default_content_settings.popups': 1, 'download.default_directory': path_save}
options.add_experimental_option('prefs', prefs)
s = Service('D:/a/pythonProject/venv/code/chromedriver.exe')
global driver
driver = webdriver.Chrome(service = s,options = options )
html1 = "https://XXXXXX"
driver.get(html1)
Why the different path_save have different results?
Ok,I get the reason. The path contain some element that python cann't recognise, the default path will be used instead.
Update Changes, problem remain****************
cheregeckodriver_autoinstaller.install()
profile = webdriver.FirefoxProfile("/Users/Toshiba/AppData/Roaming/Mozilla/Firefox/Profiles/zq6j04pa.default")
profile.set_preference("dom.webdriver.enabled",False)
profile.set_preference("useAutomationExtension", False)
profile.update_preferences()
desired = DesiredCapabilities.FIREFOX
path = '/Users/Toshiba/Desktop/backup/PythonLearning/Learning/Selenium/geckodriver'
binary = FirefoxBinary("/Users/Toshiba/AppData/Local/Mozilla Firefox/firefox.exe")
ua = UserAgent()
user_agent = ua.random
options = webdriver.FirefoxOptions()
options.add_argument(f'user-agent={user_agent}')
# options.add_argument('-incognito')
wd = webdriver.Firefox(executable_path=path, firefox_profile=profile, desired_capabilities=desired, firefox_binary=binary)
url = "https://docs.google.com/forms/u/0/"
wd.get(url)
# login to google
username_class = "whsOnd zHQkBf".replace(" ",".")
wd.find_element_by_class_name(username_class).send_keys(username)
time.sleep(random.uniform(1, 3))
btn_next_class = "VfPpkd-RLmnJb"
wd.find_elements_by_class_name(btn_next_class)[-1].click()
Problem
Automate testing software detected
Couldn't sign you in
This browser or app may not be secure. Learn more
Try using a different browser. If you’re already using a supported browser, you can refresh your screen and try again to sign in.
I want to combine two requests to the Google cloud text-to-speech API in a single mp3 output. The reason I need to combine two requests is that the output should contain two different languages.
Below code works fine for many language pair combinations, but unfortunately not for all. If I request e.g. a sentence in English and one in German and combine them everything works. If I request one in English and one in Japanes I can't combine the two files in a single output. The output only contains the first sentence and instead of the second sentence, it outputs silence.
I tried now multiple ways to combine the two outputs but the result stays the same. The code below should show the issue.
Please run the code first with:
python synthesize_bug.py --t1 'Hallo' --code1 de-De --t2 'August' --code2 de-De
This works perfectly.
python synthesize_bug.py --t1 'Hallo' --code1 de-De --t2 'こんにちは' --code2 ja-JP
This doesn't work. The single files are ok, but the combined files contain silence instead of the Japanese part.
Also, if used with two Japanes sentences everything works.
I already filed a bug report at Google with no response yet, but maybe it's just me who is doing something wrong here with encoding assumptions. Hope someone has an idea.
#!/usr/bin/env python
import argparse
# [START tts_synthesize_text_file]
def synthesize_text_file(text1, text2, code1, code2):
"""Synthesizes speech from the input file of text."""
from apiclient.discovery import build
import base64
service = build('texttospeech', 'v1beta1')
collection = service.text()
data1 = {}
data1['input'] = {}
data1['input']['ssml'] = '<speak><break time="2s"/></speak>'
data1['voice'] = {}
data1['voice']['ssmlGender'] = 'FEMALE'
data1['voice']['languageCode'] = code1
data1['audioConfig'] = {}
data1['audioConfig']['speakingRate'] = 0.8
data1['audioConfig']['audioEncoding'] = 'MP3'
request = collection.synthesize(body=data1)
response = request.execute()
audio_pause = base64.b64decode(response['audioContent'].decode('UTF-8'))
raw_pause = response['audioContent']
ssmlLine = '<speak>' + text1 + '</speak>'
data1 = {}
data1['input'] = {}
data1['input']['ssml'] = ssmlLine
data1['voice'] = {}
data1['voice']['ssmlGender'] = 'FEMALE'
data1['voice']['languageCode'] = code1
data1['audioConfig'] = {}
data1['audioConfig']['speakingRate'] = 0.8
data1['audioConfig']['audioEncoding'] = 'MP3'
request = collection.synthesize(body=data1)
response = request.execute()
# The response's audio_content is binary.
with open('output1.mp3', 'wb') as out:
out.write(base64.b64decode(response['audioContent'].decode('UTF-8')))
print('Audio content written to file "output1.mp3"')
audio_text1 = base64.b64decode(response['audioContent'].decode('UTF-8'))
raw_text1 = response['audioContent']
ssmlLine = '<speak>' + text2 + '</speak>'
data2 = {}
data2['input'] = {}
data2['input']['ssml'] = ssmlLine
data2['voice'] = {}
data2['voice']['ssmlGender'] = 'MALE'
data2['voice']['languageCode'] = code2 #'ko-KR'
data2['audioConfig'] = {}
data2['audioConfig']['speakingRate'] = 0.8
data2['audioConfig']['audioEncoding'] = 'MP3'
request = collection.synthesize(body=data2)
response = request.execute()
# The response's audio_content is binary.
with open('output2.mp3', 'wb') as out:
out.write(base64.b64decode(response['audioContent'].decode('UTF-8')))
print('Audio content written to file "output2.mp3"')
audio_text2 = base64.b64decode(response['audioContent'].decode('UTF-8'))
raw_text2 = response['audioContent']
result = audio_text1 + audio_pause + audio_text2
with open('result.mp3', 'wb') as out:
out.write(result)
print('Audio content written to file "result.mp3"')
raw_result = raw_text1 + raw_pause + raw_text2
with open('raw_result.mp3', 'wb') as out:
out.write(base64.b64decode(raw_result.decode('UTF-8')))
print('Audio content written to file "raw_result.mp3"')
# [END tts_synthesize_text_file]ls
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--t1')
parser.add_argument('--code1')
parser.add_argument('--t2')
parser.add_argument('--code2')
args = parser.parse_args()
synthesize_text_file(args.t1, args.t2, args.code1, args.code2)
You can find the answer here:
https://issuetracker.google.com/issues/120687867
Short answer: It's not clear why it is not working, but Google suggests a workaround to first write the files as .wav, combine and then re-encode the result to mp3.
I have managed to do this in NodeJS with just one function (idk how optimal is it, but at least it works). Maybe you could take inspiration from it
I have used memory-streams dependency from npm
var streams = require('memory-streams');
function mergeAudios(audios) {
var reader = new streams.ReadableStream();
var writer = new streams.WritableStream();
audios.forEach(element => {
if (element instanceof streams.ReadableStream) {
element.pipe(writer)
}
else {
writer.write(element)
}
});
reader.append(writer.toBuffer())
return reader
}
Input parameter is a list which contain ReadableStream or responce.audioContent from synthesizeSpeech operation. If it is readablestream, it uses pipe operation, if it is audiocontent, it uses write method. At the end all content is passed into an readabblestream.
I am setting up Trac, on windows. I used a Bitnami installer. It is the newest stable version 1.2.3. I have a lot of stuff setup, including notifications, but I want to see HTML notifications. The plain text emails look wierd.
I did add the TracHtmlNotificationPlugin. Before doing that I was not getting emails with the default_format.email set to text/html.
Now I get the emails but they are still in plain text.
This is my trac.ini notification section. Let me know if I am missing something.
[notification]
admit_domains = domain.com
ambiguous_char_width = single
batch_subject_template = ${prefix} Batch modify: ${tickets_descr}
default_format.email = text/html
email_sender = HtmlNotificationSmtpEmailSender
ignore_domains =
message_id_hash = md5
mime_encoding = base64
sendmail_path =
smtp_always_bcc =
smtp_always_cc =
smtp_default_domain =
smtp_enabled = enabled
smtp_from = trac#domain.com
smtp_from_author = disabled
smtp_from_name =
smtp_password =
smtp_port = 25
smtp_replyto =
smtp_server = smtp.domain.com
smtp_subject_prefix =
smtp_user =
ticket_subject_template = ${prefix} #${ticket.id}: ${summary}
use_public_cc = disabled
use_short_addr = disabled
use_tls = disabled
I have my domain replaced in the real file.
Like I said I get emails now, just not html emails.
Edit:
I changed back the setting and now
Trac[web_ui] ERROR: Failure sending notification on change to ticket #7: KeyError: 'class'
Edit 2:
Fixed the error by putting the htmlnotification_ticket.html file (from the plugin) into the templates directory.