Get an array of file names without extensions from a directory in Gulp? - npm

I want to get each of the file names in 2 directories (helpers/ and dialogs/) into an array without the file extension using Gulp and/or NPM. Note that the array will be pre-populated with values - I need to append the file names to this array.
In other words, my directory structure is like this:
helpers/
a.js
b.js
c.js
dialogs/
x.js
y.js
z.js
I have this:
var modules = ['main-module'];
And I need to populate my array like this based on the directories:
var modules = ['main-module', 'a', 'b', 'c', 'x', 'y', 'z'];
How do I do that?
I have tried using the fs module fs.readdirSync along with gulp-rename, but it would be nice to get this task done in a single streamed operation, if possible.
It would also be useful to get each directory into its own array for other operations - in other words, output a combined array and 2 individual arrays (total of 3 arrays) based on the directories.
var modules = ['main-module', 'a', 'b', 'c', 'x', 'y', 'z'];
var helpers = ['a', 'b', 'c'];
var dialogs = ['x', 'y', 'z'];

You can do it easily with glob, here is a code doing what you want.
var glob = require('glob');
var path = require('path');
var modules = ['main-module'];
var helpers = [];
var dialogs = [];
glob.sync("#(helpers|dialogs)/*.js")
.forEach(function(file) {
var module = path.basename(file, path.extname(file))
modules.push(module);
switch(path.dirname(file)) {
case 'helpers':
helpers.push(module);
break;
case 'dialogs':
dialogs.push(module);
break;
}
});

Related

Combine two TTS outputs in a single mp3 file not working

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.

How to pass variable from another lua file?

How to pass variable from another lua file? Im trying to pass the text variable title to another b.lua as a text.
a.lua
local options = {
title = "Easy - Addition",
backScene = "scenes.operationMenu",
}
b.lua
local score_label_2 = display.newText({parent=uiGroup, text=title, font=native.systemFontBold, fontSize=128, align="center"})
There are a couple ways to do this but the most straightforward is to treat 'a.lua' like a module and import it into 'b.lua' via require
For example in
-- a.lua
local options =
{
title = "Easy - Addition",
backScene = "scenes.operationMenu",
}
return options
and from
-- b.lua
local options = require 'a'
local score_label_2 = display.newText
{
parent = uiGroup,
text = options.title,
font = native.systemFontBold,
fontSize = 128,
align = "center"
}
You can import the file a.lua into a variable, then use it as an ordinary table.
in b.lua
local a = require("a.lua")
print(a.options.title)

Linqpad extension to plot graphs

