2013-03-03 18 views
3

我試圖使用request.el與Stack Exchange API獲取站點列表(列表的列表)。Emacs中的JSON請求,階段2:獲取項目集合

我在製作an Emacs major mode for Stack Exchange,所以這對Emacs用戶來說有一些很好的潛在收益。 ;)(因爲我標記了elisp,我假設這就是你們中的很多人。)

要做到這一點,一個根本的必要性是爲JSON提出請求,然後查看返回的站點列表。該StackExchange API提供的/sites資源,該資源的請求返回site對象,像這樣的集合:

{ 
    "items": [ 
    { 
     "site_type": "main_site", 
     "name": "Stack Overflow", 
     "logo_url": "http://cdn.sstatic.net/stackoverflow/img/logo.png", 
     "api_site_parameter": "stackoverflow", 
     "site_url": "http://stackoverflow.com", 
     "audience": "professional and enthusiast programmers", 
     "icon_url": "http://cdn.sstatic.net/stackoverflow/img/apple-touch-icon.png", 
     "aliases": [ 
     "http://www.stackoverflow.com" 
     ], 
     "site_state": "normal", 
     "styling": { 
     "link_color": "#0077CC", 
     "tag_foreground_color": "#3E6D8E", 
     "tag_background_color": "#E0EAF1" 
     }, 
     "launch_date": 1221436800, 
     "favicon_url": "http://cdn.sstatic.net/stackoverflow/img/favicon.ico", 
     "related_sites": [ 
     { 
      "name": "Stack Overflow Chat", 
      "site_url": "http://chat.stackoverflow.com", 
      "relation": "chat" 
     } 
     ], 
     "markdown_extensions": [ 
     "Prettify" 
     ], 
     "high_resolution_icon_url": "http://cdn.sstatic.net/stackoverflow/img/[email protected]" 
    }, 
    { 
     "site_type": "main_site", 
     "name": "Server Fault", 
     "logo_url": "http://cdn.sstatic.net/serverfault/img/logo.png", 
     "api_site_parameter": "serverfault", 
     "site_url": "http://serverfault.com", 
     "audience": "professional system and network administrators", 
     "icon_url": "http://cdn.sstatic.net/serverfault/img/apple-touch-icon.png", 
     ... 
    }, 
    { 
     "site_type": "main_site", 
     "name": "Super User", 
     ... 
    { 
     "site_type": "main_site", 
     "name": "Meta Stack Overflow", 
     ... 
    } 
    ... 
} 

我想盡量減少我做出的API調用的次數和檢索所有這些,將它們放置在一個數據結構中,以便稍後能夠理解它。

我試圖改編我在這裏找到的可愛解決方案之一,Making JSON requests within Emacs,以適合我需要做的事情。它使用tkf中的request.el庫。

的例子TKF給了我能夠採取在網站上最活躍的問題,並使用json-read,這實質上是將一個物體到一個列表抓住它titletags性能。此嘗試基於該解決方案:

(request 
"https://api.stackexchange.com/2.1/sites" 
:parser 'buffer-string 
:success (function* 
     (lambda (&key data &allow-other-keys) 
     (let* ((items (assoc-default 'items data)) 
      (names (mapcar (lambda (item) (assoc-default 'name  item)) items)) 
      (launches (mapcar (lambda (item) (assoc-default 'launch-date item)) items))) 
      (mapcar* (lambda (name launch) 
       (message "name:`%s` launch:`%s`" name launch)) 
      names 
      launches))))) 

...但似乎完全無效。其他例子完美地工作,所以這是我的用法錯誤。

request.el可以從MELPA軟件包倉庫下載,據我所知,需要curl正確運行(我有)。

我懷疑問題出在我的mapcar*使用(或其製劑),在下​​面做工作按預期:

(mapcar* (lambda (a b) (insert a) (insert b)) '(1 2 3) '(4 5 6)) 

我知道這個帖子很長,但我想提供儘可能多的信息盡我所能。

回答

0

你幾乎在那裏。這一次對我的作品:

(request 
"https://api.stackexchange.com/2.1/sites" 
:parser 'json-read 
:success (function* 
     (lambda (&key data &allow-other-keys) 
     (let* ((items (assoc-default 'items data)) 
      (names (mapcar (lambda (item) (assoc-default 'name  item)) items)) 
      (launches (mapcar (lambda (item) (assoc-default 'launch_date item)) items))) 
      (mapcar* (lambda (name launch) 
       (message "name:`%s` launch:`%s`" name launch)) 
      names 
      launches))))) 

兩個變化:1,使用json-read代替buffer-string的解析器的說法。 2.使用launch_date而不是launch-date作爲alist的關鍵。

+0

哦,天哪,我忘了我已經改變了解析器的功能。再次感謝@tkf!但有一個小問題:每次執行'request'時,都會出現一條消息:''[cl-struct-request-response nil nil nil nil nil nil'https://api.stackexchange.com/2.1/sites「nil :解析器json-read:成功(lambda(&rest -cl-rest--)「 (fn&key DATA&allow-other-keys)」(let * ...)):error(closure(t )(&rest args)(apply ... ... args)):url「https://api.stackexchange.com/2.1/sites」:response#0)# nil nil .. 。]'「 - 我做錯了什麼,或者這是正常的? – 2013-03-04 09:08:03

+1

如果您使用正常的「C-x C-e」或「C-M-x」來評估表達式。 Emacs只是打印返回的值。 – tkf 2013-03-04 09:14:10