SkyDrive API Displaying a file - javascript

I'm working with Skydrive APIs, and I would like my user tobe able to open a view about a file where you can edit it (the same view as we can have about a file when you're on the skydrive web page).
There may be a WL function for it but I can't find it. An other solution would be for me to get the URL of the view page and open it in a new window with javascript.

I have implemented this solution using SkyDrive and its API. You can try this script out within Microsoft's Interactive Live SDK online tool as well. The key is to obtain SkyDrive's redirect link for the file you are looking to open. This redirect link is returned for each file in the Get api's json result.
Processing Steps:
Initializes Windows Live jscript api client
Authenticate with Windows Live (skydrive) OAuth
GetFiles: Get a list of all files within your SkyDrive account. This could be adjusted for your needs and focused to just get a list for a specific folder with your SkyDrive account
onFilesComplete: iterate through json response looking for an item with a type='file' and file name you are looking to open. In this, case a file name 'robots.txt'
display details about the found file
using the found file's "link" attribute, open url in a new window browser window. This will open the file using SkyDrive default action. For known file types such as code files, this will open them in SkyDrive's online file editor. Otherwise, the default action will be to download the found file
Example Code:
WL.init({ client_id: clientId, redirect_uri: redirectUri });
WL.login({ "scope": "wl.skydrive" }).then(
function(response) {
getFiles();
},
function(response) {
log("Could not connect, status = " + response.status);
}
);
function getFiles() {
var files_path = "/me/skydrive/files";
WL.api({ path: files_path, method: "GET" }).then(
onGetFilesComplete,
function(response) {
log("Cannot get files and folders: " +
JSON.stringify(response.error).replace(/,/g, ",\n"));
}
);
}
function onGetFilesComplete(response) {
var items = response.data;
var foundFolder = 0;
for (var i = 0; i < items.length; i++) {
if (items[i].type === "file" &&
items[i].name === "robots.txt") {
log("Found a file with the following information: " +
JSON.stringify(items[i]).replace(/,/g, ",\n"));
foundFolder = 1;
//open file in a new browser window
window.open(items[i].link);
break;
}
}
if (foundFolder == 0) {
log("Unable to find any file(s)");
}
}
function log(message) {
var child = document.createTextNode(message);
var parent = document.getElementById('JsOutputDiv') || document.body;
parent.appendChild(child);
parent.appendChild(document.createElement("br"));
}

Related

Downloading MVC FileResult doesn't work in IE or Edge browsers

I am trying to download an excel file generated from data entered through a webpage in an MVC application.
This ajax call is executed when a button is pressed, and calls two methods in my controller. One to generate the excel file and another to download the file:
$.ajax({
type: 'POST',
data: myDataObject,
url: 'MyController/GenerateExcel/',
success: function(data) {
if (data.id != "") {
$http.get('MyController/DownloadExcel?id=' + encodeURIComponent(data.id) + '&name=' + encodeURIComponent(data.name));
return true;
}
}
});
Here is my POST method that generates the excel file and saves it to TempData:
[HttpPost]
public JsonResult GenerateExcel(Object model)
{
var fileName = "myexcel.xlsx";
var fileID = Guid.NewGuid().ToString();
var generatedReport = GenerateCustomExcel(model);
using (MemoryStream memoryStream = new MemoryStream())
{
generatedReport.SaveAs(memoryStream);
generatedReport.Dispose();
memoryStream.Position = 0;
TempData[fileID] = memoryStream.ToArray();
}
return Json(new { id = fileID, name = fileName });
}
Here is my GET method that downloads the saved excel from TempData:
[HttpGet]
public FileResult DownloadExcel(string id, string name)
{
if (TempData[id] != null)
{
byte[] fileBytes = TempData[id] as byte[];
return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", name);
}
else
{
return null;
}
}
This works flawlessly in Google Chrome and Firefox browsers. However, when using either Internet Explorer or Microsoft Edge browsers, the file refuses to download.
The debug console doesn't produce any useful errors. I have tried changing the returned File type to an octet stream and using window.location.href instead of a get request to download the file, but nothing appears to work. All of the functions are called and data passed between them correctly, so routes are not the problem.
Does anyone know how I can make the returned FileResult download?
Here is a solution. It uses the same code as in my question except for the changes listed here.
Add an iframe element to your webpage:
<iframe id="iFrameFileDownload" style="display: none;"></iframe>
In the javascript, instead of a call using $http.get(), set the 'src' attribute of the iframe element to the controller function url:
$.ajax({
type: 'POST',
data: myDataObject,
url: 'MyController/GenerateExcel/',
success: function(data) {
if (data.id != "") {
$("#iFrameFileDownload").attr("src", 'MyController/DownloadExcel?id=' + encodeURIComponent(data.id) + '&name=' + encodeURIComponent(data.name));
return true;
}
}
});
Another solution that I considered is using the window.open() function instead of $http.get(). (source: Download a file with mvc) However, that solution uses popups and would require users to enable popups in their browser before downloading the file.

