Upload Powerpoint to Google Drive as file - r

I want to upload Powerpoint files to Google drive. When I do this using the UI (clicking on "Upload File" and uploading a file), things work as I expect. However, when I use the Drive API I get some formatting issues. For example, the shading (text highlight) in my Powerpoint tables is transparent, but when I upload to Drive using the API the shading becomes white.
I have tried to work around this by specifying MIME type as application/vnd.google-apps.file, but when I get the response, the MIME type shows as application/vnd.google-apps.presentation
I am using Google Drive API v3, accessed through the R package googledrive.

Try to use this mimeType : application/vnd.openxmlformats-officedocument.presentationml.presentation
including :
application/vnd.google-apps.file
Here is an example done with NodeJS, try and let me know if it works well for you.
Just in case, try other mimeTypes (url is provided on Reference list, scroll down)
var fileMetadata = {
'name': '___Your File Name Here___',
'mimeType': 'application/vnd.google-apps.file'
};
var media = {
mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
body: fs.createReadStream('___Your File Name Here___.pptx')
};
function uploadFile(auth){
const drive = google.drive({version: 'v3', auth});
drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
}, (err, res) => {
if (err) return console.log('The API returned an error: ' + err);
})
}
// RUN script
fs.readFile('credentials.json', (err, content) => {
if (err) {
console.log('Error loading client secret file: ' + err);
return;
}
authorize(JSON.parse(content), uploadFile);
});
References:
Google mimeTypes (Google Reference)
List of mimeTypes (MDN)

Related

ionic 3 sqlite - How to execute requests from files

I am currently developing a mobile app with ionic. On this application there is a local sqlite database.
I am looking to be able to execute queries from files for possible updates of the database.
For example, when you first install the application, the tables are created if they do not exist. If changes are made to these tables after installing the application, the changes are not taken into account.
I would like to create files which can be executed one by one according to PRAGMA user_version.
Something like :
// Get pragma user version, if it's undefined, it's set to 1.
// If user_version < 1, we execute the sql file, then we update the user_version
// to 1.
db.executeSql(`PRAGMA user_version;`, []).then((res)=> {
if(res.rows.item(0).user_version < 1) {
db.sqlBatch(`app/sqlFiles/1.sql`, []).then((res)=>{
console.log(res);
}, (err) => {
console.log("Error : " + JSON.stringify(err));
});
db.executeSql(`PRAGMA user_version = 1;`, []).then((res)=>{
console.log(res);
}, (err) => {
console.log("Error : " + JSON.stringify(err));
});
}
}, (err) => {
console.log("Error : " + JSON.stringify(err));
});
I thought about using a file reader but the file is not found during the execution of the function.
this.fileOpener.open('assets/SQLFile/1.sql', 'text/plain')
.then((file) => {
var reader = new FileReader();
reader.onloadend = function(evt) {
console.log("read success");
console.log(evt.target);
};
db.sqlBatch(reader.readAsText(file)).then((res)=>{
console.log(res);
}, (err) => {
console.log("Error : " + JSON.stringify(err));
});
console.log('File is opened');
})
.catch(e => console.log('Error opening file', e));
Will anyone have an idea for doing this kind of thing? (I am looking for a solution that respects good programming practices).
Please note that I am a beginner with ionic and sqlite
Thank you in advance !
But you're getting an error or what? Since the post seems to be valid but the implementation seems to be a little off.
After reading the file, storing the content into a variable, you should execute that "sql query" as usually.
Nevertheless it's not a secure way of do that.
When something in your app change due to an update or upgrade, wouldn't be easier and safer to specify that into the code instead of a single file containing all the database info and scheme?
Edited:
If you want to add custom files to deployment, check this out https://ionicframework.com/docs/developer-resources/app-scripts/

Ionic2: get image form URL and save to native storage

