大的方向上說,從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的界面中。