大的方向上说,从Picasa服务器上取数据,有两种方式,一种是使用Google已经开放的各种语言的API,可以在页面http://code.google.com/apis/picasaweb/developers_guide_protocol.html找到很多相关的信息。另一种方式便是使用最朴素的网络请求方式来自己构造请求并解析回传的数据。

由于Picasa只提供了Java,.NET,Python和PHP的接口,而Gadget目前只能使用JavaScript,因此我们只能使用朴素方式。

继续第三节的路子,仍然使用XmlHttpRequest向Picasa服务发起请求,也要处理好四部分信息。

请求发向哪个URL为了获取Picasa的相册信息,要向http://picasaweb.google.com/data/feed/api/user/default发请求,这个URL其实可以有很多变化的地方。例如user/default这个地方是请求所附token所属的用户相册信息,这里当然可以明确的指定用户名。”api”可以换成”base”,这个将影响回传数据的格式,但Goolge推荐使用api而不是base。

请求的类型:我们是要索取数据,因此这是一个查询的动作,应该使用GET。

请求头:只需要把token放进去就好。这样来放:

xhRequest.setRequestHeader('Authorization','GoogleLogin auth=+ token);

消息体:对于我们查询相册的请求,不需要任何的消息体。

具体的代码都在Main.prototype.fetchAlbumsInfo()函数中,就像这样:


Main.prototype.fetchAlbumsInfo=function() {
    
var url="http://picasaweb.google.com/data/feed/api/user/default";
    
var token=options.getValue("token");
    xhRequest
= createXhr();
    xhRequest.open(
"GET", url, true);
    xhRequest.setRequestHeader('Authorization','GoogleLogin auth
=+ token);
    xhRequest.send(
null);
    xhRequest.onreadystatechange 
=function(){
        
if (!xhRequest) {
            
return;
        }
        
if (xhRequest.readyState != 4) {
            
return;
        }
        main.albums
=parseAlbumFeed(xhRequest.responseText);
        main.fetchAlbumThumbnail();
    }
};

最后两个函数是下一步要做的工作:解析回传的相册数据,并下载每个相册的缩略图。

 

要想解析回传数据,首先得知道回传的数据是什么。你可以把这些数据打印出来看看,应该是类似下面的样子:

clip_image001

怎么,看着有点眼熟?没错,这个回传数据所使用的格式正是标准的Atom Feed(更多的描述可以参考W3C的标准和下面的链接:http://code.google.com/intl/zh-CN/apis/picasaweb/developers_guide_protocol.html)。

可以根据Atom Feed的格式来编写我们解析回传数据的函数parseAlbumFeed(),这个函数的作用是从回传的xml数据中找出我们关心的几样东西:该用户目前拥有的所有的相册信息,包括每个相册的标题,描述,访问权限以及缩略图的地址。找出这些信息以后,将会拼成一个包含相册(Album)的数组作为函数返回值。

具体代码如下:


function parseAlbumFeed(response) {
  
var doc = createDomDocument();
  doc.loadXML(response);
  
  
//用户已经建立过的相册集合,函数的返回值
  var albums = [];

  
var entryElements = doc.getElementsByTagName('entry');
  
//具体处理每个Album的信息
  for (var i = 0; i < entryElements.length; i++) {
    
var entry = entryElements[i];
    
var album=new Album();

    
//相册标题
    album.title=entry.getElementsByTagName('title')[0].text;

    
//相册描述
    album.summary=entry.getElementsByTagName('summary')[0].text;

    
//相册的访问权限
    album.access=entry.getElementsByTagName('gphoto:access')[0].text;

    
//相册的缩略图
    var thumbnail=entry.getElementsByTagName('media:thumbnail')[0];
    album.thumbnail
=new Thumbnail(thumbnail.getAttribute('url'));
    albums.push(album);
  }

  
return albums;
};

这个函数中用到了一些我们还没有新建的类,相册(Album)以及缩略图(Thumbnail)。这些类的声明可以放在一个新的名为album.js的文件中,并在我们整个Gadget的main.xml文件中指名要导入它。因此main.xml的最后几行应该看上去是这个样子:


  <script src="album.js" />
  
<script src="main.js" />
</view>

而album.js的内容大体如下:


function Album() {
  
this.title = "";
  
this.summary="";
  
this.access="";
  
this.thumbnail=#ff0000;
}

function Thumbnail(url) {
  
this.url = url;
  
this.width = 40;
  
this.height = 40;
  
this.src = undefined;  // XML response stream
}

最后还要在main.js里面添加一个函数createDomDocument(),用来提供一个DOM对象供我们解析XML用。代码如下:


function createDomDocument() {
  
var doc = new DOMDocument();

  
try {
    doc.resolveExternals 
= false;
    doc.validateOnParse 
= false;
    doc.setProperty('ProhibitDTD', 
false);
  } 
catch(e) {
    debug.warning('Could not set MS specific properties.');
  }
  
return doc;
}

下一节来说说怎么取得相册的缩略图并显示在Gadget的界面中。