"Вся проблема в твоем коде," сказала она.
"Если подумать логически, ответ прост
Я хочу помочь тебе освободиться,
Есть пятьдесят способов поставить закладку...”
"Пятьдесят способов поставить закладку" – это эксперимент в социальных публикациях и серьёзное испытание, позволяющее определить, можно ли создать статью для developerWorks® за фиксированное время. Сам эксперимент и тема статьи были описаны в приглашении и разосланы потенциальным участникам по почте в следующем виде:
"Пятьдесят способов поставить закладку" - Вы приглашены к участию!
Главная цель эксперимента - собрать группу людей, которые смогут за один день опубликовать на сайте developerWorks статью, описывающую использование Atom Publishing Protocol (AtomPub), на как можно большем количестве языков. Чтобы продолжить серию статей об API Lotus Connections, мы приняли решение использовать Dogear в качестве сервиса AtomPub.
Добро пожаловать всем, кто может включиться в работу, все участники будут отмечены как соавторы.
Мы будем принимать публикации 10 августа 2007 года по местному времени. То есть, учитывая некоторую зигзагообразность линии перемены дат и особенности дневного времени, примерно с полуночи в Киритимити (четверг, 10 августа, 6:00 по Восточному поясному времени США) до полуночи в Гонолулу (суббота, 12 августа, 6:00 по Восточному поясному времени США).
Для публикации статьи перейдите на wiki-сайт "Пятьдесят способов поставить закладку", прочитайте правила и добавьте свой пример.
Нам нужны примеры на таких языках как Ruby, PHP, Java, Python, Flash ActionScript, C#, LotusScript и JavaScript. Также нам хотелось бы показать насколько многосторонним является API сервиса и если вы можете опубликовать примеры на APL, COBOL, PL/1, PostScript или других языках - добро пожаловать.
Для сбора публикаций и информирования авторов мы использовали свой внутренний wiki-сайт. Краткие инструкции выглядели так:
Вы (автор) подаёте заявку на определённый язык программирования, добавляя страницу wiki начиная с номера 10 (прибавляя 1 для каждого следующего языка) и указываете наименование языка, например “10 - Java”. Затем добавляете код добавления закладки на выбранном языке в соответствии с приведенным форматом. Вы можете выбрать любое количество языков, размещая их на отдельных страницах.
Авторам также нужно было сообщить, что именно они должны сделать для демонстрации запроса AtomPub к серверу Dogear, для чего мы разместили дополнительные инструкции:
Мы будем делать один и тот же запрос на каждом языке. Мы программно создадим закладку на домашней странице Lotus Connections (http://ibm.com/lotus/connections), присвоим ей теги "lotus", "connections" и "50WaysToLeaveYourBookmark", а также добавим описание "I posted this from <язык>" и заголовок "The Lotus Connections Page."
Поскольку запрос AtomPub - это обычный запрос HTTP, вот данные, которые будут передаваться серверу:
POST /dogear/api/app?email=user@company.com HTTP/1.1 Host: www.company.com Content-Type: application/atom+xml Authorization: Basic RG9uIFA1aXhvdAAAAm9jaW5hAARl <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <author><name>Author</name></author> <title>The Lotus Connections Page</title> <content type="html"><![CDATA[I posed this from <language>]]> </content> <category scheme="http://www.ibm.com/xmlns/prod/sn/type" term="bookmark" /> <category term="lotus" /> <category term="connections" /> <category term="50WaysToLeaveYourBookmark" /> <link href="http://www.ibm.com/lotus/connections" /> </entry> |
После публикации этих инструкций эксперимент начался. Каждый автор выбрал язык программирования и написал пример, отправляющий закладку на работающий сервер Dogear. Авторы опубликовали одинаковые ссылки с указанием своего языка в описании закладки (см. рис. 1).
Рисунок 1. Пример описания закладки
По прошествии первого дня мы продлили эксперимент до следующей недели, так как количество поступивших примеров оказалось меньше, чем ожидалось.
Нижеприведённые примеры показывают вызовы сервиса на разных языках.
Для получения более подробной информации об API Dogear и сервисе AtomPub прочитайте статью developerWorks “Развёртывание IBM Lotus Connections: Интеграция с другими системами.”
Далее приведены 17 примеров полученные за заданный период. Для каждого примера указаны язык программирования, используемые библиотеки, комментарии авторов и сам код.
Все примеры работают на Dogear 1.0.x и могут служить хорошим пособием для начала работы с данными сервисов Lotus Connections. Обратите внимание, что для API Lotus Connections Activities 1.0.2 вам нужно заполнять поле user-agent.
Java
Джеймс Снейлл (James Snell, snellspace.com)
Apache Abdera - разбор и генерация Atom
Abdera abdera = new Abdera();
Client client = new CommonsClient(abdera);
client.addCredentials("http://dogear.tap.ibm.com/api/app", null, null, new
UsernamePasswordCredentials("userid","password"));
ClientResponse resp = client.get("http://dogear.tap.ibm.com/api/app");
Document<Service> service_doc = resp.getDocument();
Service service = service_doc.getRoot();
Collection collection = service.getCollection("My Bookmarks", "Entries");
String coll_uri = collection.getResolvedHref().toASCIIString();
Entry entry = abdera.newEntry();
entry.setId(""); //ignored by the server, required by APP
entry.addAuthor("james"); //ignored by the server, required by APP
entry.addLink("http://ibm.com/lotus/connections"); // the url being bookmarked
entry.setTitle("The Lotus Connections Page");
entry.setContentAsHtml("I posted this from Java");
entry.addCategory("lotus");
entry.addCategory("connections");
entry.addCategory("50WaysToLeaveYourBookmark");
// optional in dogear
entry.addCategory("http://www.ibm.com/xmlns/prod/sn/type","bookmark",null);
resp = client.post(coll_uri, entry);
switch(resp.getType()) {
case SUCCESS:
String location = resp.getLocation().toASCIIString();
System.out.println("New entry created at: " + location);
break;
default:
System.out.println("Error: " + resp.getStatusText());
}
|
Java
Дейв Гриффитс (Dave Griffiths)
нет
import java.net.*;
import java.io.*;
import javax.net.ssl.*;
import javax.net.*;
/* Bare metal Java version! */
public class Bookmark {
public static void main(String[] args) throws Exception {
SocketFactory factory = SSLSocketFactory.getDefault();
Socket socket = factory.createSocket("dogear.tap.ibm.com", 443);
OutputStreamWriter out =
new OutputStreamWriter(socket.getOutputStream(), "UTF8");
out.write("POST /api/app?email=dgriff@uk.ibm.com HTTP/1.1\r\n");
out.write("Host: www.ibm.com\r\n");
String encoding =
new sun.misc.BASE64Encoder().encode("dgriff@uk.ibm.com:password".getBytes());
out.write("Authorization: Basic " + encoding + "\r\n");
String data = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
"<entry xmlns=\"http://www.w3.org/2005/Atom\">\r\n" +
"<author><name>Author</name></author>\r\n" +
"<title>The Lotus Connections Page</title>\r\n" +
"<content type=
\"html\"><![CDATA[I posted this from Java]]></content>\r\n" +
"<category scheme=\"http://www.ibm.com/xmlns/prod/sn/type\"
term=\"bookmark\" />\r\n" +
"<category term=\"lotus\" />\r\n" +
"<category term=\"connections\" />\r\n" +
"<category term=\"50WaysToLeaveYourBookmark\" />\r\n" +
"<link href=\"http://www.ibm.com/lotus/connections\" />\r\n" +
"</entry>\r\n";
out.write("Content-Length: " + data.length() + "\r\n");
out.write("Content-Type: application/atom+xml\r\n");
out.write("\r\n");
out.write(data);
out.flush();
BufferedReader in =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
}
}
|
PHP с cURL и xmlwriter
Кэролин Мэйнард (Caroline Maynard)
Существует множество способов выполнить задачу средствами PHP. Для нашего примера рассмотрим простейший вариант – использование cURL с PHP.
Код выглядит объёмнее других примеров из-за программного создания XML в функции create_entry_xmlwriter. При желании код можно сократить, загружая заранее подготовленный XML из файла либо используя heredoc.
Было обнаружено, что необходимо установить CURLOPT_SSL_VERIFYPEER чтобы избежать следующей ошибки:
“Got 60 : SSL certificate problem, verify that the CA cert is OK.
Details: error:14090086:SSL
routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed.”
PHP 5.1.x с встроенными расширениями для cURL и xmlwriter.
<?php
try {
$target = "https://dogear.tap.ibm.com/api/app/?email=caroline.maynard%40uk.ibm.com";
$user = "caroline.maynard@uk.ibm.com";
$passwd = "<password>";
$xml = create_entry_xmlwriter();
$headers = array("Content-Type: application/atom+xml ");
$handle = curl_init($target);
$curlopt_array = array(
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $xml,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERPWD => $user.':'.$passwd,
CURLOPT_FOLLOWLOCATION => true);
curl_setopt_array($handle, $curlopt_array);
$result = curl_exec($handle);
if ($result === false) {
print "Got " . curl_errno($handle) . " : " . curl_error($handle) . "\n";
curl_close ($handle);
return;
}
$response_http_code = curl_getinfo ($handle, CURLINFO_HTTP_CODE);
if ($response_http_code != 201) {
print("HTTP status code: $response_http_code \n");
curl_close($handle);
return;
}
curl_close($handle);
} catch (Exception $e) {
print $e;
}
function create_entry_xmlwriter($author = "Caroline Maynard",
$title = "The Lotus Connections Page",
$link = "http://www.ibm.com/lotus/connections",
$categories = array('lotus', 'connections', '50WaysToLeaveYourBookmark')) {
$xmlwriter = new XMLWriter();
$xmlwriter->openMemory();
$xmlwriter->startDocument("1.0", "UTF-8");
$xmlwriter->startElement('entry');
$xmlwriter->writeAttribute('xmlns', 'http://www.w3.org/2005/Atom');
$xmlwriter->startElement('author');
$xmlwriter->writeElement('name', $author);
$xmlwriter->endElement();
$xmlwriter->writeElement('title', $title);
$xmlwriter->startElement('link');
$xmlwriter->writeAttribute('href', $link);
$xmlwriter->endElement();
$xmlwriter->startElement('content');
$xmlwriter->writeAttribute('type', 'html');
$xmlwriter->text('I posted this from PHP');
$xmlwriter->endElement();
$xmlwriter->startElement('category');
$xmlwriter->writeAttribute('term', 'bookmark');
$xmlwriter->writeAttribute('scheme', 'http://www.ibm.com/xmlns/prod/sn/type');
$xmlwriter->endElement();
if ($categories) {
$categories = (array)$categories;
foreach ($categories as $category) {
$xmlwriter->startElement('category');
$xmlwriter->writeAttribute('term', $category);
$xmlwriter->endElement();
}
}
$xmlwriter->endElement();
$xmlwriter->endDocument();
return $xmlwriter->outputMemory();
}
?>
|
#!/usr/bin/ruby
require 'rexml/document'
require 'rexml/cdata'
require 'net/http'
require 'net/https'
require 'uri'
user = 'user@example.com'
password = 'password'
url = URI.parse('https://dogear.tap.ibm.com:443/api/app')
# Create the XML document
doc = REXML::Document.new('<entry xmlns="http://w3.org/2005/Atom"/>')
r = doc.root
r.add_element('author').add_element('name').text = 'Sacha Chua'
r.add_element('title').text = 'The Lotus Connections Page'
content = r.add_element 'content', { 'type' => 'html' }
content.text = REXML::CData.new('I posted this from Ruby')
r.add_element('category',
{ 'term' => 'bookmark',
'scheme' => 'http://www.ibm.com/xmlns/prod/sn/type' })
r.add_element 'category', { 'term' => 'lotus' }
r.add_element 'category', { 'term' => 'connections' }
r.add_element 'category', { 'term' => '50WaysToLeaveYourBookmark' }
r.add_element 'link', { 'href' => 'http://www.ibm.com/lotus/connections' }
doc.add(REXML::XMLDecl.new('1.0', 'UTF-8'))
http = Net::HTTP.new(url.host, url.port)
# Post the document
req = Net::HTTP::Post.new(url.path + '?email=' + user)
req.basic_auth user, password
req['Content-Type'] = 'application/atom+xml'
req.body = doc.to_s
http.use_ssl = true
http.start do |http|
response = http.request(req)
case response
when Net::HTTPSuccess
puts "Posted!" + response.body
else
response.error!
end
end
|
JavaScript
Адам Рид (Adam N. Reed)
нет
//Construct a standard XMLHttpRequest Object for Mozilla Firefox or Internet Explorer
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request) {
alert("Error initializing XMLHttpRequest!");
}
//Construct the XML to be sent in the request as a string
//The string is split and concatenated here for clarity.
var postXML = '<?xml version="1.0" encoding="utf-8"?>'
+'<entry xmlns="http://www.w3.org/2005/Atom">'
+'<author><name>Author</name></author>'
+'<title>The Lotus Connections Page</title>'
+'<content type="html">I posted this from JavaScript</content>'
+'<category scheme="http://www.ibm.com/xmlns/prod/sn/type" term="bookmark" />'
+'<category term="lotus" />'
+'<category term="connections" />'
+'<category term="50WaysToLeaveYourBookmark" />'
+'<link href="http://www.ibm.com/lotus/connections" />'
+'</entry>';
var postURL = "http://www.company.com/dogear/api/app";
request.open("POST",postURL,true,"userid","password");
request.setRequestHeader("Content-type", "application/atom+xml");
request.setRequestHeader("Content-length", postXML.length);
request.setRequestHeader("Connection", "close");
request.onreadystatechange = postResponse;
request.send(postXML);
function postResponse() {
//Check for success: HTTP 201 - Created
if (request.readyState == 4) {
if(request.status == 201) {
//Activity successfully created
//Do any post-processing here...
} else {
alert("Error: " + request.status + " - " + request.statusText);
//Further error processing...
}
}
}
|
Perl
Аксель Мегард (Axel Magard)
XML::Generator - генератор XML
LWP::UserAgent - библиотека Perl для WWW
require LWP::UserAgent;
use LWP::Debug qw(+ -conns);
my $user = "axel_magard\@de.ibm.com";
my $pw = "xxxxxxxx";
my $server = "dogear.tap.ibm.com";
my $url = "http://".$server."/api/app";
my $port = "443";
# Create a user object ...
my $ua = LWP::UserAgent->new;
$ua->agent("MyBookmark/0.1 ");
$ua->credentials($server.':'.$port, 'Dogear', $user, $pw );
push @{ $ua->requests_redirectable }, 'POST'; # Avoid the 302 return code
# Create a request ...
my $req = HTTP::Request->new(POST => $url);
use XML::Generator ':pretty';
# Build XML document ...
my $gen = XML::Generator->new(':pretty',
namespace => ["http://www.w3.org/2005/Atom"]);
$content = sprintf $gen->xml($gen->entry( $gen->author("Axel Magard"),
$gen->title("The Lotus Connections Page"),
$gen->content({type => 'html'},"I posted this from Perl."),
$gen->category({scheme => "http://www.ibm.com/xmlns/prod/sn/type",
term => "bookmark"}),
$gen->category({term=>"lotus"}),
$gen->category({term=>"connections"}),
$gen->category({term=>"50WaysToLeaveYourBookmark"}),
$gen->link({href=>"http://www.ibm.com/lotus/connections"})
)
);
# Set request content
$req->content_type('application/atom+xml');
$req->content($content);
# Pass request to the user agent and get a response back
my $res = $ua->request($req);
# Check the outcome of the response
if ($res->is_success) {
print "Bookmark posted.\n";
}
else {
print $res->status_line, "\n";
}
|
ActionScript
Дэррен Шоу (Darren Shaw)
нет
var xmlString = '<?xml version="1.0" encoding="utf-8"?>'
+'<entry xmlns="http://www.w3.org/2005/Atom">'
+'<author><name>Author</name></author>'
+'<title>The Lotus Connections Page</title>'
+'<content type="html"><\!\[CDATA\[I posed this from
ActionScript\]\]></content>'
+'<category scheme="http://www.ibm.com/xmlns/prod/sn/type"
term="bookmark" />'
+'<category term="lotus" />'
+'<category term="connections" />'
+'<category term="50WaysToLeaveYourBookmark" />'
+'<link href="http://www.ibm.com/lotus/connections" />'
+'</entry>';
// create new xml object from xml string
var xml:XML = new XML(xmlString);
// set content type
xml.contentType = "application/atom+xml";
// send to server and show result in new browser window
xml.send("https://dogear.tap.ibm.com/api/app", "_blank");
|
Сценарий командной оболочки / командная строка
Энди Пайпер (Andy Piper, http://andypiper.co.uk )
cURL - утилита командной строки для HTTP
APP API можно вызвать из любого командного процессора, отправив методом POST файл в формате Atom XML с помощью cURL.
curl -u "andy.piper@uk.ibm.com:passw0rd" -X POST -H 'Content-Type:application/atom+xml'
--data-binary @atomfile.xml https://dogear.tap.ibm.com/api/app?
email=andy.piper@uk.ibm.com
|
Из командной оболочки с использованием wget
Брайан Олор (Brian Olore, bolore@us.ibm.com)
wget - GNU Wget - свободная утилита для получения файлов через широко используемые Интернет-протоколы: HTTP, HTTPS и FTP.
Create a bookmark - wget
wget --header="Content-type: application/atom+xml" --post-file=content.txt
--http-user=bolore@us.ibm.com --http-password=passw0rd
"https://dogear.tap.ibm.com/api/app?email=bolore@us.ibm.com"
|
Message Broker и ESQL
Джефф Лоури (Jeff Lowrey)
Используйте базовый Compute Node, установив для ComputeMode значение Message And Local Environment. Соедините Compute Node с узлом HTTPRequest. Вам нужно присвоить какой либо URL узлу HTTPRequest (неважно какой). Также вам необходимо добавить узел Input для начала работы модуля. Я использовал узел MQInput, но это неважно. Имя пользователя и пароль нужно брать из UserDefinedProperties, чтобы администратор мог установить их во время развёртывания.
DECLARE user CHARACTER; DECLARE password CHARACTER; CALL CopyMessageHeaders(); -- CALL CopyEntireMessage(); SET user = 'user'; SET password = 'password'; SET OutputRoot.MQMD = NULL; SET OutputRoot.Properties.MessageDomain = 'XMLNS'; -- set the HTTP destination URL, and various HTTP headers -- these will be used by the HTTPRequest node SET OutputLocalEnvironment.Destination.HTTP.RequestURL = 'https://dogear.tap.ibm.com/api/app?email='||user; SET OutputRoot.HTTPRequestHeader."Content-Type"= 'application/atom+xml'; SET OutputRoot.HTTPRequestHeader."Authorization" = 'Basic '||b64Encode(CAST(user||': '||password as BLOB CCSID InputRoot.Properties.CodedCharSetId)); -- create the message body which contains the Atom -- format XML required to create the bookmark SET OutputRoot.XMLNSC.(XMLNSC.XmlDeclaration)*.(XMLNSC.Attribute)Version = '1.0'; SET OutputRoot.XMLNSC.(XMLNSC.XmlDeclaration)*.(XMLNSC.Attribute)Encoding = 'UTF-8'; SET OutputRoot.XMLNSC.entry.author.name='Jeff Lowrey'; SET OutputRoot.XMLNSC.entry.(XMLNSC.NamespaceDecl)xmlns:xmlns = 'http://www.w3.org/2005/Atom'; DECLARE outRef REFERENCE TO OutputRoot.XMLNSC.entry; SET outRef.title='The Lotus Connections Page'; SET outRef.(XMLNSC.CDataField)content = 'I posted this from Message Broker using ESQL'; SET outRef.content.(XMLNSC.Attribute)"type" = 'html'; SET outRef.category[1].(XMLNSC.Attribute)"scheme" = 'http://www.ibm.com/xmlns/prod/sn/type'; SET outRef.category[1].(XMLNSC.Attribute)"term" = 'bookmark'; SET outRef.category[2].(XMLNSC.Attribute)"term" = 'lotus'; SET outRef.category[3].(XMLNSC.Attribute)"term" = 'connections'; SET outRef.category[4].(XMLNSC.Attribute)"term" = '50WaysToLeaveYourBookmark'; SET outRef.link.(XMLNSC.Attribute)"href"='http://www.ibm.com/lotus/connections'; |
В файле ESQL нужен дополнительный код вне модуля Compute. Он позволит воспользоваться процедурой перекодирования в base64 для заполнения полей Basic Auth в заголовке HTTP.
CREATE PROCEDURE b64Encode(IN source BLOB) RETURNS CHARACTER LANGUAGE JAVA EXTERNAL NAME "com.ibm.broker.javacompute.Base64.encode"; |
AppleScript
Энди Пайпер (Andy Piper, http://andypiper.co.uk)
cURL - утилита командной строки для HTTP поставляемая с OS X
XML Tools Scripting Addition - расширение для создания XML в AppleScript
set outputfile to (((path to desktop) as string) & "atomentry.xml")
as file specification
set atomfile to POSIX path of outputfile as text
-- NB the XML tools extension does not support CDATA so the content is
typed "text" rather than "html"
-- also can't use an attribute named 'scheme' as it seems to get generated strangely
set theXML to
{class:XML element, XML tag:"entry",
XML attributes:{xmlns:"http://www.w3.org/2005/Atom"}, XML contents:{
{class:XML element, XML tag:"author", XML contents:
{class:XML element, XML tag:"name", XML contents:{
"Author"}}},
{class:XML element, XML tag:"title", XML contents:{"The Lotus
Connections Page"}},
{class:XML element, XML tag:"content", XML attributes:{type:"text"},
XML contents:{"I posted this from Applescript"}},
{class:XML element, XML tag:"category", XML attributes:{term:"bookmark"}},
{class:XML element, XML tag:"category", XML attributes:{term:"lotus"}},
{class:XML element, XML tag:"category", XML attributes:{term:"connections"}},
{class:XML element, XML tag:"category", XML
attributes:{term:"50WaysToLeaveYourBookmark"}},
{class:XML element, XML tag:"link", XML
attributes:{href:"http://www.ibm.com/lotus/connections"}}}}
generate XML theXML saving as (outputfile) with generating UTF8
set results to do shell script "curl --user 'andy.piper@uk.ibm.com:passw0rd' -X
POST -H 'Content-Type:application/atom+xml' --data-binary @" & atomfile &
"https://dogear.tap.ibm.com/api/app?email=andy.piper@uk.ibm.com"
if results = "" then
set results to "Successfully published the bookmark"
end if
display dialog results buttons "OK"
-- delete the generated Atom XML file to clean up
tell application "Finder"
delete file outputfile
end tell
|
ColdFusion 8.0
Сьюзен Минасян (Suzanne Minassian)
<cfxml variable="postMe"> <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <author><name>Author</name></author> <title>The Lotus Connections Page</title> <content type="html"><![CDATA[I posted this from ColdFusion]]></content> <category scheme="http://www.ibm.com/xmlns/prod/sn/type" term="bookmark" /> <category term="lotus" /> <category term="connections" /> <category term="50WaysToLeaveYourBookmark" /> <link href="http://www.ibm.com/lotus/connections" /> </entry> </cfxml> <cfhttp method="POST" url="https://dogear.tap.ibm.com/api/app/?email=minassian@us.ibm.com" username="minassian@us.ibm.com" password="myPasswordHere"> <cfhttpparam type = "XML" value = "#postMe#"> </cfhttp> |
VB.NET
Бен Рабинжер (Ben Rubinger)
Microsoft® .NET Framework 2.0
Module Module1
Sub Main()
Dim mymemstream As New System.IO.MemoryStream()
Dim mystreamwriter As New System.IO.StreamWriter(mymemstream)
Dim mywriter As New System.Xml.XmlTextWriter(mystreamwriter)
mywriter.WriteStartDocument()
mywriter.WriteStartElement("entry", "")
mywriter.WriteAttributeString("xmlns", "http://www.w3.org/2005/Atom")
mywriter.WriteStartElement("author")
mywriter.WriteElementString("name", "Ben Rubinger")
mywriter.WriteEndElement()
mywriter.WriteElementString("title", "The Lotus Connections Page")
mywriter.WriteStartElement("content", "")
mywriter.WriteAttributeString("type", "html")
mywriter.WriteValue("I posted this from VB.NET")
mywriter.WriteEndElement()
mywriter.WriteStartElement("category", "")
mywriter.WriteAttributeString("scheme", "http://www.ibm.com/xmlns/prod/sn/type")
mywriter.WriteAttributeString("term", "bookmark")
mywriter.WriteEndElement()
mywriter.WriteStartElement("category")
mywriter.WriteAttributeString("term", "lotus")
mywriter.WriteEndElement()
mywriter.WriteStartElement("category")
mywriter.WriteAttributeString("term", "connections")
mywriter.WriteEndElement()
mywriter.WriteStartElement("category")
mywriter.WriteAttributeString("term", "50WaysToLeaveYourBookmark")
mywriter.WriteEndElement()
mywriter.WriteStartElement("link", "")
mywriter.WriteAttributeString("href", "http://www.ibm.com/lotus/connections")
mywriter.WriteEndElement()
mywriter.WriteEndElement()
mywriter.WriteEndDocument()
mywriter.Flush()
Dim myrequest As System.Net.HttpWebRequest =
System.Net.WebRequest.Create
("http://dogear.tap.ibm.com/api/app?email=rubinger@us.ibm.com")
myrequest.Method = "POST"
Dim mycredentials As New System.Net.NetworkCredential
("rubinger@us.ibm.com", "********")
myrequest.Credentials = mycredentials
myrequest.ContentType = "application/atom+xml"
myrequest.ContentLength = mymemstream.Length
Dim poststream As IO.Stream
Try
poststream = myrequest.GetRequestStream()
poststream.Write(mymemstream.GetBuffer(), 0, mymemstream.Length)
Catch ex As Exception
Finally
If Not poststream Is Nothing Then poststream.Close()
End Try
mywriter.Close()
End Sub
End Module
|
C#
Крис Гэмбрелл (Chris Gambrell)
Microsoft .NET Framework
using System;
using System.Net;
using System.IO;
using System.Text;
namespace ConsoleApplication1
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
WebResponse webResponse = null;
NetworkCredential credentials = new NetworkCredential();
credentials.UserName = "chris_gambrell@us.ibm.com";
credentials.Password = "passw0rd";
string bookmark =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<entry xmlns=\"http://www.w3.org/2005/Atom\">" +
"<author><name>Author</name></author>" +
"<title>The Lotus Connections Page</title>" +
"<content type=
\"html\"><![CDATA[I posted this from C#]]></content>" +
"<category scheme=\"http://www.ibm.com/xmlns/prod/sn/type\" term=
\"bookmark\" />" +
"<category term=\"lotus\" />" +
"<category term=\"connections\" />" +
"<category term=\"50WaysToLeaveYourBookmark\" />" +
"<link href=\"http://www.ibm.com/lotus/connections\" />" +
"</entry>";
try
{
WebRequest request = WebRequest.Create
("https://dogear.tap.ibm.com/api/app?email=chris_gambrell@us.ibm.com");
request.Method = "POST";
byte[] byteArray = Encoding.UTF8.GetBytes(bookmark);
request.ContentType = "application/atom+xml";
request.ContentLength = byteArray.Length;
if (credentials != null)
request.Credentials = credentials;
Stream requestStream = request.GetRequestStream();
requestStream.Write(byteArray, 0, byteArray.Length);
requestStream.Close();
webResponse = request.GetResponse();
if (webResponse == null)
{
Console.WriteLine("response is null");
}
else
{
StreamReader responseReader = new StreamReader(webResponse.
GetResponseStream(), Encoding.UTF8);
Console.WriteLine("response = " + responseReader.ReadToEnd().Trim());
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e);
}
finally
{
if (webResponse != null)
{
webResponse.Close();
}
}
}
}
}
|
Groovy
Энди Пайпер (Andy Piper, http://andypiper.co.uk)
Apache Commons HttpClient - поставляется с Groovy, но для работы нужен commons-codec-1.3.jar в папке lib в корне Groovy
import groovy.xml.StreamingMarkupBuilder
import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.methods.*
def xml = new StreamingMarkupBuilder().bind{
mkp.yieldUnescaped '<?xml version="1.0" encoding="UTF-8"?>\n'
entry(xmlns:"http://www.w3.org/2005/Atom") {
author() {
name 'Andy Piper'
}
title 'The Lotus Connections Page'
content(type:'html') {
mkp.yieldUnescaped '<![CDATA['
mkp.yieldUnescaped 'I posted this from Groovy'
mkp.yieldUnescaped ']]>'
}
category(scheme:'http://www.ibm.com/xmlns/prod/sn/type', term:'bookmark')
category(term:'lotus')
category(term:'connections')
category(term:'50WaysToLeaveYourBookmark')
link(href:'http://www.ibm.com/lotus/connections')
}
}
println xml.toString()
username = "andy.piper@uk.ibm.com"
password = "passw0rd"
url = "https://dogear.tap.ibm.com/api/app?email=andy.piper@uk.ibm.com"
creds = new UsernamePasswordCredentials(username, password)
client = new HttpClient()
client.getState().setCredentials(null, null, creds)
post = new PostMethod(url)
post.setRequestHeader('Content-Type','application/atom+xml')
post.setRequestBody(xml.toString())
status = client.executeMethod( post )
println(status + "\n" + post.getResponseBodyAsString())
post.releaseConnection()
|
VBScript
Джефф Уилсон (Jeff K. Wilson)
url="https://dogear.tap.ibm.com/api/app"
entry = "<?xml version='1.0' encoding='utf-8'?>" &_
"<entry xmlns='http://www.w3.org/2005/Atom'>" &_
"<author><name>Author</name></author>" &_
"<title>The Lotus Connections Page</title>" &;_
"<content type='html'>I posted this from VBScript</content>" &_
"<category scheme='http://www.ibm.com/xmlns/prod/sn/type'
term='bookmark' />" &_
"<category term='lotus' />" &_
"<category term='connections' />" &_
"<category term='50WaysToLeaveYourBookmark' />" &_
"<link href='http://www.ibm.com/lotus/connections' />" &_
"</entry>"
Set objHTTP = CreateObject("Microsoft.XMLHTTP")
objHTTP.open "POST", url, False, "wilsonje@us.ibm.com", "passw0rd"
objHTTP.setRequestHeader "Content-Type", "application/atom+xml"
objHTTP.send entry
Document.Write objHTTP.statusText
Set objHTTP = Nothing
|
Python
Билл Грант (Bill Grant, billgrant.org)
base64 - модуль перекодировки
xml.dom.minidom - простой модуль для DOM
urllib2 - модуль заполнения url
import string
import base64
import xml.dom.minidom
import urllib2
from urllib2 import Request, urlopen, HTTPError, URLError
def create_bookmark(user, pw):
doc = xml.dom.minidom.Document()
doc.encoding = "utf-8"
entry = doc.createElement("entry")
entry.setAttribute("xmlns", "http://www.w3.org/2005/Atom")
doc.appendChild(entry)
# Author
# <author><name>Author</name></author>
author = doc.createElement("author")
entry.appendChild(author)
name = doc.createElement("name")
author.appendChild(name)
nameTXT = doc.createTextNode("Author")
name.appendChild(nameTXT)
# Title
# <title>The Lotus Connections Page</title>
title = doc.createElement("title")
entry.appendChild(title)
titleTXT = doc.createTextNode("The Lotus Connections Page")
title.appendChild(titleTXT)
# content
# <content type="html"><![CDATA[I posed this from <language>]]>
</content>
content = doc.createElement("content")
content.setAttribute("type", "html")
contentTXT = doc.createCDATASection("I posted this from Python")
content.appendChild(contentTXT)
entry.appendChild(content)
# category
# <category scheme="http://www.ibm.com/xmlns/prod/sn/type"
term="bookmark" />
category = doc.createElement("category")
category.setAttribute("scheme", "http://www.ibm.com/xmlns/prod/sn/type")
category.setAttribute("term", "bookmark")
entry.appendChild(category)
# category: tags
# <category term="lotus" />
# <category term="connections" />
# <category term="50WaysToLeaveYourBookmark" />
categoryTerm1 = doc.createElement("category")
categoryTerm1.setAttribute("term", "lotus")
entry.appendChild(categoryTerm1)
categoryTerm2 = doc.createElement("category")
categoryTerm2.setAttribute("term", "connections")
entry.appendChild(categoryTerm2)
categoryTerm3 = doc.createElement("category")
categoryTerm3.setAttribute("term", "50WaysToLeaveYourBookmark")
entry.appendChild(categoryTerm3)
# link
# <link href="http://www.ibm.com/lotus/connections" />
link = doc.createElement("link")
link.setAttribute("href", "http://www.ibm.com/lotus/connections")
entry.appendChild(link)
theData = doc.toxml("utf-8")
# headers
# Host: www.company.com
# Content-Type: application/atom+xml
# Authorization: Basic RG9uIFF1aXhvdGU6Um9jaW5hbnRl
theRequest = urllib2.Request("https://dogear.tap.ibm.com/api/app", theData)
theRequest.add_header("Host", "dogear.tap.ibm.com") # dogear.tap.ibm.com
theRequest.add_header("Content-Type", "application/atom+xml")
theRequest.add_header("Authorization",
string.strip("Basic " + base64.encodestring("%s:%s" % (user, pw))))
try:
theResponse = urllib2.urlopen(theRequest)
except HTTPError, e:
if (e.code == 201):
print "Bookmark created successfully."
else:
print "Bookmark was not created. (" + str(e.code) + ")"
if __name__ == '__main__':
create_bookmark("myemail@us.ibm.com", "mypassword")
|
Мы не получили желаемых 50 вариантов, но и 18 примеров показывают разнообразие способов доступа к API сервера Dogear, основанного на AtomPub. Авторы доказали, что сделать закладку на сервере возможно в разных языках и технологиях.
Мы видим, что одни авторы применяют утилиты командной строки (такие как cURL или wget), другие используют библиотеки для работы с HTTP, третьи почти не используют сторонних библиотек. Если вы хотите поближе познакомиться с Dogear, посетите Lotus Greenhouse (см. ссылку в разделе Ресурсы).
Научиться
-
Оригинал статьи: "
Fifty ways to leave your bookmark: An experiment in social authoring" (EN).
-
Прочитайте статью developerWorks "
Развёртывание
IBM Lotus Connections: Интеграция с другими системами" (EN).
-
Посетите страницу developerWorks Lotus
Connections (EN).
-
Посетите Lotus Greenhouse для доступа к работающему
серверу Dogear (EN).
-
Прочитайте Обзор Lotus
Connections V1.0 (EN).
-
Обратитесь к странице документации
Lotus Connections для получения детальной информации по установке, настройке и администрированию Lotus Connections (EN).
-
Узнайте больше об Atom Syndication Format и Publishing Protocol (EN).
Обсудить
- Примите участие в обсуждении материала на форуме.
-
Участвуйте в блоге команды Lotus на developerWorks (EN).