I'm using webwiew-ext and I want to launch events from webview-ext form to taking data and save it using nativescript script sqlite
This is the example I have done to test the events but it doesn't work :
my js file :
function callFromNativeScript() {
window.nsWebViewBridgee.emit("got", { huba: "hop" });
console.log("got a message from nativescript");
}
Loaded in the html file like that in the header:
<script src="../js/index.js" type="text/javascript"></script>
my nativescript main.js file :
const Sqlite=require("nativescript-sqlite");
exports.pageLoaded =function(args ){
page = args.object;
var db_promise = new Sqlite("test.db", function(err,db) {
if (err) {
console.error("We failed to open database", err);
} else {
console.log("Is a Sqlite Database:", Sqlite.isSqlite(db) ? "Yes" : "No");
db.get('select * from test where id=1 ', [1], function(err, row) {
if(row){
console.log("Row of data was: ", row);
}else if(err)
{
console.log("les guignols");
} // Prints [["Field1", "Field2",...]]
});
// This should ALWAYS be true, db object is open in the "Callback" if no errors occurred
console.log("Are we open yet (Inside Callback)? ", db.isOpen() ? "Yes" : "No"); // Yes
}
});
window.nsWebViewBridge.on("got",function(message){
console.log("Salut"+message);
console.log("hello");
});
console.log("bonjour");
}
My xml file file :
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded" actionBarHidden="true" xmlns:nota="#nota/nativescript-webview-ext">
<nota:WebViewExt src="~/html/index.html"> </nota:WebViewExt> </Page>
I am using another webview module
which has built in functions to execute code within the webview.
I can use the Google Drive API to do this:
drive.files.get(
{
fields: "parents",
fileId: "######"
},
(err, results) => {
...
}
);
However, I can only get the ID of the folder, one level up from the file.
How can I get the whole hierarchy of parent folders that contain the Google Drive file, the folder that contains the folder, the folder that contains that folder, and so on?
How about this method? I think that there are several solutions for your situation. So please think of this as one of them. Unfortunately, all folders including subfolders in a folder cannot be retrieved using files.get of Drive API. And when q is used for files.list of Drive API, 'folder ID' in parents retrieves only folders in folder ID. Folders under the subfolder in folder ID cannot be retrieved. So in this method, I used the following flow.
Retrieve all folders in Google Drive.
In this sample script, if the number of folders in your Google Drive is less than 1000, all folders are retrieved by one API call. If the number of folders is from 1000 to 2000, 2 API calls are used.
Create the folder tree using the list of all folders.
Sample script :
function run(auth) {
var drive = google.drive({version: 'v3', auth: auth});
getFolderTree(drive, "", []);
}
function getFolderTree(drive, nextPageToken, folderList) {
drive.files.list({
pageToken: nextPageToken ? nextPageToken : "",
pageSize: 1000,
q: "mimeType='application/vnd.google-apps.folder'",
fields: "files(id,parents),nextPageToken",
}, (err, {data}) => {
if (err) return console.log('The API returned an error: ' + err);
const token = data.nextPageToken;
Array.prototype.push.apply(folderList, data.files);
if (token) {
getFolderTree(drive, token, folderList);
} else {
// This script retrieves all folders including subfolders under this folder ID.
const folderId = "### Top folder ID ###";
const folderTree = function c(folder, folderSt, res) {
let ar = folderList.filter(e => e.parents[0] == folder);
folderSt += folder + "#_aabbccddee_#";
let arrayFolderSt = folderSt.split("#_aabbccddee_#");
arrayFolderSt.pop();
res.push(arrayFolderSt);
ar.length == 0 && (folderSt = "");
ar.forEach(e => c(e.id, folderSt, res));
return res;
}(folderId, "", []);
// Output the folder tree.
console.log(folderTree);
}
});
}
Output :
When the folder structure is as follows. (You can set the top folder ID in this sample script.)
This script creates an array as follows.
[
['topFolderId'],
['topFolderId','folderId_2a'],
['topFolderId','folderId_2b'],
['topFolderId','folderId_2b','folderId_3a'],
['topFolderId','folderId_2b','folderId_3b']
]
Note :
I confirmed that this sample script worked at the googleapis with v30.0.0.
In generally, the folder tree is created by retrieving folders from the top folder in order. But when Drive API is used for this situation, if there are a lot of folders in the top folder, a lot of APIs are required to be called. So in this method, I have tried to create the folder tree with a small number of API calls using a list of all folders.
This is a simple sample script, so please modify this to your environment.
References :
files.get
files.list
Search for Files
Edit :
This updated script retrieves the whole folder tree including the inputted folderId. For above script, run() and getFolderTree() were modified.
function run(auth) {
var drive = google.drive({version: 'v3', auth: auth});
drive.files.get({fileId: "root", fields: "id"}, (err, {data}) => {
getFolderTree(drive, "", [], data.id);
});
}
function getFolderTree(drive, nextPageToken, folderList, rootId) {
drive.files.list({
pageToken: nextPageToken ? nextPageToken : "",
pageSize: 1000,
q: "mimeType='application/vnd.google-apps.folder'",
fields: "files(id,name,parents),nextPageToken",
}, (err, {data}) => {
if (err) return console.log('The API returned an error: ' + err);
const token = data.nextPageToken;
Array.prototype.push.apply(folderList, data.files);
if (token) {
getFolderTree(drive, token, folderList, rootId);
} else {
// Please input folder ID.
const inputId = "### Folder ID ###";
const folderId = rootId;
const folderTree = function c(folder, folderSt, res) {
let ar = folderList.filter(e => e.parents[0] == folder);
folderSt += folder + "#_aabbccddee_#";
let arrayFolderSt = folderSt.split("#_aabbccddee_#");
arrayFolderSt.pop();
res.push(arrayFolderSt);
ar.length == 0 && (folderSt = "");
ar.forEach(e => c(e.id, folderSt, res));
return res;
}(folderId, "", []);
let result = folderTree.filter(e => ~e.indexOf(inputId));
if (result.length > 2) result.shift();
// Output result.
console.log(result);
}
});
}
For the above, when folderId_2b is inputted to inputId, the following result can be retrieved.
[
["topFolderId","folderId_2b","folderId_3a"],
["topFolderId","folderId_2b","folderId_3b"]
]
I have a view that i need to export to pdf but to show this view i need to send a parameter to specific route and i don't know how to call route instead html file.
My route:
viewBicsDetails(req, res)
{
var ref = req.params.stamp;
var info = request.query("query");
var compounds = request.query("query");
return Promise.all([info, compounds]).then(function(results)
{
console.log(results[0]);
res.render('management-bic-details', {info : results[0], compounds: results[1]});
});}
How can I export this render to pdf? i installed the html-pdf npm library.
https://www.npmjs.com/package/html-pdf
var fs = require('fs');
var pdf = require('html-pdf');
var html = fs.readFileSync('./test/businesscard.html', 'utf8');
var options = { format: 'Letter' };
pdf.create(html, options).toFile('./businesscard.pdf', function(err, res) {
if (err) return console.log(err);
console.log(res); // { filename: '/app/businesscard.pdf' }
});
In readFileSync i should put the route.. but how?
Thank you
Solution 1, with HTML and PDF templates
Make pdf template and fill it with javascript code. HTML and PDF templates will be different!
There are a lot packages with this functionality. For example, pdffiller
Solution 2, with single HTML template
Under the hood html-pdf implements this approach.
Fill HTML template.
Render image via phantomjs or any headless browser.
Compile image to a single pdf file.
I am using Meteor and React JS. I also added Meteor Files.
https://github.com/VeliovGroup/Meteor-Files
By using this code,
this.Images = new FilesCollection({collectionName: 'Images'});
export default class Logo extends TrackerReact(React.Component){
constructor(){
...
Meteor.subscribe('files.images.all');
}
uploadLogo(e){
if (e.currentTarget.files && e.currentTarget.files[0]) {
// We upload only one file, in case
// there was multiple files selected
var file = e.currentTarget.files[0];
if (file) {
var uploadInstance = Images.insert({
file: file,
streams: 'dynamic',
chunkSize: 'dynamic',
transport: 'http'
}, false);
uploadInstance.on('start', function() {
//template.currentUpload.set(this);
});
uploadInstance.on('end', function(error, fileObj) {
if (error) {
alert('Error during upload: ' + error.reason);
} else {
console.log("done");
alert('File "' + fileObj.name + '" successfully uploaded');
}
});
uploadInstance.start();
}
}else{
console.log("error");
}
}
render(){
...
<input type="file" id="fileinput" onChange={this.uploadLogo.bind(this)} />
}
I am able to upload the file but I don't see any files in my directory.
Here is my publish.js,
this.Images = new Meteor.Files({
debug: true,
collectionName: 'Images',
allowClientCode: false, // Disallow remove files from Client
onBeforeUpload: function (file) {
// Allow upload files under 10MB, and only in png/jpg/jpeg formats
if (file.size <= 1024*1024*10 && /png|jpg|jpeg/i.test(file.extension)) {
return true;
} else {
return 'Please upload image, with size equal or less than 10MB';
}
}
});
Meteor.publish('files.images.all', function () {
return Images.find().cursor;
});
How can I display the image? How can I limit the user to upload files that are only images?
For me, their API Docs is not rich. I can't understand what the things they are talking in their docs.
By default uploaded files are stored in the file system. Read the FAQ:
Where are files stored by default?: by default if config.storagePath
isn't passed into Constructor it's equals to assets/app/uploads and
relative to running script:
On development stage:
yourDevAppDir/.meteor/local/build/programs/server
Note: All files
will be removed as soon as your application rebuilds or you run meteor
reset. To keep your storage persistent during development use an
absolute path outside of your project folder, e.g. /data directory.
On production: yourProdAppDir/programs/server
So you need to set a location with config.storagePath
I have a pdf file located here:
/server/.files/users/test.pdf
When I display a link on a page, I'd like for the user to be able to click the link, and for the pdf to be rendered on the screen.
I've read through this SO post in particular, and others, but cannot seem to get things to work: SO Link
I tried using an IR route server side, but every time I try even something simple I get the following error:
Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions. at Object.Meteor.userId
(packages/accounts-base/accounts_server.js:19:1) at Object.Meteor.user
(packages/accounts-base/accounts_server.js:24:1) at [object
Object].Router.onBeforeAction.except
(app/both/3-router/routes.js:10:15) at
packages/iron:router/lib/router.js:277:1 at [object
Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
at [object Object].hookWithOptions
(packages/iron:router/lib/router.js:276:1) at boundNext
(packages/iron:middleware-stack/lib/middleware_stack.js:251:1) at
runWithEnvironment (packages/meteor/dynamics_nodejs.js:108:1) at
packages/meteor/dynamics_nodejs.js:121:1 at [object Object].dispatch
(packages/iron:middleware-stack/lib/middleware_stack.js:275:1)
Line: #10 in my router.js file is the first if statement here:
Router.onBeforeAction(function () {
if (!Meteor.user() || Meteor.loggingIn()) {
this.redirect('welcome.view'); } else {
Meteor.call("userFileDirectory", function (error, result) {
if (error)
throw error;
else
console.log(result);
});
this.next();
} }, { except: ['welcome.view'] });
I tried this:
Router.map(function() {
this.route('serverFile', {
where: 'server',
path: /^\/uploads_url_prefix\/(.*)$/,
action: function() {
var filePath = process.env.PWD + '/.files/users/' + this.params[1];
var data = fs.readFileSync(filePath);
this.response.writeHead(200, {
'Content-Type': 'image'
});
this.response.write(data);
this.response.end();
}
}); });
But I'm not sure what to put in the path.
With process.env.PWD you are in the directory of your meteor project.
so you should be able to access your file like this:
var file = process.env.PWD + "/server/.files/users/test.pdf"
To use the fs package of node you also need to include it and you need to be on the server:
Router.route('/pdf', function() {
var filePath = process.env.PWD + "/server/.files/users/test.pdf";
var fs = Meteor.npmRequire('fs');
var data = fs.readFileSync(filePath);
this.response.write(data);
this.response.end();
}, {
where: 'server'
});
Make sure to this package to your project (https://atmospherejs.com/meteorhacks/npm)
meteor add meteorhacks:npm
I tested it and it is working like a charm!