Let's say I have a JSON object containing users' profile including firstname, lastname,..., and profileUrl from a web API. I've already saved the text data using Sqlite, and now I want to save those images in native storage and put the file path into the sqlite database replacing the profileUrl.
You can use cordova-plugin-file-transfer for that. There is even an Ionic Native wrapper available: https://ionicframework.com/docs/native/transfer/
Example:
download() {
const url = 'http://www.example.com/file.pdf';
fileTransfer.download(url, this.file.dataDirectory + 'file.pdf').then((entry) => {
console.log('download complete: ' + entry.toURL());
}, (error) => {
// handle error
});
}

Download a file from a URL to a user accessible location

I am building an app using Nativescript/Angular 2
I want to be able to download a file from a URL and save it to the device in a location the average user would have no problems finding it. I believe downloads would be the best place for this on both iOS and Android. Please correct me if I am wrong.
The file can be any file type, not just an image. So mainly spreadsheet, word document, pdf, png, jpg, etc.
I have searched online and through the documentation. The documentation describes a method called getFile which gets a file and saves it to your device.
I have implemented this in my code as follows:
download (id) {
console.log('Download Started');
getFile("https://raw.githubusercontent.com/NativeScript/NativeScript/master/apps/tests/logo.png").then(function (r) {
console.log(r.path);
}, function (e) {
//// Argument (e) is Error!
});
}
The problem with this is that it saves it to a non-user accessible location such as:
/data/user/0/com.myapp.example/files/logo.png
Update:
I have also tried specifying the path directly with:
fs.knownFolders.documents();
However, this method gets the documents folder for the current application that is NOT accessible by the user or external applications
After some unsuccessful attempts, I finally found how to save file to user "Downloads" folder (something like sdcard/Download). You can use android.os.Environment method to get this folder.
Add this in your component:
import { getFile } from 'tns-core-modules/http';
import * as fileSystem from "tns-core-modules/file-system";
import { isAndroid } from "tns-core-modules/platform";
import { alert } from "tns-core-modules/ui/dialogs";
declare var android;
<...>
public download (url, fileName) {
if (isAndroid) {
const permissions = require("nativescript-permissions");
permissions.requestPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, "I need these permissions because I'm cool")
.then(() => {
let downloadedFilePath = fileSystem.path.join(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(), fileName);
getFile(url, downloadedFilePath).then(resultFile => {
alert({
title: 'Saved!',
okButtonText: 'OK',
message: `File saved here:\n${resultFile.path}`
});
}, error => {
alert({
title: 'Error',
okButtonText: 'OK',
message: `${error}`
});
});
});
}
}
What else you should know:
1) There is no any kind of download indicator, standard system download bar also not appears, and I don't know how to solve this.
2) For iOS you may try to use
const filePath = fileSystem.path.join(fileSystem.knownFolders.ios.downloads().path, fileName);
getFile(url, filePath).then((resultFile) => {}, (error) => {});
I think, it's the shame that NS docs don't talk straight, that you can't save files in user accessible location only with NS functions. I figured it out only when I read comments in file /node_modules/tns-core-modules/file-system/file-system.d.ts
Hope this helps you.
To get it working on iPhone, you can do the following (TypeScript):
import { knownFolders, path } from "tns-core-modules/file-system";
let destination = path.join(knownFolders.documents(), "file_name.txt");
// logic to save your file here ...
// the important thing is that you have to save your file in knownFolders.documents()
Then in Info.plist, you have to add the following permissions:
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>UIFileSharingEnabled</key>
<true/>
Now if you go to your iPhone's Files app > On My iPhone > Your App's Name, you should see the file there.
Basically, the Documents folder is a private folder inside your application's directory that only you can see. However, when you enable the two permissions above, it allows file sharing so that your user can access the folder and its contents.
The same documentation says that you can specify the file location like this:
download (id) {
console.log('Download Started');
var folder = fs.knownFolders.documents();
var file = fs.path.join(folder.path, "logo.png");
var url = "https://raw.githubusercontent.com/NativeScript/NativeScript/master/apps/tests/logo.png"
getFile(url, file).then(function (r) {
console.log(r.path);
}, function (e) {
//// Argument (e) is Error!
});
}
disclaimer: never tried it myself, just read the docs ...
You can specify a filesystem path directly, like this:
var folder = fs.Folder.fromPath('/sdcard/Download');
Note that /sdcard/Download will only work on Android; you can replace it with whatever (publicly accessible) folder you want to save your data to.
There doesn't yet seem to be a cross-platform way to choose a folder path, so you'll have to work out something manually. See this GitHub thread for more.
I realize that this is an older thread, but perhaps this can help someone:
If you use currentApp(), instead of documents(), you can access the folder you need. For example:
var directories = fs.knownFolders.currentApp();
var folder = directories.getFolder('./nameofaccessiblefolder');
I know this thread is 3 years ago but in case you have the same issue, I hope this solution will save time for you.
I solved the same issue by adding android:requestLegacyExternalStorage="true" inside the AndroidManifest.xml file
follow the thread here

