Nativescript: iOS Utils openFile - nativescript

I am working on code to open files which have been downloaded from the app, and I am using the utils.ios.openFile function. I can get the files to display on screen, however I am also getting the following warning on the console. Has anyone run into this, or have any ideas on how to resolve?
Unbalanced calls to begin/end appearance transitions for
. Cannot find
preview item for proxy: -
mobile-application.png (0)
The following is the code I am using:
var documents = fs.knownFolders.documents();
filePath = fs.path.join(documents.path, filename);
if(fs.File.exists(filePath)){
utilModule.ios.openFile(filePath)
.catch(function(error){
});
} else {
return Promise.reject(new Error("File not Found"));
}

You could set the filePath to the image, without using openFile(filePath) method. You could review the below-attached example.
let folder = fs.knownFolders.documents();
let path = fs.path.join(folder.path, "Test.png");
if(fs.File.exists(path )){
image.src=path
}

Related

NativeScript: How to copy a file from an apps folder to a user accessible folder?

I want to copy storage.db to documents or downloads folder. It's very easy to get the file path:
const filePath = application.android.context.getDatabasePath("storage.db").getAbsolutePath();
But, what isn't that easy is to copy that file to a folder users have access to. I searched this whole forum, and I found nothing useful for my case.
I'm using NativeScript 4.0.1 with vanilla JS.
If you want to share the DB file, the easiest way is to use nativescript-share-file plugin, send the file path and it will give you a nice dialog with intent picker, user may choose to Email the file Or save it to local folder etc.,
const shareFile = new ShareFile();
shareFile.open({
path: filePath,
});
I finally found the solution. I've seen so many users trying to achieve this, and I hope this will help all of you.
Add this to your AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Install nativescript-permissions:
npm i nativescript-permissions
Asking for permission:
const permissions = require('nativescript-permissions');
permissions.requestPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, "");
Require the necessary modules:
const fileSystemModule = require("tns-core-modules/file-system");
const application = require("application");
Then, create this function where you need to use it:
function copyFile() {
var myInput = new java.io.FileInputStream(appModule.android.context.getDatabasePath("storage.db").getAbsolutePath());
var myOutput = new java.io.FileOutputStream("/storage/emulated/0/databases/storage.db");
try {
var buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.class.getField("TYPE").get(null), 1024);
var length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
}
catch (err) {
console.info("Error", err);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
exports.copyFile = copyFile;
In my case, the file storage.db will be copied to /storage/emulated/0/databases. If you need to create a folder, just do the following:
try {
var javaFile = new java.io.File("/storage/emulated/0/newfolder");
if (!javaFile.exists()) {
javaFile.mkdirs();
javaFile.setReadable(true);
javaFile.setWritable(true);
}
}
catch (err) {
console.info("Error", err);
}
If the destination folder has a file with the same name as the one you want to copy, you need to remove it first. That's why you should create a specific folder to guarantee it's empty.

How can i get the picture filename from a google drive url?

I have a lot of picture links in my Google Sheet:
https://drive.google.com/file/d/1BDj24_6uz-ZQlGWLy0o1_DES6tJI3NMu/view?usp=sharing
I want to get the filename behind the link. When i open the link and save the image the image filename is: "FILENAME.jpg" or something similar
I want to get this information in Sheets.
How can i do that?
An Apps Script Solution
Thanks to #Tanaike for obtaining clarifications in the comments.
First enter your links in the format shown below in a Google Sheet.
The name of the titles is not important, but this particular script starts getting names from the 2nd row.
If you don't know how to create a script, there are tutorials here offered by Google. You should create the script from the same Sheet. That is, from the menu in the Sheet:
In the script editor, copy and paste the following code:
function getNames() {
var activeRange = SpreadsheetApp.getActiveSheet().getDataRange();
var height = activeRange.getHeight();
var links = SpreadsheetApp.getActiveSheet()
.getRange("A2:A" + height)
.getValues();
var nameValues = [];
links.forEach((row) => {
try {
var link = row[0];
var fileID = getIdFromLink(link);
var name = DriveApp.getFileById(fileID).getName();
nameValues.push([name]);
} catch (e) {
nameValues.push(["NO NAME FOUND"]);
}
});
var nameRange = SpreadsheetApp.getActiveSheet().getRange("B2:B" + height);
nameRange.setValues(nameValues);
}
function getIdFromLink(link) {
var regex = new RegExp(
/(?<=https:\/\/drive\.google\.com\/file\/d\/)(.+)(?=\/)/
);
return regex.exec(link)[0];
}
Run the getNames function. The first time it will ask you to grant some permissions, grant them. Then it should fill in the files names.
References
Apps Script Overview
Spreadsheet service in Apps Script
Drive service in Apps Script

In Swiftui, how to check the content from a URLsession?

I am using SwiftUI in Xcode 11, trying to check the content of a .txt file from the internet.
The problem is that the URLSession.shared.downloadTask takes time to finish. The code to check the content is always performed before the download is finished. Can anyone help me please? Thanks very much.
Sorry, forgot to add some codes.
let url = URL(string: "https://www.myweb.com/myfile.txt”)!
var myweb = “test”
URLSession.shared.downloadTask(with: url) { localURL, response, error in
if let localURL = localURL {
do { try myweb = String(contentsOf: localURL)}
catch { print (“test”) }
}
}.resume()
if myweb != “test” { Call some function here}
I assume that you need to create ViewModel with Published property and change it flag on true statement if downloadTask has finished. Use this property inside View

search file from document directory in ios

I have enabled itune file sharing in my Application.
I have added pdf file in my application directory.
now I want to search that file using my app. and upload it on server.
also if there multiple file and folder I want to show in application. search folder and select specific file and upload it. please suggest best way for doing that.
Appriciate for help.
do
{
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
print(dirPaths)
let Pnames = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(dirPaths) as [String]
var ProductImgs:Array<String> = Array<String>()
var ProductNames:Array<String> = Array<String>()
for name in Pnames
{
let fileName:String = name
if fileName.hasSuffix(".pdf")
{
PdfURLs.append(dirPaths.stringByAppendingString("/\(fileName)"))
PdfNames.append(fileName)
print(dirPaths.stringByAppendingString("/\(fileName)"))
}
}
}
catch
{
print(error)
}
If you are fine using third party libraries, it would be great to use Alamofire. It is an HTTP networking library written in Swift.
You can upload the file easily using this one,
let fileURL = NSBundle.mainBundle().URLForResource("Default", withExtension: "png")
Alamofire.upload(.POST, "https://httpbin.org/post", file: fileURL)
For a complete understanding of this library check out this link, https://github.com/Alamofire/Alamofire

Detecting Gmail attachment downloads

Is there a way to detect if a particular file that is being downloaded is a Gmail attachment?
I am looking for a way to write a Greasemonkey script which would help me organize the downloads, based on their download sources, say Gmail email attachments would have a different behavior from other stuff.
So far, I've found out that attachments redirect to https://mail-attachment.googleusercontent.com/attachment/u/0/ , which I guess is not sufficient.
EDIT
Since an add-on would be more powerful than a userscript, I've decided to pursue the Add On idea. However, the problem of detection remains unsolved.
This is too complicated for just one question; it has at least these major parts:
Do you want to redirect downloads when the user clicks, or automatically download select files? Clarify the question.
Your GM script must identify the appropriate download links, and on which pages, and for which views? For gMail, this is not a trivial task, and the question needs to be clearer. It's worthy of a whole question just on this issue given the variety of views and AJAX involved.
Once identified, the script probably needs to intercept clicks on those links. (Depends on your goal (clarify!) and what the Firefox extension can do.)
Greasemonkey needs to interact with an extension that either intercepts the user-initiated download, or allows for an automatic download. I've detailed the auto-download approach, below.
Once your script has identified the appropriate file URLs and/or links (Open a new question for more help with that, and include pictures of the types of pages and links you want.), it can interface with a Firefox add-on, like the one below, to automatically save those files.
Automatically saving files from Greasemonkey with the help of an additional Add-on:
WARNING: The following is a working proof of concept for education only. It has no security features, and if you use it as-is, for actual surfing, some webpage or script writer or extension writer will use it to completely pwn your computer.
If you use the Add-on builder or SDK to install or "Test" the DANGER. DANGER. DANGER. File download utility,
Then you can use a Greasemonkey script, like this, to automatically save files:
// ==UserScript==
// #name _Call our File download add-on to trigger a file download.
// #include https://mail.google.com/mail/*
// #include https://stackoverflow.com/questions/14440362/*
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// #grant GM_addStyle
// ==/UserScript==
/*- The #grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
var fileURL = "http://userscripts.org/scripts/source/29222.user.js";
var savePath = "D:\\temp\\";
var extensionLoaded = false;
window.addEventListener ("ImAlivefromExtension", function (zEvent) {
console.log ("The test extension appears to be loaded!", zEvent.detail);
extensionLoaded = true;
} );
window.addEventListener ("ReplyToDownloadRequest", function (zEvent) {
//var xxxx = JSON.parse (zEvent.detail);
console.log ("Extension replied: ", zEvent.detail);
} );
$("body").prepend ('<button id="gmFileDownloadBtn">Click to File download request.</button>');
$("#gmFileDownloadBtn").click ( function () {
if (extensionLoaded) {
detailVal = JSON.stringify (
{targFileURL: fileURL, targSavePath: savePath}
);
var zEvent = new CustomEvent (
"SuicidalDownloadRequestToAddOn",
{"detail": detailVal }
);
window.dispatchEvent (zEvent);
}
else {
alert ("The file download extension is not loaded!");
}
} );
You can test the script on this SO question page.
Note that any other extension, userscript, web page, or plugin can listen to or send spoof events, the only security, so far, is to limit which pages the extension runs on.
For reference, the extension source files are below. The rest is supplied by Firefox's Add-on SDK.
The content script:
var zEvent = new CustomEvent ("ImAlivefromExtension",
{"detail": "GM, DANGER, DANGER, DANGER, File download utility" }
);
window.dispatchEvent (zEvent)
window.addEventListener ("SuicidalDownloadRequestToAddOn", function (zEvent) {
console.log ("Extension received download request: ", zEvent.detail);
//-- Relay request to extension main.js
self.port.emit ("SuicidalDownloadRequestRelayed", zEvent.detail);
//-- Reply back to GM, or whoever is pretending to be GM.
var zEvent = new CustomEvent ("ReplyToDownloadRequest",
{"detail": "Your funeral!" }
);
window.dispatchEvent (zEvent)
} );
The background JS:
//--- For security, MAKE THESE AS RESTRICTIVE AS POSSIBLE!
const includePattern = [
'https://mail.google.com/mail/*',
'https://stackoverflow.com/questions/14440362/*'
];
let {Cc, Cu, Ci} = require ("chrome");
Cu.import ("resource://gre/modules/Services.jsm");
Cu.import ("resource://gre/modules/XPCOMUtils.jsm");
Cu.import ("resource://gre/modules/FileUtils.jsm");
let data = require ("sdk/self").data;
let pageMod = require ('sdk/page-mod');
let dlManageWindow = Cc['#mozilla.org/download-manager-ui;1'].getService (Ci.nsIDownloadManagerUI);
let fileURL = "";
let savePath = "";
let activeWindow = Services.wm.getMostRecentWindow ("navigator:browser");
let mod = pageMod.PageMod ( {
include: includePattern,
contentScriptWhen: 'end',
contentScriptFile: [ data.url ('ContentScript.js') ],
onAttach: function (worker) {
console.log ('DANGER download utility attached to: ' + worker.tab.url);
worker.port.on ('SuicidalDownloadRequestRelayed', function (message) {
var detailVal = JSON.parse (message);
fileURL = detailVal.targFileURL;
savePath = detailVal.targSavePath;
console.log ("Received request to \ndownload: ", fileURL, "\nto:", savePath);
downloadFile (fileURL, savePath);
} );
}
} );
function downloadFile (fileURL, savePath) {
dlManageWindow.show (activeWindow, 1);
try {
let newFile;
let fileURIToDownload = Services.io.newURI (fileURL, null, null);
let persistWin = Cc['#mozilla.org/embedding/browser/nsWebBrowserPersist;1']
.createInstance (Ci.nsIWebBrowserPersist);
let fileName = fileURIToDownload.path.slice (fileURIToDownload.path.lastIndexOf ('/') + 1);
let fileObj = new FileUtils.File (savePath);
fileObj.append (fileName);
if (fileObj.exists ()) {
console.error ('*** Error! File "' + fileName + '" already exists!');
}
else {
let newFile = Services.io.newFileURI (fileObj);
let newDownload = Services.downloads.addDownload (
0, fileURIToDownload, newFile, fileName, null, null, null, persistWin, false
);
persistWin.progressListener = newDownload;
persistWin.savePrivacyAwareURI (fileURIToDownload, null, null, null, "", newFile, false);
}
} catch (exception) {
console.error ("Error saving the file! ", exception);
dump (exception);
}
}
So far from what you are saying,the only thing you can do is making add-on(Firefox) and Extension(for chrome if you want).
If you have closer look at download of attachment,it happens when:
1) You click on icon of attachments
2) If you click download
For these two things you can find the click event of <a> tag containing download_url value.You can easily do that using js/jquery for creting extension.
So you can write the functionality when user tries to download attachment.
You could use Gmail contextual gadgets to modify the behavior on the Google side:
Gmail Contexual Gadgets
Contextual Gadgets don't have direct access to attachments but server side, you could use IMAP to access the attachment (based on the Gmail message ID identified by the gadget):
Gmail IMAP Extensions
Using gadgets and server-side IMAP has the advantage of being browser-agnostic.
It's not entirely clear what you want to do differently with the downloaded Gmail attachment as opposed to any given download (save it to a different location? Perform actions upon the attachment data?) But the contextual gadget and IMAP should give you some chance to modify the attachment data as needed before the browser download begins.

Resources