How do I determine the time needed to open the big file (20MB)? - win-universal-app

We are working on Universal Windows Apps in which we are opening the files (whose size is 20MB) using below code.
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.FileTypeFilter.Add(".abc");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file == null) return false;
FlowSheetFilePath = file.Path;
LaunchQuerySupportStatus status = await Launcher.QueryFileSupportAsync(file);
if (status == LaunchQuerySupportStatus.Available)
{
bool didLaunch = await Launcher.LaunchFileAsync(file);
if (didLaunch)
{
}
}
In the above code, Is there any way to determine how much time is needed to completely open the file whose size is around 20MB?

It's not possible. Note that this will depend not only on device configuration/type but ola CPU overload and so on.
If your app read/processes the file you may implement some kind of ProgressBar that will indicate how much work is already done (with implementation of IProgress<>) and how much is left, however that also won't help you with determination of time - you can think of estimating the time left basing on that what is already done, but this is only estimation and will surely change over time. But this won't also help you with Launcher.LaunchFileAsync(file).

Related

Is it possible to store Cytoscape.js layout data directly to a file format in app/web server and re-launch the same layout to minimize re-computation?

Some of the cytoscape layout is randomize where the position is not fix every time we launch it. I understand from multiple stack overflow questions where we can save the layout data (i.e. including its position x and y) into browser local storage or session storage so that we can display the same layout using the same data.
However, the problem with local storage or session storage is good for one users. But, imagine if there are thousands of users using the same app, the server will undergo mass computation for each user to store respective data to individual browsers. Can we save the data into a file format directly into app/web server so that 1000 users will see the same layout and this reduces the computation of different data set as well.
Thank you. Would like to know the possibility to convert data into a file and store in the web/app server.
Yes, you can store position data. Actually, there are 2 options in my mind.
Use cy.json(). You can store the elements as JSON like JSON.stringify(cy.json().elements) and then save this JSON string.
cy.json().elements is something like the below image
You can restore this data easily like cy.json({elements: JSON.parse(jsonStr));
As you could see cy.json().elements is a bit big thing. Position data is just a small object like {x: 0, y: 0}. Additional to position it contains many other data. So if you only need to restore the positions, you could store them manually easily with a code like below. You can use ele.id and node.position() functions.
function storePositions() {
const nodes = cy.nodes();
const nodePositions = {};
for (let i = 0; i < nodes.length; i++) {
nodePositions[nodes[i].id()] = nodes[i].position();
}
return nodePositions;
}
You can also restore node positions easily. You can use getElementById and node.position() functions.
function restorePositions(nodePositions) {
const nodes = cy.nodes();
const nodePositions = {};
for (let k in nodePositions) {
const node = cy.getElementById(k);
if (node && node.length > 0) {
node.position(nodePositions[k]);
}
}
return nodePositions;
}

How can I send selected comps in After Effects to AME via extendscript?

I've been trying to figure this out for the past day or two with minimal results. Essentially what I want to do is send my selected comps in After Effects to Adobe Media Encoder via script, and using information about them (substrings of their comp name, width, etc - all of which I already have known and figured out), and specify the appropriate AME preset based on the conditions met. The current two methods that I've found won't work for what I'm trying to do:
https://www.youtube.com/watch?v=K8_KWS3Gs80
https://blogs.adobe.com/creativecloud/new-changed-after-effects-cc-2014/?segment=dva
Both of these options more or less rely on the output module/render queue, (with the first option allowing sending it to AME without specifying preset) which, at least to my knowledge, won't allow h.264 file-types anymore (unless you can somehow trick render queue with a created set of settings prior to pushing queue to AME?).
Another option that I've found involves using BridgeTalk to bypass the output module/render queue and go directly to AME...BUT, that primarily involves specifying a file (rather than the currently selected comps), and requires ONLY having a single comp (to be rendered) at the root level of the project: https://community.adobe.com/t5/after-effects/app-project-renderqueue-queueiname-true/td-p/10551189?page=1
Now as far as code goes, here's the relevant, non-working portion of code:
function render_comps(){
var mySelectedItems = [];
for (var i = 1; i <= app.project.numItems; i++){
if (app.project.item(i).selected)
mySelectedItems[mySelectedItems.length] = app.project.item(i);
}
for (var i = 0; i < mySelectedItems.length; i++){
var mySelection = mySelectedItems[i];
//~ front = app.getFrontend();
//~ front.addItemToBatch(mySelection);
//~ enc = eHost.createEncoderForFormat("H.264");
//~ flag = enc.loadPreset("HD 1080i 25");
//app.getFrontend().addItemToBatch(mySelection);
var bt = new BridgeTalk();
bt.appName = "ame";
bt.target = "ame";
//var message = "alert('Hello')";
//bt.body = message;
bt.body="app.getFrontend().addCompToBatch(mySelection)";
bt.send();
}
}
Which encapsulates a number of different attempts and things that I've tried.
I've spent about 4-5 hours trying to scour the internet and various resources but so far have come up short. Thanks in advance for the help!

Google Apps Script creates sheets version of excel file. Issue with multiple creation of versions.

I found a solution for my original question in another post Google Apps Script creates sheets version of excel file.
Testing with the code provided in the answer I ran into another issue. Every time I run the script it creates the Spreadsheets version of the .xlsx files again even if they already exist. I have tried modifying the code withing the last If with no results. Then went back to run your code as posted in case I have missed something but it keeps creating versions of the same files.
Any idea of what could I do to fix this will be really appreciated.
The code provided int he answer is the following.
// Convert the user's stored excel files to google spreadsheets based on the specified directories.
// There are quota limits on the maximum conversions per day: consumer #gmail = 250.
function convertExcelToGoogleSheets()
{
var user = Session.getActiveUser(); // Used for ownership testing.
var origin = DriveApp.getFolderById("origin folder id");
var dest = DriveApp.getFolderById("destination folder id");
// Index the filenames of owned Google Sheets files as object keys (which are hashed).
// This avoids needing to search and do multiple string comparisons.
// It takes around 100-200 ms per iteration to advance the iterator, check if the file
// should be cached, and insert the key-value pair. Depending on the magnitude of
// the task, this may need to be done separately, and loaded from a storage device instead.
// Note that there are quota limits on queries per second - 1000 per 100 sec:
// If the sequence is too large and the loop too fast, Utilities.sleep() usage will be needed.
var gsi = dest.getFilesByType(MimeType.GOOGLE_SHEETS), gsNames = {};
while (gsi.hasNext())
{
var file = gsi.next();
if(file.getOwner().getEmail() == user.getEmail())
gsNames[file.getName()] = true;
}
// Find and convert any unconverted .xls, .xlsx files in the given directories.
var exceltypes = [MimeType.MICROSOFT_EXCEL, MimeType.MICROSOFT_EXCEL_LEGACY];
for(var mt = 0; mt < exceltypes.length; ++mt)
{
var efi = origin.getFilesByType(exceltypes[mt]);
while (efi.hasNext())
{
var file = efi.next();
// Perform conversions only for owned files that don't have owned gs equivalents.
// If an excel file does not have gs file with the same name, gsNames[ ... ] will be undefined, and !undefined -> true
// If an excel file does have a gs file with the same name, gsNames[ ... ] will be true, and !true -> false
if(file.getOwner().getEmail() == user.getEmail() && !gsNames[file.getName()])
{
Drive.Files.insert(
{title: file.getName(), parents: [{"id": dest.getId()}]},
file.getBlob(),
{convert: true}
);
// Do not convert any more spreadsheets with this same name.
gsNames[file.getName()] = true;
}
}
}
}
You want to convert Excel files in origin folder to Google Spreadsheet and put the converted Spreadsheet to dest folder.
When the filename of converted file is existing in dest folder, you don't want to convert it.
If my understanding is correct, how about this modification?
From:
if(file.getOwner().getEmail() == user.getEmail() && !gsNames[file.getName()])
To:
if(file.getOwner().getEmail() == user.getEmail() && !gsNames[file.getName().split(".")[0]])
Note:
In this modification, when the filename of converted file is found in the dest folder, the file is not converted.
When the filename has the extension like ###.xlsx and it is converted to Google Spreadsheet, it seems that the extension is automatically removed. I think that this is the reason that the duplicated files are created. So I used split(".")[0] for this situation.
Reference:
split()

Liferay, Search and Security Model

Has anyone had any experience of implementing search on Liferay that required (a moderately complex) security model? How do you deal with the fact that not all of the results you get back from search engine will have permissions to view the content? Does the built-in search in Liferay already do this? If yes, how?
Because filtering the potentially thousands of results after they have been returned can be quite expensive. And if you don't pass all the results through the filter, you don't know how many total results (hits) your search got that you can as a logged in user, 'see'.
I think it first searches from lucene and then checks whether a user has view permission on that. To check the same if you have access to source code see BaseIndexer.search. I am attaching small snippet below to show you how it does it?
PermissionChecker permissionChecker =
PermissionThreadLocal.getPermissionChecker();
int start = searchContext.getStart();
int end = searchContext.getEnd();
if (isFilterSearch() && (permissionChecker != null)) {
searchContext.setStart(0);
searchContext.setEnd(end + INDEX_FILTER_SEARCH_LIMIT);
}
Hits hits = SearchEngineUtil.search(searchContext, fullQuery);
searchContext.setStart(start);
searchContext.setEnd(end);
if (isFilterSearch() && (permissionChecker != null)) {
hits = filterSearch(hits, permissionChecker, searchContext);
}

MPMoviePlayerContentPreloadDidFinishNotification seems more reliable than MPMoviePlayerLoadStateDidChangeNotification

I am streaming small movies (1-3MB) off my website into my iPhone app. I have a slicehost webserver, I think it's a "500MB slice". Not sure off the top of my head how this translates to bandwidth, but I can figure that out later.
My experience with MPMoviePlayerLoadStateDidChangeNotification is not very good.
I get much more reliable results with the old MPMoviePlayerContentPreloadDidFinishNotification
If I get a MPMoviePlayerContentPreloadDidFinishNotification, the movie will play without stuttering, but if I use MPMoviePlayerLoadStateDidChangeNotification, the movie frequently stalls.
I'm not sure which load state to check for:
enum {
MPMovieLoadStateUnknown = 0,
MPMovieLoadStatePlayable = 1 << 0,
MPMovieLoadStatePlaythroughOK = 1 << 1,
MPMovieLoadStateStalled = 1 << 2,
};
MPMovieLoadStatePlaythroughOK seems to be what I want (based on the description in the documentation):
MPMovieLoadStatePlaythroughOK
Enough data has been buffered for playback to continue uninterrupted.
Available in iOS 3.2 and later.
but that load state NEVER gets set to this in my app.
Am I missing something? Is there a better way to do this?
Just making sure that you noticed it's a flag, not a value?
MPMoviePlayerController *mp = [aNotification object];
NSLog(#"LoadState: %i", (NSInteger)mp.loadState);
if (mp.loadState & MPMovieLoadStatePlaythroughOK)
{
// Do stuff
}

Resources