JSZip and cfs:collection in Meteor app

So, Im using udondan:jszip, cfs:collection,
cfs:standard-packages and
cfs:filesystem packages in my meteor app. The problem is that I cant store my zip files in the FS.COllection. Here is some of the code :
//Defining the collection
Reports = new FS.Collection('reports',{
stores: [new FS.Store.FileSystem('reports', {path: "~/public"})]
});
//Trying to add a file to the collection
var zip = new JSZip();
Reports.insert(zip);
After running the code Im getting this error:
Error: DataMan constructor received data that it doesn't support
Is there any way to make those packages work with each other ?
The JSZip object is not a file by itself. You can generate a file from it with the generateAsync function. The file type you'll want to create depends on if you want this to run on the client or server and how you want to use this file. The file types supported by both libraries are: (as per documentation, I haven't tested all these myself)
Blob object (client only): { type: 'blob' }
Uint8Array: { type: 'uint8array' }
ArrayBuffer: { type: 'arraybuffer' }
Buffer object (server only): { type: 'nodebuffer' }
So for example this should work:
zip.generateAsync({ type: 'arraybuffer' })
.then(function (content) {
Reports.insert(content);
});

How do I upload a image to my server with meteor?

I have a logo somewhere on my application page.
The application admin should be able to adjust the logo within the webapplication by simply upload a new one. What would be the best practice to achieve this?
How would I handle the upload on the server. It should replace the old logo with the new one. The name and location should stay the same.
Here is my approach:
I use the package UploadFS:
jalik:ufs
jalik:ufs-local
autopublish //it is still on, so the code below works without publish/subscribe I know that I will have to change that.
My code:
Upload
*.js Server & Client
//Almost Standard initialization - works so far
Logo = new Mongo.Collection('logo');
LogoStore = new UploadFS.store.Local({
collection: Logo,
name: 'logo',
path: '/uploads/logo',
mode: '0744', // directory permissions
writeMode: '0744', // file permissions
filter: new UploadFS.Filter({
minSize: 1,
maxSize: 1024 * 1000, // 1MB,
contentTypes: ['image/*'],
extensions: ['png']
})
});
*.html
//Standard initialization - works so far
<template name="upload">
<button type="button" name="upload">Select files</button>
</template>
*.js Client
//Almost Standard initialization - works so far
Template.upload.events({
'click button[name=upload]': function (ev) {
var self = this;
UploadFS.selectFiles(function (file) {
// Prepare the file to insert in database, note that we don't provide an URL,
// it will be set automatically by the uploader when file transfer is complete.
var logo = {
name: 'logo.png', //all uploaded images will have the same name
size: file.size,
type: file.type,
};
// Create a new Uploader for this file
var uploader = new UploadFS.Uploader({
// This is where the uploader will save the file
store: LogoStore,
// Optimize speed transfer by increasing/decreasing chunk size automatically
adaptive: true,
// Define the upload capacity (if upload speed is 1MB/s, then it will try to maintain upload at 80%, so 800KB/s)
// (used only if adaptive = true)
capacity: 0.8, // 80%
// The size of each chunk sent to the server
chunkSize: 8 * 1024, // 8k
// The max chunk size (used only if adaptive = true)
maxChunkSize: 128 * 1024, // 128k
// This tells how many tries to do if an error occurs during upload
maxTries: 5,
// The File/Blob object containing the data
data: file,
// The document to save in the collection
file: logo,
// The error callback
onError: function (err) {
console.error(err);
},
onAbort: function (file) {
console.log(file.name + ' upload has been aborted');
},
onComplete: function (file) {
console.log(file.name + ' has been uploaded');
},
onCreate: function (file) {
console.log(file.name + ' has been created with ID ' + file._id);
},
onProgress: function (file, progress) {
console.log(file.name + ' ' + (progress*100) + '% uploaded');
},
onStart: function (file) {
console.log(file.name + ' started');
},
onStop: function (file) {
console.log(file.name + ' stopped');
}
});
// Starts the upload
uploader.start();
// Stops the upload
uploader.stop();
// Abort the upload
uploader.abort();
});
}
});
Show uploaded Logo
*.html
<template name="whatever">
<img src="{{logoUrl}}" alt="Logo" >
</template>
*.js client only
Template.whatever.helpers({
logoUrl: function(){
return Logo.findOne().url;
}
})
So If I understand it right, what the code does is uploading the img to somewhere on the server. Also it stores some info about that image in a Mongo.Collection - Logo.
But I do not exactly know where those images are stored, in which folder. They are not stored in my default Project - Folder.
The url of an example img is: http://localhost:3000/ufs/logo/B4Fv5etkr7xQbvs5v/logo.png. That random string in the middle is the _id of that img. So I can not use a hardcoded url for that images to access them, because as soon as a new img is uploaded, that url will change completely.
Q1: So the first question is: Can I upload to the myProject/public/img folder directly? So that the url of the img would be something like:
http://localhost:3000/img/logo.png
Then I would need just to replace the old logo on the upload.
For now I have to deal with the generic url. So as next, I select the url of the now present image on the server from the Logo - collection and pass that url to my template to the place where the logo has to be placed. The problem with that is, that the url is loaded after everything else was loaded, so for several seconds I get an tag without an url in it. So that place shows the alt text only until the url is loaded. That is very ugly...
Q2: The question is, how could I get the url, before the tag is loaded. So that the logo appears with/before everything else, as if the url would be hardcoded in advance.
Q3: Is it possible to replace the old logo with the new uploaded one, on the upload? How?
Q4: If I delete the entry for the img from the Logo - Collection, is the image actually deleted from the server? Or do I have to delete it manually/in another way?
You can send a base64 encode image on server then using fs your can overwrite the file.
Like:
Client
readAsDataURL has base64 encoded data in the format of
data:image/jpeg;base64,/9j/4AAQSkZJRgABA...
So you need to get rid of the mime type and encoding information at the front.
contents = contents.split(',')[1];
Now you can send this base64 encoded data to server.
Server
Since you're receiving base64 encoded data, you can convert it buffer and write to file:
fs.writeFile(filepath, Buffer(argument,'base64'), err => {
//
})
In case the file name same as another file then it will completely overwrite your file.
Answer for question 1:
default image will be stored hide folder in your project .meteor/local/build/programs/server/ufs/uploads/
You can change destination by "path" as below code
new UploadFS.store.Local({
collection: Csvs.collection,
name: 'csv',
path: '../../../../../uploads/csv', //here change destination folder stored file
filter: new UploadFS.Filter({
maxSize: 1024 * 3000, // 3MB,
contentTypes: ['text/csv']
})
});
When doing the "Client" step in Pankaj Javav's answer, you may want to use the base64-image-upload package I whipped up, as I was having the same problem. It simplifies the process of uploading any base64 string to a server, and you do not need to get rid of the MIME type this way.

Resources