how do I show a detail content in Google Drive APIs?

I use Google Drive APIs.
https://developers.google.com/drive/v3/reference/files
When clicking on a link, we use webViewLink to show the page of view.
But I want to show detail contents...
Please refer to the attached image.
I want to show the part of the red frame.
【google drive img】
How to show a detail content in Google Drive APIs?
Thank you.
If you want to get the details of the file you can use the Files: get method:
Gets a file's metadata by ID.
Here is a sample code for javascript:
/**
* Print files.
*/
function listFiles() {
gapi.client.drive.files.list({
'pageSize': 10,
'fields': "nextPageToken, files(id, name)"
}).then(function(response) {
appendPre('Files:');
var files = response.result.files;
if (files && files.length > 0) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
appendPre(file.name + ' (' + file.id + ')');
}
} else {
appendPre('No files found.');
}
});
}
Do note that in v3, full resources are no longer returned by default. Use the fields query parameter to request specific fields to be returned. If left unspecified only a subset of commonly used fields are returned.
Hope this helps.

Outlook Add-In API Office365

I'm developing an Outlook Add-In for Outlook Online O365 with Javascript code.
Through the API I retrieve the object MailItem (Office.context.mailbox.item).
Is it possible to export the MailItem to file .msg and upload it to SharePoint Document Library?
You can upload Mailitem body as Document in Library. To get the mail Item body
var item = Office.context.mailbox.item;
if (item.itemType == Office.MailboxEnums.ItemType.Message) {
itemType = item.itemType;
itemID = item.itemId;
subject = item.subject;
body = getBody(item);
}
function getBody(item) {
Office.context.mailbox.item.body.getAsync("html", { asyncContext: "callback" }, function callback(result) {
body = result.value;
});
}
The Body content will be as Byte[]. So that You can create a new document with this byte[]. Also you can get the Attachments. So You can upload that too. Let me know if this helps.

How can I preview a PDF file generated from an external API in an iframe of my webpage, using Javascript?

