Dart splits long stdout data into two ProcessResult events - process

When listening to a long string output from a shell process, I receive the data in two chunks. How can I get the entire text?
Here is the code in question:
int i = 0;
Process.start('perl', ['print_text.pl']).then((Process p) {
p.stdout.transform(UTF8.decoder).listen((data) => print("${i++} ${data}"));
p.stdin.writeln('print');
});
The result from running this code is:
0 text.....
1 text.....
I've reported this issue as a bug here. You can run the sample app attached to the report to see the issue.

Try using UTF8.decodeStream().
import 'dart:io';
import 'dart:convert' show UTF8;
main() {
Process.start('ls', ['-la'])
.then((p) => UTF8.decodeStream(p.stdout))
.then((s) => print('Output:\n$s'));
}

I solved this problem by doing the following:
In the shell script, tag the start and the end of the shell's output with a random number.
In Dart, concatenate all the chunks together and use the tags to check if you got the complete result.
This solution does not require exiting the process to obtain the process result.
This is a sample code:
String text = '';
process.stdout.transform(UTF8.decoder).listen((String chunk) {
text = text + chunk;
if (text.substring(errors.length - 1) == text.substring(0, 1)) {
text = text.replaceFirst(new RegExp(r'^(\d+)'), '').replaceFirst(new RegExp(r'(\d+)$'), '');
// use process result then clear text value for subsequent process results
text = '';
}
});

It's not clear what the actual question is but I assume this is what you are looking for:
import 'dart:io';
import 'dart:convert' show UTF8;
void main() {
int i = 0;
String text = '';
Process.start('perl', ['analyze.pl']).then((p) {
p.stdout.transform(UTF8.decoder).listen((data) =>
text += data);
p.exitCode.then((_) => print(text));
});
}

Related

How to exclude certain images from autosave in Gatan Digital Micrograph (GMS) in DM-script