I tried to plot some graphs in Linqpad with with "Util.RawHtml()" and "Dump()" but it is not working with this example from amcharts.com. I created a string variable including all the HTML source code but the result is not working.
string html = "";
using (System.Net.WebClient client = new System.Net.WebClient ())
{
html = client.DownloadString(#"http://pastebin.com/raw/pmMMwXhm");
}
Util.RawHtml(html).Dump();
Later versions of LinqPad 5 now support charting out of the box with Util.Chart. You can see the samples in the Samples Tab (next to My Queries) under
LINQPad Tutorial&Reference
Scratchpad Features
Charting with Chart
The following script is the Chart() - dual scale sample:
// Each y-series can have a different series type, and can be assigned to the secondary y-axis scale on the right.
var customers = new[]
{
new { Name = "John", TotalOrders = 1000, PendingOrders = 50, CanceledOrders = 20 },
new { Name = "Mary", TotalOrders = 1300, PendingOrders = 70, CanceledOrders = 25 },
new { Name = "Sara", TotalOrders = 1400, PendingOrders = 60, CanceledOrders = 17 },
};
customers.Chart (c => c.Name)
.AddYSeries (c => c.TotalOrders, Util.SeriesType.Spline, "Total")
.AddYSeries (c => c.PendingOrders, Util.SeriesType.Column, "Pending", useSecondaryYAxis:true)
.AddYSeries (c => c.CanceledOrders, Util.SeriesType.Column, "Cancelled", useSecondaryYAxis:true)
.Dump();
As I understand it, this will not work because the html contains scripts that will not be executed.
As an alternative, you can still use the old (and deprecated) google charts api, eg
var link = #"http://chart.apis.google.com/chart?chxt=y&chbh=a&chs=300x225&cht=bvg&chco=A2C180,3D7930&chd=t:10,20,30,40,50,60|30,35,40,45,55,60&chtt=Sample";
Util.Image (link).Dump();
or see
http://blog.divebomb.org/2012/11/dumping-charts-in-linqpad/
Not sure if it's the answer you're after but there may be value in looking at the DisplayWebPage method on the Util class in Linqpad. This correctly rendered your chart in the result window, (although there was a script error). Obviously, this may not solve your underlying issue.
I used version 5.10.00 to test this.

trie implementation in python , object reference

im looking at the following implementation of trie in python:
tree = {}
def add_to_tree(root, value_string):
for character in value_string:
root = root.setdefault(character, {})
def main():
tree={}
add_to_tree(tree, 'abc')
print tree
if __name__=="__main__":
main()
What is not clear to me is:
why is it returning {a:{b:{c:{}}}} instead of {a:{},b:{},c:{}} ?
I ran the code through this which gives a visualization of it. After iterating though 'a' I get tree = {'a':{}}, root = {} then after 'b' I get tree = {a:{b:{}}}, root={}. Whats not clear is what variable is holding the reference to {b:{}} which gets assigned to {a:{}} to change it to {a:{b:{}}} ?
You are reassigning root to the newly created dict for every character, change this line:
root = root.setdefault(character, {})
To becomes:
root.setdefault(character, {})
This gives the desired output (note that dict are unordered):
{'a': {}, 'c': {}, 'b': {}}

New Google reCaptcha: How to change text "I'm not a robot"

I've installed the latest Google reCaptcha tool on our yoga website. Now the users are confused about the text "I'm not a robot" that appears next to the checkbox.
Most of our users do not know what the word "robot" means in this context and they think the form is broken. They also feel less safe using our form as it is weird to see the word "robot" on a yoga website.
How do I change the text "I'm not a robot" to something else that the users understand?
The docs appear silent on this point...
Also, it seems like the contents of the reRecaptcha are completely locked down via remote JS and CSS. I've unsuccessfully tried using the following javascript to change the text for Googles recaptcha-anchor-label:
<script type="text/javascript">
$(document).ready(function () {
$("#recaptcha-anchor-label").text("Something different.");
});
</script>
It is possible to change "I'm not a robot" in Google Recaptcha into a different language by using language codes for the hl script parameter.
This is how you force Spanish, for example:
<script type="text/javascript" src="https://www.google.com/recaptcha/api.js?hl=es">
Source: Google ReCaptcha Docs
It is currently impossible using their tool. If you want to use a different method of stopping robots: Uninstall reCaptcha, and use something you have control over, maybe a simple randomized question and answer that pertains to yoga.
You cannot change that specific text because it belongs to a third party iframe, though there is a workaround that fulfils exactly what the OP is asking for.
You can append a new div on the parent div you can control, aligning and overlapping it on the label text, considering the Google Captcha has always a fixed size. Therefore, according to documentation, considering you may have the main Captcha div on your code with class="g-recaptcha", you simply do:
$('.g-recaptcha').append('<div id="new_label"></div>');
$('#new_label').text("My own text");
$('#new_label').css({"position":"absolute", "width":"160px", "top":"27px", "left":"53px", "background-color":"#f9f9f9"});
it works :)
This is not possible because the Same Origin Policy prohibits any script (that's on your site) trying to access an iframe (the captcha) that has another origin (Google server).
We should have no problem running the code below if we own both servers :)
$( ".g-recaptcha > div > div > iframe" ).contents().find( "#recaptcha-anchor-label" ).text('Custom Text');
Coming back to this old question - there is now an invisible version of the reCAPTCHA widget that allows you to design the UI on your own. You can bind the execution of the challenge to a button you've created or invoke it programmatically in the background.
I'm citing the docs page here for quick reference, you can read more about this here.
The necessary attributes are a class name 'g-recaptcha', your site key in the data-sitekey attribute, and the name of a JavaScript callback to handle completion of the captcha in the data-callback attribute.
Head:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
function onSubmit(token) {
document.getElementById("demo-form").submit();
}
</script>
Body:
<form id='demo-form' action="?" method="POST">
<button class="g-recaptcha" data-sitekey="your_site_key" data-callck='onSubmit'>Submit</button>
<br/>
</form>
I used client side captcha here is my code.its working fine for my portal.
this.canvas = document.getElementById( 'myCanvas' ) as HTMLCanvasElement;
var context = this.canvas.getContext( '2d' );
context.clearRect( 0, 0, this.canvas.width, this.canvas.height );
var alpha = [];
alpha = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'2', '3', '4', '5', '6', '7', '8', '9'];
var i;
for ( i = 0; i < 6; i++ ) {
var a = alpha[Math.floor( Math.random() * alpha.length )];
var b = alpha[Math.floor( Math.random() * alpha.length )];
var c = alpha[Math.floor( Math.random() * alpha.length )];
var d = alpha[Math.floor( Math.random() * alpha.length )];
var e = alpha[Math.floor( Math.random() * alpha.length )];
var f = alpha[Math.floor( Math.random() * alpha.length )];
var g = alpha[Math.floor( Math.random() * alpha.length )];
}
this.captchaCode = a + ' ' + b + ' ' + ' ' + c + ' ' + d + ' ' + e + ' ' + f + ' ' + g;
var ctext = this.captchaCode;
this.loginForm.controls['captcha'].setValue( this.captchaCode.replace( /\s/g, "" ) );
Here is I am drawing canvas image
/*Text to image captcha */
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage( imageObj, 0, 0 );
context.font = "24px arial";
context.fillText( ctext, 84, 32 );
};
imageObj.src = 'assets/modules/dummy-assets/common/img/captcha2.jpg';