I've been trying to find an example online where a PDF is returned by an external API (file sent in response, with the response headers for the Content-Type set to application/pdf) and then the file is processed in JS and shown in an embedded div/iframe.
I've been trying to find an example of that using PDF.js or PDFObject but all I can find use direct path to pdf files hosted on the server. I need to do this on the client-side and the file can only be retrieved using an API.
I apologize if that has been responded somewhere but I can't find anything matching my request, I hope I'm describing it well enough!
//Pseudo code of what I'd like to achieve
$.get('http.service.com/getPDF', function(data) {
var pdfString = changeDataToPDFString(data);
magicLibrary.previewPDF(pdfString, $('#container_pdf'));
}
For whomever stumbles upon this, here is my very specific solution using RequireJS and PDFJS.
changeDataToPDFString: function(file) {
var base64ToUint8Array = function(base64) {
var raw = atob(base64),
uint8Array = new Uint8Array(raw.length);
for (var i = 0; i < raw.length; i++) {
uint8Array[i] = raw.charCodeAt(i);
}
return uint8Array;
},
base64Data = file.split(',')[1],
pdfData = base64ToUint8Array(base64Data);
return pdfData;
},
renderPDF: function(file, container) {
var self = this,
pdfData = self.changeDataToPDFString(file);
require(['pdfjs-dist/build/pdf'], function(app){
var iframe;
if(container.find('iframe').length) {
iframe = container.find('iframe')[0];
iframe.contentWindow.PDFViewerApplication.open(pdfData);
}
else {
iframe = $('<iframe src="js/lib/pdfjs/web/viewer.html" style="width: 100%; height: 700px;" allowfullscreen="" webkitallowfullscreen=""></iframe>')[0];
iframe.onload = function() {
iframe.contentWindow.PDFViewerApplication.open(pdfData);
}
container.append(iframe);
}
});
}

local file system access - solutions?

2nd question I've posted. still very new to web programming so excuse my ignorance.
I have a web based javascript which accesses a users Gmail account and downloads attachments to the local downloads folder as assigned in Chrome.
These files are then manually transferred to another directory and an Excel VBA script processes the files.
I'd like to be able to skip the manual transfer step and save the files directly to to the folder that Excel is looking at. I can get the Excel script to move the files but it only works if the user has not changed the Chrome default downloads folder location so it's not foolproof.
I believe this is impossible with javascript but is it possible with other languages or do I need a completely different approach? if it is possible with other languages which one and which methods do I need to be looking at?
This is the download section of the code as it stands at the minute at the request of a user OmegaStripes below:
<html>
<head>Google Drive File Download Process:
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<script type="text/javascript">
var CLIENT_ID = 'XXXXXXXXXXX';//removed for privacy
var SCOPES = 'https://www.googleapis.com/auth/drive';
/**
* Called when the client library is loaded to start the auth flow.
*/
function handleClientLoad() {
window.setTimeout(checkAuth, 1);
}
/**
* Check if the current user has authorized the application.
*/
function checkAuth() {
gapi.auth.authorize({
'client_id': CLIENT_ID,
'scope': SCOPES,
'immediate': true
},
handleAuthResult);
}
/**
* Called when authorization server replies.
*
*/
function handleAuthResult(authResult) {
var authButton = document.getElementById('authorizeButton');
var filePicker = document.getElementById('filePicker');
authButton.style.display = 'none';
filePicker.style.display = 'none';
if (authResult && !authResult.error) {
// Access token has been successfully retrieved, requests can be sent to the API.
filePicker.style.display = 'block';
filePicker.onclick = downloadFile; // to allow for manual start of downloads
window.setTimeout(downloadFile(), 5000);
} else {
// No access token could be retrieved, show the button to start the authorization flow.
authButton.style.display = 'block';
authButton.onclick = function() {
gapi.auth.authorize({
'client_id': CLIENT_ID,
'scope': SCOPES,
'immediate': false
},
handleAuthResult);
};
}
}
/**
* Start the file download.
*
*
*/
function downloadFile() {
console.log("call drive api");
gapi.client.load('drive', 'v2', makeRequest);
}
function makeRequest() {
console.log("make request");
var request = gapi.client.drive.files.list();
request.execute(function(resp) {
var x = []; //array for revised list of files to only include those not in the trash and those which have a suffix #FHM#
for (i = 0; i < resp.items.length; i++) {
if (resp.items[i].labels.trashed != true && resp.items[i].title.substring(0, 5) == "#FHM#") {
x.push([resp.items[i].title, resp.items[i].webContentLink, resp.items[i].id]);
}
}
if (x.length == 0) {
document.getElementById("filePicker").value = "There are no files to download";
}
for (i = 0; i < x.length; i++) {
console.log(x.length);
var dlUrl = x[i][1];
fileIdentity = x[i][2];
downloadUrl(dlUrl);
trashFile(fileIdentity);
filePicker.style.display = 'none';
document.getElementById("bodyText").innerHTML = "<br>Download " + (i + 1) + " of " + x.length + " completed.";
}
});
//window.setTimeout(function() {
// self.close;
//}, 5000);
}
function downloadUrl(url) {
var iframe = document.createElement("iframe");
iframe.src = url;
iframe.style.display = "none";
document.body.appendChild(iframe);
}
function trashFile(id) {
var requestTrash = gapi.client.drive.files.trash({
'fileId': id
});
requestTrash.execute(function(resp) {});
}
</script>
<script type="text/javascript" src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
</head>
<body>
<!--Add buttons for the user to start the process -->
<input type="button" id="filePicker" style="display: none" value="If download does not start after 5 seconds, click here" />
<input type="button" id="authorizeButton" style="display: none" value="Authorize" />
<b id="bodyText"></b>
</body>
thanks
Your code could try to copy the files and if unsuccessful, ask the user to provide the correct path to the extracted file(s). You are right it cannot be done by Javascript. If you want to avoid having to ask the user for the path, you can implement a module to search for the file.
Is there a way you could know whether a file was extracted? If so, you can use this knowledge to know whether the lack of successful copying should trigger a file search or file path requesting.

Categories