Change filename of existing file on SharePoint Document library using REST API - rest

I have a question on how to change an existing file on SharePoint document library using REST API. I have a couple of files in the location http://site url/<RootFolder>/<SubFolder>/File.docx. I have a UI where it lists all the files from this subfloder location. When the user clicks on edit i am enabling the file name as textbox where the user can change the name of the file.
After doing some research i found that Constructing an endpoint that looks like this: https://<site url>/_api/web/lists/getbytitle('Documents')/items(<item id>) we can edit the file metadata properties. But i could not able to figure out the best way to update the filename of existing document that resides on SharePoint Doc library.
Could someone please help me with the REST API query to fetch the file and the approach to update the filename?

You could consider at least two options:
Option 1. Rename file name
You could update the name of the existing list item as demonstrated below
Example
function rename(webUrl,listTitle,itemId,fileName){
var endpointUrl = webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items(" + itemId + ")";
return executeJson(endpointUrl)
.then(function(data){
var itemPayload = {};
itemPayload['__metadata'] = {'type': data.d['__metadata']['type']};
itemPayload['Title'] = fileName;
itemPayload['FileLeafRef'] = fileName;
var itemUrl = data.d['__metadata']['uri'];
var headers = {};
headers["X-HTTP-Method"] = "MERGE";
headers["If-Match"] = "*";
return executeJson(itemUrl,"POST",headers,itemPayload);
});
}
var webUrl = _spPageContextInfo.webAbsoluteUrl; // web url
var listTitle = "Documents"; //list title
var itemId = 1; //list item id
var fileName = "SP User Guide.docx"; //new file name
rename(webUrl,listTitle,itemId,fileName)
.done(function(item){
console.log('Renamed');
})
.fail(function(error){
console.log(error);
});
Option 2. Move file via MoveTo REST endpoint
Example
function moveTo(webUrl,sourceFileUrl,targetFileUrl){
var endpointUrl = webUrl + "/_api/web/getfilebyserverrelativeurl('" + sourceFileUrl + "')/moveto(newurl='" + targetFileUrl + "',flags=1)";
return executeJson(endpointUrl,"POST");
}
var webUrl = _spPageContextInfo.webAbsoluteUrl; // web url
var sourceFileUrl = "/Documents/SP2010.docx";
var targetFileUrl = "/Documents/SP2013.docx";
moveTo(webUrl,sourceFileUrl,targetFileUrl)
.done(function(item){
console.log('Done');
})
.fail(function(error){
console.log(error);
});
executeJson function:
function executeJson(url,method,headers,payload)
{
headers = headers || {};
method = method || 'GET';
headers["Accept"] = "application/json;odata=verbose";
if(method == "POST") {
headers["X-RequestDigest"] = $("#__REQUESTDIGEST").val();
}
var ajaxOptions =
{
url: url,
type: method,
contentType: "application/json;odata=verbose",
headers: headers
};
if(method == "POST") {
ajaxOptions.data = JSON.stringify(payload);
}
return $.ajax(ajaxOptions);
}

You need to use the MoveTo Method to do this as described here in MSDN https://msdn.microsoft.com/en-us/library/office/dn450841.aspx#bk_FileMoveTo.
executor.executeAsync({
url: "<app web url>/_api/SP.AppContextSite(#target)/web
/getfilebyserverrelativeurl('/Shared Documents/filename.docx')
/moveto(newurl='/Other Folder/filename.docx',flags=1)
?#target='<host web url>'",
method: "POST",
success: successHandler,
error: errorHandler
});

Related

How to find out permissions for each tree element(folder or file) for another user using sharepoint api?

