Currently I am using Canvas Fingerprinting and other device parameters to find the unique device. But in recent post i came to hear that Canvas Fingerprinting is going to be blocked by Firefox browser. So i need alternate solution for identifying devices effectively. Can anyone suggest me a effective way to achieve this?
var _speedconstant = 8.9997e-9; //if speed=(c*a)/t, then constant=(s*t)/a and time=(a*c)/s
var d = new Date();
var amount = 150000000;
var estprocessor = 1.7; //average processor speed, in GHZ
console.log("JSBenchmark by Aaron Becker, running loop "+amount+" times. Estimated time (for "+estprocessor+"ghz processor) is "+(Math.round(((_speedconstant*amount)/estprocessor)*100)/100)+"s");
for (var i = amount; i>0; i--) {}
var newd = new Date();
var accnewd = Number(String(newd.getSeconds())+"."+String(newd.getMilliseconds()));
var accd = Number(String(d.getSeconds())+"."+String(d.getMilliseconds()));
var di = accnewd-accd;
//console.log(accnewd,accd,di);
if (d.getMinutes() != newd.getMinutes()) {
di = (60*(newd.getMinutes()-d.getMinutes()))+di}
spd = ((_speedconstant*amount)/di);
console.log("Time: "+Math.round(di*1000)/1000+"s, estimated speed: "+Math.round(spd*1000)/1000+"GHZ");
This utility was free. It's probably better for validating performance than for fingerprinting.
Related
I'm using this script to build statistics on each of my coworkers and it includes 15 pivot tables that frequently need to have their filters updated for different time periods. I have a lot of coworkers on this sheet, so the script for 15 tables per person ends up taking way too long and times out.
I am including one table, but the code would have 15 iterations of this per person (times 20+ people).
How can I prevent it from timing out? Either through a work around or cleaning up my code to be more efficient.
function MassUpdateofFilters() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('Andrew!A1').activate();
var sourceData = spreadsheet.getRange('Batches!1:997');
var pivotTable = spreadsheet.getRange('A1').createPivotTable(sourceData);
pivotTable.setValuesDisplayOrientation(SpreadsheetApp.Dimension.ROWS);
var pivotValue = pivotTable.addPivotValue(3, SpreadsheetApp.PivotTableSummarizeFunction.SUM);
var pivotGroup = pivotTable.addRowGroup(5);
pivotGroup.showTotals(false)
.sortDescending()
.sortBy(pivotTable.getPivotValues()[0], []);
pivotGroup = pivotTable.addRowGroup(4);
pivotGroup.showTotals(false);
var criteria = SpreadsheetApp.newFilterCriteria()
.setVisibleValues(['Andrew'])
.build();
pivotTable.addFilter(5, criteria);
criteria = SpreadsheetApp.newFilterCriteria()
.setVisibleValues([ '1', '2', '3', '5', '6', '7'])
.build();
pivotTable.addFilter(16, criteria);
criteria = SpreadsheetApp.newFilterCriteria()
.setVisibleValues(['April'])
.build();
pivotTable.addFilter(15, criteria);
criteria = SpreadsheetApp.newFilterCriteria()
.setVisibleValues(['2019'])
.build();
pivotTable.addFilter(17, criteria);
};
Google has a guide to best practices here: https://developers.google.com/apps-script/guides/support/best-practices
I see that you are calling the SpreadsheetApp service seven times. This is slow. It would be better to call it once to get the data, then call it again to write the data, (if at all possible). Also, could you use the cache service to pull the data from the spreadsheet once, and manipulate copies of it over and over for each separate user?
https://developers.google.com/apps-script/reference/cache/cache
I would first recommend going through and the best practice.
That being said I did have to run a script across a few thousand sheets and developed this little bit of code to help with timeout issues. It runs a loop that times itself out, and you can set a trigger to run it ever 5 or 10 minutes. After a few hours, it will do the trick. Keep in mind that Google will eventually time you out if you do this too much, and you may have to wait a day or so till you can run it again.
function changeAll() {
var startd = new Date();
var diff = 0;
var start = Number(PropertiesService.getScriptProperties().getProperty("START"));
Logger.log(start);
for(var i = start; i < YOUR_MAX && diff < 280; i++){
//MAKE CHANGES HERE **************************************************************************
//END CHANGE AREA ****************************************************************************
//Change time and counter for next run
PropertiesService.getScriptProperties().setProperty("START", i);
var now = new Date();
var difdate = (now.getTime() - startd.getTime()) * 0.001;
diff = difdate;
Logger.log("DIFF: " + diff);
}
}
Is it possible to get the time that is needed to read a specific message ? I would like to use the SpeechSynthesisUtterance Web API and it only has to work in google chrome.
Would it be recommendet to use a third party libary ? Is it viable to messure the time in the background ?
For a workaround (using SpeechSynthesisUtterance) I meassure the time with the help of the onend event. This is not feasible for all situations, since it will take some time to meassure and is not very precise. You could increase the speed (up to 10) but it will get very unprecise.
var speed = 2;
var text = "Test";
var speech = new SpeechSynthesisUtterance(text);
var speakDuration;
speech.volume = 0;
speech.rate = speed;
speech.onend = function (event) {
speakDuration = event.elapsedTime / speed;
console.log(speakDuration)
};
window.speechSynthesis.speak(speech);
I have built a tool for timing indirect workers, it consists of a start and stop button which both place a time stamp into the google sheet and then calculates the difference to record a time. It works great however when I share it with some people it does not allow them to use it saying that they do no have access to run the script. If they open script editor they can manually run it however that will no fly because I will be sending this out to approximately 50 people.
Here is the code and start and stop are two different scripts. Please let me know if I am missing something and I appreciate the help. Thanks
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var start = new Date();
function StartScript() {
var last = ss.getLastRow();
ss.getRange(last+1,1).setValue(last+1)
var source = ss.getRange(last+1,1).getValue();
source = Number(source);
if (source <= 16) {
ss.getRange(last+1,2).setValue(start);
}
else {
ss.getRange(last+1,2).setValue("Stop Timing");
}
}
function stop() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var date = new Date();
var last1 = ss.getLastRow();
ss.getRange(last1, 3).setValue(date);
var lastrow = ss.getLastRow()
ss.getRange("D" + (lastrow)).setFormula("=C" + (lastrow) + "-B" + (lastrow));
}
I am using the below google apps script to search recent email from a particular mail address in my inbox. This email has no labels and this script is trying to look at all mails. How to minimize the search for an email and pull out the recent one.
function myFunction()
{
var searchterm = 'myemail#mydomain.com';
var threads = GmailApp.search(searchterm);
var messages = GmailApp.getMessagesForThreads(threads);
for (var i = 0; i < threads.length; i++)
{
for (var j = 0; j < messages[i].length; j++)
{
var mailFrom = messages[i][j].getFrom();
}
}
}
How about this sample script?
Modification points :
For var threads = GmailApp.search(searchterm);, threads[0] is the latest thread.
When From is only the particular mail address, it retrieves the mail.
When thread[0] is processed by loop using forEach(), the lower element is newer one.
The script reflected these is as follows.
Script :
var mailAddress = "myemail#mydomain.com";
var mailFrom;
var thread = GmailApp.search("from:" + mailAddress);
thread[0].getMessages().forEach(function(message) {
var f = message.getFrom();
var d = message.getDate();
if (!~f.indexOf(mailAddress)) return;
mailFrom = [f, d];
});
Result :
[name <myemail#mydomain.com>, Sat Jan 1 12:34:56 GMT 2017]
When the process time is measured, I confirmed that this script brought the improvement about 30% for your sample script. Although I don't know whether this is the best, if this is useful for you, I'm glad.
If I misunderstand your question, I'm sorry.
You may use the following search term:
var searchterm = "from: myemail#mydomain.com newer:"+parseInt(date/1000);
where date is the time value of javascript date variable. For example current date can be calculated as:
date = new Date().getTime();
This searchterm would return the email threads that are newer than the above date
What is the correct way to implement a Peak Meter like those in Logic Pro with the Web Audio API AnalyserNode?
I know AnalyserNode.getFloatFrequencyData() returns decibel values, but how do you combine those values to get the one to be displayed in the meter? Do you just take the maximum value like in the following code sample (where analyserData comes from getFloatFrequencyData():
let peak = -Infinity;
for (let i = 0; i < analyserData.length; i++) {
const x = analyserData[i];
if (x > peak) {
peak = x;
}
}
Inspecting some output from just taking the max makes it look like this is not the correct approach. Am I wrong?
Alternatively, would it be a better idea to use a ScriptProcessorNode instead? How would that approach differ?
If you take the maximum of getFloatFrequencyData()'s results in one frame, then what you are measuring is the audio power at a single frequency (whichever one has the most power). What you actually want to measure is the peak at any frequency — in other words, you want to not use the frequency data, but the unprocessed samples not separated into frequency bins.
The catch is that you'll have to compute the decibels power yourself. This is fairly simple arithmetic: you take some number of samples (one or more), square them, and average them. Note that even a “peak” meter may be doing averaging — just on a much shorter time scale.
Here's a complete example. (Warning: produces sound.)
document.getElementById('start').addEventListener('click', () => {
const context = new(window.AudioContext || window.webkitAudioContext)();
const oscillator = context.createOscillator();
oscillator.type = 'square';
oscillator.frequency.value = 440;
oscillator.start();
const gain1 = context.createGain();
const analyser = context.createAnalyser();
// Reduce output level to not hurt your ears.
const gain2 = context.createGain();
gain2.gain.value = 0.01;
oscillator.connect(gain1);
gain1.connect(analyser);
analyser.connect(gain2);
gain2.connect(context.destination);
function displayNumber(id, value) {
const meter = document.getElementById(id + '-level');
const text = document.getElementById(id + '-level-text');
text.textContent = value.toFixed(2);
meter.value = isFinite(value) ? value : meter.min;
}
// Time domain samples are always provided with the count of
// fftSize even though there is no FFT involved.
// (Note that fftSize can only have particular values, not an
// arbitrary integer.)
analyser.fftSize = 2048;
const sampleBuffer = new Float32Array(analyser.fftSize);
function loop() {
// Vary power of input to analyser. Linear in amplitude, so
// nonlinear in dB power.
gain1.gain.value = 0.5 * (1 + Math.sin(Date.now() / 4e2));
analyser.getFloatTimeDomainData(sampleBuffer);
// Compute average power over the interval.
let sumOfSquares = 0;
for (let i = 0; i < sampleBuffer.length; i++) {
sumOfSquares += sampleBuffer[i] ** 2;
}
const avgPowerDecibels = 10 * Math.log10(sumOfSquares / sampleBuffer.length);
// Compute peak instantaneous power over the interval.
let peakInstantaneousPower = 0;
for (let i = 0; i < sampleBuffer.length; i++) {
const power = sampleBuffer[i] ** 2;
peakInstantaneousPower = Math.max(power, peakInstantaneousPower);
}
const peakInstantaneousPowerDecibels = 10 * Math.log10(peakInstantaneousPower);
// Note that you should then add or subtract as appropriate to
// get the _reference level_ suitable for your application.
// Display value.
displayNumber('avg', avgPowerDecibels);
displayNumber('inst', peakInstantaneousPowerDecibels);
requestAnimationFrame(loop);
}
loop();
});
<button id="start">Start</button>
<p>
Short average
<meter id="avg-level" min="-100" max="10" value="-100"></meter>
<span id="avg-level-text">—</span> dB
</p>
<p>
Instantaneous
<meter id="inst-level" min="-100" max="10" value="-100"></meter>
<span id="inst-level-text">—</span> dB
</p>
Do you just take the maximum value
For a peak meter, yes. For a VU meter, there's all sorts of considerations in measuring the power, as well as the ballistics of an analog meter. There's also RMS power metering.
In digital land, you'll find a peak meter to be most useful for many tasks, and by far the easiest to compute.
A peak for any given set of samples is the highest absolute value in the set. First though, you need that set of samples. If you call getFloatFrequencyData(), you're not getting sample values, you're getting the spectrum. What you want instead is getFloatTimeDomainData(). This data is a low resolution representation of the samples. That is, you might have 4096 samples in your window, but your analyser might be configured with 256 buckets... so those 4096 samples will be resampled down to 256 samples. This is generally acceptable for a metering task.
From there, it's just Math.max(-Math.min(samples), Math.max(samples)) to get the max of the absolute value.
Suppose you wanted a higher resolution peak meter. For that, you need all the raw samples you can get. That's where a ScriptProcessorNode comes in handy. You get access to the actual sample data.
Basically, for this task, AnalyserNode is much faster, but slightly lower resolution. ScriptProcessorNode is much slower, but slightly higher resolution.