I am trying to mimic the autosave function in GMS v3 so that I can use in version 1 and 2. I would like to first acknowledge that the main bulk of the script originates from Dr Bernhard Schaffer's "How to script... Digital Micrograph Scripting Handbook". I have modified it a bit, so that any new image recorded by the camera can be autosave into the file. However, I met some problems because if I decide to click on live-view image and move the image around, or using live-fft, the live view image or the FFT image will be saved as well. One of the ideas I have is to use the taggroup information such as the "Acquisition:Parameters:Parameter Set Name" because for live view or live-FFT, this would be either in search or focus mode. Another idea is to use the document ID e.g iDocID = idoc.ImageDocumentGETID() to locate the ID of the live image. However, i am clueless then how to use this information to exclude them from autosaving. Can anyone point to me how i can proceed with this script?
Below is the script
Class PeriodicAutoSave : Object
{
Number output
PeriodicAutoSave(Object self) Result("\n Object ID"+self.ScriptObjectGetID()+" created.")
~PeriodicAutoSave(Object self) Result("\n Object ID"+self.ScriptObjectGetID()+" destroyed")
Void Init2(Object self, Number op)
output=op
Void AutoSave_SaveAll(Object self)
{
String path, name, targettype, targettype1, area, mag, mode, search, result1
ImageDocument idoc
Number nr_idoc, count, index_i, index, iDocID, iDocID_search
path = "c:\\path\\"
name = "test"
targettype=="Gatan Format (*.dm4)"
targettype1 = "dm4"
If (output) Result("\n AutoSave...")
nr_idoc = CountImageDocuments()
For (count = 1; count<nr_idoc; count++)
{
idoc = GetImageDocument(count) //imagedocument
index = 1 // user decide the index to start with
index_i= nr_idoc - index
If (idoc.ImageDocumentIsDirty())
{
idoc = getfrontimagedocument()
iDocID = idoc.ImageDocumentGetID()
TagGroup tg = ImageGetTagGroup(idoc.ImageDocumentGetImage(0)) // cannot declare an 'img' for this line as it will prompt an error?
tg.TagGroupGetTagAsString("Microscope Info:Formatted Indicated Mag", mag)
Try{
{
idoc.ImageDocumentSavetoFile( "Gatan Format", path+index_i+"-"+name+"-"+mag+".dm4")
idoc.ImageDocumentSetName(index_i + "-"+name+"-"+mag+".dm4")
idoc.ImageDocumentClean()
}
If (Output) Result("\n\t saving: "+idoc.ImageDocumentGetCurrentFile())
}
Catch{
Result("\n image cannot be saved at the moment:" + GetExceptionString())
Break
}
Result("\ Continue autosave...")
}
}
}
}
Void LaunchAutoSave()
{
Object obj = Alloc(PeriodicAutoSave)
obj.Init2(2)
Number task_id = obj.AddMainThreadPeriodicTask("AutoSave_SaveALL",6)
//Sleep(10)
while(!shiftdown()) 1==2
RemoveMainThreadTask(task_id)
}
LaunchAutoSave()
thank you very much for your pointers! I have tried and it works very well with my script. as the 'TagGroupDoesTagExist' only refers to the taggroup, I modified further to include the tags I want to filter e.g "Search" or "Focus" and it seems to work well. The script that I modified to your existing ones is as below :
If (idoc.ImageDocumentIsDirty())
{
//now find out what is a filter condition and skip if it is true
skip = 0
TagGroup tg = idoc.ImageDocumentGetImage(0).ImageGetTagGroup()
tg.TagGroupGetTagAsString("Microscope Info:Formatted Indicated Mag", mag)
tg.TagGroupGetTagAsString("Acquisition:Parameters:Parameter Set Name", mode)
skip = tg.TagGroupDoesTagExist("Acquisition:Parameters:Parameter Set Name")
if(skip && (mode == "Search" || mode== "Focus")) continue
Your idea of filtering is a good one, but there is something strange with your for loop.
in
nr_idoc = CountImageDocuments()
For (count = 1; count<nr_idoc; count++)
{
idoc = GetImageDocument(count) //imagedocument
you iterate over all currently open imageDocuments (except the first one!?) and get them one by one, but then in
If (idoc.ImageDocumentIsDirty())
{
idoc = getfrontimagedocument()
you actually get the front-most (selected) document instead each time. Why are you doing this?
Why not go with:
number nr_idoc = CountImageDocuments()
for (number count = 0; count<nr_idoc; count++)
{
imagedocument idoc = GetImageDocument(count)
If (idoc.ImageDocumentIsDirty())
{
// now find out what is a filter condition and skip if it is true
number skip = 0
TagGroup tg = idoc.ImageDocumentGetImage(0).ImageGetTagGroup()
skip = tg.TagGroupDoesTagExist("Microscope Info:Formatted Indicated Mag")
if (skip) continue
// do saving
}
}

How to save List<Point> into preferences and get List<Point> from preferences in flutter?

Error while using json_serializable
json_serializable:json_serializable on .../sign_point_model.dart:
Error running JsonSerializableGenerator
Could not generate fromJson code for valList because of type Point<num>.
None of the provided TypeHelper instances support the defined type.
json_serializable doesn't know how to convert a Point into JSON. Since you know it's just a pair of nums you could easily convert the list yourself.
import 'dart:convert';
void main() async {
var points = [
Point(Offset(123, 456), PointType.tap),
Point(Offset(3.14159, 3.16227), PointType.move),
];
var simplified =
points.map((e) => [e.offset.dx, e.offset.dy, e.type.index]).toList();
String j = json.encode(simplified);
print(j);
var decoded = json.decode(j) as List;
var asPoints = decoded
.map((e) => Point(Offset(e[0], e[1]), PointType.values[e[2]]))
.toList();
print(asPoints);
}

How to write a string to clipboard (Windows OS) with a Kotlin/Native application?

I'm very new to Kotlin and making a command line .exe, on Windows using Kotlin/Native. The application should read from a text file and print on screen, line by line. When it reaches the last line of the file, it should put it in the clipboard.
aFile.txt looks something like this:
one
two
three
...
...
the last line
and the code read.kt (Kotlin/Native) I have so far is this:
import kotlinx.cinterop.*
import platform.posix.*
fun main(args: Array<String>) {
if (args.size != 1) {
println("Usage: read.exe <file.txt>")
return
}
val fileName = args[0]
val file = fopen(fileName, "r")
if (file == null) {
perror("cannot open input file $fileName")
return
}
try {
memScoped {
val bufferLength = 64 * 1024
val buffer = allocArray<ByteVar>(bufferLength)
do {
val nextLine = fgets(buffer, bufferLength, file)?.toKString()
if (nextLine == null || nextLine.isEmpty()) break
print("${nextLine}")
} while (true)
}
} finally {
fclose(file)
}
}
The code above prints each line on the screen, but how do I write the string "the last line" in the computer's clipboard? I'm looking for a native (not Java) solution if that's possible.
Thank you very much.
Update:
Obviously, this is not the solution I was looking for, but I don't understand yet what are they talking about here (https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setclipboarddata).
As a temporary fix, I was able to get what I needed using system(), echo and clip with code like this:
system("echo ${nextLine} | clip")
print("${nextLine}")
Try the following:
import java.awt.Toolkit
import java.awt.datatransfer.Clipboard
import java.awt.datatransfer.StringSelection
fun setClipboard(s: String) {
val selection = StringSelection(s)
val clipboard: Clipboard = Toolkit.getDefaultToolkit().systemClipboard
clipboard.setContents(selection, selection)
}
In Windows, you can work with the Clipboard through WinAPI, as you can see there. The reference says, that you got to use functions from the winuser.h header. This header is included in windows.h, as far as I know, so it is in your platform.windows.* package. You can approve it by checking Kotlin/Native repository files.
To clarify, what I meant, I wrote this small example of platform.windows.* usage. You can add this function to your code, and call it when you got to copy some string.
import platform.windows.*
fun toClipboard(lastLine:String?){
val len = lastLine!!.length + 1
val hMem = GlobalAlloc(GMEM_MOVEABLE, len.toULong())
memcpy(GlobalLock(hMem), lastLine.cstr, len.toULong())
GlobalUnlock(hMem)
val hwnd = HWND_TOP
OpenClipboard(hwnd)
EmptyClipboard()
SetClipboardData(CF_TEXT, hMem)
CloseClipboard()
}

Read 'hidden' input for CLI Dart app

What's the best way to receive 'hidden' input from a command-line Dart application? For example, in Bash, this is accomplished with:
read -s SOME_VAR
Set io.stdin.echoMode to false:
import 'dart:io' as io;
void main() {
io.stdin.echoMode = false;
String input = io.stdin.readLineSync();
// or
var input;
while(input != 32) {
input = io.stdin.readByteSync();
if(input != 10) print(input);
}
// restore echoMode
io.stdin.echoMode = true;
}
This is a slightly extended version, key differences are that it uses a finally block to ensure the mode is reset if an exception is thrown whilst the code is executing.
The code also uses a waitFor call (only available in dart cli apps) to turn this code into a synchronous call. Given this is a cli command there is no need for the complications that futures bring to the table.
The code also does the classic output of '*' as you type.
If you are doing much cli work the below code is from the dart package I'm working on called dcli. Have a look at the 'ask' method.
https://pub.dev/packages/dcli
String readHidden() {
var line = <int>[];
try {
stdin.echoMode = false;
stdin.lineMode = false;
int char;
do {
char = stdin.readByteSync();
if (char != 10) {
stdout.write('*');
// we must wait for flush as only one flush can be outstanding at a time.
waitFor<void>(stdout.flush());
line.add(char);
}
} while (char != 10);
} finally {
stdin.echoMode = true;
stdin.lineMode = true;
}
// output a newline as we have suppressed it.
print('');
return Encoding.getByName('utf-8').decode(line);
}

Fiddler: Programmatically add word to Query string

Please be kind, I'm new to Fiddler
My purpose:I want to use Fiddler as a Google search filter
Summary:
I'm tired of manually adding "dog" every time I use Google.I do not want the "dog" appearing in my search results.
For example:
//www.google.com/search?q=cat+-dog
//www.google.com/search?q=baseball+-dog
CODE:
dog replaced with -torrent-watch-download
// ==UserScript==
// #name Tamper with Google Results
// #namespace http://superuser.com/users/145045/krowe
// #version 0.1
// #description This just modifies google results to exclude certain things.
// #match http://*.google.com
// #match https://*.google.com
// #copyright 2014+, KRowe
// ==/UserScript==
function GM_main () {
window.onload = function () {
var targ = window.location;
if(targ && targ.href && targ.href.match('https?:\/\/www.google.com/.+#q=.+') && targ.href.search("/+-torrent/+-watch/+-download")==-1) {
targ.href = targ.href +"+-torrent+-watch+-download";
}
};
}
//-- This is a standard-ish utility function:
function addJS_Node(text, s_URL, funcToRun, runOnLoad) {
var D=document, scriptNode = D.createElement('script');
if(runOnLoad) scriptNode.addEventListener("load", runOnLoad, false);
scriptNode.type = "text/javascript";
if(text) scriptNode.textContent = text;
if(s_URL) scriptNode.src = s_URL;
if(funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
targ.appendChild(scriptNode);
}
addJS_Node (null, null, GM_main);
At first I was going to go with Tampermonkey userscripts,Because I did not know about Fiddler
==================================================================================
Now,lets focus on Fiddler
Before Request:
I want Fiddler to add text at the end of Google Query string.
Someone suggested me to use
static function OnBeforeRequest(oSession: Session) {
if (oSession.uriContains("targetString")) {
var sText = "Enter a string to append to a URL";
oSession.fullUrl = oSession.fullUrl + sText;
}
}
Before Response:
This is where my problem lies
I totally love the HTML response,Now I just want to scrape/hide the word in the search box without changing the search results.How can it be done? Any Ideas?
http://i.stack.imgur.com/4mUSt.jpg
Can you guys please take the above information and fix the problem for me
Thank you
Basing on goal definition above, I believe you can achieve better results with your own free Google custom search engine service. In particular, because you have control over GCSE fine-tuning results, returned by regular Google search.
Links:
https://www.google.com/cse/all
https://developers.google.com/custom-search/docs/structured_search