I want to get answer for question:
Does userA can read the folder/tree ?
Application uses another user to communicate with sharpoint via sharepoint API.
I've googled the following request:
http://aissp2013/sites/Team/_api/web/lists/getbytitle('L2')/EffectiveBasePermissions
But it doesn't resolve my problem because it responds with permissions for current user!
Is there way to get permissions for another user for concrete element(folder or file or library)
Is there way to get permissions for another user for all elements and sub-elements ?
To get permissions per user SP.ListItem.getUserEffectivePermissions method is intended:
for SP.Folder
Url /_api/web/getFolderByServerRelativeUrl('<folder-rel-url>')/ListItemAllFields/getusereffectivepermissions(#u)?#u='<account>'
Method: Get
for SP.File
Url /_api/web/getFileByServerRelativeUrl('<file-rel-url>')/ListItemAllFields/getusereffectivepermissions(#u)?#u='<account>'
Method: Get
Note: account parameter needs to be provided in claims format
Regarding the question:
Does userA can read the folder/tree ?
the following example demonstrates how to retrieve permissions for a folder
const accountName = "i:0#.f|membership|<name>#<tenant>.onmicrosoft.com";
let endpointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getFolderByServerRelativeUrl('/Shared Documents/Achive')/ListItemAllFields/getusereffectivepermissions(#u)?#u='" + encodeURIComponent(accountName) + "'";
const content = await executeJson(endpointUrl);
let roles = parseBasePermissions(content.d.GetUserEffectivePermissions);
if(roles.viewListItems)
console.log(`${accountName} has been granted permissions.`);
where
function parseBasePermissions(value)
{
let permissions = new SP.BasePermissions();
permissions.initPropertiesFromJson(value);
let result = {};
for(var levelName in SP.PermissionKind.prototype) {
if (SP.PermissionKind.hasOwnProperty(levelName)) {
var permLevel = SP.PermissionKind.parse(levelName);
if(permissions.has(permLevel))
result[levelName] = true;
else
result[levelName] = false;
}
}
return result;
}
is used to parse permission mask into roles
and
async function executeJson(url,options) {
options = options || {};
options.method = options.method || 'GET';
options.headers = options.headers || {};
options.headers["Accept"] = "application/json;odata=verbose";
options.headers["Content-Type"] = "application/json;odata=verbose";
if(options.method == "POST") {
options.headers["X-RequestDigest"] = document.getElementById("__REQUESTDIGEST").value;
}
if (options.body) {
options.body = JSON.stringify(options.body);
}
const rawResponse = await fetch(url,options);
const content = await rawResponse.json();
return content;
}
to perform REST request

Moodle get course information + all lessons through Api

I am trying to collect all information related to Moodle course (course + lessons) Using Moodle Api I got the course information, but gets only some basic information, I want course details and its lessons (created under course)
Eg : var domainname = 'http://<server URL>/moodle';
var token = 'df337369637c692303d903f8cacf1eb0';
var functionname = 'core_course_get_courses';
var serverurl = domainname + '/webservice/rest/server.php' ;
var data = {
wstoken: token,
wsfunction: functionname,
moodlewsrestformat: 'json'
} var response = $.ajax(
{ type: 'GET',
data: data,
url: serverurl
}
);
And the output looks like
{"id":2,"shortname":"IV Support Queries","categoryid":1,"categorysortorder":10001,"fullname":"IV Support Queries","displayname":"IV Support Queries","idnumber":"","summary":"<p>IV Support Queries Desc<br \/><\/p>","summaryformat":1,"format":"topics","showgrades":1,"newsitems":5,"startdate":1479168000,"numsections":5,"maxbytes":0,"showreports":0,"visible":1,"hiddensections":1,"groupmode":0,"groupmodeforce":0,"defaultgroupingid":0,"timecreated":1479127227,"timemodified":1479198758,"enablecompletion":0,"completionnotify":0,"lang":"","forcetheme":"","courseformatoptions":[{"name":"numsections","value":5},{"name":"hiddensections","value":1},{"name":"coursedisplay","value":1}]}
I want the lesson details created under course .How can i get the information through Api . Thanks
Using function
"core_course_get_contents"
getting all the informations related with course.
var domainname = 'http://<server URL>/moodle';
var token = 'df337369637c692303d903f8cacf1eb0';
var functionname = 'core_course_get_contents';
var serverurl = domainname + '/webservice/rest/server.php' ;
var data = {
wstoken: token,
wsfunction: functionname,
moodlewsrestformat: 'json' ,
courseid: 2 //Retrieve results based on course Id 2
}
var response = $.ajax(
{ type: 'GET',
data: data,
url: serverurl
}
);
Thanks

Facebook api multiple request

I am creating a facebook application generator. And I need to check if the user has currently added the application on this facebook page or not.
In order to do that, i first request facebook api to give a list of his pages. Then i loop through all the pages. And request for apps on each of these pages.
Lastly i compare the appId with the one user just created and displays the display the warning accordingly.
The problem is , when i loop through each of the pageId and request FbApi for subpages, the request response is delayed and the for each loop completes its cycle before the results are fetched from facebook.
Here is my code, which is quite complex... Any ideas to fix the issue is highly appreciated.
FB.login(function (response) {
FB.api('/me/accounts', function (apiresponse) {
var totalPages = apiresponse.data.length;
var pageIndex = 0;
$.each(apiresponse.data, function (pageNumber, pageData) {
var pageAccessToken = pageData.access_token;
var tabPageName = pageData.name;
var tabPageId = pageData.id;
FB.api("/" + tabPageId + "/tabs", function (response) {
var foundApp = false
$.each(response.data, function (index, value) {
var exsistingAppId = (value.id).split("app_").pop();
if (exsistingAppId == fbAppId) {
foundApp = true;
}
});
if (foundApp === true) {
var data = {
PageId: tabPageId,
Url: window.location.href.split("/").pop()
}
$.ajax({
type: "POST",
url: '/facebook/Match',
contentType: "application/json",
data: JSON.stringify(data),
success: function (data) {
if (data == "True") {
$("#addToFacebookModal ul").append("<li><span class='pageTab'><a class='pageTabName' target='_blank' href='https://facebook.com/profile.php?id=" +tabPageId + "'>" +tabPageName + "</a></span><a class='deleteAppFromPageTab' data-id='" +tabPageId + "' data-accessToken='" +pageAccessToken + "'>[x]</a></li>");
alreadyAdded.push(true);
} else {
alreadyAdded.push(false);
}
pageIndex++;
if (pageIndex == totalPages) {
console.log("Total Pages = " + totalPages + ", Looped through = " + alreadyAdded.length);
if (alreadyAdded.indexOf(true) >= 0) {
$("#addToFacebookModal").modal();
} else {
addToFacebook();
}
}
}
});
}
else {
pageIndex++;
}
});
});
});
}, { scope: 'manage_pages' });
Here is pseudocode of what i am doing
var myVariable
-Fb.Api Callback function returns response array
-Loop through the response array
-Get new Response array based on the previous response in that array
-Loop through each item of the new response array and compare it with myVariable.
The problem is that responses are delayed while the loop finishes up before the responses arrive. As i result i cant compare the nested Item with myVariable.
If by "facebook page" you mean a business page / organization page (not a profile), you can get the same information more easily by checking the endpoint '/{{page_id}}/tabs/{{app_id}}.
Replace page_id with the ID of the page you want to check and app_id similarly with your app ID. I don't have working code at the moment, but something like this:
FB.api(
'/' + checkPageID + '/tabs/{{app_id}}',
function (response) {
// Do console.log(response) to figure out how to see if installed or not
}
)
YOu can use fields expansion:
https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#fieldexpansion
FB.api('/me/accounts', {fields: 'name, address{city}'},function (response)
{
//do something here.
}

Convert Google Doc to Docx using Google Script

Is it possible to convert a Google document to a Word docx file programmatically using Google Script ?
This should work
function myFunction() {
var token = ScriptApp.getOAuthToken();
//Make sure to replace the correct file Id
// Fetch the docx blob
var blb = UrlFetchApp.fetch('https://docs.google.com/feeds/download/documents/export/Export?id=<ID_of_Google_Document>&exportFormat=docx',
{
headers : {
Authorization : 'Bearer '+token
}
}).getBlob();
//Create file in Google Drive
var file = DriveApp.createFile(blb).setName('<name_of_exported_file>.docx');
//Put the file in a drive folder
DriveApp.getFolderById('<FOLDER_ID>').addFile(file);
}
Quoting from this item on the issue tracker...
You can convert a Google Document to docx today using the Drive
Advanced Service:
https://developers.google.com/apps-script/advanced/drive
Here is a small example:
function convertToDocx(documentId) {
var file = Drive.Files.get(documentId);
var url = file.exportLinks['application/vnd.openxmlformats-officedocument.wordprocessingml.document'];
var oauthToken = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + oauthToken
}
});
return response.getBlob();
}

Using Facebook graph in Chrome Extensions

I'm trying to use Facebook graph in Chrome extensions, but I'm having trouble in using access token to have permissions. My extension folder has a background.html file with the this code:
function displayUser(user) {
var userName = document.getElementById('userName');
var greetingText = document.createTextNode('Greetings, ' + user.name + '.');
userName.appendChild(greetingText);
}
var appID = "XXXXX";
if (window.location.hash.length == 0) {
var path = 'https://www.facebook.com/dialog/oauth?';
var queryParams = ['client_id=' + appID,'redirect_uri=https://www.facebook.com/connect/login_success.html', 'response_type=token'];
var query = queryParams.join('&');
var url = path + query;
window.open(url);
} else {
var accessToken = window.location.hash.substring(1);
var path = "https://graph.facebook.com/me?";
var queryParams = [accessToken, 'callback=displayUser'];
var query = queryParams.join('&');
var url = path + query;
// use jsonp to call the graph
var script = document.createElement('script');
script.src = url;
document.body.appendChild(script);
}
When I run the extension, it opens a new tab with the app authorization. When I accept it, it just says "Success" and the url of this tab is like this:
https://www.facebook.com/connect/login_success.html#access_token=AAABtoJwdQQgBAP8KK6QYmlQ1CJOSjQxWjXoa7qgUthF507BGPgLeWEplB87fZBpDZBZBd7CKoIWb4Fa3S2laBuZAUf795p1N3QZDZD&expires_in=5549
So now how can I use this access token in background.html and close that authorization tab?
You should watch (in the extension code) for the tab changes with success url like this
chrome.tabs.onUpdated.addListener(onTabUpdated);
Then the handler function:
function onTabUpdated(tabId, changeInfo, tab) {
if (changeInfo.url && changeInfo.url.indexOf(SUCCESS_URL) == 0) {
// extract access token from url
Extract function:
function accessTokenFromSuccessURL(url) {
var hashSplit = url.split('#');
if (hashSplit.length > 1) {
var paramsArray = hashSplit[1].split('&');
for (var i = 0; i < paramsArray.length; i++) {
var paramTuple = paramsArray[i].split('=');
if (paramTuple.length > 1 && paramTuple[0] == 'access_token')
return paramTuple[1];
}
}
return null;
}
Judging by redirect_uri=https://www.facebook.com/connect/login_success.html, I'm assuming you're building a desktop or a client side app.
Try adding var RedirectURI = window.location;
And change the redirect URI in the queryParams array to redirect_uri= RedirectURI
If required, you can add http://localhost to the Site URL entry in https://developers.facebook.com/apps
Once the token is obtain, it is redirected to your previous page with the authorization token added as a hash which is automatically handled by the else { } block in your code.