Sys-Admin Forum

SharePoint - получение данных при помощи Curl

У SP есть неплохой REST сервис, посрдеством которого можно быстро получать данные (да и вообще работать с данными) используя его api… Для работы посредством Curl необходимо использовать ntlm авторизацию:

curl --ntlm --user domain/user http://site/

Используем api для получения фида со списком листов:

curl --ntlm --user domain/user http://site/my/personal/user_name/_api/web/lists/GetByTitle\(\'WmaAggregatorList_User\'\)

Для удобного вывода можно использовать xml2

curl --ntlm --user domain/user http://site/my/personal/user_name/_api/web/lists/GetByTitle\(\'WmaAggregatorList_User\'\) | xml2
...
/entry/content/m:properties/d:Id/@m:type=Edm.Guid
/entry/content/m:properties/d:Id=d894fe8c-000-47d7-44а-d36d053f4ed2

Мне понравилось работать через SOAP. Список полей в листе получается при отработаке скрипта в консоли после успешного соединения.


<?php 
//Authentication details
$authParams = array('login' => 'user',
                    'password' => 'password');
 
/* A string that contains either the display name or the GUID for the 
list.
 * It is recommended that you use the GUID, which must be surrounded by 
curly
 * braces ({}).
 */
$listName = "List";
$rowLimit = '300';
 
/* Local path to the Lists.asmx WSDL file (localhost). You must first 
download
 * it manually from your SharePoint site (which should be available at
 * yoursharepointsite.com/subsite/_vti_bin/Lists.asmx?WSDL)
 */
$wsdl = "http://localhost/localdir/filename.wsdl";
 
//Creating the SOAP client and initializing the GetListItems method parameters
$soapClient = new SoapClient($wsdl, $authParams);
$params = array('listName' => $listName,
                'rowLimit' => $rowLimit);

 
//Calling the GetListItems Web Service
$rawXMLresponse = null;
try{
    $rawXMLresponse = 
$soapClient->GetListItems($params)->GetListItemsResult->any;
}
catch(SoapFault $fault){
    echo 'Fault code: '.$fault->faultcode;
    echo 'Fault string: '.$fault->faultstring;
}
echo '<pre>' . $rawXMLresponse . '</pre>';
 
//Loading the XML result into parsable DOM elements
$dom = new DOMDocument();
$dom->loadXML($rawXMLresponse);
$results = $dom->getElementsByTagNameNS("#RowsetSchema", "*");

 
//Fetching the elements values. Specify more attributes as necessary
foreach($results as $result){

# debug
echo "<BR>";
echo $result->getAttribute("ows_LinkTitle")." : ";
echo $result->getAttribute("ows_Contract_x0020_Number")." : ";
echo $result->getAttribute("ows_Expiry_x0020_Date")." <BR> ";

unset($soapClient);

?>

Слушай, ты случаем не знаешь как “быстро” дернуть все задачи пользователя (которые расположены в разных листах) в рамках одной коллекции?

Привет. Вангую что нет быстрого способа, так как листы разные. Но по идее никто не мешает задать листы массивом и опросить их через soap последовательно с фильтром по имени пользователя.
Второй более интерактивный способ - это создать веб страницу в sharepoint, на нее закинуть webpart с текстовым полем ввода и кучку вебпартов листов с задачами. Далее указать в настройках вебпартов листов что они берут фильтр из текстового поля.

Можно, то это шибко “ручной” способ… Надо знать имена листов, если создастся новый лист, надо будет его добавлять и т.п… Я нашел фичу - в персональном сайте, в разделе Tasks, на странице AllTasks.aspx отображаются все задачи пользователя, подтягиваются они туда автоматом… хотелось бы что то подобное… как временное решение, пока пробую данные вытаскивать из этого листа, дабы не собирать все в кучу руками… Проблема в том, что у одного пользователя я провалился в эти задачи, у другого не могу найти этот лист… так как по Title не провалишься (нужно знать guid группы), щаз пробую собирать все гуиды из персонального сайта, и вычислять в каком хранятся таски, соответсвенно юзаю для этих целей REST, завтра допишу свой bash скрипт по опросу…

Сам не особо шарю в SP… а с такой задачей столкнулся буквально сегодня… Так что если посмотришь и подскажешь как можно что то подобное реализовать, буду признателен…

Я тоже не спец по SPS, иначе пример был не на php :smile3: Давай подумаем совместно.

Оказалось, все просто до безобразия. Есть веб-парт с названием Content Query, который сам без кодинга может вытащить определенные элементы из всех листов. Пример на скрине.


Итак, произвел небольшое расследование, написал небольшой скрипт, который собирает все guid листов со страницы AllTasks.aspx в профилле пользователя, каковых собирается порядка ± 10-ти листов, из них только один содрежит все задачи пользователя, путем сравнения было определено, что фид содержащий задачи имеет метку - Data.WmaAggregatorList_x005f_UserItem

USER="user_name"
SITE="http://server/my/personal"
CURL="curl -sS --ntlm --netrc-file data.txt "

TASK_GUIDS=(`$CURL $SITE/$USER/_api/web/lists | xml2 | grep 'Id=' | grep -v '0000000$' | sed 's/.*=//'`)

for i in ${TASK_GUIDS[@]}; do
  RES=`$CURL $SITE/$USER/_api/web/lists\(guid\'$i\'\)/Items | xml2 | grep 'WmaAggregatorList_x005f_UserItem'`
  if [[ ! -z $RES ]]; then
    $CURL $SITE/$USER/_api/web/lists\(guid\'$i\'\)/Items | xml2 | grep 'Title='
  fi
done

В итоге получаем следующий результат:

/feed/entry/content/m:properties/d:Title=ProjectServerProvider
/feed/entry/content/m:properties/d:Title=Testing
/feed/entry/content/m:properties/d:Title=Testing: Tasks
/feed/entry/content/m:properties/d:Title=Task VPS
/feed/entry/content/m:properties/d:Title=Test Personal
/feed/entry/content/m:properties/d:Title=Test Complete
/feed/entry/content/m:properties/d:Title=Test SSH

Далее упрощаем строку определения листа с задачами, команда вытаскивает чистую ссылку к листу:

TASK_LIST=`$CURL $($CURL $SITE/$USER/_api/web/lists | xml2 | grep -B 200 'Data.WmaAggregatorList_x005f_UserItem' | grep 'id=' | sed 's/.*=//' | sed 's/.*=//' | sed "s/'/\\\\'/g" | sed "s/)/\\\\)/g" | sed "s/(/\\\\(/g")/Items | xml2 | grep -i 'id=web/lists(guid' | grep -i 'Items.*)$' | sed "s/\/feed\/entry\/id=//"`

В итоге получается спискок содержащий линки к таскам:

Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(1)
Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(2)
Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(3)
Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(4)
Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(5)
Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(6)
Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(7)
Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(8)
Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(9)
Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(10)
Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(11)

Далее перебираем их / проваливаемся в задачи:

function e {
    $CURL $SITE/$USER/_api/$1 | xml2 | grep 'Title='
    $CURL $SITE/$USER/_api/$1 | xml2 | grep -i 'TxEditUrl='
    $CURL $SITE/$USER/_api/$1 | xml2 | grep -i 'TxIsCompleted='
}

for i in $TASK_LIST; do
  e $i
done

Где Title - Имя задачи
Поле TxEditUrl - говорит о том, что задача создана где то в листе и можно провалиться в лист
Поле TxIsCompleted - говорит о том, задача завершена или нет

Задачи с TxEditUrl не имеют статуса TxIsCompleted и наоборот TxIsCompleted не имеют TxEditUrl, результат выглядит так:


....
/entry/content/m:properties/d:Title=Task VPS
/entry/content/m:properties/d:TxEditUrl=http://server/testing/_layouts/15/listform.aspx?PageType=4&ListId=0f78e65b-9137-4853-90b9-ca7e44728c05&ID=2&ContentTypeID=0x00C2208B8CE6E1422CADC1C521EAB2A68B

/entry/content/m:properties/d:Title=Test Personal
/entry/content/m:properties/d:TxIsCompleted=false

/entry/content/m:properties/d:Title=Test Complete
/entry/content/m:properties/d:TxIsCompleted=true

/entry/content/m:properties/d:Title=Test SSH
/entry/content/m:properties/d:TxEditUrl=http://server/testing/_layouts/15/listform.aspx?PageType=4&ListId=0f78e65b-9137-4853-90b9-ca7e44728c05&ID=3&ContentTypeID=0x00C2208B8CE6E1422CADC1C521EAB2A68B

От сюда видно, что задачи Test Personal, Test Complete это персональные задачи. Задачи Test SSH, Task VPS созданы в листах… Далее остается делом техники получить данные по задачам…

Вся эта эпопея производилась для наглядности, так как сама методология нигде не описана (методология сбора всех задач при помощи REST), по крайней мере я не нашел, если кто деал подобное прошу скинуть ссылку…

Далее ради интереса берем одну ссылку (полученную в результате работы скрипта), вида:

.....my/personal/user_name/_api/Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')/Items(5)

Пробуем заюзать аякс из JavaScript’а повешеннго на страницу SP, результат пока выкладываем в консоль:

var endpointUrl = _spPageContextInfo.webAbsoluteUrl + "/my/personal/user_name/_api/Web/Lists(guid'56813350-6d0d-4820-b0d9-3e21fc457328')?$expand=items,fields";

getJson(endpointUrl)
.done(function(data)
{
    var fields = data.d.Fields.results; //get fields
    var items = data.d.Items.results; //get items

    console.log(fields);
    console.log(items);
  })
.fail(
	function(error){
		console.log(JSON.stringify(error));
	});
;

function getJson(url)
{
	return $.ajax({
		url: url,
		type: "GET",
		contentType: "application/json;odata=verbose",
		headers: {
			"Accept": "application/json;odata=verbose"
		}
	});
}

В итоге смотрим консоль (см. аттач) и вуаля, проваливаемся в первый попавшийся объект и видим (см. аттач):

null
Title
:
"Test SSH"
TxCustomAttributes
:
null
TxDescription
:
"​SSH Description"
TxDueDate
:
"2016-12-16T18:00:00Z"
TxEditUrl
:
"http://server/testing/_layouts/15/listform.aspx?PageType=4&ListId=0f78e65b-9137-4853-90b9-ca7e44728c05&ID=3&ContentTypeID=0x00C2208B8CE6E1422CADC1C521EAB2A68B"
TxEffectiveCreated
:
"2016-12-02T04:22:52Z"
TxEffectiveLastModified
:
"2016-12-02T04:22:52Z"
TxEffectiveLocationGroupOrder
:
"-2162.00000000000"

Что дальше:
Запилить скрипт, который будет вытаскивать данные оз объектов и вешать в красивом виде на страницу…


sp-rest1.jpg